如何使用NAudio将淡出正确写入WAV文件? [英] How to properly write a fade-out to a WAV file using NAudio?

查看:435
本文介绍了如何使用NAudio将淡出正确写入WAV文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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));

但是,这导致波形编写器仅写最后两秒钟这是有道理的,所以我尝试使用

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文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆