はじめに
ここでは、簡単な WAVE サウンド録音プログラムの例を示します (サンプル コード (Visual Basic 6.0/Visual Basic 2010) は、こちらからダウンロードできます)。
このプログラムを実行するには、以下のようにしてください。以下は、Visual Basic 6.0 を使用した例です。
- 新しいプロジェクトを作成します。
- ツール ボックスに、“WAVE オーディオ デバイス インターフェイス コントロール” を追加します (「Visual Basic で WaveIn コントロールを使用する」を参照)。
- フォーム (Form1) に、WaveIn コントロールを配置します。
- フォーム (Form1) に、4 つのコマンド ボタンを配置します。
- それぞれのオブジェクトのプロパティを表のように設定し、このページの下の方にあるコードをコード モジュールに貼りつけます。
プログラムの概要
- フォームがロードされると、”~Record.tmp” という名前の一時ファイルをカレント フォルダに作成します (実際は、Windows API の GetTempFileName 関数を用いて一時ファイル用のファイル名を取得した方が良いでしょう)。
- [録音] ボタンをクリックすると、録音を開始し、録音されたデータを “~Record.tmp” に保存します。
- [停止] ボタンをクリックすると、録音を停止します。
- [保存] ボタンをクリックすると、InputBox 関数によるダイアログ ボックスが表示されます。ここにファイル名を入力し、[OK] ボタンをクリックすると、録音したデータを WAVE サウンド形式で保存します (通常、WAVE ファイルを扱う場合は、Windows API の mmio 系関数を用いますが、ここでは簡単にするため、Visual Basic のファイル アクセス ステートメントのみを使用しています)。
- [新規作成] ボタンをクリックすると、一時ファイルをいったん削除し、再度、空の一時ファイルを作成します。
- プログラムを終了すると、一時ファイルは削除されます。
このサンプル プログラムでは、最低限必要なコードしか書いてありません。したがって、実用的なプログラムにするためには、エラー処理のコードなども加える必要があります。
各オブジェクトのプロパティ
プロパティ | 値 |
---|---|
オブジェクト名 (Name) | cmdNew |
Caption | 新規作成(&N) |
プロパティ | 値 |
---|---|
オブジェクト名 (Name) | cmdSave |
Caption | 保存(&A)… |
プロパティ | 値 |
---|---|
オブジェクト名 (Name) | cmdRec |
Caption | 録音(&R) |
プロパティ | 値 |
---|---|
オブジェクト名 (Name) | cmdStop |
Caption | 停止(&S) |
プロパティ | 値 |
---|---|
Name (オブジェクト名) | WaveIn |
BitsPerSample | 8 – wifBPS8Bit |
BufferSize | 32768 |
Channels | 1 – wifMono |
DeviceID | -1 |
NumBuffers | 16 |
SamplesPerSec | 22050 |
サンプル コード
RecSamp.frm ファイル
VB
' 宣言セクション
Dim Buffer() As Byte ' 録音されたデータを受け取るためのバッファ
Dim fileRec As Integer ' 録音されたデータを保存する一時ファイルのファイル番号
Dim strRecFileName As String ' 一時ファイルのファイル名
Dim WaveSize As Long ' 録音されたデータのサイズ
' 新規作成のプロシージャ
Private Sub cmdNew_Click()
' 初期化します。
Init
' [録音] ボタンにフォーカスを設定します。
cmdRec.SetFocus
End Sub
' 録音を開始するプロシージャ
Private Sub cmdRec_Click()
' 録音を開始します。
Dim i As Integer
' デバイスを開きます。
WaveIn.Open
' バッファを確保します。
ReDim Buffer(WaveIn.BufferSize - 1)
' バッファを追加します。
For i = 0 To WaveIn.NumBuffers - 1
WaveIn.AddBuffer i
Next i
' 録音を開始します。
WaveIn.Start
End Sub
' 保存のプロシージャ
Private Sub cmdSave_Click()
' 録音したサウンドを WAVE ファイルに保存します。
Dim strFileName As String
strFileName = InputBox("ファイル名を入力してください。", "WAVE ファイルの保存", "Sound.wav")
If (strFileName <> "") Then
SaveWaveFile strFileName, fileRec
End If
End Sub
' 録音を停止するプロシージャ
Private Sub cmdStop_Click()
' 録音を停止します。
WaveIn.Stop
End Sub
' 終了処理
Private Sub Form_Unload(Cancel As Integer)
' 録音を停止します。
WaveIn.Stop
' デバイスを閉じます。
WaveIn.Close
' ファイルを閉じます。
Close
' 録音用の一時ファイルを削除します。
DeleteTmpFile
End Sub
' OnBusyFlagChange イベントの処理
Private Sub WaveIn_OnBusyFlagChange()
' 録音中であれば、
If (WaveIn.IsBusy) Then
' [録音]、[保存]、[新規作成] ボタンを無効にします。
cmdRec.Enabled = False
cmdSave.Enabled = False
cmdNew.Enabled = False
' [停止] ボタンを有効にします。
cmdStop.Enabled = True
' [停止] ボタンにフォーカスを設定します。
cmdStop.SetFocus
' 録音中でなければ、
Else
' WAVE 入力デバイスを閉じます。
WaveIn.Close
' [録音]、[保存]、[新規作成] ボタンを有効にします。
cmdRec.Enabled = True
cmdSave.Enabled = True
cmdNew.Enabled = True
' [停止] ボタンを無効にします。
cmdStop.Enabled = False
End If
End Sub
' OnDone イベントの処理
Private Sub WaveIn_OnDone(ByVal BufferIndex As Integer, ByVal BytesRecorded As Long, ByVal bStopped As Boolean)
' データが録音されていれば、
If (BytesRecorded > 0) Then
' 録音されたデータを取得します。
WaveIn.GetData Buffer, BufferIndex, BytesRecorded
If (UBound(Buffer) > (BytesRecorded - 1)) Then
' 無効なデータが書き込まれないように、配列のサイズを調整します。
ReDim Preserve Buffer(BytesRecorded - 1)
' データをファイルに保存します。
If (fileRec <> 0) Then
Put fileRec, , Buffer
End If
' 配列のサイズを元に戻します。
ReDim Buffer(WaveIn.BufferSize - 1)
Else
' データをファイルに保存します。
If (fileRec <> 0) Then
Put fileRec, , Buffer
End If
End If
' 録音されたデータ量を保存します。
WaveSize = WaveSize + BytesRecorded
End If
' Stop メソッドが実行されていなければ、
If (bStopped = False) Then
' 録音用のバッファを追加します。
WaveIn.AddBuffer BufferIndex
End If
End Sub
' Form_Load イベントの処理
Private Sub Form_Load()
' 一時ファイルを開きます。
strRecFileName = "~Record.tmp"
OpenTmpFile
' 初期化します。
Init
End Sub
' 一時ファイルを開く
Private Function OpenTmpFile() As Boolean
' 録音用のファイルを開いていなければ、
If (fileRec = 0) Then
' 録音のための一時ファイルを開きます。
fileRec = FreeFile
Open strRecFileName For Binary Access Read Write Lock Write As fileRec
End If
End Function
' 一時ファイルを閉じる
Private Sub CloseTmpFile()
' 録音用の一時ファイルを閉じます。
If (fileRec <> 0) Then
Close fileRec
fileRec = 0
End If
End Sub
' 一時ファイルを削除する
Private Sub DeleteTmpFile()
' 録音用の一時ファイルを削除します。
CloseTmpFile
If (Dir(strRecFileName) <> "") Then
Kill strRecFileName
WaveSize = 0
End If
End Sub
' 初期化
Private Sub Init()
' 初期化を行います。
' 一時ファイルを削除します。
DeleteTmpFile
' 一時ファイルを開きます。
OpenTmpFile
' [録音] ボタンを有効にします。
cmdRec.Enabled = True
' [停止]、[保存] ボタンを無効にします。
cmdStop.Enabled = False
cmdSave.Enabled = False
' 変数を初期化します。
WaveSize = 0
End Sub
' WAVE ファイルを保存する
Private Sub SaveWaveFile(strFileName As String, DataFile As Integer)
' 録音されたデータを WAVE ファイルとして保存します。
' strFileName : 保存するファイル名。
' DataFile : PCM データが記録されている一時ファイルのファイル番号。
Dim hdr As WAVEFILEHEADER
Dim file As Integer
Dim DataSize As Long
Dim BytesWritten As Long
Dim BytesToWrite As Long
Const BufferSize = 65536 ' ファイルの読み書きに使用するバッファのサイズ。
Dim Buffer() As Byte ' ファイルの読み書きに使用するバッファ。
' DataFile が開いていなければ、リターンします。
If (DataFile = 0) Then
Exit Sub
End If
' ファイルの先頭へシークします。
Seek DataFile, 1
' PCM データのサイズを取得します。
DataSize = LOF(DataFile)
' 空いているファイル番号を取得します。
file = FreeFile()
' バイナリ書き込みモードでファイルを開きます。
Open strFileName For Binary Access Write As file
' ファイルに書き込むヘッダ情報を初期化します。
With hdr
.ckidRIFF = "RIFF" ' RIFF チャンクの ID。
.ckSizeRIFF = DataSize + 36 ' PCM データのサイズ + 36 バイト。
.fccType = "WAVE" ' WAVE ファイルであることを示します。
.ckidFmt = "fmt " ' fmt チャンクの ID。
.ckSizeFmt = 16 ' fmt チャンクのサイズ。
With .WaveFmt ' フォーマット情報。
With .wf
.wFormatTag = WAVE_FORMAT_PCM ' フォーマット タグ。
.nChannels = WaveIn.Channels ' チャネル数。
.nSamplesPerSec = WaveIn.SamplesPerSec ' サンプリング周波数。
.nAvgBytesPerSec = WaveIn.AvgBytesPerSec ' 平均データ レート。
.nBlockAlign = WaveIn.BlockAlign ' ブロック アラインメント。
End With
.wBitsPerSample = WaveIn.BitsPerSample ' 量子化ビット数。
End With
.ckidData = "data" ' data チャンクの ID。
.ckSizeData = DataSize ' PCM データのサイズ。
End With
' ヘッダ情報を書き込みます。
Put file, , hdr
' ファイルの書き込みに使用するバッファを確保します。
ReDim Buffer(BufferSize - 1) As Byte
' PCM データを書き込みます。
Do Until EOF(DataFile)
BytesToWrite = Min(BufferSize, (DataSize - BytesWritten))
If (BytesToWrite = 0) Then
Exit Do
End If
ReDim Buffer(BytesToWrite - 1)
Get DataFile, , Buffer
Put file, , Buffer
BytesWritten = BytesWritten + BytesToWrite
Loop
' ファイルを閉じます。
Close file
End Sub
' 小さい方の値を返す関数
Private Function Min(a As Long, b As Long) As Long
' a, b のうち、小さい方を返します。
If (a > b) Then
Min = b
Else
Min = a
End If
End Function
Declares.bas ファイル
VB
' WAVE ファイルのフォーマットタグ。
Public Const WAVE_FORMAT_PCM = 1
' WAVEFORMAT 構造体。
Type WAVEFORMAT
wFormatTag As Integer
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
End Type
' PCMWAVEFORMAT 構造体。
Type PCMWAVEFORMAT
wf As WAVEFORMAT
wBitsPerSample As Integer
End Type
' WAVE ファイルのヘッダ。
Type WAVEFILEHEADER
ckidRIFF As String * 4
ckSizeRIFF As Long
fccType As String * 4
ckidFmt As String * 4
ckSizeFmt As Long
WaveFmt As PCMWAVEFORMAT
ckidData As String * 4
ckSizeData As Long
End Type