这篇文章是网络上流行的比较广泛的针对WAVE头分析的文章, 整体写的简单明了非常好,但是
应该是不对的, 如果按这个该文章的计算,WAVE头只有42byte, 实际上wave头是44byte. 参考MS的标准文档知道这个采样率是占4byte的.(见 WAVE PCM soundfile format ) // ---------------------------------------------------------------- WAVE文件格式剖析 WAVE文件格式说明表 [!21ki@][@21ki!]
PCM数据的存放方式: [!21ki@][@21ki!]
WAVE文件的每个样本值包含在一个整数i中,i的长度为容纳指定样本长度所需的最小字节数。首先存储低有效字节,表示样本幅度的位放在i的高有效位上,剩下的位置为0,这样8位和16位的PCM波形样本的数据格式如下所示。 [!21ki@][@21ki!]
分析WAVE头的代码 /* WAVE文件头(PCM格式) field size type description ----------------------------------------------------------------------- ChunkID 4 char "RIFF"标志 ChunkSize 4 long int 文件长度(WAVE文件的大小, 不含前8个字节) Format 4 char "WAVE"标志 SubChunk1ID 4 char "fmt "标志 SubChunk1Size 4 过渡字节(不定) AudioFormat 2 short int 格式类别(1为PCM格式的声音数据) NumChannels 2 short int 通道数(单声道为1, 双声道为2) SampleRate 4 long int 采样率(每秒样本数), 表示每个通道的播放速度 一般情况是每秒采样44100次 ByteRate 4 long int 波形音频数据传输速率, 其值为:通道数*每秒数据位数*每样本的数据位数/8 播放软件可以利用该值估计缓冲区大小 2 * BlockAlign 2 short int 每样本的数据位数(按字节算), 其值为:通道数*每样本的数据位值/8, 播放 软件需要一次处理多个该值大小的字节数据, 以便将其值用于缓冲区的调整 每样本占几个字节 : NumChannels * 16/8 BitsPerSample 2 每样本的数据位数, 表示每个声道中各个样本的数据位数. 如果有多个声道, 对每个声道而言, 样本大小都一样 就是分辨率, 一般是16位, 8位也有但是要少一些. SubChunk2ID 4 char 数据标记"data" SubChunk2Size 4 long int 语音数据的长度 */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <mem.h> /* WAVE文件头 */ typedef struct wave_tag { char ChunkID[5]; // "RIFF"标志 unsigned long int ChunkSize; // 文件长度(WAVE文件的大小, 不含前8个字节) char Format[5]; // "WAVE"标志 char SubChunk1ID[5]; // "fmt "标志 unsigned long int SubChunk1Size; /* * 过渡字节(不定) * 16 for PCM. This is the size of the rest of the * Subchunk which follows this number. */ unsigned short int AudioFormat; /* * 格式类别(10H为PCM格式的声音数据) * PCM=1 (i.e. Linear quantization) * Values other than 1 indicate some form of compression. */ unsigned short int NumChannels; // 通道数(单声道为1, 双声道为2) //unsigned short int SampleRate; // 采样率(每秒样本数), 表示每个通道的播放速度 unsigned long int SampleRate; // 采样率(每秒样本数), 表示每个通道的播放速度 unsigned long int ByteRate; /* * 波形音频数据传输速率, 其值为:通道数*每秒数据位数*每样本的数据位数/8 * 播放软件可以利用该值估计缓冲区大小 */ unsigned short int BlockAlign; /* * 每样本的数据位数(按字节算), 其值为:通道数*每样本的数据位值/8, 播放 * 软件需要一次处理多个该值大小的字节数据, 以便将其值用于缓冲区的调整 */ unsigned short int BitsPerSample; /* * 每样本的数据位数, 表示每个声道中各个样本的数据位数. 如果有多个声道, * 对每个声道而言, 样本大小都一样 */ char SubChunk2ID[5]; // 数据标记"data" unsigned long int SubChunk2Size; // 语音数据的长度 } WAVE; /* 分辨率为16的样本 */ typedef struct swatch16_tag { char swing; } swatch16; /* 分辨率为8的样本 */ typedef struct swatch8_tag { } swatch8; // 爱情复兴 :), 长度: 41.5MB(43,554,860 字节) #define FILE_PATH "aiqingfuxing1.wav" /* * 分析音频文件格式 */ int main ( void ) { FILE *stream; WAVE wav; stream = fopen( FILE_PATH, "r" ); /* open a file for reading */ /* * 读wav文件的各个field */ fread(wav.ChunkID, 4, 1, stream); wav.ChunkID[4] = (char)0; fread(&(wav.ChunkSize), 4, 1, stream); fread(wav.Format, 4, 1, stream); wav.Format[4] = (char)0; fread(wav.SubChunk1ID, 4, 1, stream); wav.SubChunk1ID[4] = (char)0; fread(&(wav.SubChunk1Size), 4, 1, stream); fread(&(wav.AudioFormat), 2, 1, stream); fread(&(wav.NumChannels), 2, 1, stream); fread(&(wav.SampleRate), 4, 1, stream); fread(&(wav.ByteRate), 4, 1, stream); fread(&(wav.BlockAlign), 2, 1, stream); fread(&(wav.BitsPerSample), 2, 1, stream); fread(wav.SubChunk2ID, 4, 1, stream); wav.SubChunk2ID[4] = (char)0; fread(&(wav.SubChunk2Size), 4, 1, stream); printf("ChunkID---->%s/n", wav.ChunkID); printf("ChunkSize---->%ld/n", wav.ChunkSize); printf("Format---->%s/n", wav.Format); printf("SubChunk1ID---->%s/n", wav.SubChunk1ID); printf("SubChunk1Size---->%ld/n", wav.SubChunk1Size); printf("AudioFormat---->%d/n", wav.AudioFormat); printf("NumChannels---->%d/n", wav.NumChannels); printf("SampleRate---->%ld/n", wav.SampleRate); printf("ByteRate---->%ld/n", wav.ByteRate); printf("BlockAlign---->%d/n", wav.BlockAlign); printf("BitsPerSample---->%d/n", wav.BitsPerSample); printf("SubChunk2ID---->%s/n", wav.SubChunk2ID); printf("SubChunk2Size---->%ld/n", wav.SubChunk2Size); printf("*************rrr**********/n"); // system( "pause" ); return 0; } /* 打印结果 ChunkID---->RIFF ChunkSize---->43554852 Format---->WAVE SubChunk1ID---->fmt SubChunk1Size---->16 AudioFormat---->1 NumChannels---->2 SampleRate---->44100 ByteRate---->176400 BlockAlign---->4 BitsPerSample---->16 SubChunk2ID---->data SubChunk2Size---->43554816 *************rrr********** 请按任意键继续. . . */ /* WAVE头的16进制码 52 49 46 10 00 00 00 01 00 02 00 04 00 10 00 64 61 74 52 49 46 46 ChunkID "RIFF" C4 86 01 00 ChunkSize 57 41 56 45 Format "WAVE" 66 6D 74 20 SubChunk1ID "fmt " 10 00 00 00 SubChunk1Size 01 00 AudioFormat 02 00 NumChannels 10 B1 02 00 ByteRate 04 00 BlockAlign 10 00 BitsPerSample 64 61 74 61 SubChunk2ID A0 86 01 00 SubChunk2Size */ |
|