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

マイクの音をほぼリアルタイムにスピーカーに流す ~Delphiソースコード集

検索:

マイクの音をほぼリアルタイムにスピーカーに流す ~Delphiソースコード集

プロジェクトを作成する

Delphiを起動し、メニューから「ファイル」⇒「新規作成」⇒「Windows VCLアプリケーション -Delphi(W)」 をクリックする。

ソースコードの入力

Form1のOnCreate、OnDestroyなどに以下のソースコードを記述します。

unit Unit1;

interface

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

{
  ※注意1   OSの「マイクブースト」の機能を切る必要があります
  (マイクブースト機能対応デバイスで、この機能を使用している場合)
  ツールバーの右側にある「スピーカー」アイコンを右クリック
    ⇒「サウンドの設定を開く」を左クリック
      ⇒マイクの「デバイスのプロパティ」を左クリック
        ⇒「追加のデバイスのプロパティ」を左クリック
          ⇒「レベル」タブを左クリックして切り替え、
            [マイクブースト]を0.0dbに設定して[OK]ボタンを押す


  ※注意2   マイクとスピーカーを近づけて使用するとハウリングが発生します
  例えばノートパソコンの内臓マイクと内臓スピーカーを使用すると
  マイクとスピーカーの距離が近すぎてハウリング(キーンと高い音)が発生します。
  外付けマイク又は外付けスピーカーなどで離して使用してください。
}


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

//コールバック関数
procedure WaveInCallBackFunc(hW:HWAVEOUT;uMsg:Cardinal;
  dwInstance,dwParam1,dwParam2:UINT_PTR);stdcall;

var
  Form1: TForm1;
const
  //バッファの数
  BufNum:Integer=16;


implementation

{$R *.dfm}

//コールバック関数
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チャンネル(モノラル)
  WaveFmt.nChannels:=1;
  //サンプリング周波数 11025 又は 22050 又は 44100
  WaveFmt.nSamplesPerSec:=11025;
  WaveFmt.wBitsPerSample:=16;//符号付き16Bit整数
  WaveFmt.nBlockAlign:=WaveFmt.nChannels*WaveFmt.wBitsPerSample div 8;
  WaveFmt.nAvgBytesPerSec:=WaveFmt.nBlockAlign*WaveFmt.nSamplesPerSec;
  WaveFmt.cbSize:=0;//必ず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
    //バッファサイズの設定
    SetLength(BufIn[i],1024);
    //バッファの設定
    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.

実行

実行時には以下の注意点があります。以下の注意点を踏まえたうえで実行してください。

※注意1 OSの「マイクブースト」の機能を切る必要があります
(マイクブースト機能対応デバイスで、この機能を使用している場合)
ツールバーの右側にある「スピーカー」アイコンを右クリック
⇒「サウンドの設定を開く」を左クリック
⇒マイクの「デバイスのプロパティ」を左クリック
⇒「追加のデバイスのプロパティ」を左クリック
⇒「レベル」タブを左クリックして切り替え、
[マイクブースト]を0.0dbに設定して[OK]ボタンを押す
※注意2 マイクとスピーカーを近づけて使用するとハウリングが発生します
例えばノートパソコンの内臓マイクと内臓スピーカーを使用すると
マイクとスピーカーの距離が近すぎてハウリング(キーンと高い音)が発生します。
外付けマイク又は外付けスピーカーなどで離して使用してください。