本人想做一个语音通信的软件,通过SOCKET控件来传送声音信息。做了很久都没有什么眉目。正在烦中!
   各位前辈能否先给出个简单现声音传送和接收的例子?(通过API中的WAVEINOPEN系列函数来实现的,并通过回调函数来实现声音的发送和接收等等)。
   (为了不让给的分石沉大海,所以解决后给分,请谅解!) 
  谢谢!
  我想用的WINAPI中的WAVEXXXXX来实现实,不想用专用的语音控件,(其实实现语音通信的控件我也有。)(http://redspider.html.533.net/audio/winaudio.htm  上面有介绍,是VC的,不过实现其来不太懂)!谢谢!请高手帮帮我!

解决方案 »

  1.   

    同意楼上的观点
    这也是中国软件事业不能很好发展的一个因素吧
    真希望大家无私奉献
    ----------------------------------------------------------
    只要你的问题问得合理,不非常难,不用写本书,简单数十句话就能回答,我想还没有人在CSDN上得不到答案吧?
      

  2.   

    其实我也查了很多网上的资料,大概一个星期了吧,但是那些资料都五花八门,我真的摸不着头脑了,所以才来CSDN问的!
      

  3.   

    这个程序部分代码如下,等一下我会点出出错的地方,望大家帮看一看::
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,mmsystem, ScktComp;type
      TForm1 = class(TForm)
        Button1: TButton;
        ClientSocket1: TClientSocket;
        Button2: TButton;
        Button3: TButton;
        CheckBox1: TCheckBox;
        CheckBox2: TCheckBox;
        procedure Button1Click(Sender: TObject);
        procedure CallBack(uMsg,dwInstance,dwParam1,dwParam2 : DWORD); stdcall;
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure send;
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    type
      WAVEFORMATEX=record
      wFormatTag:word;
      nChannels:word;
      nSamplesPerSec:Dword;
      nAvgBytesPerSec:Dword;
      nBlockAlign:word;
      wBitsPerSample:word;
      cbSize:word;
      end;
    var
      Form1: TForm1;
      phwi:hwavein;
      WaveInHeader1: pWaveHdr;
      WaveInHeader2: pWaveHdr;
      buffer1:lpstr;
      buffer2:lpstr;
    const
      RecordBufferSize=2048;
      

  4.   

    unit ShareWav;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
         mmsystem, ShareFunc;
    //     , CltUnit1type
      TWaveInBufferStatuses = (wibsEmpty, wibsData, wibsInUse);
      TWaveOutBufferStatuses = (wobsEmpty, wobsData, wobsMerged, wobsInUse);
      TWaveInBuffer = Record
                          hwavhdr: integer;
                          pwavhdr: PWAVEHDR;
                          hdatabuf: integer;
                          status: TWaveInBufferStatuses;
                      end;
      PWaveInBuffer = ^TWaveInBuffer;
      TWaveOutBuffer = Record
                          hwavhdr: integer;
                          pwavhdr: PWAVEHDR;
                          hdatabuf: integer;
                          status: TWaveOutBufferStatuses;
                        end;
      PWaveOutBuffer = ^TWaveOutBuffer;var
      WaveInNums: integer;
      WaveInDevID: integer;
      WaveInDevHandle: HWAVEIN;
      WaveInWindowHandle: HWND;
      WaveIn_OnOff: Boolean = False;
      WaveInBuf1, WaveInBuf2: TWaveInBuffer;  WaveOutNums: integer;
      WaveOutDevID: integer;
      WaveOutDevHandle: HWAVEIN;
      WaveOutWindowHandle: HWND;
      WaveOut_OnOff: Boolean = False;
      WaveOutBuf1, WaveOutBuf2: TWaveOutBuffer;  mWaveFormat: TPCMWaveFormat;//  hwavhdrtype
      TWavForm = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
        procedure mWaveInOpen(wnd: HWND);
        procedure mWaveInClose;
        procedure mWaveOutOpen(wnd: HWND);
        procedure mWaveOutClose;
        procedure mWaveInOpenNotify(var msg: TMessage);  Message MM_WIM_OPEN;
        procedure mWaveInCloseNotify(var msg: TMessage);  Message MM_WIM_CLOSE;
        procedure mWaveInDataNotify(var msg: TMessage);  Message MM_WIM_DATA;    procedure mWaveOutOpenNotify(var msg: TMessage);  Message MM_WOM_OPEN;
        procedure mWaveOutCloseNotify(var msg: TMessage);  Message MM_WOM_CLOSE;
        procedure mWaveOutDoneNotify(var msg: TMessage);  Message MM_WOM_DONE;
        function mWaveOutPlay(pSoundData: pByte; size: integer): integer;  end;var
      WavForm: TWavForm;
      WaveErrCode: integer = 0;
      ErrCodeBool: Boolean;
      

  5.   

    implementationuses CltUnit1;{$R *.DFM}/////打开声音输入设备
    procedure TWavForm.mWaveInOpen(wnd: HWND);
    var
      TmpHandle: integer;
    begin
      if WaveInNums > 0 then
      begin
        WaveErrCode := WaveInOpen(@TmpHandle, 0, @mWaveFormat, Handle,
                      0, WAVE_ALLOWSYNC or CALLBACK_WINDOW);
        if WaveErrCOde = 0 then
        begin
          WaveInDevHandle := TmpHandle;
          WaveInDevID := 0;
          WaveInWindowHandle := wnd;
          WaveErrCode := WaveInPrepareHeader(WaveInDevHandle, WaveInBuf1.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveInPrepareHeader(WaveInDevHandle, WaveInBuf2.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveInAddBuffer(WaveInDevHAndle, WaveInBuf1.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveInAddBuffer(WaveInDevHAndle, WaveInBuf2.pwavhdr, sizeof(WAVEHDR));
          case WaveErrCode of
            0:
              begin
                 WaveInStart(WaveInDevHandle);
              end;
            MMSYSERR_INVALHANDLE,
            MMSYSERR_NOMEM:
               Inc(WaveErrCode);
          end;
        end;
      end;end;procedure TWavForm.mWaveInClose();
    begin
      WaveErrCode := WaveInStop(WaveInDevHandle);
      WaveErrCode := WaveInReset(WaveInDevHandle);
      WaveErrCode := WaveInClose(WaveInDevHandle);
    end;////打开声音输出设备
    procedure TWavForm.mWaveOutOpen(wnd: HWND);
    var
      TmpHandle: integer;
    begin
      if WaveOutNums > 0 then
      begin
        WaveErrCode := WaveOutOpen(@TmpHandle, 0, @mWaveFormat, Handle,
                      0, WAVE_ALLOWSYNC or CALLBACK_WINDOW);
        if WaveErrCode = 0 then
        begin
          WaveOutDevHandle := TmpHandle;
          WaveOutDevID := 0;
          WaveOutWindowHandle := wnd;
          WaveErrCode := WaveOutPrepareHeader(WaveOutDevHandle, WaveOutBuf1.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveOutPrepareHeader(WaveOutDevHandle, WaveOutBuf2.pwavhdr, sizeof(WAVEHDR));
        end;
      end;
    end;procedure TWavForm.mWaveOutClose();
    begin
      WaveErrCode := WaveOutClose(WaveOutDevHandle);
    end;procedure TWavForm.mWaveInOpenNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveInWindowHandle, MM_WIM_OPEN, msg.wParam, msg.lParam);
      WaveIn_OnOff := True;    // open record
    end;procedure TWavForm.mWaveInCloseNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveInWindowHandle, MM_WIM_CLOSE, msg.wParam, msg.lParam);
      WaveIn_OnOff := False;
    end;
      

  6.   

    ////输入声音数据(即录音)
    procedure TWavForm.mWaveInDataNotify(var msg: TMessage);
    var
      tpiwavhdr: PWAVEHDR;
    begin  {}
      if not WaveIn_OnOff then exit;
      tpiwavhdr := PWAVEHDR(msg.lParam);
      if tpiwavhdr.dwBytesRecorded = 0 then exit;
    {
      if BYTES_PER_SAMPLE = 1 then
        tmpb := MyMaxByte(pByte(tpiwavhdr.lpData), tpiwavhdr.dwBytesRecorded)
      else
        tmpb := MyMaxWord(pByte(tpiwavhdr.lpData), tpiwavhdr.dwBytesRecorded);
      if tmpb >= MIN_SOUND then
    }
        CltDemoForm.mWaveInDataNotify(msg);  WaveErrCode := WaveInAddBuffer(WaveInDevHandle, tpiwavhdr, sizeof(WAVEHDR));
    end;
    procedure TWavForm.mWaveOutOpenNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveOutWindowHandle, MM_WOM_OPEN, msg.wParam, msg.lParam);
      WaveOut_OnOff := True;    // open record
    end;procedure TWavForm.mWaveOutCloseNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveOutWindowHandle, MM_WOM_CLOSE, msg.wParam, msg.lParam);
      WaveOut_OnOff := False;
    end;////输出声音完毕
    procedure TWavForm.mWaveOutDoneNotify(var msg: TMessage);
    var
      tpwavhdr: PWAVEHDR;
    begin  {}
      PostMessage(WaveOutWindowHandle, MM_WOM_DONE, msg.wParam, msg.lParam);
      tpwavhdr := PWAVEHDR(msg.lParam);
      tpwavhdr.dwUser := 0;   // indicate buffer is free
    end;procedure mWaveInBufInit(var inbuffer: TWaveInBuffer);
    begin
      inbuffer.hdatabuf := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, SEG_SIZE);
      inbuffer.hwavhdr := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, sizeof(WAVEHDR));
      inbuffer.pwavhdr := GlobalLock(inbuffer.hwavhdr);
      inbuffer.pwavhdr.lpData := GlobalLock(inbuffer.hdatabuf);
      inbuffer.pwavhdr.dwBufferLength := SEG_SIZE;
    end;procedure mWaveInBufFree(var inbuffer: TWaveInBuffer);
    begin
      ErrCodeBool := GlobalUnLock(inbuffer.hdatabuf);
      ErrCodeBool := GlobalUnLock(inbuffer.hwavhdr);
      WaveErrCode := GlobalFree(inbuffer.hdatabuf);
      WaveErrCode := GlobalFree(inbuffer.hwavhdr);
    end;procedure mWaveOutBufInit(var outbuffer: TWaveOutBuffer);
    begin
      outbuffer.hdatabuf := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, SEG_SIZE);
      outbuffer.hwavhdr := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, sizeof(WAVEHDR));
      outbuffer.pwavhdr := GlobalLock(outbuffer.hwavhdr);
      outbuffer.pwavhdr.lpData := GlobalLock(outbuffer.hdatabuf);
      outbuffer.pwavhdr.dwBufferLength := SEG_SIZE;
    end;procedure mWaveOutBufFree(var outbuffer: TWaveOutBuffer);
    begin
      ErrCodeBool := GlobalUnLock(outbuffer.hdatabuf);
      ErrCodeBool := GlobalUnLock(outbuffer.hwavhdr);
      WaveErrCode := GlobalFree(outbuffer.hdatabuf);
      WaveErrCode := GlobalFree(outbuffer.hwavhdr);
    end;var
      LastWaveHdr: integer;//////////播放声音
    function TWavForm.mWaveOutPlay(pSoundData: pByte; size: integer): integer;
    var
      tpwavhdr: PWAVEHDR;
    begin
      if LastWaveHdr = 1 then
      begin
        tpwavhdr := WaveOutBuf2.pwavhdr;
        LastWaveHdr := 2;
      end
      else
      begin
        tpwavhdr := WaveOutBuf1.pwavhdr;
        LastWaveHdr := 1;
      end;
      if tpwavhdr.dwUser = 0 then  //
      begin
        MemCopy(pSoundData, pByte(tpwavhdr.lpData), size);
        tpwavhdr.dwBufferLength := size;
        Result := WaveOutWrite(WaveOutDevHandle, tpwavhdr, sizeof(WAVEHDR));
        if Result = 0 then
          tpwavhdr.dwUser := 1;   // set buffer in use;
      end else Result := 10;    // buffer full
    end;initialization
      WaveInNums := WaveInGetNumDevs;
      WaveOutNums := WaveOutGetNumDevs;  mWaveFormat.wf.wFormatTag := WAVE_FORMAT_PCM;
      mWaveFormat.wf.nChannels := 1;
      mWaveFormat.wf.nSamplesPerSec := 22050;
      mWaveFormat.wf.nAvgBytesPerSec := 22050 * BYTES_PER_SAMPLE;
      mWaveFormat.wf.nBlockAlign := BITS_PER_SAMPLE div 8;
      mWaveFormat.wBitsPerSample := BITS_PER_SAMPLE;  mWaveInBufInit(WaveInBuf1);
      mWaveInBufInit(WaveInBuf2);
      mWaveOutBufInit(WaveOutBuf1);
      mWaveOutBufInit(WaveOutBuf2);finalization
      mWaveInBufFree(WaveInBuf1);
      mWaveInBufFree(WaveInBuf2);
      mWaveOutBufFree(WaveOutBuf1);
      mWaveOutBufFree(WaveOutBuf2);end.
      

  7.   

    implementation
    {$R *.dfm}
    procedure tform1.CallBack(uMsg,dwInstance,dwParam1,dwParam2 : DWORD); stdcall; //回调函数
    BEGIN  case uMsg of
      //WIM_OPEN :
      mm_WIM_DATA :
      begin
      showmessage('一个缓冲区已满发回的消息');
     try
        //凡是用到控件都报会错,和那线程中的EXECUTE直接用VCL控件的错法一些。怎么解决?
       clientsocket1.Socket.SendBuf(pointer(dwparam1),2048); //????????出问题了。
     except
       showmessage('is bad');
      end;
      end;
      mm_WIM_CLOSE: showmessage('波形输入设备关闭成功发回的消息');
      mm_WOM_DONE:showmessage('已清空');
    end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    var
    waveformat:WAVEFORMATEX ;MMR: MMResult;begin
      waveformat.wFormatTag:=WAVE_FORMAT_PCM;
      waveformat.nChannels:=1;
      waveformat.nSamplesPerSec:=8000;
      waveformat.nAvgBytesPerSec:=16000;
      waveformat.nBlockAlign:=2;
      waveformat.cbSize:=0;
      waveformat.wBitsPerSample:=16;
       Buffer1 := nil;
       Buffer2 := nil;
       WaveInHeader1:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(WAVEHDR));
       WaveInHeader2:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(WAVEHDR));
       Buffer1:=GlobalAllocPtr(GHND or GMEM_SHARE,2048);
       Buffer2:=GlobalAllocPtr(GHND or GMEM_SHARE,2048);  if ( waveInGetNumDevs()<>0) then
        showmessage('ok!');
         MMR:=waveInOpen(addr(phwi),WAVE_MAPPER,addr(waveformat),DWORD(@Tform1.callback),DWORD(@form1),CALLBACK_FUNCTION+ WAVE_ALLOWSYNC);   if MMR <> MMSYSERR_NOERROR then
       beginApplication.MessageBox ('无法打开输入设备,请检查设定。', '错误',MB_OK);
    exit;
    end;
    if (Buffer1 = nil) or (Buffer2 = nil) then
    begin
      showmessage('bad');
      exit;
    end;
    waveInHeader1.lpData := Buffer1;
    waveInHeader1.dwBufferLength := RecordBufferSize;
    waveInHeader1.dwBytesRecorded := 0;
    waveInHeader1.dwUser := 0; // 32 bits of user data
    waveInHeader1.dwFlags := 0;
    waveInHeader1.dwLoops := 0;
    waveInHeader1.lpNext := nil; // reserved; must be zero
    waveInHeader1.reserved := 0;
    MMR := waveInPrepareHeader (phwi, waveInHeader1,sizeof (WAVEHDR));
    if MMR <> MMSYSERR_NOERROR then
    begin
      Application.MessageBox ('第一录音缓冲区准备出错。', '错误', MB_OK);
      exit;
    end;
    waveInHeader2.lpData := Buffer2;
    waveInHeader2.dwBufferLength := RecordBufferSize;
    waveInHeader2.dwBytesRecorded := 0;
    waveInHeader2.dwUser := 0; // 32 bits of user data
    waveInHeader2.dwFlags := 0;
    waveInHeader2.dwLoops := 0;
    waveInHeader2.lpNext := nil; // reserved; must be zero
    waveInHeader2.reserved := 0;
    MMR := waveInPrepareHeader (phwi,waveInHeader2,sizeof (WAVEHDR));
    if MMR <> MMSYSERR_NOERROR then
    begin
      waveInUnprepareHeader (phwi, waveInHeader1, sizeof(WAVEHDR));
      Application.MessageBox ('第二录音缓冲区准备出错。', '错误', MB_OK);
      exit;
    end;
    MMR := waveInAddBuffer (phwi, waveInHeader1, sizeof (WAVEHDR));
    if MMR <> MMSYSERR_NOERROR then
    begin
      waveInUnprepareHeader (phwi, waveInHeader1, sizeof(WAVEHDR));
      waveInUnprepareHeader (phwi, waveInHeader2, sizeof(WAVEHDR));  Application.MessageBox ('添加第一缓冲区出错。', '错误', MB_OK);
      exit;
    end;
    MMR := waveInAddBuffer (phwi, waveInHeader2, sizeof(WAVEHDR));if MMR <> MMSYSERR_NOERROR then
    begin
      waveInUnprepareHeader (phwi, Addr (waveInHeader1), sizeof(waveInHeader1));
      waveInUnprepareHeader (phwi, Addr (waveInHeader2), sizeof(waveInHeader2));
      FreeMem (Buffer1); FreeMem (Buffer2);
      Application.MessageBox ('添加第二缓冲区出错。', '错误', MB_OK);
      exit;
    end;
    MMR := waveInStart (phwi);if MMR <> MMSYSERR_NOERROR then
    begin
      waveInUnprepareHeader (phwi, Addr (waveInHeader1), sizeof(waveInHeader1));
      waveInUnprepareHeader (phwi, Addr (waveInHeader2), sizeof(waveInHeader2));
      FreeMem (Buffer1); FreeMem (Buffer2);
      Application.MessageBox ('未能开始录音。', '错误', MB_OK);
      exit;
    end;
    end;
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      clientsocket1.Active:=true;end;
        为什么在上面有问号的地方会出错呢,我发现在那凡是用到控件都会报错,错误信息:
      project project1.exe raised exception class EAccessViolation with message 'Access violation at address 00453CB0 in module 'project1.exe'.Read of address FEEEFF2E'.Process stopped .Use step or Run to continue.
      这是为什么?怎么解决??
      

  8.   

    刚才哪个编译不过,改了一下。
    // sample rate 22.05K, 8 bits, 1 channelunit ShareWav;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
         mmsystem;const
      SEG_SIZE = 22050;
      BYTES_PER_SAMPLE = 1;
      BITS_PER_SAMPLE = BYTES_PER_SAMPLE * 8;type
      TWaveInBufferStatuses = (wibsEmpty, wibsData, wibsInUse);
      TWaveOutBufferStatuses = (wobsEmpty, wobsData, wobsMerged, wobsInUse);
      TWaveInBuffer = Record
                          hwavhdr: integer;
                          pwavhdr: PWAVEHDR;
                          hdatabuf: integer;
                          status: TWaveInBufferStatuses;
                      end;
      PWaveInBuffer = ^TWaveInBuffer;
      TWaveOutBuffer = Record
                          hwavhdr: integer;
                          pwavhdr: PWAVEHDR;
                          hdatabuf: integer;
                          status: TWaveOutBufferStatuses;
                        end;
      PWaveOutBuffer = ^TWaveOutBuffer;var
      WaveInNums: integer;
      WaveInDevID: integer;
      WaveInDevHandle: HWAVEIN;
      WaveInWindowHandle: HWND;
      WaveIn_OnOff: Boolean = False;
      WaveInBuf1, WaveInBuf2: TWaveInBuffer;  WaveOutNums: integer;
      WaveOutDevID: integer;
      WaveOutDevHandle: HWAVEIN;
      WaveOutWindowHandle: HWND;
      WaveOut_OnOff: Boolean = False;
      WaveOutBuf1, WaveOutBuf2: TWaveOutBuffer;  mWaveFormat: TPCMWaveFormat;//  hwavhdrtype
      TWavForm = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
        procedure mWaveInOpen(wnd: HWND);
        procedure mWaveInClose;
        procedure mWaveOutOpen(wnd: HWND);
        procedure mWaveOutClose;
        procedure mWaveInOpenNotify(var msg: TMessage);  Message MM_WIM_OPEN;
        procedure mWaveInCloseNotify(var msg: TMessage);  Message MM_WIM_CLOSE;
        procedure mWaveInDataNotify(var msg: TMessage);  Message MM_WIM_DATA;    procedure mWaveOutOpenNotify(var msg: TMessage);  Message MM_WOM_OPEN;
        procedure mWaveOutCloseNotify(var msg: TMessage);  Message MM_WOM_CLOSE;
        procedure mWaveOutDoneNotify(var msg: TMessage);  Message MM_WOM_DONE;
        function mWaveOutPlay(pSoundData: pByte; size: integer): integer;  end;var
      WavForm: TWavForm;
      WaveErrCode: integer = 0;
      ErrCodeBool: Boolean;implementation{$R *.DFM}
    procedure TWavForm.mWaveInOpen(wnd: HWND);
    var
      TmpHandle: integer;
    begin
      if WaveInNums > 0 then
      begin
        WaveErrCode := WaveInOpen(@TmpHandle, 0, @mWaveFormat, Handle,
                      0, WAVE_ALLOWSYNC or CALLBACK_WINDOW);
        if WaveErrCOde = 0 then
        begin
          WaveInDevHandle := TmpHandle;
          WaveInDevID := 0;
          WaveInWindowHandle := wnd;
          WaveErrCode := WaveInPrepareHeader(WaveInDevHandle, WaveInBuf1.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveInPrepareHeader(WaveInDevHandle, WaveInBuf2.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveInAddBuffer(WaveInDevHAndle, WaveInBuf1.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveInAddBuffer(WaveInDevHAndle, WaveInBuf2.pwavhdr, sizeof(WAVEHDR));
          case WaveErrCode of
            0:
              begin
                 WaveInStart(WaveInDevHandle);
              end;
            MMSYSERR_INVALHANDLE,
            MMSYSERR_NOMEM:
               Inc(WaveErrCode);
          end;
        end;
      end;end;
      

  9.   

    procedure TWavForm.mWaveInClose();
    begin
      WaveErrCode := WaveInStop(WaveInDevHandle);
      WaveErrCode := WaveInReset(WaveInDevHandle);
      WaveErrCode := WaveInClose(WaveInDevHandle);
    end;procedure TWavForm.mWaveOutOpen(wnd: HWND);
    var
      TmpHandle: integer;
    begin
      if WaveOutNums > 0 then
      begin
        WaveErrCode := WaveOutOpen(@TmpHandle, 0, @mWaveFormat, Handle,
                      0, WAVE_ALLOWSYNC or CALLBACK_WINDOW);
        if WaveErrCode = 0 then
        begin
          WaveOutDevHandle := TmpHandle;
          WaveOutDevID := 0;
          WaveOutWindowHandle := wnd;
          WaveErrCode := WaveOutPrepareHeader(WaveOutDevHandle, WaveOutBuf1.pwavhdr, sizeof(WAVEHDR));
          WaveErrCode := WaveOutPrepareHeader(WaveOutDevHandle, WaveOutBuf2.pwavhdr, sizeof(WAVEHDR));
        end;
      end;
    end;procedure TWavForm.mWaveOutClose();
    begin
      WaveErrCode := WaveOutClose(WaveOutDevHandle);
    end;procedure TWavForm.mWaveInOpenNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveInWindowHandle, MM_WIM_OPEN, msg.wParam, msg.lParam);
      WaveIn_OnOff := True;    // open record
    end;procedure TWavForm.mWaveInCloseNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveInWindowHandle, MM_WIM_CLOSE, msg.wParam, msg.lParam);
      WaveIn_OnOff := False;
    end;procedure TWavForm.mWaveInDataNotify(var msg: TMessage);
    var
      tpiwavhdr: PWAVEHDR;
    begin  {}
      if not WaveIn_OnOff then exit;
      tpiwavhdr := PWAVEHDR(msg.lParam);
      if tpiwavhdr.dwBytesRecorded = 0 then
        exit;  {   &Otilde;&acirc;&Agrave;&iuml;&acute;&brvbar;&Agrave;í&Acirc;&frac14;&Ograve;&ocirc;&Ecirc;&yacute;&frac34;&Yacute;&pound;&not;tpiwavhdr.lpData&Ecirc;&Ccedil;&Eacute;ù&Ograve;&ocirc;&Ecirc;&yacute;&frac34;&Yacute;&iexcl;&pound;
           }  WaveErrCode := WaveInAddBuffer(WaveInDevHandle, tpiwavhdr, sizeof(WAVEHDR));
    end;
    procedure TWavForm.mWaveOutOpenNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveOutWindowHandle, MM_WOM_OPEN, msg.wParam, msg.lParam);
      WaveOut_OnOff := True;    // open record
    end;procedure TWavForm.mWaveOutCloseNotify(var msg: TMessage);
    begin  {}
      PostMessage(WaveOutWindowHandle, MM_WOM_CLOSE, msg.wParam, msg.lParam);
      WaveOut_OnOff := False;
    end;procedure TWavForm.mWaveOutDoneNotify(var msg: TMessage);
    var
      tpwavhdr: PWAVEHDR;
    begin  {}
      PostMessage(WaveOutWindowHandle, MM_WOM_DONE, msg.wParam, msg.lParam);
      tpwavhdr := PWAVEHDR(msg.lParam);
      tpwavhdr.dwUser := 0;   // indicate buffer is free
    end;
      

  10.   

    procedure mWaveInBufInit(var inbuffer: TWaveInBuffer);
    begin
      inbuffer.hdatabuf := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, SEG_SIZE);
      inbuffer.hwavhdr := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, sizeof(WAVEHDR));
      inbuffer.pwavhdr := GlobalLock(inbuffer.hwavhdr);
      inbuffer.pwavhdr.lpData := GlobalLock(inbuffer.hdatabuf);
      inbuffer.pwavhdr.dwBufferLength := SEG_SIZE;
    end;procedure mWaveInBufFree(var inbuffer: TWaveInBuffer);
    begin
      ErrCodeBool := GlobalUnLock(inbuffer.hdatabuf);
      ErrCodeBool := GlobalUnLock(inbuffer.hwavhdr);
      WaveErrCode := GlobalFree(inbuffer.hdatabuf);
      WaveErrCode := GlobalFree(inbuffer.hwavhdr);
    end;procedure mWaveOutBufInit(var outbuffer: TWaveOutBuffer);
    begin
      outbuffer.hdatabuf := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, SEG_SIZE);
      outbuffer.hwavhdr := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, sizeof(WAVEHDR));
      outbuffer.pwavhdr := GlobalLock(outbuffer.hwavhdr);
      outbuffer.pwavhdr.lpData := GlobalLock(outbuffer.hdatabuf);
      outbuffer.pwavhdr.dwBufferLength := SEG_SIZE;
    end;procedure mWaveOutBufFree(var outbuffer: TWaveOutBuffer);
    begin
      ErrCodeBool := GlobalUnLock(outbuffer.hdatabuf);
      ErrCodeBool := GlobalUnLock(outbuffer.hwavhdr);
      WaveErrCode := GlobalFree(outbuffer.hdatabuf);
      WaveErrCode := GlobalFree(outbuffer.hwavhdr);
    end;var
      LastWaveHdr: integer;
    function TWavForm.mWaveOutPlay(pSoundData: pByte; size: integer): integer;
    var
      tpwavhdr: PWAVEHDR;
    begin
      if LastWaveHdr = 1 then
      begin
        tpwavhdr := WaveOutBuf2.pwavhdr;
        LastWaveHdr := 2;
      end
      else
      begin
        tpwavhdr := WaveOutBuf1.pwavhdr;
        LastWaveHdr := 1;
      end;
      if tpwavhdr.dwUser = 0 then  //
      begin
        MemCopy(pSoundData, pByte(tpwavhdr.lpData), size);//&Auml;&Uacute;&acute;&aelig;&cedil;&acute;&Ouml;&AElig;
        tpwavhdr.dwBufferLength := size;
        Result := WaveOutWrite(WaveOutDevHandle, tpwavhdr, sizeof(WAVEHDR));
        if Result = 0 then
          tpwavhdr.dwUser := 1;   // set buffer in use;
      end else Result := 10;    // buffer full
    end;initialization
      WaveInNums := WaveInGetNumDevs;
      WaveOutNums := WaveOutGetNumDevs;  mWaveFormat.wf.wFormatTag := WAVE_FORMAT_PCM;
      mWaveFormat.wf.nChannels := 1;
      mWaveFormat.wf.nSamplesPerSec := 22050;
      mWaveFormat.wf.nAvgBytesPerSec := 22050 * BYTES_PER_SAMPLE;
      mWaveFormat.wf.nBlockAlign := BITS_PER_SAMPLE div 8;
      mWaveFormat.wBitsPerSample := BITS_PER_SAMPLE;  mWaveInBufInit(WaveInBuf1);
      mWaveInBufInit(WaveInBuf2);
      mWaveOutBufInit(WaveOutBuf1);
      mWaveOutBufInit(WaveOutBuf2);finalization
      mWaveInBufFree(WaveInBuf1);
      mWaveInBufFree(WaveInBuf2);
      mWaveOutBufFree(WaveOutBuf1);
      mWaveOutBufFree(WaveOutBuf2);end.
      

  11.   

    ahjoe(强哥):
      帮我解决一下刚才我刚才发的代码吧!谢谢!
      

  12.   

    好像DELPHI没有MEMCOPY这个函数吧???
      

  13.   

    ahjoe(强哥):
       你这程序怎么用啊,说一下它的运行流程吧!看不太懂!