To 楼主:
一、您说您读取文件头没问题,我看未必吧。标准 PCM 文件的文件头至少要满足下面 5 个条件:
1、具有"RIFF"标识和"WAVE"标识;
2、数据域不嵌套;
3、用"fmt "标识 PCMWAVEFORMAT 结构;
4、没有作者信息、编辑时间等内容;
5、用"data"标识数据域。
我不知道您的 Wave 文件满足了其中几个条件?一旦文件头不是标准 PCM,那读出的数据自然不会正确。
二、网上流传的 TWaveHeader 格式有多种,我一般用这个:
TWaveFileHeader = record
szChunkID: array[0..3] of Char;//"RIFF"标志
dwChunkSize: DWORD;//文件大小 - 8
szFormat: array[0..3] of Char;//"WAVE"标志
szSubChunk1ID: array[0..3] of Char;//"fmt "标志
dwSubChunk1Size: DWORD;//SizeOf(PCMWAVEFORMAT)
wFormatTag: Word;//为 1 表示是PCM格式,否则就是经过压缩了
wChannels: Word;//通道数
dwSamplesPerSec: DWORD;//采样率
dwAvgBytesPerSec: DWORD;//传输速率
wBlockAlign: Word;//样本数据位数
wBitsPerSample: Word;//采样大小
szSubChunk2ID: array[0..3] of Char;//"data"标记
dwSubChunk2Size: DWORD;//音频数据大小
end;
三、我注意到您的数据域是用 data(Byte 类型)读取的,显然很令人费解!Wave 的数据域是以字(双字节)为单位的,您读取也应该读取一个字吧,读取一个字节算什么呢?再说其存储结构与声道有关:
1、单声道:
---------------------------------
采样1 | 采样2 |……
---------------------------------
低字节 高字节|低字节 高字节|……
---------------------------------
2、双声道:
---------------------------------
采样1 |……
---------------------------------
左声道 | 右声道 |……
---------------------------------
低字节 高字节|低字节 高字节|……
---------------------------------
四、我这写了个例子,它可以把数据域所有内容一次性读入内存中,至于怎么处理这些数据你自己看着办吧:
procedure GetWaveData(const FileName: string);
var
hFile: THandle;
wfh: TWaveFileHeader;
r, i: DWORD;
data, p: PWord;
begin
hFile := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
if hFile = INVALID_HANDLE_VALUE then
Exit;
ReadFile(hFile, wfh, SizeOf(wfh), r, nil);
if (wfh.szChunkID <> 'RIFF') or (wfh.szFormat <> 'WAVE') or
(wfh.szSubChunk1ID <> 'fmt ') or (wfh.wFormatTag <> 1) or
(wfh.szSubChunk2ID <> 'data') then
Exit;
data := AllocMem(wfh.dwSubChunk2Size);
//将所有音频数据读入内存,data 指向内存中数据的首地址
ReadFile(hFile, data^, wfh.dwSubChunk2Size, r, nil);
p := data;
//防止程序无休止循环,取 6 个数据意思一下就行了
for i := 0 to 5{wfh.dwSubChunk2Size div 16 - 1}do
begin
Inc(p, 16*i);
ShowMessage(IntToStr(p^));
end;
FreeMem(data);
CloseHandle(hFile);
end;
你可以用 "C:/WINDOWS/Media/Windows XP 关机.wav" 试一下,能不能用给个话,好吧?