{归拢多少个 Wav 文件的函数}

合并两个 Wav 文件的函数

图片 1
unit Unit1;

图片 2
unit Unit1;

实例一

interface

interface

unit Unit1;

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
MMSystem;{引用mmsystem单元}
const
FNumBuffers = 4;

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

interface

type TACMWAVEFORMAT = packed record
    case Integer of
      0: (Format: twaveformatex);
      1: (Rawdata: array[0..128] of byte);
end;

type
TForm1 = class(TForm)
    CheckBox1: TCheckBox;
    Button1: TButton;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    ComboBox1: TComboBox;
    ComboBox2: TComboBox;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
private
    n, T: integer;
    ACMI: TACMIn;
    ACMO: TACMOut;
    ACMC: TACMConvertor;
    procedure BufferFull(Sender: TObject; Data: Pointer; Size: Integer);
    procedure ShowSize(var Msg: TMessage); message WM_USER;
public
    { Public declarations }
end;

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

type
TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
private
    FBufferSize :integer;
    FWaveInHandle: HWaveIn;
    WaveFmt: TACMWAVEFORMAT;
public
    { Public declarations }
end;

var
Form1: TForm1;

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

var
Form1: TForm1;

implementation

var
Form1: TForm1;

implementation

{$R *.dfm}

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
ACMO := TACMOut.Create(nil);
ACMC := TACMConvertor.Create;
ACMO.NumBuffers := 0;
ACMO.Open(ACMC.FormatIn);
end;

{$R *.dfm}

procedure WaveInCallback(hWave: HWAVEIN; uMsg: cardinal; pform1: tform1; dwParam1, dwParam2: cardinal) stdcall;

procedure TForm1.FormDestroy(Sender: TObject);
begin
ACMC.Active := False;
ACMC.Free;
ACMO.Close;
ACMO.Free;
ACMI.Free;
end;

{合并两个 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;

var
Header: PWaveHdr;
Res: Integer;
BytesRecorded: Integer;
Data: Pointer;
begin
if (uMsg = MM_WIM_DATA) then
begin
    header := PWaveHdr(dwParam1);
    Res := WaveInUnPrepareHeader(hWave, Header, sizeof(TWavehdr));
    if Res <> 0 then Exit;
    BytesRecorded := header.dwBytesRecorded;
    begin
      Getmem(Data, BytesRecorded);
      try
        move(header.lpData^, Data^, BytesRecorded);
         {此处进行数据处理 采集的data }
        pform1.Label1.Caption := Format(' %0.1f KB/S', [BytesRecorded / 1024]);

procedure TForm1.Button1Click(Sender: TObject);
begin
ACMI := TACMIn.Create;
ACMI.OnBufferFull := BufferFull;
if ComboBox2.Text = 'Stereo' then ACMC.FormatIn.Format.nChannels := 2
else ACMC.FormatIn.Format.nChannels := 1;
ACMC.FormatIn.Format.nSamplesPerSec := StrToInt(ComboBox1.Text);
   ACMC.FormatIn.Format.wBitsPerSample := 16;
ACMC.FormatIn.Format.nBlockAlign := (ACMC.FormatIn.Format.wBitsPerSample div 8) * ACMC.FormatIn.Format.nChannels;
ACMC.FormatIn.Format.nAvgBytesPerSec := ACMC.FormatIn.Format.nSamplesPerSec * ACMC.FormatIn.Format.nBlockAlign;

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

      finally
        Freemem(Data);
      end;

ACMC.InputBufferSize := ACMC.FormatIn.Format.nAvgBytesPerSec;
ACMI.BufferSize := ACMC.InputBufferSize;
ACMC.Active := True;
ACMI.Open(ACMC.FormatIn);
t := getTickCount;
end;
{声音充满缓冲区在此得到声音数据DATA……}
procedure Tform1.BufferFull(Sender: TObject; Data: Pointer; Size: Integer);
var
NewSize: Integer;
begin
Move(Data^, ACMC.BufferIn^, Size);
NewSize := ACMC.Convert;
Application.ProcessMessages;
inc(n, newsize);
if getTickCount - t >= 1000 then //每秒数据流量
begin
    SendMessage(Handle, WM_USER, n, 0);
    t := getTickCount;
    n := 0;
end;

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

      {清空缓冲区,并添加到录音设备}
      header.dwbufferlength := pform1.FBufferSize;
      header.dwBytesRecorded := 0;
      header.dwUser := 0;
      header.dwflags := 0;
      header.dwloops := 0;
      FillMemory(Header.lpData, pform1.FBufferSize, 0);
      Res := WaveInPrepareHeader(hWave, Header, sizeof(TWavehdr));
      if Res <> 0 then Exit;
      Res := WaveInAddBuffer(hWave, Header, sizeof(TWaveHdr));
      if Res <> 0 then Exit;
    end;
end;
end;

//自己的方式传输声音数据 ~.WriteBuffer(ACMC.BufferOut^, NewSize);
    //网络传输数据......//
//接受数据(ACMC.BufferOut^, NewSize)

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)

procedure TForm1.Button1Click(Sender: TObject);
var
Res: Integer;
J: Integer;
Header: PWaveHdr;
begin
FWaveInHandle := 0;
/////////////////////////////////////
/////////GSM 6.10////////////
/////////////////////////////////////
WaveFmt.Format.wFormatTag := 49;
WaveFmt.Format.nChannels := 1;
                                                            {1k/s       2k          4k     8k}
WaveFmt.Format.nSamplesPerSec := 8000; //11025//22050//44100
WaveFmt.Format.nAvgBytesPerSec := 1625;//2239//4478//8957
WaveFmt.Format.nBlockAlign := 65;
WaveFmt.Format.wBitsPerSample := 0;
WaveFmt.Format.cbSize := 2;
Wavefmt.Rawdata[18] := 64;
Wavefmt.Rawdata[19] := 1;

{声音输出}
if not checkbox1.Checked then ACMO.Play(ACMC.Bufferout^, NewSize);

  • 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}

FBufferSize :=WaveFmt.Format.nAvgBytesPerSec;
{用回调函数取得采集的音频数据}
res := WaveInOpen(@FWaveInHandle, WAVE_MAPPER, @Wavefmt, cardinal(@WaveInCallback), cardinal(Self), CALLBACK_FUNCTION);
if Res <> 0 then exit;

end;

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

{为音频输入设备一次添加多个缓冲区,这些缓冲区有系统调度}

procedure TForm1.ShowSize(var Msg: TMessage);
begin
Caption := Format('AUDIO %0.1fK/s', [Msg.WParam / 1024]);
end;

end.

for j := 1 to FNumBuffers do
begin
    Getmem(Header, SizeOf(TWaveHDR));
    with Header^ do begin
      Getmem(lpData, FBufferSize);
      dwBufferLength := FBufferSize;
      dwBytesRecorded := 0;
      dwFlags := 0;
      dwLoops := 0;
      Res := WaveInPrepareHeader(FWaveInHandle, Header, sizeof(TWaveHDR));
      if Res <> 0 then Exit;
      Res := WaveInAddBuffer(FWaveInHandle, Header, SizeOf(TWaveHDR));
      if Res <> 0 then Exit;
    end;
end;
Res := WaveInStart(FWaveInHandle);
if Res <> 0 then exit;
end;

end.
///////////////////////

实例二

{ WaveFmt.Format.wFormatTag := 49;
   WaveFmt.Format.nChannels := 1;
   WaveFmt.Format.nSamplesPerSec := 22050;
   WaveFmt.Format.nAvgBytesPerSec := 4478;
   WaveFmt.Format.nBlockAlign := 65;
   WaveFmt.Format.wBitsPerSample := 0;
   WaveFmt.Format.cbSize := 2;
   Wavefmt.Rawdata[18] := 64;
   Wavefmt.Rawdata[19] := 1;
}

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.

本文由美高梅4688官方网站发布于最新话题,转载请注明出处:{归拢多少个 Wav 文件的函数}

您可能还会对下面的文章感兴趣: