マルチメディアAPI(MME)利用してマイクから録音する
(その3)

音声データの入力完了通知

waveInAddBuffer()にてサウンド入力デバイスにキューイングされたデータブロックにサンプリングした音声データが全て書き込まれると、サウンド入力デバイスより MM_WIM_DATAメッセージが、waveInOpen()の第4引数で指定したウインドウハンドルでメッセージ待ちをしているアプリケーションに送られます。

MM_WIM_DATAメッセージの、第1パラメータ(WPARAM)にサウンド入力デバイスのハンドル、 第2パラメータ(LPARAM)にデータ入力が完了したデータブロック(WAVEHDR構造体)のアドレスが通知されます。

入力が完了したデータブロック(WAVEHDR構造体)のdwFlagsメンバにWHDR_DONEビットがセットされます。


サンプルコードでは、サンプリングが完了したブロックをWAVファイルに保存し、その後に空いている出力データにコピーして出力デバイスからモニタ出力を行います。
最後にデータブロックをクリアして、入力デバイスの入力バッファに再度キューイングします。

(一応WAVファイルへの保存を先に行うのは、その方がWAVファイルにデータを保存した時間分出力データの再生完了が遅れるので、少しでも出力側のバッファの枯渇が防げるかな。という理由です。
まぁ、気休め程度ですが。。。)

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


/****************************************************************************/
/*!
 *  @brief  サウンド入力データの取込み完了通知.
 *
 *  @param  [in]    hDlg    ダイアログのウインドウ・ハンドル.
 *  @param  [in]    wh      データブロック構造体のポインタ.
 *
 *  @retval なし.
 */
static void     SoundInputDone( HWND hDlg, WAVEHDR* wh )
{
    if( hWI ){
        if( wh->dwBytesRecorded > 0 ){

            //! 録画中の場合のみWAVファイルに入力音声データを保存する.
            if( RecFlag ){
                if( WritedWaveFile( wh->lpData, wh->dwBytesRecorded ) == 0 ){
                    CloseWaveFile();
                }
            }

            //! 空いている出力データバッファを探して、入力音声データをコピーする.
            for( DWORD i = 0; i < 2; i++ ){
                if( OutHdr[i].dwBufferLength == 0 && OutHdr[i].lpData ){
                    memcpy( OutHdr[i].lpData, wh->lpData, wh->dwBytesRecorded );
                    OutHdr[i].dwBufferLength = wh->dwBytesRecorded;
                    waveOutWrite( hWO, &OutHdr[i], sizeof(WAVEHDR) );
                    break;
                }
            }

            //! デバイスに空いた入力バッファをキューイングする.
            wh->dwBytesRecorded = 0;
            waveInAddBuffer( hWI, wh, sizeof(WAVEHDR) );
        }
    }
}
	



Windowsは米国Microsoft Corporationの登録商標です。