マルチメディアAPI(MME)を利用してWAVファイルを再生する
(その4)

WAVファイルの再生を一時停止する

WAVファイル再生中にダイアログの[一時再生]ボタンを押されたら、WAVファイルの再生を一時停止します。

WAVファイルの再生を一時停止させる場合、サウンド出力を終了させます。

サウンド出力を終了する場合、

の順に処理します。

サンプルコードを以下に示します。


/****************************************************************************/
/*!
 *  @brief  WAVファイルの再生を一時停止する.
 *
 *  @param  [in]    hDlg    ダイアログのウインドウ・ハンドル.
 *
 *  @retval なし.
 */
static void     PauseSoundOutput( HWND hDlg )
{
    //! サウンド出力デバイスをクローズする.
    CloseSoundOutputDevice();

    EnableWindow( GetDlgItem( hDlg, IDC_PLAY          ), TRUE  );
    EnableWindow( GetDlgItem( hDlg, IDC_PAUSE         ), FALSE );
    EnableWindow( GetDlgItem( hDlg, IDC_STOP          ), FALSE );
    EnableWindow( GetDlgItem( hDlg, IDC_FILENAME      ), TRUE  );
    EnableWindow( GetDlgItem( hDlg, IDC_FILE_SELECT   ), TRUE  );
    EnableWindow( GetDlgItem( hDlg, IDC_OUTPUT_DEVICE ), TRUE  );
}
	


/****************************************************************************/
/*!
 *  @brief  サウンド出力デバイスをクローズする.
 *
 *  @param  なし.
 *
 *  @retval なし.
 */
static void     CloseSoundOutputDevice( void )
{
    if( hWO ){
        //! -1.サウンド出力を停止する.
        waveOutReset( hWO );

        for( int i = 0; i < 2; i++ ){
            //! -2.出力デバイスに登録したデータブロックを解放する.
            waveOutUnprepareHeader( hWO, &OutHdr[i], sizeof(WAVEHDR) );

            //! -3.データバッファを解放する.
            if( OutHdr[i].lpData ){
                delete [] OutHdr[i].lpData;
                OutHdr[i].lpData = NULL;
            }
        }
        //! -4.出力デバイスをクローズする.
        waveOutClose( hWO );
        hWO = NULL;
    }
}
	

サンプルコードの再生停止の方法だと、出力デバイスにキューイングされているが、まだ再生されていないデータブロックの オーディオ・ブロックのデータが再生されずに捨てられてしまい、再度再生を開始したときは、このデータブロックの次のデータから 再生を始めるために厳密にはレジュームができていません。
一時停止するときに、2データブロック分の無音データを再生停止する前に投入し、この無音データの再生が終了した時点で サウンド出力の終了処理を行えばよいのですが、処理が少し複雑になるので対応しないことにします。

WAVファイルの再生を停止する

WAVファイル再生中にダイアログの[停止]ボタンを押されたら、WAVファイルの再生を停止します。

WAVファイルの再生を停止させる場合、サウンド出力を終了させてからWAVファイルをクローズします。

サンプルコードを以下に示します。


/****************************************************************************/
/*!
 *  @brief  WAVファイルの再生を停止する.
 *
 *  @param  なし.
 *
 *  @retval なし.
 */
static void     StopSoundOutput( HWND hDlg )
{
    //! サウンド出力デバイスをクローズする.
    CloseSoundOutputDevice();

    //! 再生したWAVファイルをクローズする.
    CloseWaveFile();

    //! WAVファイルの読み込み用バッファを解放する.
    if( DataBuff ){
        delete [] DataBuff;
        DataBuff = NULL;
    }
    EnableWindow( GetDlgItem( hDlg, IDC_PLAY          ), TRUE  );
    EnableWindow( GetDlgItem( hDlg, IDC_PAUSE         ), FALSE );
    EnableWindow( GetDlgItem( hDlg, IDC_STOP          ), FALSE );
    EnableWindow( GetDlgItem( hDlg, IDC_FILENAME      ), TRUE  );
    EnableWindow( GetDlgItem( hDlg, IDC_FILE_SELECT   ), TRUE  );
    EnableWindow( GetDlgItem( hDlg, IDC_OUTPUT_DEVICE ), TRUE  );
}
	

サウンド出力処理を停止する

waveOutReset()を呼び出して、現在動作中のサウンド出力処理を停止します。


    MMRESULT waveOutReset( HWAVEOUT hwo )
	

引数説明
hwoサウンド出力デバイスのハンドル

waveOutReset()からの戻り値がMMSYSERR_NOERRORであれば、サウンド出力は停止されます。

waveOutWrite()によりサウンド出力要求されて、まだ未処理のデータブロックは、 すべて処理済みとしてアプリケーションにコールバックされます。

データブロックをサウンド出力デバイスから切り離す(クリーンアップ)

waveOutUnprepareHeader()を呼び出して、waveOutPrepareHeader()にて関連付けたデータブロックを切り離します。


    MMRESULT waveOutUnprepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh )
	

引数説明
hwoサウンド出力デバイスのハンドル
pwhクリーンアップするデータブロック(WAVEHDR構造体)のポインタ
cbwhWAVEHDR構造体のバイト数

waveOutUnprepareHeader()からの戻り値がMMSYSERR_NOERRORであれば、データブロックの切り離しは完了です。

データブロックのクリーンアップが完了すれば、データブロックに割り付けていたデータバッファ等は解放できます。

サウンド出力デバイスをクローズする

waveOutClose()を呼び出して、サウンド出力デバイスをクローズします。


    MMRESULT waveOutClose( HWAVEOUT hwo )
	

引数説明
hwoサウンド出力デバイスのハンドル

waveOutClose()からの戻り値がMMSYSERR_NOERRORであれば、デバイスのクローズは完了です。



商標に関する表示