惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Security Blog
Microsoft Security Blog
P
Proofpoint News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
F
Full Disclosure
Martin Fowler
Martin Fowler
G
Google Developers Blog
F
Fortinet All Blogs
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
Hacker News: Ask HN
Hacker News: Ask HN
T
Tailwind CSS Blog
Cloudbric
Cloudbric
U
Unit 42
MyScale Blog
MyScale Blog
TaoSecurity Blog
TaoSecurity Blog
T
The Blog of Author Tim Ferriss
博客园 - 司徒正美
博客园 - Franky
AI
AI
爱范儿
爱范儿
L
LangChain Blog
小众软件
小众软件
D
DataBreaches.Net
M
MIT News - Artificial intelligence
GbyAI
GbyAI
Y
Y Combinator Blog
有赞技术团队
有赞技术团队
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Cloudflare Blog
Help Net Security
Help Net Security
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
P
Privacy International News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
A
About on SuperTechFans
Scott Helme
Scott Helme
The GitHub Blog
The GitHub Blog
V
V2EX
N
Netflix TechBlog - Medium
S
Security Affairs
Security Archives - TechRepublic
Security Archives - TechRepublic
H
Heimdal Security Blog
WordPress大学
WordPress大学

博客园 - 云梦鸿

Winform界面显示的“语言”切换 Linux使用笔记 QT 练习笔记 QT 读写配置文件(*.INI) ubuntu 配置网口静态IP C++ 读写文件 C#编写Windows服务 C#代码计算农历(日期、节气、节日) 中标麒麟,使用笔记 关于无密码访问 Windows7/10 的远程桌面/共享 颜色转换:HSB颜色 与 RGB颜色 QT 信号(槽)绑定的使用_connect QT 给控件(Label)设置显示图片 QT 打包Windows应用程序(*.exe) C#程序执行Python脚本 C#监控U盘插拔 C# AnimateWindow 设置窗体动画 C# GetWindowRect 获取窗体在屏幕中的位置信息 VS2019错误:CS8370 的处理方法
C# 创建音频WAVE文件头信息(*.wav)
云梦鸿 · 2020-12-01 · via 博客园 - 云梦鸿

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