unit Unit1;
interface 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls,MMsystem; 
type  
  //定义一个Wave文件头 
  TWaveHeader=record 
              rId:longint;    //固定标记,值为"RIFF" 
              rLen:longint;    //随后的字节数,值为(wSampleLength+36) 
              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;  
TRecorder = class 
  private 
    { Private declarations }
  public 
    { Public declarations } 
    FWaveFmt:TWaveFormatEx;//指向PCMWAVEFORMAT数据结构的指针,重新封装后包括PCMWAVEFORMAT和WAVEFORMAT 
    WaveHandle:HWaveIn;//设备句柄 
    WaveHdr1:PWAVEHDR; // 为采样数据分配缓冲空间 1 
    WaveHdr2:PWAVEHDR; // 为采样数据分配缓冲空间 2 
    WaveBuffer1:lpstr;  //数据缓冲1 
    WaveBuffer2:lpstr;  //数据缓冲2 
    Procedure CallBack(uMsg,dwInstance,dwParam1,dwParam2:DWORD);stdcall; 
end; 
  
  TForm1 = class(TForm)
    initial: TButton;
    start: TButton;
    stop: TButton;
    close: TButton;
    Label1: TLabel;
    procedure startClick(Sender: TObject);
    procedure stopClick(Sender: TObject);
    procedure initialClick(Sender: TObject);
    procedure FormCreate(Sender: TObject); 
    //channelse为声道数,resolution为采样位数,rate为采样频率,fn为对应的文件名称 
    procedure CreateWave(channels:word;resolution:word;rate:longint;fn:string); 
    procedure closeClick(Sender: TObject);
  private
    { Private declarations }
  public 
    { Public declarations }
  end; 
var 
  Form1: TForm1; 
  Recorder:TRecorder; 
  //定义一个缓冲控制变量 
  flag:integer;  
implementation 
{$R *.dfm} 
Procedure TRecorder.CallBack(uMsg,dwInstance,dwParam1,dwParam2:DWORD);stdcall;//回调函数声明 
var
i,k:integer; //循环变量
SPByte:^Byte;  //假设在打开设备时采用8位量化 
SingleData:Integer;
fd:TFileStream;    //保存结果
f:textfile;
begin
//******************************************// 
case uMsg of //
      MM_WIM_OPEN : //波形输入设备成功打开发回的消息
      begin
        application.MessageBox('波形输入设备成功打开','ok',mb_OK);
      end;
      //感觉是以下部分出了错[/b]
      MM_WIM_DATA : //一个缓冲区已满发回的消息处理,此处需要修改
          begin
                if(flag=0) then
                  begin
                      form1.Label1.caption:='ok1';
                      WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,sizeof(TWAVEHDR)); 
                      WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
                      WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
                      flag:=1;
                  end 
                else 
                  begin
                  form1.Label1.caption:='ok2';
                  WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,sizeof(TWAVEHDR)); 
                  WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR)); 
                  WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR)); 
                  flag:=0; 
                  end; 
                SPByte:=Pointer(dwParam1);
            //////////////////////////////////////////////////  
            fd:=TFileStream.Create('C:\test.wav',fmCreate);            
            for i:=0 to 1023 do  // Recorder.DataLength-1
                  begin 
                    SingleData:=SPByte^;//通过SPByte来访问缓冲区的数据 
                    //application.MessageBox(StrtoInt(SingleData),'');
                    /////////////////此处有内容省略
                    fd.read(SingleData,sizeof(SingleData));
                    write('C:\test.wav', SingleData);
                    Inc(SPByte);//Increments an ordinal value by one or N.
                  end;
                    fd.Free; //closefile(f);
              if(flag=1) then
              begin
                  //dispose(Recorder.WaveHdr1.lpData);
                 //dispose(Recorder.WaveHdr1);
              end 
              else 
              begin 
                  //dispose(Recorder.WaveHdr2.lpData);
                 //dispose(Recorder.WaveHdr2);
              end;
          end; 
      MM_WIM_CLOSE : //波形输入设备关闭成功发回的消息 
    //释放内存 
          begin;    
            WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,sizeof(TWAVEHDR));//解除置换保护
            WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,sizeof(TWAVEHDR));
            GlobalFreePtr(Recorder.WaveBuffer1); //释放分配的内存
            GlobalFreePtr(Recorder.WaveBuffer2); //释放分配的内存
            application.MessageBox('录音设备已经关闭','Congratuations!',mb_OK);
            end;
      end; 
end; 
procedure TForm1.CreateWave(channels:word;resolution:word;rate:longint;fn:string);
var 
wf : file of TWaveHeader;
wh : TWaveHeader; 
begin
wh.rId := $46464952;
wh.rLen:= 36; 
wh.wId := $45564157; 
wh.fId := $20746d66; 
wh.fLen:= 16; 
wh.wFormatTag:= 1; 
wh.nChannels := channels; 
wh.nSamplesPerSec:= rate;
wh.nAvgBytesPerSec := channels*rate*(resolution div 8);
wh.nBlockAlign:= channels*(resolution div 8); 
wh.wBitsPerSample:= resolution; 
wh.dId := $61746164; 
wh.wSampleLength:= 0;
assignfile(wf,fn); {打开对应文件 }
rewrite(wf); {移动指针到文件头}
write(wf,wh);{写进文件头}
closefile(wf);{关闭文件}
end;
procedure TForm1.startClick(Sender: TObject);
begin
 //开始录音
//检验
WaveInStart(Recorder.WaveHandle);
if(WaveInStart(Recorder.WaveHandle)<>0) then application.MessageBox('Strart error/启动波形输入设备错误','Error',mb_OK);
initial.Enabled:=FALSE;
//stop.Enabled:=TRUE;
end;

解决方案 »

  1.   


    procedure TForm1.stopClick(Sender: TObject);
    begin 
    WaveInStop(Recorder.WaveHandle);        //停止录音 
    WaveInReset(Recorder.WaveHandle);      //  重置语音射入设备 
    WaveInClose(Recorder.WaveHandle);      //  关闭语音射入设备
    application.MessageBox('关闭录音设备','Congratuations!',mb_OK);
    initial.Enabled:=TRUE; 
    //start.Enabled:=TRUE;
    //stop.Enabled:=FALSE;
    //close.Enabled:=TRUE;
    end;
    procedure TForm1.initialClick(Sender: TObject);
    begin
      CreateWave(1,8,11025,'d:\test.wav');// 创建文件头  flag:=0;
    //设置我们需要的格式
      Recorder:=TRecorder.Create;
      Recorder.FWaveFmt.wFormatTag:=WAVE_FORMAT_PCM; 
      Recorder.FWaveFmt.nChannels:=1;
      Recorder.FWaveFmt.wBitsPerSample:=8;  
      Recorder.FWaveFmt.nSamplesPerSec:=11025; 
      Recorder.FWaveFmt.nAvgBytesPerSec:=11025;
      Recorder.FWaveFmt.nBlockAlign:=2;
      WaveInOpen(@Recorder.WaveHandle,Wave_Mapper,(@Recorder.FWaveFmt),DWORD(@TRecorder.CallBack),DWORD(@Recorder),CALLBACK_FUNCTION + WAVE_ALLOWSYNC);  //打开波形输入设备//*********************//
    //为采样分配缓冲空间 
      Recorder.WaveHdr1:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间 
      Recorder.WaveBuffer1:=GlobalAllocPtr(GHND or GMEM_SHARE,1024); //为Buffer1分配内存空间
      Recorder.WaveHdr1.lpData:=Recorder.WaveBuffer1;
      Recorder.WaveHdr1.dwBufferLength:=1024;
      Recorder.WaveHdr2:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间 
      Recorder.WaveBuffer2:=GlobalAllocPtr(GHND or GMEM_SHARE,1024);//为Buffer2分配内存空间
      Recorder.WaveHdr2.lpData:=Recorder.WaveBuffer2;// 
      Recorder.WaveHdr2.dwBufferLength:=1024;
      WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));  
      WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR)); 
      WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));//将缓冲区送往波形输入设备
      WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
      //start.Enabled:=TRUE;end;procedure TForm1.FormCreate(Sender: TObject); 
    begin 
    //判断是否有声卡 
    if (WaveInGetNumDevs()=0) then 
       application.MessageBox('There is no recording sound cadd in your computer!','Error',mb_OK)
    else
       application.MessageBox('There is a recording sound cadd in your computer!','ok',mb_OK)
    end;
    procedure TForm1.closeClick(Sender: TObject);
    begin 
    waveInStop(Recorder.WaveHandle);
    waveInClose(Recorder.WaveHandle);
    end;
    end.
      

  2.   


    procedure TForm1.stopClick(Sender: TObject);
    begin 
    WaveInStop(Recorder.WaveHandle);        //停止录音 
    WaveInReset(Recorder.WaveHandle);      //  重置语音射入设备 
    WaveInClose(Recorder.WaveHandle);      //  关闭语音射入设备
    application.MessageBox('关闭录音设备','Congratuations!',mb_OK);
    initial.Enabled:=TRUE; 
    //start.Enabled:=TRUE;
    //stop.Enabled:=FALSE;
    //close.Enabled:=TRUE;
    end;
    procedure TForm1.initialClick(Sender: TObject);
    begin
      CreateWave(1,8,11025,'d:\test.wav');// 创建文件头  flag:=0;
    //设置我们需要的格式
      Recorder:=TRecorder.Create;
      Recorder.FWaveFmt.wFormatTag:=WAVE_FORMAT_PCM; 
      Recorder.FWaveFmt.nChannels:=1;
      Recorder.FWaveFmt.wBitsPerSample:=8;  
      Recorder.FWaveFmt.nSamplesPerSec:=11025; 
      Recorder.FWaveFmt.nAvgBytesPerSec:=11025;
      Recorder.FWaveFmt.nBlockAlign:=2;
      WaveInOpen(@Recorder.WaveHandle,Wave_Mapper,(@Recorder.FWaveFmt),DWORD(@TRecorder.CallBack),DWORD(@Recorder),CALLBACK_FUNCTION + WAVE_ALLOWSYNC);  //打开波形输入设备//*********************//
    //为采样分配缓冲空间 
      Recorder.WaveHdr1:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间 
      Recorder.WaveBuffer1:=GlobalAllocPtr(GHND or GMEM_SHARE,1024); //为Buffer1分配内存空间
      Recorder.WaveHdr1.lpData:=Recorder.WaveBuffer1;
      Recorder.WaveHdr1.dwBufferLength:=1024;
      Recorder.WaveHdr2:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间 
      Recorder.WaveBuffer2:=GlobalAllocPtr(GHND or GMEM_SHARE,1024);//为Buffer2分配内存空间
      Recorder.WaveHdr2.lpData:=Recorder.WaveBuffer2;// 
      Recorder.WaveHdr2.dwBufferLength:=1024;
      WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));  
      WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR)); 
      WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));//将缓冲区送往波形输入设备
      WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
      //start.Enabled:=TRUE;end;procedure TForm1.FormCreate(Sender: TObject); 
    begin 
    //判断是否有声卡 
    if (WaveInGetNumDevs()=0) then 
       application.MessageBox('There is no recording sound cadd in your computer!','Error',mb_OK)
    else
       application.MessageBox('There is a recording sound cadd in your computer!','ok',mb_OK)
    end;
    procedure TForm1.closeClick(Sender: TObject);
    begin 
    waveInStop(Recorder.WaveHandle);
    waveInClose(Recorder.WaveHandle);
    end;
    end.