不知道谁有用过这个很不错的声音控件TAudioIO,
用来对波形音频的录制和播放,还可同时显示声音的峰值,
下载地址:
http://www.csdn.net/dev/Delphi/vcl/multimedia/taudioio.zip我的问题是:
这个控件录音时只存到buffer中,
我想把录音的数据存成wav文件,不知道怎么做啊。
希望各位帮忙。先谢了。TAudioIO分成TAudioIn和TAudioOut,其中TAudioIn是用来录音的,
它有一个事件叫,AudioIn1BufferFilled().
这个事件在录音的过程中不停的被激活,
它是把产生的数据填入buffer中,然后产生声音峰值,
如何才能把这些buffer中的数据最终存成.wav文件呢。具体如下:
unit TAudioInputDemo;interfaceuses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, AudioIO, ExtCtrls, Buttons, ComCtrls, MMSYSTEM;type
  TForm1 = class(TForm)
    StartButton: TButton;
    Timer1: TTimer;
    StopButton: TButton;
    RunStatusLabel: TLabel;
    BufferStatusLabel: TLabel;
    TimeStatusLabel: TLabel;
    Panel1: TPanel;
    RecordSpeedButton: TSpeedButton;
    ProgressBar1: TProgressBar;
    MaxLabel: TLabel;
    AudioIn1: TAudioIn;
    procedure StartButtonClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure AudioIn1Stop(Sender: TObject);
    procedure UpdateStatus;
    procedure StopButtonClick(Sender: TObject);
    procedure RecordSpeedButtonClick(Sender: TObject);
    function AudioIn1BufferFilled(Buffer: PChar;
      var Size: Integer): Boolean;
  private
    { Private declarations }
  public
    { Public declarations }
    Min, Max : Integer;
    TempMax  : Integer;
  end;var
  Form1: TForm1;implementation{$R *.DFM}procedure TForm1.StartButtonClick(Sender: TObject);
begin
   If (Not AudioIn1.Start(AudioIn1)) Then ShowMessage(AudioIn1.ErrorMessage)
   Else
     Begin
        Min := 0;
        Max := 0;
        RecordSpeedButton.Down := TRUE;
     End;
end;function TForm1.AudioIn1BufferFilled(Buffer: PChar; var Size: Integer): Boolean;
Var
  SP    : ^SmallInt;
  i, N,  v  : Integer;
  xMin, xMax : Integer;begin
  N := Size Div 2;
  SP := Pointer(Buffer);
  xMin := SP^;
  xMax := xMin;
  For i := 0 to N-1 Do
     Begin
       v := SP^; Inc(SP);
       If (xMin > v) Then xMin := v;
       If (xMax < v) Then xMax := v;
     End;  If (Min > xMin) Then Min := xMin;
  If (Max < xMax) Then Max := xMax;  TempMax := xMax;
  If (Abs(xMin) > xMax) Then TempMax := Abs(xMin);
  Result := TRUE;
end;Procedure TForm1.UpdateStatus;
begin
  With AudioIn1 Do
   If (AudioIn1.Active) Then
     Begin
       RunStatusLabel.Caption := 'Started';
       BufferStatusLabel.Caption := Format('Queued: %3d;  Processed: %3d',[QueuedBuffers, ProcessedBuffers]);
       TimeStatusLabel.Caption := Format('Seconds %.3n',[ElapsedTime]);
     End
   Else
     Begin
       RunStatusLabel.Caption := 'Stopped';
       BufferStatusLabel.Caption := '';
       TimeStatusLabel.Caption := '';
     End;   { Update the progress bar }
   If (AudioIn1.Active) Then
     Begin
       ProgressBar1.Position := Round(100*TempMax/36768.0);
       If (Abs(Min) > Max) Then Max := Abs(Min);
       MaxLabel.Caption := Format('Max %5d;  Peak %5d',[Max,TempMax]);
     End
   Else
     Begin
       ProgressBar1.Position := 0;
       MaxLabel.Caption := '';
     End;End;procedure TForm1.Timer1Timer(Sender: TObject);
begin
  UpdateStatus;
end;procedure TForm1.AudioIn1Stop(Sender: TObject);
begin
   RecordSpeedButton.Down := FALSE;
end;
procedure TForm1.StopButtonClick(Sender: TObject);
begin
  AudioIn1.StopAtOnce;
end;procedure TForm1.RecordSpeedButtonClick(Sender: TObject);
begin
  If (RecordSpeedButton.Down) Then
     StartButtonClick(Sender)
  Else
     AudioIn1.StopAtOnce;
end;end.

解决方案 »

  1.   

    怎么没有人回答?就是声音已经存到buffer中,怎样才能从buffer中输出到wav文件中?谢谢。
      

  2.   

    我帮你改了一下,在D7下通过,代码如下:
    unit TAudioInputDemo;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, AudioIO, ExtCtrls, Buttons, ComCtrls, MMSYSTEM;type
      TWaveHeader = record   
        rId : longint;      //固定标记 值为"RIFF"
        rLen : longint;     //随后的字节数   值为文件大小-8
        wId : longint;     //固定标记 值为"WAVE"
        fId : longint;     //ckID 值为"fmt "
        fLen : longint;     //nChunkSize Wave文件块的大小  16
        wFormatTag : word; //音频数据的编码方式 此值常为1 表示PCM方式
        nChannels : word;      //声道数
        nSamplesPerSec : longint;  //每秒采样频率
        nAvgBytesPerSec : longint;  //每秒字节数
        nBlockAlign : word;       //一次输出的字节数  值为采样位数*声道数/8
        wBitsPerSample : word;     //采样位数  一般16位和8位
        dId : longint;           //固定标记  值为"data"
        wSampleLength : longint;   //采样数据长度 值为文件大小-文件头大小(44)  
      end;  TForm1 = class(TForm)
        StartButton: TButton;
        Timer1: TTimer;
        StopButton: TButton;
        RunStatusLabel: TLabel;
        BufferStatusLabel: TLabel;
        TimeStatusLabel: TLabel;
        Panel1: TPanel;
        RecordSpeedButton: TSpeedButton;
        ProgressBar1: TProgressBar;
        MaxLabel: TLabel;
        AudioIn1: TAudioIn;
        Label1: TLabel;
        procedure StartButtonClick(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
        procedure AudioIn1Stop(Sender: TObject);
        procedure UpdateStatus;
        procedure StopButtonClick(Sender: TObject);
        procedure RecordSpeedButtonClick(Sender: TObject);
        function AudioIn1BufferFilled(Buffer: PAnsiChar;
          var Size: Integer): Boolean;
      private  public
        { Public declarations }
        WaveHeader : TWaveHeader ;
        fs : TFileStream ;
        Min, Max : Integer;
        TempMax  : Integer;
      end;var
      Form1: TForm1;implementation{$R *.DFM}procedure TForm1.StartButtonClick(Sender: TObject);
    begin   fs := TFileStream.Create('d:\b.wav',fmCreate);
       WaveHeader.rId := $46464952;
       WaveHeader.wId := $45564157;
       WaveHeader.fId := $20746d66;
       WaveHeader.dId := $61746164;
       WaveHeader.wFormatTag := 1 ;
       WaveHeader.nChannels :=2;
       WaveHeader.nSamplesPerSec := 11025;
       WaveHeader.wBitsPerSample := 16;
       WaveHeader.wSampleLength  := 0;
       WaveHeader.fLen := WaveHeader.wBitsPerSample;
       WaveHeader.nAvgBytesPerSec := WaveHeader.wBitsPerSample *
                                    WaveHeader.nSamplesPerSec *
                                    WaveHeader.nChannels div 8;
       WaveHeader.nBlockAlign := WaveHeader.wBitsPerSample*WaveHeader.nChannels div 8;
       fs.Write(WaveHeader,Sizeof(WaveHeader));   If (Not AudioIn1.Start(AudioIn1)) Then ShowMessage(AudioIn1.ErrorMessage)
       Else
         Begin
            Min := 0;
            Max := 0;
            RecordSpeedButton.Down := TRUE;
         End;
    end;Procedure TForm1.UpdateStatus;
    begin
      With AudioIn1 Do
       If (AudioIn1.Active) Then
         Begin
           RunStatusLabel.Caption := 'Started';
           BufferStatusLabel.Caption := Format('Queued: %3d;  Processed: %3d',[QueuedBuffers, ProcessedBuffers]);
           TimeStatusLabel.Caption := Format('Seconds %.3n',[ElapsedTime]);
         End
       Else
         Begin
           RunStatusLabel.Caption := 'Stopped';
           BufferStatusLabel.Caption := '';
           TimeStatusLabel.Caption := '';
         End;   { Update the progress bar }
       If (AudioIn1.Active) Then
         Begin
           ProgressBar1.Position := Round(100*TempMax/36768.0);
           If (Abs(Min) > Max) Then Max := Abs(Min);
           MaxLabel.Caption := Format('Max %5d;  Peak %5d',[Max,TempMax]);
         End
       Else
         Begin
           ProgressBar1.Position := 0;
           MaxLabel.Caption := '';
         End;End;procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      UpdateStatus;
    end;procedure TForm1.AudioIn1Stop(Sender: TObject);
    begin
       RecordSpeedButton.Down := FALSE;
    end;
    procedure TForm1.StopButtonClick(Sender: TObject);
    begin
      AudioIn1.StopAtOnce;
      WaveHeader.rLen := WaveHeader.wSampleLength+36;
      fs.Seek(0,soFromBeginning);
      fs.Write(WaveHeader,Sizeof(WaveHeader));
      fs.Free;
    end;procedure TForm1.RecordSpeedButtonClick(Sender: TObject);
    begin
      If (RecordSpeedButton.Down) Then
         StartButtonClick(Sender)
      Else
         AudioIn1.StopAtOnce;
    end;function TForm1.AudioIn1BufferFilled(Buffer: PAnsiChar;
      var Size: Integer): Boolean;
    Var
      SP    : ^SmallInt;
      i, N,  v  : Integer;
      xMin, xMax : Integer;
    begin
      fs.Write(buffer^,Size);
      WaveHeader.wSampleLength := WaveHeader.wSampleLength + Size;
      Label1.Caption := IntToStr(WaveHeader.wSampleLength);  N := Size Div 2;
      SP := Pointer(Buffer);
      xMin := SP^;
      xMax := xMin;  For i := 0 to N-1 Do
         Begin
           v := SP^; Inc(SP);
           If (xMin > v) Then xMin := v;
           If (xMax < v) Then xMax := v;
         End;  If (Min > xMin) Then Min := xMin;
      If (Max < xMax) Then Max := xMax;  TempMax := xMax;
      If (Abs(xMin) > xMax) Then TempMax := Abs(xMin);
      Result := TRUE;
    end;end.
      

  3.   

    最好请将procedure TForm1.StartButtonClick(Sender: TObject);过程中的
       WaveHeader.nChannels :=2;
       WaveHeader.nSamplesPerSec := 11025;
       WaveHeader.wBitsPerSample := 16;
    成如下
       if AudioIn1.Stereo then WaveHeader.nChannels :=2
       else WaveHeader.nChannels := 1;
       WaveHeader.nSamplesPerSec := AudioIn1.FrameRate;
       WaveHeader.wBitsPerSample := AudioIn1.Quantization;