Skip to main content.

Monday, May 21, 2007

DirectShowオーディオキャプチャでのMP3ファイル出力

前回のプログラムではwavファイルに出力しましたが、今回はMP3ファイルへ出力します。何といってもMP3形式の方がファイルサイズが小さいので応用がきくかと思います。前回のグラフにMP3のコンプレッサフィルタを追加したグラフが以下になります。

GraphEditでのグラフ


オーディオコンプレッサフィルタはGraphEditのメニュー → Insert Filters → Audio Compressors → MPEG Layer-3 で追加出来ます。以下は私のPCでの画面です。


プログラムとしては前回のプログラムにコンプレッサの機能を追加したというイメージです。まずはメインプログラムです。
メインプログラム
//
// メイン関数
//
int _tmain(int argc, _TCHAR* argv[])
{
    // COMを初期化
    CoInitialize(NULL);

    // FilterGraphを生成
    IGraphBuilder *pGraphBuilder;
    CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(LPVOID *)&pGraphBuilder);

    // グラフ構築の一連の処理
    // オーディオ入力デバイスを取得してグラフに追加する
    HRESULT hr;
    IBaseFilter *pDeviceFilter = NULL;
    hr = AddAudioInputDevice(pGraphBuilder,&pDeviceFilter);
    if(FAILED(hr)){
        return hr;
    }

    // Compressorフィルタをグラフに追加
    IBaseFilter *pAudioEncoder = NULL;
    AddAudioCompressor(pGraphBuilder, &pAudioEncoder);

    // WavDestをグラフに追加
    GUID CLSID_WavDest;
    UuidFromString((RPC_CSTR)"3C78B8E2-6C4D-11D1-ADE2-0000F8754B99", &CLSID_WavDest);

    IBaseFilter *pWavDest = NULL;
    AddFilter(pGraphBuilder, CLSID_WavDest , L"Wav Dest", &pWavDest);

    // FileWriterをグラフに追加
    IBaseFilter *pFileWriter = NULL;
    AddFilter(pGraphBuilder, CLSID_FileWriter, L"Writer", &pFileWriter);

    // 各フィルタを接続してファイル名を設定する
    // オーディオ入力 → MPEG Layer-3
    ConnectFilters(pGraphBuilder, pDeviceFilter,pAudioEncoder);

    // MPEG Layer-3 → WavDest
    ConnectFilters(pGraphBuilder, pAudioEncoder,pWavDest);

    // WavDest → FileWriter
    ConnectFilters(pGraphBuilder, pWavDest,pFileWriter);

    // ファイル名を設定する
    IFileSinkFilter *pSink;
    pFileWriter->QueryInterface(IID_IFileSinkFilter2,(VOID**)&pSink);
    pSink->SetFileName(WAVFILE_NAME_L, NULL);
    pSink->Release();

    // 出力ファイルを一応削除する
    DeleteFile(WAVFILE_NAME);

    // MediaControlインターフェース取得
    IMediaControl *pMediaControl = NULL;
    pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID *)&pMediaControl);
 
    // 録音開始
    pMediaControl->Run();

    // 録音終了待ち
    MessageBox(NULL,"終了待ち","録音",MB_OK);

    // 録音終了
    pMediaControl->Stop();

    // 終了処理
    pMediaControl->Release();
    pDeviceFilter->Release();
    pWavDest->Release();
    pFileWriter->Release();
    pGraphBuilder->Release();

    CoUninitialize();

    return 0;
}


プログラム全体はこちらから
プログラム全体

※デバッガでの注意点
このプログラムをデバッガでデバッグした場合、コンプレッサを取得するところで、デバッガが異常終了します。ただし、普通に実行すると正常に動くようです。この現象は既に世界中で出ていたようで原因は分かっているようです。どうやら「Voxware audio codec」というのが原因のようです。コントロールパネルからこの機能を無効にする方法があるようです。私の場合は、単純にwindows?system32配下のvct3216.acmというファイルを別のディレクトリに移動しておきました。これらの方法でデバッガが利用できるようになります。
この問題について、コントロールパネルから設定する方法等
DirectShowに関する情報

ソースファイル一式
プロジェクトファイル一式(Visual C++ 2005 Express Editionで作成)

参考リンク
オーディオ キャプチャ(Microsoft DirectX 9.0)
キャプチャ アプリケーションの書き方(※Microsoft DirectX 8.0のドキュメントです)

参考プログラム
Converting Wav file to MP3 or other format using DirectShow

Windowsプログラミング関連記事