代码之家  ›  专栏  ›  技术社区  ›  Luiz Alves

用delphi在LINEAR16中捕捉mic音频

  •  0
  • Luiz Alves  · 技术社区  · 6 年前

    所以我得到了下一个单位代码来捕捉麦克风音频。 我喜欢用捕捉到的音频发送到谷歌语音识别api。

    googlespeechapi只接受一些编码格式。

    我需要的音频在线性16未压缩16位有符号小尾数样本。

    Sample of use:
    
        procedure TForm1.Timer1Timer(Sender: TObject);
        begin
            SNDProcWaveIn(ind);
            //code for proc data in "ind" buffer
        end;
    
    unit WaveSound;
    
    interface
    
    uses
      SysUtils, MMSystem;
    
    const
      NUMSAMPLES = 1024;    // Number of Samples
    
    type
      TIndata      = array[0 .. NUMSAMPLES - 1] of Integer;
      PIndata      = ^TIndata;
    
      TFrec= record
        Fx, dx  :Integer;
      end;
    
      function SNDInitWaveIn: Cardinal;
      procedure SNDProcWaveIn(var Indata : TIndata);
      procedure SNDStopWave;
    
    implementation
    
    var
      DevHandle   : Integer;
      WAVEFORMAT1 : TWAVEFORMATEX;
      Wave        : WAVEHDR;
    
    function SNDInitWaveIn: Cardinal;
    begin
        with WAVEFORMAT1 do begin
            wFormatTag := WAVE_FORMAT_PCM;
            nChannels := 1;
            nSamplesPerSec := 44100;// 11025; //11khz
            wBitsPerSample := 16;
            nBlockAlign := (nChannels * wBitsPerSample) div 8;
            nAvgBytesPerSec := nBlockAlign * nSamplesPerSec;
            cbSize := 0;
        end;
        Result:= waveInOpen(@DevHandle, cardinal(-1),@WAVEFORMAT1, cardinal(0), cardinal(0), cardinal(0));
        If not(DevHandle = 0) Then waveInStart(DevHandle);
    end;
    
    procedure SNDProcWaveIn(var Indata : TIndata);
    begin
      //lpdata requires the address of an array to fill up data with
          Wave.lpData := @Indata;
      //the buffer length
          Wave.dwBufferLength := NUMSAMPLES;
          Wave.dwFlags := 0;
       //prepare device for input
          waveInPrepareHeader(DevHandle, @Wave, sizeof(Wave));
          waveInAddBuffer(DevHandle, @Wave, sizeof(Wave));
          // if the following statement is removed, the vis. will be a lot faster (avs style)
          // but uses up 100% of cpu!
          // this is why i hate avs
          Sleep(10); // give device a breather
          // the following loop is quite useless, but anyway...
          repeat
              //Just wait for the blocks to be done or the device to close
          until (((Wave.dwFlags and WHDR_DONE)= WHDR_DONE) or (DevHandle = 0));
          If (DevHandle = 0) Then Exit;  //Cut out if the device is closed
          waveInUnprepareHeader(DevHandle, @Wave, sizeof(Wave));
    end;
    
    procedure SNDStopWave;
    begin
        waveInReset(DevHandle);
        waveInClose(DevHandle);
        DevHandle := 0;
    end;
    end.
    
    0 回复  |  直到 6 年前