delphi 合并两个 Wav 文件流的函数
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.