wave文件格式分析

来源:互联网 发布:数据统计的目的 编辑:程序博客网 时间:2024/06/03 04:05

(1).综述
wave(waveform audio file format)文件格式是微软和IBM的音频标准文件格式,支持压缩和无压缩,但通常为无压缩格式,所以文件较大,音质较好。
它采用RIFF即chunk文件存储方式。类似于一个容器存贮,存贮顺序


| 4字节标签 |


| 4字节数据块大小 |


|数据块,在数据块内可包含多个容器|


(2).数据组织方式
wave文件中数据存储采用小尾存储,低位在前,高位在后。如
char |7-0|
short |7-0| |15-8|

音频量化比特数由文件信息给出,当量化bit大于8时,以2的补码的形式存储,可能宽为9-32bit。例如16bit量化的wave文件,数据范围最大为+32767(0x7fff),最小为-32768(0x8000);而小于等于8bit则直接由原码给出。
cpu处理数据时一般以字节为单位读取数据,当wave文件以无压缩方式存贮时,若量化bit不为8的倍数则上取整,并在低位补零,例如以12bit量化的101000010111,存储为1010 0001 0111 0000,以2字节存贮,wave以小尾字节序存贮,故实际存储为30 a1。若是wave文件有压缩应该一个字节共同存储几个样本点。
当有多通道数据时,采用各样点值交替存贮的方式,如
单声道 sample1 sample2
stereo chanel1-sample1 chanel2-sample1 chanel1-sample2 chanel2-sample2 chanel1-sample3 chanel2-sample3……

wave还支持压缩方式,压缩方式由wFormatTag给出,常用的压缩格式有
0x0001 WAVE_FORMAT_PCM
0x0002 WAVE_FORMAT_ADPCM
0x0005 WAVE_FORMAT_IBM_CVSD
0x0006 WAVE_FORMAT_ALAW
0x0007 WAVE_FORMAT_MULAW
0x0031 WAVE_FORMAT_GSM610
0x0050 WAVE_FORMAT_MPEG
(3).文件组织方式
wave文件的组织方式为


Id=riff //4字节文件标识
Long length=filesize-8 //以字节为单位
Fileid=wave //RIFF类型,可能是wave或者avi
Data //数据块,包含其他chunk


在data中,必须包含fmt-ck和data-ck,而cue-ck、playlist-ck和list-ck等则是可选的,它们具体的含义如下
1.fmt-ck描述wave文件的基本信息

typedef struct {  ID             chunkID;    //fmt  long           chunkSize; //除chunkId和chunkSize外chunk长度  short          wFormatTag; //指示wave是否压缩,为1时无压缩  unsigned short wChannels;//音频的通道数  unsigned long  dwSamplesPerSec;//采样率,常用22050,44100hz  unsigned long  dwAvgBytesPerSec;//每秒播放的字节数,等于dwSamplesPerSec * wBlockAlign  unsigned short wBlockAlign;   //如果无压缩,每帧的字节数,等于 wChannels*(wBitsPerSample/8)  unsigned short wBitsPerSample;//量化比特数/* 若是有压缩,在此处存储附加信息用于解压,若是无压缩没有这部分信息*/} FormatChunk;

2.cue-ck包含一个或多个cue-points或者markers,每个cue-points根据wave data定义偏移量,来存储跳转信息,用于在实际中快速调整播放顺序。

typedef struct {  long    dwIdentifier;//标识关键帧  long    dwPosition;//关键帧在播放次序中的位置  ID      fccChunk; //定义cuePoint参考的data 或者 wave list id  long    dwChunkStart; //定义从cuePoint参考的data 或者 wave list 的偏移量  long    dwBlockStart;  long    dwSampleOffset;//不知道是以字节为单位还是以样本点的字节数为单位} CuePoint;
typedef struct {  ID        chunkID; //cue  long      chunkSize;//容器长度  long      dwCuePoints;//CuePoint的数目  CuePoint  points[];} CueChunk;

3.playlist-ck定义关键帧的播放顺序

typedef struct {  long    dwIdentifier;//用于标识播放的关键帧  long    dwLength;  long    dwRepeats;} Segment;
typedef struct {  ID        chunkID; //plst  long      chunkSize;//除chunkId和chunkSize外的容器大小  long      dwSegments;//播放立标中segment的数目  Segment   Segments[];} PlaylistChunk;

4.assoc-data-list
说明cuePoint的标签信息,包含的二级chunk主要有‘labl’,’note’,‘ltxt’

typedef struct {  ID      listID;      /* 'list' */  long    chunkSize;   /* 所有接下来的二级chunk的大小 */  ID      typeID;     /* 'adtl' */} ListHeader;typedef struct {  ID      chunkID;  //labl  long    chunkSize;  long    dwIdentifier; //指明标记的关键帧  char    dwText[];//标签数据} LabelChunk;typedef struct {  ID      chunkID;//note  long    chunkSize;  long    dwIdentifier;//指明备注的关键帧  char    dwText[];//备注信息} NoteChunk;typedef struct {  ID      chunkID;//ltxt  long    chunkSize;  long    dwIdentifier;  long    dwSampleLength;//指明每一段wave data中样本点的数目  long    dwPurpose; //指明该段文本的类型或作用  short   wCountry;//定义country code  short   wLanguage;//定义语言  short   wDialect;  short   wCodePage;  char    dwText[];} LabelTextChunk;typedef struct {  ID      chunkID;//ltxt  long    chunkSize;  long    dwIdentifier;  long    dwSampleLength;//指明每一段wave data中样本点的数目  long    dwPurpose; //指明该段文本的类型或作用  short   wCountry;//定义country code  short   wLanguage;//定义语言  short   wDialect;  short   wCodePage;  char    dwText[];} LabelTextChunk;

5.wave-data存储实际的wave数据,如果无压缩就是实际的采样数据

typedef struct {  ID             chunkID; //data  long           chunkSize;  unsigned char  waveformData[]; //实际数据} DataChunk
0 0