文章目录

  • 第一个子chunk
  • 另一个子chunk
  • 实例:用C语言解析wav文件
  • 运行结果:
  • 通过WinHex验证结果


根据网络上的各种资料可以得知WAVE文件本质上就是一种RIFF格式,它可以抽象成一颗树(数据结构的一种)来看。

我们看到这张图上面,从上到下分别对应着二进制数据在文件中相对于起始位置的偏移量。每一个格子对应一个字段,field size表示每个字段所占据的大小,根据这个大小以及当前的偏移量,我们也可以计算出下一个字段的起始地址(偏移量)。

一个chunk结构其实就是三个部分,第一部分标识符用于说明这个chunk是存什么内容,第二部分是说明这个chunk的内容有多大,用于让程序知道如果要找到下一个chunk该把地址偏移多少去读取,第三部分则是实际内容

顶级chunk: 说明这个chunk是存什么内容

子chunk

第一个子chunk

Subchunk1ID 在WAV文件中恒定为fmt,表示该subchunk的内容为该WAV音频文件的一些元数据,即WAV音频的一些格式信息

AudioFormat这个字段一般为1,表示这个WAV音频为PCM编码

NumChannels则是该WAV音频文件的声道数量。1为单声道,2为双声道。

SampleRate 则为采样率

ByteRate 为数据传输速率。其值为:通道数*每秒数据位数*每样本的数据位数/8

BlockAlign 则是每个block的平均大小,它等于NumChannels * BitsPerSample/8,至于block是什么,以及它的计算公式是怎么得来的需要来看看另一个Subchunk。BitsPerSample则为每秒采样比特,有的地方称它为量化精度或者PCM位宽。

另一个子chunk

Subchunk2ID 是在WAV文件中恒定为data,即WAV音频文件的实际音频数据,里面存储的是音频的采样数据。但是我们的音频如果是双声道,那么实际上某一个采样时刻采样的数据是由左声道和右声道共同组成的。而这个共同组成的采样我们把他成为block。前面有讲到BlockAlign = NumChannels * BitsPerSample / 8,这个现在就很好理解了,至于为什么末尾要除以8,这是因为计算机中是以8个二进制数表示一个字节,所以要除以8来求出字节数。

音频的持续长度,我们可以通过Subchunk2Size除以ByteRate,也就是实际音频data的chunk总长度除以每秒字节数得到持续多少秒。

实例:用C语言解析wav文件

#include <stdio.h>
#include <stdint.h> /*struct类型里面我用的是uint32_t等类型,而不是传统的int,short等等这些类型是由stdint.h头文件提供*/
#include <stdlib.h>typedef struct wave_tag //声明结构体的相关参数 {char ChunkID[4]; // "RIFF"标志unsigned int ChunkSize; // 文件长度(WAVE文件的大小, 不含前8个字节)char Format[4]; // "WAVE"标志char SubChunk1ID[4]; // "fmt "标志unsigned long int SubChunk1Size; // 过渡字节(不定)unsigned short int AudioFormat; // 格式类别(10H为PCM格式的声音数据)unsigned short int NumChannels; // 通道数(单声道为1, 双声道为2)unsigned short int SampleRate; // 采样率(每秒样本数), 表示每个通道的播放速度unsigned int ByteRate; // 波形音频数据传输速率, 其值为:通道数*每秒数据位数*每样本的数据位数/8unsigned short int BlockAlign; // 每个样点的Byte数(按字节算), 其值为:通道数*每样本的数据位数/8unsigned short int BitsPerSample; // 每个样点的数据位数, 表示每个声道中各个样本的数据位数.char SubChunk2ID[4]; // 数据标记"data"unsigned long int SubChunk2Size; // 语音数据的长度} WAVE;int main(int argc, char *argv[]){FILE *fp;                      //定义指针型文件 WAVE wav;                     //调用结构体wav fp=fopen("E:\\test_wave\\2.wav","rb"); /*以二进制方式打开并读取(rb)wav文件,通常r是正常方式读取文件 */ fread(&wav, sizeof(WAVE), 1, fp);     //读取文件信息 //打印输出wave文件头的相关信息
printf("ChunkID=\t%c%c%c%c \n",wav.ChunkID[0],wav.ChunkID[1],wav.ChunkID[2],wav.ChunkID[3]); //输出"RIFF"标志printf("ChunkSize=\t%d\n",wav.ChunkSize); //输出文件长度,即WAVE文件的大小printf("Format=\t\t%c%c%c%c\n",wav.Format[0],wav.Format[1],wav.Format[2],wav.Format[3]);//输出"WAVE"标志 printf("SubChunk1ID=\t%c%c%c%c\n",wav.SubChunk1ID[0],wav.SubChunk1ID[1],wav.SubChunk1ID[2],wav.SubChunk1ID[3]);// 输出"fmt "标志printf("SubChunk1Size=\t%ld\n",wav.SubChunk1Size);// 输出过渡字节(不定)printf("AudioFormat=\t%x\n",wav.AudioFormat); // 输出格式类别(10H为PCM格式的声音数据)printf("NumChannels=\t%d\n",wav.NumChannels);//输出通道数 printf("SampleRate=\t%d\n",wav.SampleRate);//输出采样率 printf("ByteRate=\t%d\n",wav.ByteRate);// 输出波形音频数据传输速率printf("BlockAlign=\t%d\n",wav.BlockAlign);//输出每个样点的Byte数printf("BitsPerSample=\t%d\n",wav.BitsPerSample);// 输出每个样点的数据位数printf("SubChunk2ID=\t%c%c%c%c \n",wav.SubChunk2ID[0],wav.SubChunk2ID[1],wav.SubChunk2ID[2],wav.SubChunk2ID[3]);//输出data标志 printf("SubChunk2Size=\t%ld\n",wav.SubChunk2Size);//输出数据的长度 return 0;}

运行结果:

通过WinHex验证结果

WinHex 是一款以通用的 16 进制编辑器为核心,专门用来对付计算机取证、数据恢复、低级数据处理、以及 IT 安全性、各种日常紧急情况的高级工具: 用来检查和修复各种文件、恢复删除文件、硬盘损坏、数码相机卡损坏造成的数据丢失等。可进行 2 进制、16 进制 ASCII, Intel 16 进制, 和 Motorola S 转换。

WAV文件的二进制格式解析相关推荐

  1. 使用FFmpeg转换mp3或wav文件为pcm格式文件

    使用FFmpeg转换mp3或wav文件为pcm格式文件 由于项目开发中需要验证pcm格式音频的播放,可以使用FFmpeg进行转换 安装时这里推荐一个便捷方式,sudo apt install smpl ...

  2. js File文件转换为二进制格式和base64转换为图片

    // 图片转换为base64imageToBase64(img) {return new Promise((resolve) => {let reader = new FileReader(); ...

  3. Qt 之 WAV文件解析

    简介 最近看了一下Qt的处理音频方面的资料,本身利用QAudioInput 和 QAudioOutput 就可以实现录音和播放功能,代码也很简单,但是录音生成的文件并不能用播放器打开,就算更改后缀名也 ...

  4. MP3、AAC、WMA、Ogg、MPC、WAV、FLAC、APE、WV、CD、MIDI、RealVideo等音频格式解析及对比

    音频格式详解 无论是随身听还是手机或者是多媒体DC,产品支持的音频格式多样,然而它们都有各自的特性.我们在应用中选择的时候必须考虑到各种格式的适用场合,这要求我们对很多方面有个系统的了解. 有损压缩格 ...

  5. android 视频转字节,如何将视频文件(.mp4)格式转换为android中的二进制格式?...

    我想在网络服务器上传视频.我得到了我想要以二进制格式传递文件的服务,我该怎么做?如何将视频文件(.mp4)格式转换为android中的二进制格式? 我试图通过base64将视频文件转换为二进制格式.. ...

  6. 解析MYSQL BINLOG二进制格式(10)--问题解答

    原创转发请注明出处 上接 http://blog.itpub.net/7728585/viewspace-2133188/ 解析MYSQL BINLOG 二进制格式(1)--准备工作  http:// ...

  7. AVI文件格式简介与WAV文件分析

    AVI文件格式简介与WAV文件分析 AVI文件格式(回答问题) 所有AVI文件至少包含2个必须的LIST Chunk和一个索引Chunk Chunk: LIST Chunk: 小端:数据的低位保存在内 ...

  8. python服务器传输wav文件,Python处理wav文件(二进制文件读写)

    wav文件信息格式图 前44字节为头信息,后面的为音频数据. import struct import array # 读取wav文件,二进制要记得用b file = open('Love Story ...

  9. python读取wav文件并进行FFT变换

    一.wav格式文件 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台 ...

最新文章

  1. C#用户权限控制架构,可以控制到类【重发】
  2. Linux防火墙详解(二)
  3. 【ES6基础】Object的新方法
  4. ${ctx} 的那些事
  5. java/05/(Swing包)窗体,组件,布局管理器,面板,监听事件
  6. SpringMVC中注解@RequestBody和@ResponseBody的使用区别
  7. 2020八年级计算机会考计划,初二下学期学习计划2020
  8. 计算机电影院管理系统开题报告,开题报告电影院网上订票系统.doc
  9. QR码和PDF417比较
  10. matlab最速下降法例子,matlab 最速下降法 steepest descent (实例并附有详细说明)
  11. 支付中心设计与方案,收藏了
  12. 服务器temp文件夹文件都能清理吗,Temp文件夹是什么?Windows中Temp文件夹下内容可以随意删除吗?...
  13. 协同软件市场一盘散沙 春种能否秋收心中没底
  14. Origin使用自定义函数拟合曲线函数
  15. c语言char s[] 语句,35、若有定义和语句: char s[10]=abcd;printf(%s\n,s); 则结果是(以下u代表空格)...
  16. 【python 问题解决】---- no such column
  17. Linux sed精确匹配和替换
  18. ibatis批量插入数据-iterate标签详解及应用
  19. corosync-qdevice详解
  20. 订餐服务网络“橄榄订餐网”复制携程的“互联网+传统行业”模式已见成效

热门文章

  1. Could not obtain transaction-synchronized Session for current thread原因及解决方案
  2. 阿里云OSS创建Access,并连接到cloudreve
  3. 计算机网络八校联考试题,2019届高三信息技术3月联考试卷有解析与答案
  4. 为什么很少人学汇编_要想精通C语言,必须先学习汇编吗
  5. 将本地文件push到gitee上面
  6. nextpolish安装_希望组自主三代组装软件NextDenovo最新版本全球学术开源!
  7. 2020蓝桥杯校内模拟赛1-5(详细版本,看完就会)
  8. C++ STL list的成员函数splice的使用
  9. cube 一站式云原生开源机器学习平台
  10. java发送接收组播(多播)数据包(UDP包)