Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用NAudio正确地将淡出写入WAV文件?_C#_.net_Audio_Wav_Naudio - Fatal编程技术网

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

C# 如何使用NAudio正确地将淡出写入WAV文件?,c#,.net,audio,wav,naudio,C#,.net,Audio,Wav,Naudio,我正在使用NAudio转换和修剪一些音频文件,并尝试在每个文件的最后几秒钟添加淡出 我已经检查了,但是所有的答案都是关于播放带有淡入淡出的wav文件,而我实际上需要将淡入淡出写入输出文件 那么,有没有办法用NAudio做到这一点?如果没有,我愿意接受其他建议 编辑:这是我尝试过的: private void PerformFadeOut(string inputPath, string outputPath) { WaveFileReader waveSource = new Wave

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

我已经检查了,但是所有的答案都是关于播放带有淡入淡出的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编写器只在最后两秒钟编写,这是有意义的,因此我尝试使用该类而不是
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));
    }
}
以下是写入淡出之前和之后的文件:

如上所示,淡出不会从正确的位置开始

DelayFadeOutSampleProvider
中进行了一些调查之后,我在
Read
方法中发现了一个bug,因此我对其进行了如下修改:

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)用这个补丁更新原始要点。

您的原始代码使用原始
波源作为输入,这就是您没有褪色的原因

以下备选方案使用淡出对象
fadeOut

WaveFileWriter.CreateWaveFile16(outputPath, fadeOut);
CreateWaveFile16
的签名为:

public static void CreateWaveFile16(string filename, ISampleProvider sourceProvider)
这一点可以从中看出

另一种选择是使用该类并将您的
fadeOut
对象转换为
IWaveProvider
,这允许您使用常规的
CreateWaveFile
方法

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

正如您所知,在所有情况下,您的输出文件将只包含与淡出相对应的最后k秒,如果您希望整个文件具有淡出,则需要另一个类。

是否尝试使用WaveFileWriter.CreateWaveFile(输出路径,淡出);相反?@yms
CreateWaveFile
方法需要第二个
IWaveProvider
类型的参数。显然,
FadeInutsSampleProvider
类没有实现这个接口,因此无法强制转换。然后是WaveFileWriter.CreateWaveFile16(outputPath,fadeOut)或WaveFileWriter.CreateWaveFile(outputPath,new SampleToWaveProvider(fadeOut))。请参见此处:@yms
CreateWaveFile16
也不起作用,因为它需要相同类型的参数。但第二个建议可能确实有效。让我试试看.“它需要相同类型的参数”不,它不。。。至少在源代码中没有指出:publicstaticvoidcreatewavefile16(stringfilename,isampleprovidersourceprovider)非常感谢,您让我走上了正确的道路。我真的很感谢你的帮助。投票表决通过,一旦有可能,将授予赏金。@AhmedAbdelhameed我很高兴它起到了作用