マイクの音を録音して.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」ファイルに保存されます。
***の箇所は連番の数字が入ります。
