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



    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.
    
  • 相关阅读:
    Mapreduce实例——MapReduce自定义输出格式
    Mapreduce实例——MapReduce自定义输入格式
    Mapreduce实例——ChainMapReduce
    Mapreduce实例——倒排索引
    Cache 和 Buffer 都是缓存,主要区别是什么?
    Pycharm 2019 破解激活方法
    Python 两个list合并成一个字典
    Python中常见字符串去除空格的方法总结
    操作的系统的PV操作
    信号与信号量的区别
  • 原文地址:https://www.cnblogs.com/del/p/1599435.html
Copyright © 2020-2023  润新知