向高手请教,windows下怎么控制声卡直接产生波形(正弦波)?
用DirectX,还是I/o,还是嵌汇编?

解决方案 »

  1.   

    gzing
    用AudioIN组件获取音频数据,再自己画波形。
      

  2.   

    刚才为你写了个例程,供你参考
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,shellApi,mmsystem, TeEngine, Series, ExtCtrls,
      TeeProcs, Chart;
    const  BUF_SIZE=100;
      BUF_NUM=10;
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Chart1: TChart;
        Series1: TFastLineSeries;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
        waveformIn:TWAVEFORMATEX;
        hWaveIn:HWAVEIN;
        pWaveHdr1,pWaveHdr2:PWAVEHDR;
        bEndRecord:boolean;
        Ind:integer;
            Memos:array[0..BUF_NUM-1]of Pointer;
        pBuffer1,pBuffer2:array [0..BUF_SIZE-1] of char;
            pWaveHdrs:array [0..BUF_NUM-1] of  PWAVEHDR;
        procedure mmwimopen(var Msg: TMessage); message MM_WIM_OPEN;
        procedure mmwimdata(var Msg: TMessage); message MM_WIM_DATA;
        procedure mmwimclose(Var Msg:TMessage);message MM_WIM_CLOSE;
         procedure StartSendSound;
         procedure EndSendSound;  public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.EndSendSound;
    begin
      bEndRecord:=true;
      waveInReset(hwaveIn);
    end;procedure TForm1.mmwimclose(var Msg: TMessage);
    begin
       waveInUnprepareHeader (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
       waveInUnprepareHeader (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
    end;procedure TForm1.mmwimdata(var Msg: TMessage);
    Var
      pBuffer:Pointer;
      count:integer;
      pSaveBuf:array [0..BUF_SIZE-1] of char;
      i:integer;
    begin
      if bEndRecord then
      begin
        WaveInClose(hWaveIn);
        exit;
      end;
      pBuffer:= Pointer(PWAVEHDR(Msg.lParam).lpData);
      count:= (PWAVEHDR(Msg.lParam)).dwBytesRecorded;
      CopyMemory(Addr(pSaveBuf[0]),pBuffer,count);
      if Count>0 then
      for i:=0 to count-1 do
      begin     Series1.addXY(ind,Ord(pSaveBuf[i])-128);
         Inc(ind);
         if Series1.Count>1000 then
           Series1.Delete(0);  end;
      waveInAddBuffer (hWaveIn, PWAVEHDR(Msg.lParam), sizeof (WAVEHDR)) ;
    end;procedure TForm1.mmwimopen(var Msg: TMessage);
    begin
      waveInAddBuffer(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));
      waveInAddBuffer(hWaveIn,pWaveHdr2,sizeof(WAVEHDR));
      waveInStart(hWaveIn);
    end;procedure TForm1.StartSendSound;
    begin
       waveformIn.wFormatTag:=WAVE_FORMAT_PCM;
       waveformIn.nChannels:=1;
      // waveformIn.nSamplesPerSec:=11025;
      // waveformIn.nAvgBytesPerSec:=22050;
       waveformIn.nSamplesPerSec:=1000;
       waveformIn.nAvgBytesPerSec:=2000;
       waveformIn.nBlockAlign:=1;
       waveformIn.wBitsPerSample:=16;
       waveformIn.cbSize:=0;
       if WaveInOpen(@hWaveIn,WAVE_MAPPER,@waveformIn,handle,0,CALLBACK_WINDOW)
        <>MMSYSERR_NOERROR then
       begin
         ShowMessage('录音设备打开失败');
       end;
      pWaveHdr1.lpData:=(pBuffer1);
      pWaveHdr1.dwBufferLength:= BUF_SIZE;
      pWaveHdr1.dwBytesRecorded:=0;
      pWaveHdr1.dwUser:=0;
      pWaveHdr1.dwFlags:=0;
      pWaveHdr1.dwLoops:=1;
      pWaveHdr1.lpNext:=nil;
      pWaveHdr1.reserved:=0;
      waveInPrepareHeader(hWaveIn,pWaveHdr1,SizeOf(WAVEHDR));
      pWaveHdr2.lpData:=(pBuffer2);
      pWaveHdr2.dwBufferLength:= BUF_SIZE;
      pWaveHdr2.dwBytesRecorded:=0;
      pWaveHdr2.dwUser:=0;
      pWaveHdr2.dwFlags:=0;
      pWaveHdr2.dwLoops:=1;
      pWaveHdr2.lpNext:=nil;
      pWaveHdr2.reserved:=0;
      waveInPrepareHeader(hWaveIn,pWaveHdr2,SizeOf(WAVEHDR));
      bEndRecord:=false;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      StartSendSound;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      EndSendSound;
    end;procedure TForm1.FormCreate(Sender: TObject);
    var
      i:integer;
    begin
      Ind:=0;
      new(pWaveHdr1);
      new(pWaveHdr2);
      for i:=0 to BUF_NUM-1 do
        Memos[i]:=AllocMem(BUF_SIZE);  for i:=0 to BUF_NUM-1 do
      begin
        new(pWaveHdrs[i]);
        pWaveHdrs[i].lpData:=Memos[i];
        pWaveHdrs[i].dwBufferLength:= BUF_SIZE;
        pWaveHdrs[i].dwBytesRecorded:=0;
        pWaveHdrs[i].dwUser:=0;
        pWaveHdrs[i].dwFlags:=0;
        pWaveHdrs[i].dwLoops:=1;
        pWaveHdrs[i].lpNext:=nil;
        pWaveHdrs[i].reserved:=0;
      end;end;
    procedure TForm1.FormDestroy(Sender: TObject);
    var
      i:integer;
    begin
      dispose(pWaveHdr1);
      dispose(pWaveHdr2);
      for i:=0 to BUF_NUM-1 do
      begin
        FreeMem(Memos[i]);
        dispose(pWaveHdrs[i]);
      end;
    end;end.