1 struct RIFF_HEADER
 2 {
 3      char szRiffID[4];   // 'R','I','F','F'
 4      DWORD dwRiffSize;
 5      char szRiffFormat[4]; // 'W','A','V','E'
 6 };
 7 
 8 struct WAVE_FORMAT
 9 {
10      WORD wFormatTag;
11      WORD wChannels;
12      DWORD dwSamplesPerSec;
13      DWORD dwAvgBytesPerSec;
14      WORD wBlockAlign;
15      WORD wBitsPerSample;
16 };
17 struct waveHead
18 {
19      RIFF_HEADER riff;
20      char   szFmtID[4]; // 'f','m','t',' '
21      DWORD   dwFmtSize;
22      WAVE_FORMAT wavFormat;
23 };
24 
25 struct FACT_BLOCK
26 {
27      char   szFactID[4]; // 'f','a','c','t'
28      DWORD   dwFactSize;
29 };
30 
31 struct DATA_BLOCK
32 {
33      char szDataID[4]; // 'd','a','t','a'
34      DWORD dwDataSize;
35 };
36 
37 #define WAVE_FORMAT_PCM 0x0001 
38 #define WAVE_FORMAT_ADPCM 0x0002
39 
40          else if (m_iSoundType == wavesound)
41          {
42              waveHead aHeader;
43              fseek(m_soundf, 0, SEEK_SET);
44              fread(&aHeader, 1, sizeof(waveHead), m_soundf);
45              if (aHeader.wavFormat.wFormatTag != WAVE_FORMAT_PCM)
46              {
47                  PGELOG(LOG_ERROR, "不支持的Wave格式:%s", caFile);
48                  fclose(m_soundf);
49                  m_soundf = 0;
50                  return -1;
51              }
52              memcpy(&m_wformat, &(aHeader.wavFormat), sizeof(WAVE_FORMAT));
53              m_wformat.cbSize = 0;
54              //if (aHeader.dwFmtSize == 18)
55              //fread(&(m_wformat.cbSize), 1, sizeof(WORD), m_soundf);
56              fseek(m_soundf, aHeader.dwFmtSize-16, SEEK_CUR);
57              FACT_BLOCK fact;
58              DATA_BLOCK data;
59              fread(&fact, 1, sizeof(FACT_BLOCK), m_soundf);
60              if (*((DWORD*)fact.szFactID) == *((DWORD*)"fact"))
61              {
62                  fseek(m_soundf, fact.dwFactSize, SEEK_CUR);
63                  fread(&data, 1, sizeof(DATA_BLOCK), m_soundf);
64              }
65              else if (*((DWORD*)fact.szFactID) == *((DWORD*)"data"))
66                  memcpy(&data, &fact, sizeof(DATA_BLOCK));
67              m_iDataStart = ftell(m_soundf);
68              m_iDataSize = data.dwDataSize;
69 fread(m_pWaveData, 1, m_iDataSize, m_soundf);
70          }

附上wave文件格式:

下面我们具体地分析 WAVE 文件的格式

 

endian

field name

Size

 
big ChunkID 4 文件头标识,一般就是" RIFF" 四个字母
little ChunkSize 4 整个数据文件的大小,不包括上面ID和Size本身
big Format 4 一般就是" WAVE" 四个字母
big SubChunk1ID 4 格式说明块,本字段一般就是"fmt "
little SubChunk1Size 4 本数据块的大小,不包括ID和Size字段本身
little AudioFormat 2 音频的格式说明
little NumChannels 2 声道数
little SampleRate 4 采样率
little ByteRate 4 比特率,每秒所需要的字节数
little BlockAlign 2 数据块对齐单元
little BitsPerSample 2 采样时模数转换的分辨率
big SubChunk2ID 4 真正的声音数据块,本字段一般是"data"
little SubChunk2Size 4 本数据块的大小,不包括ID和Size字段本身
little Data N 音频的采样数据

以下是对各个字段的详细解说:

ChunkID 4bytes ASCII 码表示的“RIFF”。(0x52494646)
ChunkSize 4bytes 36+SubChunk2Size,或是 
4 + ( 8 + SubChunk1Size ) + ( 8 + SubChunk2Size ), 
这是整个数据块的大小(不包括ChunkID和ChunkSize的大小)
Format 4bytes ASCII 码表示的“WAVE”。(0x57415645)
     
SubChunk1ID   新的数据块(格式信息说明块) 
ASCII 码表示的“fmt ”——最后是一个空格。(0x666d7420)
SubChunk1Size 4bytes 本块数据的大小(对于PCM,值为16)。
AudioFormat 2bytes PCM = 1 (比如,线性采样),如果是其它值的话,则可能是一些压缩形式
NumChannels 2bytes 1 => 单声道  |  2 => 双声道
SampleRate 4bytes 采样率,如 8000,44100 等值
ByteRate 4bytes 等于: SampleRate * numChannels * BitsPerSample / 8
BlockAlign 2bytes 等于:NumChannels * BitsPerSample / 8
BitsPerSample 2bytes 采样分辨率,也就是每个样本用几位来表示,一般是 8bits 或是 16bits
     
SubChunk2ID 4bytes 新数据块,真正的声音数据 
ASCII 码表示的“data ”——最后是一个空格。(0x64617461)
SubChunk2Size 4bytes 数据大小,即,其后跟着的采样数据的大小。
Data N bytes 真正的声音数据

对于Data块,根据声道数和采样率的不同情况,布局如下(每列代表8bits):

1. 8 Bit 单声道:

采样1 采样2
数据1 数据2

2. 8 Bit 双声道

采样1   采样2  
声道1数据1 声道2数据1 声道1数据2 声道2数据2

1. 16 Bit 单声道:

采样1   采样2  
数据1低字节 数据1高字节 数据1低字节 数据1高字节

2. 16 Bit 双声道

采样1      
声道1数据1低字节 声道1数据1高字节 声道2数据1低字节 声道2数据1高字节
采样2      
声道1数据2低字节 声道1数据2高字节 声道2数据2低字节 声道2数据2高字节

 

下面我们看一个具体的例子,声音文件如下:

52 49 46 46 24 08 00 00 57 41 56 45 
66 6d 74 20 10 00 00 00 01 00 02 00 
22 56 00 00 88 58 01 00 04 00 10 00 
64 61 74 61 00 08 00 00 00 00 00 00 
24 17 1e f3 3c 13 3c 14 16 f9 18 f9 
34 e7 23 a6 3c f2 24 f2 11 ce 1a 0d 

对应的分析如下图所示:

untitled

自己测试了下暂时还没有弄通。

posted on 2013-05-04 10:49  瓦楞球  阅读(1060)  评论(0编辑  收藏  举报