o任飘零o

别人给了你一滴水,你给了别人些什么?
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

wav文件的文件头信息详解

Posted on 2013-02-04 13:51  o任飘零o  阅读(5992)  评论(1编辑  收藏  举报

wav文件的文件头

wave文件的格式:
 
00H 4 char "RIFF"标志  04H 4 long int 文件长度  08H 4 char "WAVE"标志  0CH 4 char "fmt"标志  10H 4   过渡字节(不定)  14H 2 int 格式类别(10H为PCM形式的声音数据)  16H 2 int 通道数,单声道为1,双声道为2  18H 2 int 采样率(每秒样本数),表示每个通道的播放速度,  1CH 4 long int 波形音频数据传送速率,其值为通道数×每秒数据位数×每样                本的数据位数/8。播放软件利用此值可以估计缓冲区的大小。  20H 2 int 数据块的调整数(按字节算的),其值为通道数×每样本的数据位            值/8。播放软件需要一次处理多个该值大小的字节数据,以便将其            值用于缓冲区的调整。  22H 2   每样本的数据位数,表示每个声道中各个样本的数据位数。如果有多          个声道,对每个声道而言,样本大小都一样。  24H 4 char 数据标记符"data"  28H 4 long int 语音数据的长度 

楼主的帖子,文件头长度加起来是42字节,但是实际长度是44个字节(用UltraEdit打开一个WAVE文件,数一下就知道了)。如果用以个结构体来定义WAVE文件头应该为: struct WAVEFILEHEADER {  char chRIFF[4];  DWORD dwRIFFLen;  char chWAVE[4];  char chFMT[4];  DWORD dwFMTLen;  PCMWAVEFORMAT pwf;  char chDATA[4];  DWORD dwDATALen; };

但是实际测试,并不是所有的wave文件头都一样。比较麻烦的就是windows下自带的那个录音机录下的wav,文件头有58个Byte。所以,比较好的办法是,首先读取n长的一段字符,例如60个;然后从中查找关键字“data”,“data”之后的一个DWORD是实际音频数据的长度,得到这个长度len,再从这DWORD后开始读取len个字节,就可以读到文件尾。如果是双声道的,那么数据是交替存放的;如果是16bit采样的,每两个字节会以小端的方式存储一个AD值。根据这样的方式,就可以顺利读取音频数据了。

有一个问题就是:在不知道文件头多长的情况下,采用直接读取60个Byte的方法是不够严谨的。如果是标准的wav格式,那么文件头只有44byte,就存在整个文件都没有60Byte长的可能性。实际中当然不大可能,但是严谨考虑,应该先读取36个Byte,从37开始,4个4个的读取,判断是否有“data”关键字,进而得出文件头的实际长度。

就想到了这些,暂时记下来。