unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{合并两个 Wav 文件的函数}
function ConWavFile(AWavFile1, AWavFile2, ANewFile: string): Boolean;
type
  TWavFormat = packed record
    ChunkID: array[0..3] of AnsiChar;     {'RIFF'}
    ChunkSize: Longword;                  {size-8}
    Format: array[0..3] of AnsiChar;      {'WAVE'}
    SubChunk1ID: array[0..3] of AnsiChar; {'fmt '}
    SubChunk1Size: Longword;              {hex10}
    AudioFormat: Word;                    {hex 01}
    NumOfChannels: Word;                  {1 mono, 2 stereo}
    SampleRate: Longword;                 {number of samples/sec}
    ByteRate: Longword;                   {samplerate* num of channels*bytes per (mono) sample}
    BytesperSample: Word;                 {size of (mono) sample}
    BitsPerSample: Word;                  {BytesperSample *8}
    SubChunk2ID: array[0..3] of AnsiChar; {'data'}
    SubChunk2Size: Longword;              {number of data bytes}
  end;
var
  vWavFormat1: TWavFormat;
  vWavFormat2: TWavFormat;
  vFileHandle1: THandle;
  vFileHandle2: THandle;
  vFileStream1: TFileStream;
  vFileStream2: TFileStream;
  vChunkSize1, vChunkSize2: Integer;
begin
  Result := False;
  if not FileExists(AWavFile1) then Exit;
  if not FileExists(AWavFile2) then Exit;

  vFileHandle1 := _lopen(PAnsiChar(AnsiString(AWavFile1)), OF_READ or OF_SHARE_DENY_NONE);
  vFileHandle2 := _lopen(PAnsiChar(AnsiString(AWavFile2)), OF_READ or OF_SHARE_DENY_NONE);

  if (Integer(vFileHandle1) <= 0) or (Integer(vFileHandle2) <= 0) then
  begin
    _lclose(vFileHandle1);
    _lclose(vFileHandle2);
    Exit;
  end;

  vFileStream1 := TFileStream.Create(vFileHandle1);
  vFileStream2 := TFileStream.Create(vFileHandle2);
  try
    if vFileStream1.Read(vWavFormat1, SizeOf(TWavFormat)) <> SizeOf(TWavFormat) then Exit;
    if vFileStream2.Read(vWavFormat2, SizeOf(TWavFormat)) <> SizeOf(TWavFormat) then Exit;
    if vWavFormat1.ChunkID <> 'RIFF' then Exit;
    if vWavFormat1.SubChunk2ID <> 'data' then Exit;
    vChunkSize1 := vWavFormat1.SubChunk2Size;
    vChunkSize2 := vWavFormat2.SubChunk2Size;
    vWavFormat1.ChunkSize := 0;
    vWavFormat1.SubChunk2Size := 0;
    vWavFormat2.ChunkSize := 0;
    vWavFormat2.SubChunk2Size := 0;
    if not CompareMem(@vWavFormat1, @vWavFormat2, SizeOf(TWavFormat)) then Exit; {格式不同}
    with TMemoryStream.Create do try
      vWavFormat1.ChunkSize := vChunkSize1 + vChunkSize2 + SizeOf(vWavFormat1) - 8;
      vWavFormat1.SubChunk2Size := vChunkSize1 + vChunkSize2;
      Write(vWavFormat1, SizeOf(TWavFormat));
      CopyFrom(vFileStream1, vChunkSize1);
      CopyFrom(vFileStream2, vChunkSize2);
      try
        SaveToFile(ANewFile);
      except
        Exit;
      end;
    finally
      Free;
    end;
  finally
    vFileStream1.Free;
    vFileStream2.Free;
  end;
  Result := True;
end; { ConWavFile End}


{测试}
procedure TForm1.Button1Click(Sender: TObject);
var
  Wav1,Wav2,WavDest: string;
begin
  Wav1 := 'c:\temp\1.wav';
  Wav2 := 'c:\temp\2.wav';
  WavDest := 'c:\temp\12.wav';
  if ConWavFile(Wav1, Wav2, WavDest) then
    ShowMessageFmt('''%s'' 和 ''%s'' 已成功合并到 ''%s''', [Wav1,Wav2,WavDest]);
end;

end.

分类:

技术点:

相关文章:

相关资源