delphi 合并两个 Wav 文件流的函数

合并两个 Wav 文件的函数

实例一

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.

实例二

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

Button2: TButton;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

uses MMSystem;

{合并两个 Wav 文件流的函数}

function ConWavStream(AWavStream1, AWavStream2: TStream; var ANewStream: TStream): 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;

vChunkSize1, vChunkSize2: Integer;

begin

Result := False;

if AWavStream1.Read(vWavFormat1, SizeOf(TWavFormat)) <> SizeOf(TWavFormat) then Exit;

if AWavStream2.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; {格式不同}

vWavFormat1.ChunkSize := vChunkSize1 + vChunkSize2 + SizeOf(vWavFormat1) - 8;

vWavFormat1.SubChunk2Size := vChunkSize1 + vChunkSize2;

ANewStream.Write(vWavFormat1, SizeOf(TWavFormat));

ANewStream.CopyFrom(AWavStream1, vChunkSize1);

ANewStream.CopyFrom(AWavStream2, vChunkSize2);

Result := True;

end; { ConWavStream End}

var

WavStream: TStream;

{合并两个资源流; 之前要在资源中分别加载两个 WAV 文件, 并分别命名: wav1、wav2}

procedure TForm1.FormCreate(Sender: TObject);

var

rs1,rs2: TResourceStream;

begin

rs1 := TResourceStream.Create(HInstance, 'wav1', RT_RCDATA);

rs2 := TResourceStream.Create(HInstance, 'wav2', RT_RCDATA);

WavStream := TMemoryStream.Create;

ConWavStream(rs1, rs2, WavStream);

rs1.Free;

rs2.Free;

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

WavStream.Free;

end;

{循环播放}

procedure TForm1.Button1Click(Sender: TObject);

begin

sndPlaySound(TMemoryStream(WavStream).Memory, SND_ASYNC or SND_MEMORY or SND_LOOP);

end;

{暂停}

procedure TForm1.Button2Click(Sender: TObject);

begin

sndPlaySound(nil, 0);

end;

end.