(7): 建立一个空的 Wave 文件(三种方法)

unit Unit1; 
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. 

你可能感兴趣的:(操作Wave,文件系列)