wave文件格式分析

(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

你可能感兴趣的:(数据压缩)