unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} uses MMSystem; //chan: 1 单声道、2 立体声; //freq: 频率, 取值: 11025, 22050, 44100 //bit : 每个样本的大小, 取值 8、16 function CreateWav1(chan, freq, bit: Word; const FilePath: string): Boolean; var h: HMMIO; ckiRiff, ckiFmt, ckiData: TMMCKInfo; fmt: TPCMWaveFormat; begin //此函数是使用 mmioCreateChunk 函数来分别建立 Wave 文件的每个块. {初识化相关结构} ZeroMemory(@ckiRiff, SizeOf(TMMCKInfo)); ckiRiff.cksize := 36; {mmioCreateChunk 函数会自动写上 ckid, 但其 cksize 需要手动给} ckiRiff.fccType := mmioStringToFOURCC('WAVE', 0); ZeroMemory(@ckiFmt, SizeOf(TMMCKInfo)); ckiFmt.ckid := mmioStringToFOURCC('fmt', 0); ZeroMemory(@ckiData, SizeOf(TMMCKInfo)); ckiData.ckid := mmioStringToFOURCC('data', 0); {指定 Wave 格式} fmt.wf.wFormatTag := WAVE_FORMAT_PCM; fmt.wf.nChannels := chan; fmt.wf.nSamplesPerSec := freq; fmt.wf.nAvgBytesPerSec := freq * chan * bit div 8; fmt.wf.nBlockAlign := chan * bit div 8; fmt.wBitsPerSample := bit; h := mmioOpen(PChar(FilePath), nil, MMIO_CREATE or MMIO_WRITE); if h = 0 then Exit(False); {分别建立 RIFF、fmt、data 块} if (mmioCreateChunk(h, @ckiRiff, MMIO_CREATERIFF) = MMSYSERR_NOERROR) and (mmioCreateChunk(h, @ckiFmt, 0) = MMSYSERR_NOERROR) and (mmioWrite(h, PAnsiChar(@fmt), SizeOf(TPCMWaveFormat)) = SizeOf(TPCMWaveFormat)) and (mmioAscend(h, @ckiFmt, 0) = MMSYSERR_NOERROR) and (mmioCreateChunk(h, @ckiData, 0) = MMSYSERR_NOERROR) then Result := True; mmioClose(h, 0); end; //把 PCM 编码的 WAVE 文件的前 44 个字节看成一个结构来操作: function CreateWav2(chan, freq, bit: Word; const FilePath: string): Boolean; type TWaveHeader = record Riff_ckid : DWORD; Riff_cksize : DWORD; Riff_fccType : DWORD; fmt_ckid : DWORD; fmt_cksize : DWORD; wFormatTag : Word; nChannels : Word; nSamplesPerSec : DWORD; nAvgBytesPerSec: DWORD; nBlockAlign : Word; wBitsPerSample : Word; data_ckid : DWORD; data_cksize : DWORD; end; var wh: TWaveHeader; hFile: Integer; begin wh.Riff_ckid := FOURCC_RIFF; wh.Riff_cksize := 36; wh.Riff_fccType := mmioStringToFOURCC('WAVE', 0); wh.fmt_ckid := mmioStringToFOURCC('fmt', 0); wh.fmt_cksize := 16; wh.wFormatTag := WAVE_FORMAT_PCM; wh.nChannels := chan; wh.nSamplesPerSec := freq; wh.nAvgBytesPerSec := freq * chan * bit div 8; wh.nBlockAlign := chan * bit div 8; wh.wBitsPerSample := bit; wh.data_ckid := mmioStringToFOURCC('data', 0); wh.data_cksize := 0; hFile := FileCreate(FilePath); Result := (FileWrite(hFile, wh, SizeOf(TWaveHeader)) <> -1); FileClose(hFile); end; //同上, 只是改用流来写文件 function CreateWav3(chan, freq, bit: Word; const FilePath: string): Boolean; type TWaveHeader = record Riff_ckid : DWORD; Riff_cksize : DWORD; Riff_fccType : DWORD; fmt_ckid : DWORD; fmt_cksize : DWORD; wFormatTag : Word; nChannels : Word; nSamplesPerSec : DWORD; nAvgBytesPerSec: DWORD; nBlockAlign : Word; wBitsPerSample : Word; data_ckid : DWORD; data_cksize : DWORD; end; var wh: TWaveHeader; begin wh.Riff_ckid := FOURCC_RIFF; wh.Riff_cksize := 36; wh.Riff_fccType := mmioStringToFOURCC('WAVE', 0); wh.fmt_ckid := mmioStringToFOURCC('fmt', 0); wh.fmt_cksize := 16; wh.wFormatTag := WAVE_FORMAT_PCM; wh.nChannels := chan; wh.nSamplesPerSec := freq; wh.nAvgBytesPerSec := freq * chan * bit div 8; wh.nBlockAlign := chan * bit div 8; wh.wBitsPerSample := bit; wh.data_ckid := mmioStringToFOURCC('data', 0); wh.data_cksize := 0; with TFileStream.Create(FilePath, fmCreate) do begin Result := (Write(wh, SizeOf(TWaveHeader)) = SizeOf(TWaveHeader)); Free; end; end; procedure TForm1.FormCreate(Sender: TObject); begin CreateWav1(1, 11025, 8, 'C:\Temp\X1.wav'); CreateWav2(2, 22050, 16, 'C:\Temp\X2.wav'); CreateWav3(2, 44100, 16, 'C:\Temp\X3.wav'); end; end.