如何使用NAudio将3个wav文件加入到C#中有3个通道的单个文件中?

时间:2011-08-05 20:35:06

标签: .net audio naudio

使用C#和NAudio,我有三个波形文件,我想加入一个有三个通道的波形文件,每个通道对应三个输入文件中的一个。此外,我希望每个wave文件中的音频剪辑从最终流中的不同点开始。例如,如果三个波形文件的长度是3秒,5秒。分别为2秒,输出波形文件长10秒......

  • 通道1包含来自文件1的3秒声音,然后是7 沉默的几秒钟。

  • 频道2包含3秒的静音,然后是5秒钟 来自文件2的声音,然后是2秒的沉默。

  • 频道3包含8秒的静音,然后是2秒 来自文件3的声音。

我一直在尝试为每个文件创建一个WaveChannel32实例,然后使用WaveOffsetStream类,但我对这类事情不熟悉并且我没有取得多大成功。

有人有任何建议吗?

1 个答案:

答案 0 :(得分:2)

您可以通过编写自己的自定义IWaveProvider / WaveStream来完成此操作,其输出WaveFormat有三个通道。它包含对三个输入文件中的每个文件的引用。 然后,在Read方法中,它计算出所请求的样本数,并从每个源文件中读取相应的数字。然后需要交错样本 - 一个来自第一个文件,一个来自第二个,一个来自第三个。为了延迟你只需将零填入。

这是一些未经测试的示例代码,它们从各种源文件中交错(必须具有相同的位深度和采样率),这有望为您指明正确的方向:

int Read(byte[] buffer, int offset, int bytesRequired)
{
    int bytesPerSample = this.WaveFormat.BitsPerSample / 8;
    int samplesRequired = bytesRequired / bytesPerSample;
    int channels = this.WaveFormat.Channels; // 3
    int samplesPerChannel = samplesRequired / channels;
    byte[] readBuffer = new byte[samplesPerChannel * bytesPerSample];
    for (int channel = 0; channel < channels; channel++)
    {
        int read = inputs[channel].Read(readBuffer, 0, samplesPerChannel * bytesPerSample);
        int outOffset = offset + channel * bytesPerSample;
        for (int i = 0; i < read; i += bytesPerSample)
        {
             Array.Copy(readBuffer, i, buffer, outOffset, bytesPerSample);
             outOffset += channels * bytesPerSample;
        } 
    }
}

为了防止代码变得过于复杂,您可以通过创建另一个派生的IWaveProvider / WaveStream来进行静默插入,其Read方法返回适当的静默量,然后从输入文件返回实际数据。然后,这可以用作交错WaveStream的输入。