使用C#和NAudio,我有三个波形文件,我想加入一个有三个通道的波形文件,每个通道对应三个输入文件中的一个。此外,我希望每个wave文件中的音频剪辑从最终流中的不同点开始。例如,如果三个波形文件的长度是3秒,5秒。分别为2秒,输出波形文件长10秒......
通道1包含来自文件1的3秒声音,然后是7 沉默的几秒钟。
频道2包含3秒的静音,然后是5秒钟 来自文件2的声音,然后是2秒的沉默。
频道3包含8秒的静音,然后是2秒 来自文件3的声音。
我一直在尝试为每个文件创建一个WaveChannel32实例,然后使用WaveOffsetStream类,但我对这类事情不熟悉并且我没有取得多大成功。
有人有任何建议吗?
答案 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的输入。