问题描述
我正在使用NAudio转换&修剪一些音频文件,然后尝试在每个文件的最后几秒钟添加淡入淡出效果.
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.
我已经检查了这个问题,和此,但是所有答案都在讨论淡化播放wav文件,而我实际上需要将该淡入淡写到输出文件中.
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.
那么,有什么办法可以使用NAudio做到这一点?如果没有,我愿意接受其他建议.
So, is there any way to do this using NAudio? If not, I'm open to other suggestions.
编辑:这是我尝试过的操作:
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();
}
当我使用上述方法所示的Player.Play()
-应用淡入淡出效果后播放音频-时,它可以正常工作,并且可以听到淡入淡出的声音.现在,我想将此结果导出到输出WAV文件.
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?
推荐答案
好吧,让我们总结一下,以防将来有人遇到相同的问题:
在@yms的大力帮助下,我设法使用以下方法将淡入度写入文件:
With the great help of @yms, I managed to write the fade to a file by using:
WaveFileWriter.CreateWaveFile(outputPath, new SampleToWaveProvider(fadeOut));
但是,这导致波形编写器仅写最后两秒钟这是有道理的,所以我尝试使用 DelayFadeOutSampleProvider
类而不是FadeInOutSampleProvider
.这样我就可以写入整个文件,但是最终导致淡入淡出从错误的位置开始(保存时更明显.播放时 Not )
But that caused the wave writer to only write the last two seconds which makes sense, so I tried using the DelayFadeOutSampleProvider
class instead of FadeInOutSampleProvider
. 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).
我用Audacity生成了一个10秒的wav文件,并使用以下方法进行测试:
I generated a 10 seconds wav file with Audacity, and used the following method for testing:
private static void PerformFadeOut(string inputPath, string outputPath, bool playNoSave = false)
{
WaveFileReader waveSource = new WaveFileReader(inputPath);
ISampleProvider sampleSource = waveSource.ToSampleProvider();
// Two seconds fade
var fadeOut = new DelayFadeOutSampleProvider(sampleSource);
fadeOut.BeginFadeOut(8000, 2000);
if(playNoSave)
{
// Here the fade is played exactly where expected (@00:08)
var player = new WaveOut();
player.Init(fadeOut);
player.Play();
}
else
{
// But when saving, the fade is applied @00:04!
WaveFileWriter.CreateWaveFile(outputPath, new SampleToWaveProvider(fadeOut));
}
}
这是&之前的文件写入淡出后:
Here's the file, before & after writing the fade-out:
如上所示,淡入不是从正确的位置开始.
As shown above, the fade-out doesn't start at the right position.
在DelayFadeOutSampleProvider
中进行了一些调查之后,我发现了Read
方法中的错误,因此我对此进行了修改:
After some investigation in the DelayFadeOutSampleProvider
, I found a bug in the Read
method, so I modified it like this:
public int Read(float[] buffer, int offset, int count)
{
int sourceSamplesRead = source.Read(buffer, offset, count);
lock (lockObject)
{
if (fadeOutDelaySamples > 0)
{
int oldFadeOutDelayPos = fadeOutDelayPosition;
fadeOutDelayPosition += sourceSamplesRead / WaveFormat.Channels;
if (fadeOutDelayPosition > fadeOutDelaySamples)
{
int normalSamples = (fadeOutDelaySamples - oldFadeOutDelayPos) * WaveFormat.Channels;
int fadeOutSamples = (fadeOutDelayPosition - fadeOutDelaySamples) * WaveFormat.Channels;
// apply the fade-out only to the samples after fadeOutDelayPosition
FadeOut(buffer, offset + normalSamples, fadeOutSamples);
fadeOutDelaySamples = 0;
fadeState = FadeState.FadingOut;
return sourceSamplesRead;
}
}
if (fadeState == FadeState.FadingIn)
{
FadeIn(buffer, offset, sourceSamplesRead);
}
else if (fadeState == FadeState.FadingOut)
{
FadeOut(buffer, offset, sourceSamplesRead);
}
else if (fadeState == FadeState.Silence)
{
ClearBuffer(buffer, offset, count);
}
}
return sourceSamplesRead;
}
现在一切正常.
如果有人感兴趣,这是我全班的叉子要求作者(@ mark-heath)使用此修复程序更新原始要点.
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.
这篇关于如何使用NAudio将淡出正确写入WAV文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!