I'm using NAudio to convert & trim some audio files, and I'm trying to add a fade-out to the last few seconds of each file.
I have checked this question, this, and this, but all the answers are talking about playing the wav file with fade, while I need to actually write that fade to an output file.
So, is there any way to do this using NAudio? If not, I'm open to other suggestions.
Edit: This is what I've tried:
private void PerformFadeOut(string inputPath, string outputPath)
{
WaveFileReader waveSource = new WaveFileReader(inputPath);
ISampleProvider sampleSource = waveSource.ToSampleProvider();
OffsetSampleProvider fadeOutSource = new OffsetSampleProvider(sampleSource);
// Assume the length of the audio file is 122 seconds.
fadeOutSource.SkipOver = TimeSpan.FromSeconds(120); // Hard-coded values for brevity
// Two seconds fade
var fadeOut = new FadeInOutSampleProvider(fadeOutSource);
fadeOut.BeginFadeOut(2000);
Player = new WaveOut();
Player.Init(fadeOut);
Player.Play();
}
When I play the audio after applying the fade using Player.Play()
-as shown in the method above-, it works perfectly as expected, and I can hear the fade. Now, I would like to export this result to an output WAV file.
I tried doing that by adding the following line:
WaveFileWriter.CreateWaveFile(outputPath, waveSource);
However, the output file doesn't have any fade applied to it. So, what am I missing here?
Okay, let's wrap everything up in case someone encounters the same issue in the future:
With the great help of @yms, I managed to write the fade to a file by using:
But that caused the wave writer to only write the last two seconds which makes sense, so I tried using the
DelayFadeOutSampleProvider
class instead ofFadeInOutSampleProvider
. With that I was able to write the whole file, but it ended up causing the fading to start in a wrong position (it's more obvious when saving though. Not when playing).I generated a 10 seconds wav file with Audacity, and used the following method for testing:
Here's the file, before & after writing the fade-out:
As shown above, the fade-out doesn't start at the right position.
After some investigation in the
DelayFadeOutSampleProvider
, I found a bug in theRead
method, so I modified it like this:And now everything works just fine.
Here's my fork of the whole class if someone is interested, and I already asked the author (@mark-heath) to update the original gist with this fix.
You original code was using the original
waveSource
as input, which is why you had no fade.The following alternative uses the
fadeOut
object:The signature of
CreateWaveFile16
would be:This can be seen in the source code of the class WaveFileWriter.
Another alternative is to use the class SampleToWaveProvider and covert your
fadeOut
object into anIWaveProvider
, and that allows you to use the regularCreateWaveFile
method.As you know, in all cases your output file will only contain the last k seconds corresponding to the fadeout, a different class is needed if you want the whole file with a fadeout.