(1).综述 wave(waveform audio file format)微软和文件格式IBM标准的音频文件格式支持压缩和无压缩,但通常是无压缩格式,因此文件大,音质好。 它采用RIFF即chunk存储文件的方式。类似于容器存储,存储顺序 为
| 4字节标签 |
| 四字节数据块大小 |
|数据块,在数据块内可包含多个容器|
(2).数据组织 wave文件中的数据存储采用小尾存储,低位在前,高位在后。 char |7-0| short |7-0| |15-8|
文件信息给出音频量化比特数bit8点以2补码的形式存储,可能宽9-32bit。例如16bit量化的wave数据范围最大的文件 32767(0x7fff),最小为-32768(0x8000)bit原码直接给出。 cpu在处理数据时,通常以字节为单位读取数据wave当文件以无压缩的方式存储时,如果量化bit取整不是8的倍数,在低位补零,如12bit101000101111定量存储在1010 0001 0111 以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