トップへ(mam-mam.net/)

Play Microphone Audio in Near Real Time – Delphi Source Code Collection

Japanese

Play Microphone Audio in Near Real Time – Delphi Source Code Collection

Create a New Project

Start Delphi, then choose “File” ⇒ “New” ⇒ “Windows VCL Application – Delphi (W)” from the menu.

Enter the Source Code

Add the following source code to Form1, including the OnCreate and OnDestroy events.

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, MMSystem;

{
  * Note 1: You may need to disable the OS "Microphone Boost" feature
    (only for devices that support and use this feature).
    Right‑click the speaker icon on the taskbar
      ⇒ Click "Open Sound settings"
        ⇒ Click "Device properties" under the microphone
          ⇒ Click “Additional device properties”
            ⇒ Open the "Levels" tab and set [Microphone Boost] to 0.0 dB, then click [OK].

  * Note 2: Feedback (howling) will occur if the microphone and speakers are too close.
    For example, using a laptop’s built‑in microphone and built‑in speakers
    will cause high‑pitched feedback because the distance is too short.
    Use an external microphone or external speakers placed farther apart.
}

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    WaveFmt: TWaveFormatEx;
    BufIn: array of TBytes;
  public
    { Public declarations }
    WaveInHandle: HWAVEIN;
    WaveOutHandle: HWAVEOUT;
    BufNumId: Integer;
    WaveHeader: array of TWaveHdr;
  end;

// Callback function
procedure WaveInCallBackFunc(hW: HWAVEOUT; uMsg: Cardinal;
  dwInstance, dwParam1, dwParam2: UINT_PTR); stdcall;

var
  Form1: TForm1;

const
  // Number of buffers
  BufNum: Integer = 16;

implementation

{$R *.dfm}

// Callback function
procedure WaveInCallBackFunc(hW: HWAVEOUT; uMsg: Cardinal;
  dwInstance, dwParam1, dwParam2: UINT_PTR); stdcall;
var
  OldBufId: Integer;
begin
  if uMsg = MM_WIM_DATA then
  begin
    OldBufId := Form1.BufNumId;
    Inc(Form1.BufNumId);
    if Form1.BufNumId >= BufNum then
      Form1.BufNumId := 0;

    waveInAddBuffer(
      Form1.WaveInHandle, @Form1.WaveHeader[Form1.BufNumId], SizeOf(TWaveHdr));
    waveOutWrite(
      Form1.WaveOutHandle, @Form1.WaveHeader[OldBufId], SizeOf(TWaveHdr));
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  WaveFmt.wFormatTag := WAVE_FORMAT_PCM;
  // 1 channel (mono)
  WaveFmt.nChannels := 1;
  // Sampling rate: 11025, 22050, or 44100
  WaveFmt.nSamplesPerSec := 11025;
  WaveFmt.wBitsPerSample := 16; // signed 16‑bit integer
  WaveFmt.nBlockAlign := WaveFmt.nChannels * WaveFmt.wBitsPerSample div 8;
  WaveFmt.nAvgBytesPerSec := WaveFmt.nBlockAlign * WaveFmt.nSamplesPerSec;
  WaveFmt.cbSize := 0; // must be 0

  waveInOpen(
    @WaveInHandle, WAVE_MAPPER, @WaveFmt, NativeUInt(@WaveInCallBackFunc),
    0, CALLBACK_FUNCTION + WAVE_ALLOWSYNC);
  waveOutOpen(
    @WaveOutHandle, WAVE_MAPPER, @WaveFmt, 0, 0,
    CALLBACK_FUNCTION + WAVE_ALLOWSYNC);

  SetLength(WaveHeader, BufNum);
  SetLength(BufIn, BufNum);

  for i := 0 to BufNum - 1 do
  begin
    // Set buffer size
    SetLength(BufIn[i], 1024);
    // Configure buffer
    WaveHeader[i].lpData := PAnsiChar(BufIn[i]);
    WaveHeader[i].dwBufferLength := Length(BufIn[i]);
    WaveHeader[i].dwBytesRecorded := 0;
    WaveHeader[i].dwUser := i;
    WaveHeader[i].dwFlags := 0;
    WaveHeader[i].dwLoops := 0;
    WaveHeader[i].lpNext := nil;
    WaveHeader[i].reserved := 0;

    waveInPrepareHeader(WaveInHandle, @WaveHeader[i], SizeOf(TWaveHdr));
    waveOutPrepareHeader(WaveOutHandle, @WaveHeader[i], SizeOf(TWaveHdr));
  end;

  BufNumId := 0;
  waveInAddBuffer(WaveInHandle, @WaveHeader[BufNumId], SizeOf(TWaveHdr));
  waveInStart(WaveInHandle);
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to BufNum - 1 do
  begin
    waveInUnprepareHeader(WaveInHandle, @WaveHeader[i], SizeOf(TWaveHdr));
    waveOutUnprepareHeader(WaveOutHandle, @WaveHeader[i], SizeOf(TWaveHdr));
  end;

  waveInClose(WaveInHandle);
  waveOutClose(WaveOutHandle);
end;

end.

Running the Application

Please note the following points before running the application. Make sure to check these items to avoid unexpected issues.

* Note 1: You may need to disable the OS “Microphone Boost” feature
(Only for devices that support and use the Microphone Boost feature)
Right‑click the speaker icon on the right side of the taskbar
⇒ Click “Open Sound settings”
⇒ Click “Device properties” under the microphone
⇒ Click “Additional device properties”
⇒ Open the “Levels” tab
Set [Microphone Boost] to 0.0 dB and click [OK]
* Note 2: Feedback (howling) will occur if the microphone and speakers are too close
For example, using a laptop’s built‑in microphone and built‑in speakers
will cause high‑pitched feedback because the distance between them is too short.
Please use an external microphone or external speakers placed farther apart.