C# 創建音頻WAVE文件頭信息(*.wav)
給一段音頻數據(AD采集值),創建一個wav格式文件頭信息,可以將它保存成音頻文件,使用播放器播放。
/// <summary>
/// 創建WAV音頻文件頭信息 /// </summary>
/// <param name="data_Len">音頻數據長度</param>
/// <param name="data_SoundCH">音頻聲道數</param>
/// <param name="data_Sample">采樣率,常見有:11025、22050、44100等</param>
/// <param name="data_SamplingBits">采樣位數,常見有:4、8、12、16、24、32</param>
/// <returns></returns>
private static byte[] CreateWaveFileHeader(int data_Len, int data_SoundCH, int data_Sample, int data_SamplingBits)
{ // WAV音頻文件頭信息
List<byte> WAV_HeaderInfo = new List<byte>(); // 長度應該是44個字節
WAV_HeaderInfo.AddRange(Encoding.ASCII.GetBytes("RIFF")); // 4個字節:固定格式,“RIFF”對應的ASCII碼,表明這個文件是有效的 "資源互換文件格式(Resources lnterchange File Format)"
WAV_HeaderInfo.AddRange(BitConverter.GetBytes(data_Len + 44 - 8)); // 4個字節:總長度-8字節,表明從此后面所有的數據長度,小端模式存儲數據
WAV_HeaderInfo.AddRange(Encoding.ASCII.GetBytes("WAVE")); // 4個字節:固定格式,“WAVE”對應的ASCII碼,表明這個文件的格式是WAV
WAV_HeaderInfo.AddRange(Encoding.ASCII.GetBytes("fmt ")); // 4個字節:固定格式,“fmt ”(有一個空格)對應的ASCII碼,它是一個格式塊標識
WAV_HeaderInfo.AddRange(BitConverter.GetBytes(16)); // 4個字節:fmt的數據塊的長度(如果沒有其他附加信息,通常為16),小端模式存儲數據
var fmt_Struct = new { PCM_Code = (short)1, // 4B,編碼格式代碼:常見WAV文件采用PCM脈沖編碼調制格式,通常為1。
SoundChannel = (short)data_SoundCH, // 2B,聲道數
SampleRate = (int)data_Sample, // 4B,沒個通道的采樣率:常見有:11025、22050、44100等
BytesPerSec = (int)(data_SamplingBits * data_Sample * data_SoundCH / 8), // 4B,數據傳輸速率 = 聲道數×采樣頻率×每樣本的數據位數/8。播放軟件利用此值可以估計緩沖區的大小。
BlockAlign = (short)(data_SamplingBits * data_SoundCH / 8), // 2B,采樣幀大小 = 聲道數×每樣本的數據位數/8。
SamplingBits = (short)data_SamplingBits, // 4B,每個采樣值(采樣本)的位數,常見有:4、8、12、16、24、32
}; // 依次寫入fmt數據塊的數據(默認長度為16)
WAV_HeaderInfo.AddRange(BitConverter.GetBytes(fmt_Struct.PCM_Code)); WAV_HeaderInfo.AddRange(BitConverter.GetBytes(fmt_Struct.SoundChannel)); WAV_HeaderInfo.AddRange(BitConverter.GetBytes(fmt_Struct.SampleRate)); WAV_HeaderInfo.AddRange(BitConverter.GetBytes(fmt_Struct.BytesPerSec)); WAV_HeaderInfo.AddRange(BitConverter.GetBytes(fmt_Struct.BlockAlign)); WAV_HeaderInfo.AddRange(BitConverter.GetBytes(fmt_Struct.SamplingBits)); /* 還 可以繼續寫入其他的擴展信息,那么fmt的長度計算要增加。*/ WAV_HeaderInfo.AddRange(Encoding.ASCII.GetBytes("data")); // 4個字節:固定格式,“data”對應的ASCII碼
WAV_HeaderInfo.AddRange(BitConverter.GetBytes(data_Len)); // 4個字節:正式音頻數據的長度。數據使用小端模式存放,如果是多聲道,則聲道數據交替存放。
/* 到這里文件頭信息填寫完成,通常情況下共44個字節*/
return WAV_HeaderInfo.ToArray(); }
那么,接下來就是將這個頭信息,寫在音頻數據最前面了
byte[] WAV_HEADER = CreateWaveFileHeader(data_Len, data_SoundCH, data_Sample, data_SamplingBits);
MemoryStream WAV_Stream = new MemoryStream(); WAV_Stream.Write(WAV_HEADER, 0, WAV_HEADER.Length); // 寫入頭信息 WAV_Stream.Write(data, 0, data_Len); // 寫入正式數據 // 可以直接播放流,也可以寫入文件中保存 FileStream WAV_FS = new FileStream("G:\\123.wav", FileMode.OpenOrCreate); WAV_Stream.WriteTo(WAV_FS); WAV_FS.Close();
以上,參考自:wav文件格式分析與詳解 - nigaopeng - 博客園 (cnblogs.com) 感謝!!!