2012-07-29 80 views
3

我有一个RAW音频文件,它由几个连接的较小的WAV文件组成。我可以在Sound Forge中打开并播放该文件为48,000,8位PCM,带符号单声道。删除几个WAV文件的头文件,然后将其余数据连接成一个RAW文件

我想在C#中做的事情是用程序在文件中用相同或更小长度的新数据覆盖每个单独的WAV,我认为我相当接近能够做到这一点。我可以在RAW文件上做一个File.ReadAllBytes,遍历字节数组,并确定每个WAV的开始和结束位置。然后,我在PC上选取新的WAV文件,删除标题,并将其余数据写入我的RAW文件。如果新的WAV比目标小,我用0填充差值。

但是,当我在上面提到的设置中打开Sound Forge中的新文件时,我的所有WAV看起来都比实际的“圣诞树”形状更像固体块,并且它们都会大声和失真。第一次经历这个之后,我发现所有新的源WAV都是41,000,16位PCM,有符号立体声格式。我以这种格式打开了我新创建的RAW文件,它看起来很好。

我想我必须将我所有的新WAV转换为48,000,8位PCM,签名,单声道,第一,然后运行应用程序将它们复制到RAW文件中。我使用NAudio编写了一些代码,用于在将数据复制到RAW文件之前对文件进行转换,而且我仍然遇到同样的问题。我也试着先在Sound Forge中手动转换每个新的WAV,但仍然有同样的问题。

我在这里错过了什么?谢谢。

+0

你可能意味着44,100而不是41,000。 – 2012-07-29 22:53:10

+0

感谢您的建议。我明白了这一点。这是有符号/无符号音频文件的区别。我做了一些Google搜索,并且读取默认情况下8位PCM WAV文件未签名。为了解决这个问题,使用NAudio将文件转换为8位后,我循环遍历字节并从每个字节中减去128。我随心所欲地做了这件事。我相信有更好的方法来做到这一点。 – user1561302 2012-07-30 05:45:26

回答

1

此代码执行您所描述的操作(不带填充)。它打开mainFile并在指定位置插入另一个文件。如果这两个文件具有相同的格式,它将工作得很好。

public void InsertWave(string mainFile, string insertFile, long position) 
{ 
    byte[] data = File.ReadAllBytes(insertFile); 

    using (FileStream main = File.OpenWrite(mainFile)) 
    { 
     main.Seek(position, SeekOrigin.Begin); 
     main.Write(data, 0, data.Length); 
     main.Close(); 
    } 
} 

如果这两个文件都是48,000赫兹,8位PCM,带符号,单声道你不能做任何错误。 但是,如果一个文件是单声道而另一个是立体声,或者如果一个是8位而另一个是16位,则输出将失真。

它甚至不关心文件实际使用的格式。只要两者具有相同的格式,并且您的位置是样本大小的倍数,您将始终以有效的波形文件结束。

因此,如果您的输出失真,那么这些文件很可能具有不同的格式。 如果您将立体声转换为单声道,您还必须意识到您不能混合两个声道。您必须将音量降低6dB以保持相同的音量。

+0

您的位置实际上必须是框架大小的倍数,而不是样本大小。此外,您必须降低水平约6dB,而不是3dB。更准确地说,你必须降低一半的水平,以确保你没有削减,6dB不完全是一半。 – 2012-07-29 22:56:40

+0

你是对的:我已经把3dB改成了6dB。 我知道,在多通道文件中,您需要多倍的帧大小才能让所有内容都正确无误。然而,重点是对于有效的文件(即不失真),样本量的倍数足够好(通道将被交换)。 – pescolino 2012-07-29 23:09:25

相关问题