gpt4 book ai didi

c# - 如何使用 NAudio 正确地将淡出写入 WAV 文件?

转载 作者:行者123 更新时间:2023-11-30 23:09:17 29 4
gpt4 key购买 nike

我正在使用 NAudio 转换和修剪一些音频文件,我正在尝试为每个文件的最后几秒添加淡出效果。

我检查了this question , this , 和 this ,但所有答案都在谈论使用淡入淡出播放 wav 文件,而我需要实际将淡入淡出写入输出文件。

那么,有没有办法使用 NAudio 来做到这一点?如果没有,我愿意接受其他建议。


编辑:这是我试过的:

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 文件。

我尝试通过添加以下行来做到这一点:

WaveFileWriter.CreateWaveFile(outputPath, waveSource);

但是,输出文件没有应用任何淡入淡出。那么,我在这里缺少什么?

最佳答案

好的,让我们总结一下,以防将来有人遇到同样的问题:

在@yms 的大力帮助下,我设法使用以下方法将淡入淡出写入文件:

WaveFileWriter.CreateWaveFile(outputPath, new SampleToWaveProvider(fadeOut));

但这导致 wave writer 只写最后两秒这是有道理的,所以我尝试使用 DelayFadeOutSampleProvider类而不是 FadeInOutSampleProvider。这样我就可以写入整个文件,但最终会导致淡入淡出在错误的位置开始(不过保存时更明显。播放时) .

我用Audacity生成了一个10秒的wav文件,用下面的方法进行测试:

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));
}
}

这是文件,在编写淡出之前和之后:

Before & after writing the fade-out

如上所示,淡出没有从正确的位置开始。

经过对DelayFadeOutSampleProvider的一些调查,我发现Read方法有一个错误,所以我修改它如下:

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;
}

现在一切正常。

Here's my fork如果有人有兴趣,我已经要求作者 (@mark-heath) 使用此修复程序更新原始要点。

关于c# - 如何使用 NAudio 正确地将淡出写入 WAV 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45892543/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com