详解wave头格式(尽可能详细并附代码)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
整理网上和读书时的资料,结合自己的实际经验,给出wav头格式的解释和源代码,既是对自己的总结,同时又服务大家。另外在给出几个实际例子,如果看了这篇文档还不能正确写出wave文件,那就要吊起来打了^_^。
——flywen 2010-10-13
参考网址一:/sshcx/archive/2007/05/01/1593923.aspx
参考网址二:/share/detail/15909594
WAVE 文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是"RIFF"。WAVE 文件由文件头和数据体两大部分组成。其中文件头又分为RIFF/WAV文件 标识段和声音数据格式说明段两部分。
常见的声音文件主要有两种,分别对应于单声道(11.025KHz 采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。采样率是指:声音信号在"模→数"转换过程中单位时间内采样的次数。 采样值是指每一次采样周期内声音模拟信号的积分值。
[!21ki@][@21ki!]
对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。
WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。WAVE文件是由样本组织而成的。在单声道WAVE文件中,声道0代表左声道,声道1代表右声道。在多声道WAVE文件中,样本是交替出现的。
参考网址一和二中都给出了wav的头定义,但有一个小区别,一中将这个44个字节作为一个大的头,给定在一个结构体中,而二中则是按照四个不同的chunk处理的,所以就给了四个结构体,后面我的代码也是根据二来写的,个人觉得这样比较清晰,不过这纯属个人感觉。
下面就是根据四个结构体写的代码,注意FACT不是必须的,可以不用写入头,不写的话就是44个字节,写的话wave的头是56个字节。
一:源代码(参考二中也有比较详细的读wave头的代码)
#if !defined(_WAV_INFO_)
#define _WAV_INFO_
// 一些和声音数据相关的宏
#define SAMPLE_RATE 22050 // sample rate,每秒22050个采样点 #define QUANTIZATION 0x10 // 16bit量化,
#define BYTES_EACH_SAMPLE 0x2 // QUANTIZATION / 8, 所以每个采样点、
// 是short,占个2个字节
#define CHANNEL_NUN 0x1 // 单声道
#define FORMAT_TAG 0x1 // 线性PCM
// 一个wave file包括四个CHUNK,除了FACT之外,其它是必须的,并且第一个RIFF是整个文件的头,// 所以别名为WAV_HEADER,而不是RIFF
/*------------------------Wave File Structure ------------------------------------ */ typedef struct RIFF_CHUNK{
char fccID[4]; // must be "RIFF"
unsigned long dwSize; // all bytes of the wave file subtracting 8,
// which is the size of fccID and dwSize char fccType[4]; // must be "WAVE"
}WAVE_HEADER;
// 12 bytes
typedef struct FORMAT_CHUNK{
char fccID[4]; // must be "fmt "
unsigned long dwSize; // size of this struct, subtracting 8, which
// is the sizeof fccID and dwSize unsigned short wFormatTag; // one of these: 1: linear,6: a law,7:u-law unsigned short wChannels; // channel number
unsigned long dwSamplesPerSec; // sampling rate
unsigned long dwAvgBytesPerSec; // bytes number per second
unsigned short wBlockAlign; // 每样本的数据位数(按字节算), 其值为:通道
// 数*每样本的数据位值/8,播放软件需要一次处
// 理多个该值大小的字节数据, 以便将其值用于
// 缓冲区的调整每样本占几个字节:
// NumChannels * uiBitsPerSample/8
unsigned short uiBitsPerSample; // quantization
}FORMAT;
// 24 bytes
// The fact chunk is required for all new WAVE formats.
// and is not required for the standard WAVE_FORMAT_PCM files
// 也就是说,这个结构体目前不是必须的,一般当wav文件由某些软件转化而成,则包含该Chunk
// 但如果这里写了,则必须是如下的结构,并且在四个结构体中的位置也要放在第三
typedef struct {
char fccID[4]; // must be "fact"
unsigned long id; // must be 0x4
unsigned long dwSize; // 暂时没发现有啥用
}FACT;
// 12 bytes
// 数据结构
typedef struct {
char fccID[4]; // must be "data"
unsigned long dwSize; // byte_number of PCM data in byte
}DATA;
// 8 bytes
/*------------------------Wave File Structure ------------------------------------ */
void WriteWaveHeader(FILE *fpwav,long length)
{
WAVE_HEADER WaveHeader;
FORMAT WaveFMT;
DATA WaveData;