为内存中的流创建有效的wav文件头

我有raw-headerless wav音频数据作为MemoryStream s。

 Stream rawAudioStream = Producer.GetRawAudioFileStream(...); 

我知道那些流数据格式:

 // WaveFormat(int rate, int bits, int channels); WaveFormat waveformat = new WaveFormat(8000, 16, 1); 

我想要的是以编程方式为这些内存流添加正确的头信息,而无需将它们写入物理文件。

我怎样才能做到这一点?

PS:我检查了NAudio库,但只找到了一种通过将流写入真实物理文件来创建标题的方法,这不适合我的情况

 var waveformat = new WaveFormat(8000,16,1); var reader = new RawSourceWaveStream(rawAudioMemStream, waveformat); using (var convertedStream = WaveFormatConversionStream.CreatePcmStream(reader)) { WaveFileWriter.CreateWaveFile(fileName, convertedStream); } rawAudioMemStream.Close(); 

下面的代码将Wav标头写入MemoryStream的开头。 这意味着您首先需要将标题写入流中,然后您可以编写样本。 否则,您的流开头的样本将被元数据覆盖,

 // totalSampleCount needs to be the combined count of samples of all channels. So if the left and right channels contain 1000 samples each, then totalSampleCount should be 2000. // isFloatingPoint should only be true if the audio data is in 32-bit floating-point format. private void WriteWavHeader(MemoryStream stream, bool isFloatingPoint, ushort channelCount, ushort bitDepth, int sampleRate, int totalSampleCount) { stream.Position = 0; // RIFF header. // Chunk ID. stream.Write(Encoding.ASCII.GetBytes("RIFF"), 0, 4); // Chunk size. stream.Write(BitConverter.GetBytes(((bitDepth / 8) * totalSampleCount) + 36), 0, 4); // Format. stream.Write(Encoding.ASCII.GetBytes("WAVE"), 0, 4); // Sub-chunk 1. // Sub-chunk 1 ID. stream.Write(Encoding.ASCII.GetBytes("fmt "), 0, 4); // Sub-chunk 1 size. stream.Write(BitConverter.GetBytes(16), 0, 4); // Audio format (floating point (3) or PCM (1)). Any other format indicates compression. stream.Write(BitConverter.GetBytes((ushort)(isFloatingPoint ? 3 : 1)), 0, 2); // Channels. stream.Write(BitConverter.GetBytes(channelCount), 0, 2); // Sample rate. stream.Write(BitConverter.GetBytes(sampleRate), 0, 4); // Bytes rate. stream.Write(BitConverter.GetBytes(sampleRate * channelCount * (bitDepth / 8)), 0, 4); // Block align. stream.Write(BitConverter.GetBytes((ushort)channelCount * (bitDepth / 8)), 0, 2); // Bits per sample. stream.Write(BitConverter.GetBytes(bitDepth), 0, 2); // Sub-chunk 2. // Sub-chunk 2 ID. stream.Write(Encoding.ASCII.GetBytes("data"), 0, 4); // Sub-chunk 2 size. stream.Write(BitConverter.GetBytes((bitDepth / 8) * totalSampleCount), 0, 4); }