PlaySound関数によるWAVE(ファイル/リソース)再生

概要:一番簡単なWAVEの再生方法

WAVE 再生には幾つもの方法があります。
今回はその一つであり、一番簡単な PlaySound 関数による再生方法を解説します。

■PlaySound 関数

PlaySound 関数は WAVE を再生させる関数です。
WAVE は実行環境で再生できるものでなければなりません。

BOOL PlaySound(
  LPCSTR pszSound,  // 再生対象のサウンド
  HMODULE hmod,   // インスタンスハンドル
  DWORD fdwSound  // 再生フラグ
);


winmm.lib をリンクする必要があります。

hmod には、リソースから再生させる時はインスタンスハンドルを、その他は NULL を指定します。
fdwSound には一つ、または複数のフラグを組み合わせて指定します。
 沢山あるので、よく使うものだけを取り上げます。

SND_ASYNC サウンドを非同期再生し、サウンドが開始されると、PlaySound 関数は即座に制御を返します。非同期再生されているサウンドを停止するには、pszSound パラメータで NULL を指定して PlaySound 関数を呼び出してください。
SND_FILENAME pszSound パラメータは、ファイル名を表します。
SND_LOOP サウンドを繰り返し再生します。pszSound パラメータで NULL を指定して PlaySound 関数を呼び出すと、サウンドが停止します。サウンドイベントを非同期再生するよう指示するために、SND_ASYNC と同時に指定しなければなりません。
SND_MEMORY サウンドイベントのファイルは、メモリ内に既にロードされています。pszSound パラメータは、メモリ内のサウンドイメージへのポインタを表します。
SND_RESOURCE pszSound パラメータは、リソース識別子を表します。hmod パラメータで、リソースを保持している実行可能ファイルのインタンスハンドルを指定しなければなりません。
SND_SYNC サウンドイベントを同期再生します。PlaySound 関数は、サウンドの再生が完了した後で制御を返します。

ここで重要なのは非同期再生と同期再生の違いです。
上記説明にもある通り、非同期再生は制御を直ぐに返すのに対して、同期再生は再生を終了するまで制御を返しません。
再生終了まで他の全ての処理が停止してしまうのは困るので、一般的には非同期再生を指定します。

SND_FILENAME を指定すると、ファイルから直接読み込んで再生してくれます。
オープン、リード、クローズ等の処理も全て請け負ってくれるので超便利です。
ただし、ファイルから読み込むのは時間がかかるので、
プログラム起動直後から最後まで再生し続けるBGM等の特殊な用途にしか使いません。
効果音など、即時性を要求するサウンドはメモリに読み込んでおきます。
メモリからの再生は次節で解説します。

SND_LOOP を指定すると、自動的に無限ループ再生してくれます。
ただし、何のメッセージも来ないのが欠点です。

サウンドを停止したい時は、pszSound に NULL を指定して PlaySound 関数を実行します。
一時停止ではなく、停止です。
PlaySound 関数は常に一番最初から再生します。

サウンド再生中に新しいサウンドを再生させようとすると、
以前のサウンドは停止され、新しいサウンドが再生されます
( SND_NOSTOP フラグを指定すると、現在の再生が継続され、新しいサウンドは再生されません)。

以上のように、PlaySound 関数は非常に簡単で便利なのですが、
細かい操作ができないのが欠点です。

■WAVEファイル再生&停止

マウスの左ボタンをクリックするとWAVEファイルを無限ループ非同期再生、
右ボタンをクリックすると停止するプログラムを作ってみましょう。

// winmm.lib をリンクする
#pragma comment(lib,"winmm")

#define FILENAME "Windows XP Startup.wav"

LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    switch(uMsg){
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_LBUTTONDOWN:    //再生
            PlaySound(FILENAME,NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);
            return 0;
        case WM_RBUTTONDOWN:    //停止
            PlaySound(NULL,NULL,0);
            return 0;
    }
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

★☆ ソースファイル表示 ☆★

ライブラリのリンクには #pragma を使う他に、プロジェクトメニューから追加する方法があります。
後者の方が推奨されているようです。

■WAVEリソースの再生&停止

WAVEリソースの再生方法はWAVEファイルの再生方法と殆ど同じです。
再生フラグ SND_FILENAME を SND_RESOURCE に替えるだけです。
SND_RESOURCE を指定すると、リソースからの読み込み処理も自動的に行われます。

// winmm.lib をリンクする
#pragma comment(lib,"winmm")

LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    HINSTANCE hInst;

    switch(uMsg){
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_LBUTTONDOWN:    //再生
            hInst=(HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE);
            PlaySound("WinXP_Startup",hInst,SND_RESOURCE | SND_ASYNC | SND_LOOP);
            return 0;
        case WM_RBUTTONDOWN:    //停止
            PlaySound(NULL,NULL,0);
            return 0;
    }
    return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

リソースファイルには以下のように登録されています。

/////////////////////////////////////////////////////////////////////////////
//
// WAVE
//

WinXP_Startup           WAVE                    "Windows XP Startup.wav"

★☆ ソースファイル表示 ☆★

PlaySound 関数はただ再生させたい場合には非常に簡単で便利でしょう。
自由度がないので敬遠されがちですが、条件が合致すれば、この簡単さは大きな魅力です。


戻る / ホーム