C# 创建音频WAVE文件头信息(*.wav)

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)  感谢!!!

 

posted on 2020-12-01 21:06  云梦鸿  阅读(1236)  评论(0编辑  收藏  举报