はじめに
ここでは、簡単な WAVE サウンド再生プログラムの例を示します (サンプル コード (Visual Basic 6.0/Visual Basic 2010) は、こちらからダウンロードできます)。
このプログラムを実行するには、以下のようにしてください。以下は、Visual Basic 6.0 を使用した例です。
- 新しいプロジェクトを作成します。
- ツール ボックスに、“WAVE オーディオ デバイス インターフェイス コントロール” を追加します (「Visual Basic で WaveOut コントロールを使用する」を参照)。
- フォーム (Form1) に、WaveOut コントロールを配置します。
- フォーム (Form1) に、3 つのコマンド ボタンを配置します。
- それぞれのオブジェクトのプロパティを表のように設定し、このページの下の方にあるコードをコード モジュールに貼りつけます。

プログラムの概要
- [開く…] ボタンをクリックすると、InputBox 関数によるダイアログ ボックスが表示されます。ここに既存の WAVE ファイル名を出力し、[OK] ボタンをクリックすると、ファイルが開かれます (通常、WAVE ファイルを扱う場合は、Windows API の mmio 系関数を用いますが、ここでは簡単にするため、Visual Basic のファイル アクセス ステートメントのみを使用しています)。この時、ファイルのフォーマットがチェックされ、正しい WAVE ファイルでない場合は、エラー メッセージが表示されます。
- [再生] ボタンをクリックすると、再生を開始します。
- [停止] ボタンをクリックすると、再生を停止します。
- プログラムを終了すると、デバイスおよびファイルを閉じます。
このサンプル プログラムでは、最低限必要なコードしか書いてありません。したがって、実用的なプログラムにするためには、エラー処理のコードなども加える必要があります。
各オブジェクトのプロパティ
プロパティ | 値 |
---|---|
オブジェクト名 (Name) | cmdOpen |
Caption | 開く(&O)… |
プロパティ | 値 |
---|---|
オブジェクト名 (Name) | cmdPlay |
Caption | 再生(&P) |
プロパティ | 値 |
---|---|
オブジェクト名 (Name) | cmdStop |
Caption | 停止(&S) |
プロパティ | 値 |
---|---|
Name (オブジェクト名) | WaveOut |
BufferSize | 65536 |
DeviceID | -1 |
NumBuffers | 16 |
サンプル コード
PlaySamp.frm ファイル
VB
' 宣言セクション
Dim DataSize As Long ' サウンド データのサイズ。
Dim DataOffset As Long ' ファイルの先頭からサウンド データまでのオフセット。
Dim WaveFile As Integer ' 開いた WAVE ファイルのファイル番号。
Dim Buffer() As Byte ' 再生時に使用するバッファ。
' WAVE ファイルを開く
Private Sub cmdOpen_Click()
' WAVE ファイルを開きます。
Dim strFileName As String
strFileName = InputBox("ファイル名を入力してください。", "WAVE ファイルを開く")
If (strFileName <> "") Then
' 初期化します。
Init
' ファイルを開きます。
If (OpenWaveFile(strFileName) = True) Then
' [再生] ボタンを有効にします。
cmdPlay.Enabled = True
' [再生] ボタンにフォーカスを設定します。
cmdPlay.SetFocus
End If
End If
End Sub
' WAVE ファイルを開く関数
Private Function OpenWaveFile(strFileName As String) As Boolean
' WAVE ファイルを開きます。
' strFileName : 開く WAVE ファイル名。
' 戻り値 : 成功した場合は True、失敗した場合は False。
Dim hdr As WAVEFILEHEADER
' 空いているファイル番号を取得します。
WaveFile = FreeFile()
' バイナリ読み取りモードでファイルを開きます。
Open strFileName For Binary Access Read As WaveFile
' ヘッダ情報を取得します。
Get WaveFile, , hdr
' ファイルのフォーマットをチェックします。
If (hdr.ckidRIFF <> "RIFF") Then
' エラー メッセージを表示し、ファイルを閉じます。
MsgBox "このファイルは RIFF ファイルではありません。"
CloseWaveFile
OpenWaveFile = False
Exit Function
End If
If (hdr.fccType <> "WAVE") Then
' エラー メッセージを表示し、ファイルを閉じます。
MsgBox "このファイルは WAVE ファイルではありません。"
CloseWaveFile
OpenWaveFile = False
Exit Function
End If
If (hdr.ckidFmt <> "fmt ") Then
' エラー メッセージを表示し、ファイルを閉じます。
MsgBox "このファイルにはフォーマット情報がありません。"
CloseWaveFile
OpenWaveFile = False
Exit Function
End If
If (hdr.ckidData <> "data") Then
' エラー メッセージを表示し、ファイルを閉じます。
MsgBox "このファイルにはサウンド データがありません。"
CloseWaveFile
OpenWaveFile = False
Exit Function
End If
If (hdr.WaveFmt.wf.wFormatTag <> WAVE_FORMAT_PCM) Then
' エラー メッセージを表示し、ファイルを閉じます。
MsgBox "この WAVE ファイルは PCM 形式ではありません。"
CloseWaveFile
OpenWaveFile = False
Exit Function
End If
' WaveOut コントロールのプロパティを設定します。
With WaveOut
.Channels = hdr.WaveFmt.wf.nChannels
.SamplesPerSec = hdr.WaveFmt.wf.nSamplesPerSec
.BitsPerSample = hdr.WaveFmt.wBitsPerSample
End With
' サウンド データのサイズを保存します。
DataSize = hdr.ckSizeData
' ファイルの先頭からサウンド データまでのオフセットを保存します。
DataOffset = Seek(WaveFile)
OpenWaveFile = True
End Function
' WAVE ファイルを閉じる
Private Sub CloseWaveFile()
' WAVE ファイルを閉じます。
If (WaveFile <> 0) Then
Close WaveFile
WaveFile = 0
End If
End Sub
' 再生を開始する
Private Sub cmdPlay_Click()
Dim i As Integer
Dim SizeToPlay As Long
' WAVE データの先頭にシークします。
Seek WaveFile, DataOffset
' デバイスを開きます。
WaveOut.Open
' 再生を一時停止しておきます。
WaveOut.Pause
' バッファを確保します。
ReDim Buffer(WaveOut.BufferSize - 1)
For i = 0 To WaveOut.NumBuffers - 1
' 再生するデータ サイズを計算します。
SizeToPlay = Min(DataSize - (Seek(WaveFile) - DataOffset), WaveOut.BufferSize)
' サイズが 0 以下ならば (データがなければ)、ループを抜けます。
If (SizeToPlay <= 0) Then
Exit For
End If
' データを読み込みます。
Get WaveFile, , Buffer
' デバイスにデータを書き込みます。
WaveOut.SetData Buffer, i
WaveOut.AddBuffer i, SizeToPlay
' ファイルの最後まで来ていたら、ループを抜けます。
If (EOF(WaveFile)) Then
Exit For
End If
Next i
' 再生を開始します。
WaveOut.Restart
End Sub
' 再生を停止する
Private Sub cmdStop_Click()
' 再生を停止します。
WaveOut.Stop
End Sub
' Form_Load イベントの処理
Private Sub Form_Load()
' 初期化します。
Init
End Sub
' 終了処理
Private Sub Form_Unload(Cancel As Integer)
' 再生を停止します。
WaveOut.Stop
' デバイスを閉じます。
WaveOut.Close
' ファイルを閉じます。
CloseWaveFile
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
' OnBusyFlagChange イベントの処理
Private Sub WaveOut_OnBusyFlagChange()
' 再生中であれば、
If (WaveOut.IsBusy) Then
' [再生]、[開く] ボタンを無効にします。
cmdPlay.Enabled = False
cmdOpen.Enabled = False
' [停止] ボタンを有効にします。
cmdStop.Enabled = True
' 再生中でなければ、
Else
' WAVE 出力デバイスを閉じます。
WaveOut.Close
' [再生]、[開く] ボタンを有効にします。
cmdPlay.Enabled = True
cmdOpen.Enabled = True
' [再生] ボタンにフォーカスを設定します。
cmdPlay.SetFocus
' [停止] ボタンを無効にします。
cmdStop.Enabled = False
End If
End Sub
' OnDone イベントの処理
Private Sub WaveOut_OnDone(ByVal BufferIndex As Integer, ByVal bStopped As Boolean)
Dim SizeToPlay As Long
' Stop メソッドが実行されていなければ、
If (bStopped = False) Then
' すでにファイルの最後まで達していたら、何も処理しません。
If (EOF(WaveFile)) Then
Exit Sub
End If
' 再生するデータ サイズを計算します。
SizeToPlay = Min(DataSize - (Seek(WaveFile) - DataOffset), WaveOut.BufferSize)
' サイズが 0 以下ならば (データがなければ)、リターンします。
If (SizeToPlay <= 0) Then
Exit Sub
End If
' データを読み込みます。
Get WaveFile, , Buffer
' デバイスにデータを追加します。
WaveOut.SetData Buffer, BufferIndex
WaveOut.AddBuffer BufferIndex, SizeToPlay
End If
End Sub
' 初期化
Private Sub Init()
' 初期化を行います。
' [再生]、[停止] ボタンを無効にします。
cmdPlay.Enabled = False
cmdStop.Enabled = False
' [開く] ボタンを有効にします。
cmdOpen.Enabled = True
' ファイルを閉じます。
CloseWaveFile
' 変数を初期化します。
DataSize = 0
DataOffset = 0
Erase Buffer
End Sub
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