マイクの音を録音して.wavファイルに保存する ~Delphiソースコード集
Delphiだけでマイクの音を録音して.wavファイルに保存するするアプリケーションを作成します。 「waveInAddBuffer」でマイクからの音をデータとして取得し、TFileStreamで.wavファイルに保存します。
プロジェクトを作成する
Delphiを起動し、メニューから「ファイル」⇒「新規作成」⇒「Windows VCLアプリケーション -Delphi(W)」 をクリックする。
TCombobox × 2個、TButton × 2個をフォームにドラッグ&ドロップします。

ソースコードの入力
キーボードの「F12」キーを押してソースコードエディタに切り替え、以下のソースコードをコピー&ペーストします。
キーボードの「F12」キーを押してデザインモードに切り替え、
Form1のOnCreateイベントに「FormCreate」を設定し、Form1のOnCloseに「FormClose」を設定します。
Button1のOnClickイベントに「Button1Click」を設定し、Button2のOnClickイベントに「Button2Click」を設定します。
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, MMSystem, Vcl.ExtCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; ComboBox1: TComboBox; ComboBox2: TComboBox; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private 宣言 } WaveFmt:TWaveFormatEx; //サンプリングバッファ BufIn:array of TBytes; WaveInHandle:HWAVEIN; NowBufId:Integer; WaveHeader:array of TWaveHdr; //Waveバッファ WaveBuf:TBytes; BufInLen:Integer; SaveCount:Integer; public { Public 宣言 } end; var Form1: TForm1; const //サンプリングバッファの数 BufInNum:Integer=8; implementation {$R *.dfm} //コールバック関数 procedure WaveInCallBackFunc(hW:HWAVEOUT;uMsg:Cardinal; dwInstance,dwParam1,dwParam2:UINT_PTR);stdcall; var OldBufId, n:Integer; begin if uMsg=MM_WIM_DATA then begin OldBufId := Form1.NowBufId; inc(Form1.NowBufId); Form1.NowBufId := Form1.NowBufId mod BufInNum; waveInAddBuffer( Form1.WaveInHandle, @Form1.WaveHeader[Form1.NowBufId], SizeOf(TWaveHdr) ); n := Length(Form1.WaveBuf); SetLength(Form1.WaveBuf, n + Form1.BufInLen); Move(Form1.BufIn[OldBufId][0], Form1.WaveBuf[n], Form1.BufInLen); end; end; procedure SaveWaveFile(filename:string); var ChunkID:array[0..3] of AnsiChar; FileStream:TFileStream; Size:Cardinal; begin FileStream := TFileStream.Create(Filename, fmCreate); try // 'RIFF'チャンク ChunkID := 'RIFF'; FileStream.WriteBuffer(ChunkID, SizeOf(ChunkID)); Size := 4 + (8 + SizeOf(Form1.WaveFmt)) + (8 + Length(Form1.WaveBuf)); FileStream.WriteBuffer(Size, SizeOf(Size)); // 'WAVE'フォーマット ChunkID := 'WAVE'; FileStream.WriteBuffer(ChunkID, SizeOf(ChunkID)); // 'fmt 'チャンク ChunkID := 'fmt '; FileStream.WriteBuffer(ChunkID, SizeOf(ChunkID)); Size := SizeOf(Form1.WaveFmt); FileStream.WriteBuffer(Size, SizeOf(Size)); FileStream.WriteBuffer(Form1.WaveFmt, size); // 'data'チャンク ChunkID := 'data'; FileStream.WriteBuffer(ChunkID, SizeOf(ChunkID)); Size := Length(Form1.WaveBuf); FileStream.WriteBuffer(Size, SizeOf(Size)); FileStream.WriteBuffer(Form1.WaveBuf[0], Size); finally FileStream.Free; end; end; //録音開始 procedure TForm1.Button1Click(Sender: TObject); var i:Integer; begin ComboBox1.Enabled:=False; ComboBox2.Enabled:=False; Button1.Enabled:=False; Button2.Enabled:=True; SetLength(WaveBuf, 0); ZeroMemory(@WaveFmt,SizeOf(TWaveFormatEx)); WaveFmt.wFormatTag:=WAVE_FORMAT_PCM; //1チャンネル(モノラル or ステレオ) WaveFmt.nChannels := ComboBox1.ItemIndex + 1; //サンプリング周波数 8000 11025 22050 44100 48000 //対応しているかどうかはハードウェアによる if ComboBox2.ItemIndex=0 then WaveFmt.nSamplesPerSec := 11025 else if ComboBox2.ItemIndex=1 then WaveFmt.nSamplesPerSec := 22050 else if ComboBox2.ItemIndex=2 then WaveFmt.nSamplesPerSec := 44100 else WaveFmt.nSamplesPerSec := 48000; //1サンプル当たりのビット数を指定(符号付き16Bit整数 -32768~32767の範囲) WaveFmt.wBitsPerSample := 16; //1ブロックのバイト数 WaveFmt.nBlockAlign := WaveFmt.nChannels * WaveFmt.wBitsPerSample div 8; //1秒当たりの平均バイト数 WaveFmt.nAvgBytesPerSec := WaveFmt.nBlockAlign * WaveFmt.nSamplesPerSec; //必ず0 WaveFmt.cbSize := 0; waveInOpen( @WaveInHandle, WAVE_MAPPER, @WaveFmt, DWORD_PTR(@WaveInCallBackFunc), 0, CALLBACK_FUNCTION+WAVE_ALLOWSYNC ); BufInLen := WaveFmt.nSamplesPerSec * WaveFmt.nChannels; SetLength(WaveHeader, BufInNum); SetLength(BufIn, BufInNum); for i := 0 to BufInNum-1 do begin //バッファサイズの設定 SetLength(BufIn[i], BufInLen); //バッファの設定 WaveHeader[i].lpData := PAnsiChar(BufIn[i]); WaveHeader[i].dwBufferLength := BufInLen; 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)); end; NowBufId := 0; waveInAddBuffer(WaveInHandle, @WaveHeader[NowBufId], SizeOf(TWaveHdr)); waveInStart(WaveInHandle); end; //録音停止 procedure TForm1.Button2Click(Sender: TObject); var i:Integer; begin ComboBox1.Enabled := True; ComboBox2.Enabled := True; Button1.Enabled := True; Button2.Enabled := False; waveInStop(WaveInHandle); for i := 0 to BufInNum-1 do waveInUnprepareHeader(WaveInHandle, @WaveHeader[i], SizeOf(TWaveHdr)); waveInClose(WaveInHandle); SaveWaveFile('sample'+SaveCount.ToString+'.wav'); Inc(SaveCount); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Action:=caFree; //録音中なら停止させる if Button2.Enabled then Button2Click(Button2); end; procedure TForm1.FormCreate(Sender: TObject); begin BufInLen := 11025; SaveCount := 1; ComboBox1.Style:=csDropDownList; ComboBox1.Items.Add('モノラル'); ComboBox1.Items.Add('ステレオ'); ComboBox1.ItemIndex := 0; ComboBox2.Style:=csDropDownList; ComboBox2.Items.Add('11025'); ComboBox2.Items.Add('22050'); ComboBox2.Items.Add('44100'); ComboBox2.Items.Add('48000'); ComboBox2.ItemIndex := 0; Button2.Enabled := False; end; end.
実行
内臓又は外付けマイクをパソコンに接続してください。
実行してButton1をクリックすると録音を開始します。
Button2をクリックすると録音を終了してファイル名「sample***.wav」ファイルに保存されます。
***の箇所は連番の数字が入ります。