3

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

  • 通道 1 包含文件 1 中 3 秒的声音,然后是 7 秒的静音。

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

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

我一直在尝试为每个文件创建一个 WaveChannel32 实例,然后使用 WaveOffsetStream 类,但我对这种事情很陌生,而且我没有取得太大的成功。

有人有什么建议吗?

4

1 回答 1

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 的输入。

于 2011-08-10T10:10:12.663 回答