常见的声音文件主要有两种,分别对应于单声道(11.025KHz 采样率、8Bit的采样值)和
双声道(44.1KHz采样率、16Bit的采样值)。
对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声
声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。
下面就是根据四个结构体写的代码,注意FACT不是必须的,可以不用写入头,不写的话就
是
44个字节,写的话wave的头是56个字节
。
1)
一个wave file包括四个CHUNK,除了FACT之外,其它是必须的
2)第一个RIFF是整个文件的头,
所以别名为WAV_HEADER,而不是RIFF
1.
12个字节
typedef struct
RIFF_CHUNK{
char
fccID[4];
// must be "RIFF"
unsigned long
dwSize;
// all bytes of the wave file subtracting 8, 44-8+length or 56-8 +
length
// which is the size of fccID and dwSize,
dwSize =
fileSize - 8
char
fccType[4];
// must be "WAVE"
}WAVE_HEADER;
2. 24
个字节
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
// 24-8=16 -->0x10, 0x12
unsigned short
wFormatTag;
// one of these: 1: linear,6: a law,7:u-law,
FORMAT_TAG
unsigned short
wChannels;
// channel number
unsigned long
dwSamplesPerSec;
// sampling rate,
SAMPLE_RATE,AC
44
=44100
unsigned long
dwAvgBytesPerSec;
// bytes number per second, 2*
AC
44*2=2B110
//CHANNEL_NUN * SAMPLE_RATE * BYTES_EACH_SAMPLE
unsigned short
wBlockAlign;
// 每样本的数据位数(按字节算), 其值为:通道,
BYTES_EACH_SAMPLE
// 数*每样本的数据位值/8,播放软件需要一次处
// 理多个该值大小的字节数据, 以便将其值用于
// 缓冲区的调整每样本占几个字节
// NumChannels * uiBitsPerSample/8 2* 16/8 =4
unsigned short
uiBitsPerSample;
// quantization 1
}FORMAT;
3.
12个字节
// 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; // 暂时没发现有啥用, length
}FACT;
4. 8
个字节
// 数据结构
typedef struct
{
char
fccID[4];
// must be "data"
unsigned long
dwSize;
//
dwSize =
fileSize - 44/56, byte_number of PCM data in byte,
WAVE_HEADER.size -
dwSize =
44-8 or 56-8
}DATA;