Микрофон в реальном времени в Delphi?

#delphi #audio-recording #microphone

#дельфи #аудиозапись #микрофон

Вопрос:

Существует ли компонент Delphi для микрофона в реальном времени?

Я ищу тот, который предоставляет результаты без буфера.

Комментарии:

1. Что вы подразумеваете под «без буфера». Аудиоданные всегда нужно немного буферизировать. Просто часто читайте содержимое буфера, чтобы быстро получить звук. Какую проблему вы на самом деле пытаетесь решить?

2. Я хотел бы создать живой осциллограф для записи сэмплов с микрофона, а затем быстро построить его (или обработать). Например, мне нужно посмотреть, получу ли я входной импульс, а затем очень быстро что-то сделать, не делая тайм-аута.

3. Звуковой тракт уже имеет значительные задержки. Просто создайте таймер, скажем, с таймаутом 10 мс, в течение которого вы считываете буфер и отображаете новые полученные вами образцы. Если вы хотите реагировать на сигнал в течение нескольких миллисекунд, обычные аудио API-интерфейсы — это не то, что вам нужно, и Windows может быть даже не той ОС, которую вы хотите.

4. вы видели это? oscilloscope-lib.com

Ответ №1:

Вам понадобится аудиокарта с драйверами ASIO, например, более дорогие карты Sound Blaster. ASIO имеет очень низкую задержку, поскольку обеспечивает минимальный уровень связи между программным и аппаратным обеспечением. Тогда вы можете использовать это:

Проект Delphi ASIO и VST

Другие альтернативы включают использование порта FFMPEG Delphi и, конечно же, Direct X от Jedi.

Комментарии:

1. ASIO — это то, что использует все музыкальное программное обеспечение, верно? Я полагаю, что FruityLoops изначально был написан на Delphi и использовал ASIO.

2. @Warren P, если ты говоришь о синхронизации с такими инструментами, как клавишные / ударные, то это MIDI и VST.

3. FruityLoops — это синтезатор, управляемый плагином virtual instrument (VST), и секвенсор MIDI in / out с эффектами реального времени. Итак, все вышеперечисленное.

Ответ №2:

Есть аудиолаборатория от Mitov Software, которая утверждает, что делает то, что вы описываете. Я еще не пробовал этого делать.

Ответ №3:

Данные микрофона в режиме реального времени собираются в один массив :

 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;
/////////// [sample of use : ] /////////////////
var
  ind :TIndata;    
procedure TForm1.FormCreate(Sender: TObject);
begin
  SNDInitWaveIn;
  Timer1.Enabled:= true;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
    SNDProcWaveIn(ind);
    //code for proc data in "ind" buffer
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    SNDStopWave;
end;