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

概要

以前作成した『マルチメディアAPI(MME)を利用してWAVファイルを再生する』サンプルプログラムを改造して、マルチメディアAPIの入力機能を利用して外部から音声データを入力して、WAVEファイルに保存するサンプルプログラムを作ります。

サウンド入力処理もサウンド出力処理と同様に、データブロックというバッファ単位で入力された音声データがサンプリングされるので、アプリケーション側ではサンプリングが完了してブロック単位にファイル保存なりの処理を行うことになります。

MMEを利用するには、以下のインクルードファイルとライブラリが必要になります。

追加するインクルード

mmsystem.h

追加するライブラリ

winmm.lib

サンプルプログラムの仕様

作成するサンプルプログラムは以下の仕様にします。

  • ウインドウ・スタイルはダイアログにする。
  • サウンドを入出力するデバイスが複数ある場合、ユーザーが選択できる。
  • 録音するWAVファイルは、ユーザーが選択できる。
  • WAVファイルを選択後、[録音]ボタンでマイクからの録音を開始する。
  • マイクからの入力をモニタする為に、入力した音声データをそのままサウンド出力デバイスに送る。
  • 録音中に[一時停止]ボタンを押すと、録音を一時中断し、再度[録音]ボタンを押すとマイクからの録音を再開する。
  • 録音の一時停止中であっても、マイクのモニタ出力は継続する。
  • [停止]ボタンを押すと録音を終了する。
  • 入力モニタの音量調節をダイアログから行えるようにする。
    (但しファイルに記録する音声データの音量は変化させない。)

サンプルプログラムの外観は以下のようにします。

ダイアログの初期処理

WM_INITDIALOGメッセージを受けたときに、ダイアログの初期処理を行います。

ダイアログの初期処理では、サウンド入出力デバイスのリストの作成と、音量ボリュームのトラックバーの初期化を行います。

サウンド出力デバイスのリスト作成は、『マルチメディアAPI(MME)を利用してWAVファイルを再生する』を参考にしてください。

サウンド入力デバイスのリスト作成は、APIが違うだけで出力デバイスのリスト作成を同様の処理になります。

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


/****************************************************************************/
/*!
 *  @brief  ダイアログの初期処理.
 *
 *  @param  [in]    hDlg    ダイアログのウインドウ・ハンドル.
 *
 *  @retval なし.
 */
static void     OnInitDialog( HWND hDlg )
{
    //! 出力デバイスリストを作成する.
    DWORD dev_num = waveOutGetNumDevs();
    if( dev_num != 0 ){
        HWND hlist = GetDlgItem( hDlg, IDC_OUTPUT_DEVICE );

        ComboBox_ResetContent( hlist );
        for( DWORD i = 0; i < dev_num; i++ ){
            // 出力デバイスの性能を取得する.
            WAVEOUTCAPS caps;
            if( waveOutGetDevCaps( i, &caps, sizeof(caps) ) == MMSYSERR_NOERROR ){
                ComboBox_AddString( hlist, caps.szPname );
            }
        }
        ComboBox_SetCurSel( hlist, 0 );
    }
    //! 入力デバイスリストを作成する.
    dev_num = waveInGetNumDevs();
    if( dev_num != 0 ){
        HWND hlist = GetDlgItem( hDlg, IDC_INPUT_DEVICE );

        ComboBox_ResetContent( hlist );
        for( DWORD i = 0; i < dev_num; i++ ){
            // 入力デバイスの性能を取得する.
            WAVEINCAPS caps;
            if( waveInGetDevCaps( i, &caps, sizeof(caps) ) == MMSYSERR_NOERROR ){
                ComboBox_AddString( hlist, caps.szPname );
            }
        }
        ComboBox_SetCurSel( hlist, 0 );
    }
    //! 音量ボリュームのトラックバーを設定する.
    HWND hbar = GetDlgItem( hDlg, IDC_VOLUME );
    SendMessage( hbar, TBM_SETRANGE, TRUE, MAKELONG( 0, 100 ) );
    SendMessage( hbar, TBM_SETPOS  , TRUE, 50 );
}
	

サウンド入力デバイスの個数を取得する

waveInGetNumDevs()を呼び出して、サウンド入力デバイスの個数を取得します。


    UINT waveInGetNumDevs( VOID )
	

waveInGetNumDevs()からの戻り値としてサウンド入力デバイスの数が返ります。
エラーまたはデバイスが存在しない場合、0が返ります。

サウンド入力デバイス名を取得する

取得したサウンド入力デバイスの個数分、waveInGetDevCaps()を呼び出してサウンド入力デバイス名を取得します。


    MMRESULT waveInGetDevCaps( UINT uDeviceID, LPWAVEINCAPS pwic, UINT cbwic )
	

引数説明
uDeviceID

次のいずれかを指定。
 - サウンド入力デバイスの識別子(0~デバイスの個数-1の値)
 - オープンしているサウンド入力デバイスのハンドル
 - WAVE_MAPPER定数

pwicWAVEINCAPS構造体のポインタ
cbwicWAVEINCAPS構造体のバイト数

waveInGetDevCaps()からの戻り値がMMSYSERR_NOERRORであれば、デバイス性能に関する情報の取得は完了です。

デバイス性能に関する情報(WAVEINCAPS構造体)は以下のとおりです。

メンバ名説明
wMidベンダID
wPidプロダクトID
vDriverVersionドライバのバージョン
szPname[MAXPNAMELEN]デバイス名の文字列
dwFormatsサポートしているオーディオ形式
wChannelsサポートしているチャンネル数

waveInGetDevCaps()の第1引数で指定するデバイス番号は、waveInOpen()の第2引数で指定する 「オープンするサウンド出力デバイスの識別子」と同じ値になります。



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