マルチメディアAPI(MME)を利用してWAVファイルを再生する
(その4)
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ファイルをクローズします。
サンプルコードを以下に示します。
/****************************************************************************/
/*!
* @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構造体)のポインタ |
cbwh | WAVEHDR構造体のバイト数 |
waveOutUnprepareHeader()からの戻り値がMMSYSERR_NOERRORであれば、データブロックの切り離しは完了です。
データブロックのクリーンアップが完了すれば、データブロックに割り付けていたデータバッファ等は解放できます。
waveOutClose()を呼び出して、サウンド出力デバイスをクローズします。
MMRESULT waveOutClose( HWAVEOUT hwo )
引数 | 説明 |
---|---|
hwo | サウンド出力デバイスのハンドル |
waveOutClose()からの戻り値がMMSYSERR_NOERRORであれば、デバイスのクローズは完了です。