zoukankan      html  css  js  c++  java
  • 操作 Wave 文件(15): 合并与剪裁 wav 文件


    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    uses MMSystem;
    
    //从指定 wav 文件中获取格式信息和波形数据的函数
    function GetWaveFmtData(const path: string; var fmt: TWaveFormatEx; var buf: TBytes): Boolean;
    var
      hFile: HMMIO;
      ckiRIFF,ckiFmt,ckiData: TMMCKInfo;
    begin
      Result := False;
      hFile := mmioOpen(PChar(path), nil, MMIO_READ);
      if hFile = 0 then Exit;
      ZeroMemory(@ckiRIFF, SizeOf(TMMCKInfo));
      ZeroMemory(@ckiFmt, SizeOf(TMMCKInfo));
      ZeroMemory(@ckiData, SizeOf(TMMCKInfo));
      ckiRIFF.fccType := mmioStringToFOURCC('WAVE', 0);
      ckiFmt.ckid := mmioStringToFOURCC('fmt', 0);
      ckiData.ckid := mmioStringToFOURCC('data', 0);
      ZeroMemory(@fmt, SizeOf(TWaveFormatEx));
      mmioDescend(hFile, @ckiRIFF, nil, MMIO_FINDRIFF);
      if (ckiRIFF.ckid = FOURCC_RIFF) and (ckiRIFF.fccType = mmioStringToFOURCC('WAVE',0)) and
         (mmioDescend(hFile, @ckiFmt, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) and
         (mmioRead(hFile, @fmt, ckiFmt.cksize) = ckiFmt.cksize) and
         (mmioAscend(hFile, @ckiFmt, 0) = MMSYSERR_NOERROR) and
         (mmioDescend(hFile, @ckiData, @ckiRIFF, MMIO_FINDCHUNK) = MMSYSERR_NOERROR) then
      begin
        SetLength(buf, ckiData.cksize);
        Result := (mmioRead(hFile, PAnsiChar(buf), ckiData.cksize) = ckiData.cksize);
      end;
      mmioClose(hFile, 0);
    end;
    
    //根据格式信息和波形数据建立 wav 文件的函数
    function CreateWave(const path: string; const fmt: TWaveFormatEx; const buf: TBytes): Boolean;
    var
      h: HMMIO;
      ckiRiff, ckiFmt, ckiData: TMMCKInfo;
    begin
      ZeroMemory(@ckiRiff, SizeOf(TMMCKInfo));
      ckiRiff.cksize := 44 - 8 + Length(buf);
      ckiRiff.fccType := mmioStringToFOURCC('WAVE', 0);
    
      ZeroMemory(@ckiFmt, SizeOf(TMMCKInfo));
      ckiFmt.ckid := mmioStringToFOURCC('fmt', 0);
    
      ZeroMemory(@ckiData, SizeOf(TMMCKInfo));
      ckiData.ckid := mmioStringToFOURCC('data', 0);
      ckiData.cksize := Length(buf);
    
      h := mmioOpen(PChar(path), nil, MMIO_CREATE or MMIO_WRITE);
      if (h <> 0) and (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 := (mmioWrite(h, PAnsiChar(buf), Length(buf)) = Length(buf));
      mmioClose(h, 0);
    end;
    
    
    //截取 wav 文件, 本例截留了文件的 1/4
    procedure TForm1.Button1Click(Sender: TObject);
    const
      pathSource = 'C:\WINDOWS\Media\Windows XP 启动.wav';
      pathDest = 'C:\Temp\New1.wav';
    var
      fmt: TWaveFormatEx;
      buf: TBytes;
    begin
      GetWaveFmtData(pathSource, fmt, buf);
      SetLength(buf, Length(buf) div 4);
      CreateWave(pathDest, fmt, buf);
    end;
    
    //合并 wav 文件
    procedure TForm1.Button2Click(Sender: TObject);
    const
      path1 = 'C:\WINDOWS\Media\Windows XP 启动.wav';
      path2 = 'C:\WINDOWS\Media\Windows XP 关机.wav';
      pathDest = 'C:\Temp\New2.wav';
    var
      fmt1,fmt2: TWaveFormatEx;
      buf1,buf2: TBytes;
      oldLen: Integer;
    begin
      GetWaveFmtData(path1, fmt1, buf1);
      GetWaveFmtData(path2, fmt2, buf2);
    
      if CompareMem(@fmt1, @fmt2, SizeOf(TWaveFormatEx)) then
      begin
        oldLen := Length(buf1);
        SetLength(buf1, Length(buf1) + Length(buf2));
        CopyMemory(@buf1[oldLen], Pointer(buf2), Length(buf2));
        CreateWave(pathDest, fmt1, buf1);
      end else ShowMessage('文件格式不一致, 没有执行合并!');
    end;
    
    end.
    
  • 相关阅读:
    Combine 框架,从0到1 —— 4.在 Combine 中使用计时器
    Combine 框架,从0到1 —— 4.在 Combine 中使用通知
    Combine 框架,从0到1 —— 3.使用 Subscriber 控制发布速度
    Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
    使用 Swift Package Manager 集成依赖库
    iOS 高效灵活地配置可复用视图组件的主题
    构建个人博客网站(基于Python Flask)
    Swift dynamic关键字
    Swift @objcMembers
    仅用递归函数操作逆序一个栈(Swift 4)
  • 原文地址:https://www.cnblogs.com/del/p/1601905.html
Copyright © 2011-2022 走看看