サウンド再生プログラムの例

ここでは、簡単な WAVE サウンド再生プログラムの例を示します (サンプル コード (Visual Basic 6.0/Visual Basic 2010) は、こちらからダウンロードできます)。

このプログラムを実行するには、以下のようにしてください。以下は、Visual Basic 6.0 を使用した例です。

  1. 新しいプロジェクトを作成します。
  2. ツール ボックスに、“WAVE オーディオ デバイス インターフェイス コントロール”を追加します (「Visual Basic で WaveOut コントロールを使用する」を参照)。
  3. フォーム (Form1) に、WaveOut コントロールを配置します。
  4. フォーム (Form1) に、3 つのコマンド ボタンを配置します。
  5. それぞれのオブジェクトのプロパティをのように設定し、このページの下の方にあるコードをコード モジュールに貼りつけます。

フォーム上のコントロールの配置図

注意 : このサンプル プログラムは自由に利用できますが、このプログラムの使用によって生じた問題に対して、作者は一切責任を持ちません。


プログラムの概要

このサンプル プログラムでは、最低限必要なコードしか書いてありません。したがって、実用的なプログラムにするためには、エラー処理のコードなども加える必要があります。


表 : 各オブジェクトのプロパティ

コマンド ボタンのプロパティ
プロパティ
オブジェクト名 (Name) cmdOpen
Caption 開く(&O)...
コマンド ボタンのプロパティ
プロパティ
オブジェクト名 (Name) cmdPlay
Caption 再生(&P)
コマンド ボタンのプロパティ
プロパティ
オブジェクト名 (Name) cmdStop
Caption 停止(&S)
WaveOut コントロールのプロパティ
プロパティ
Name (オブジェクト名) WaveOut
BufferSize 65536
DeviceID -1
NumBuffers 16

サンプル コード

' 宣言セクション
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
' 以下のコードは、標準モジュール (.bas) に貼りつけてください。
' 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

リターン WaveOut コントロールのページへもどる

Copyright © 1998-2023, Kentaro HARA. All rights reserved.
コンテンツの複製・転載・二次使用には、著作権者の許諾が必要です。