QDSAudio 使用手引き

QDSAudio コンポーネントの使用方法について解説します。

COM インターフェイスの使用

DirectShow は、COM インターフェイスをベースとした API ですので、COM インターフェイス に関する基本的な知識が必要です。このサンプルでは、利便性を考慮し ATL の COM スマートポインター を使用します。

COM 使用の際は、アプリケーション開始時に、初期化用関数を呼び出す必要があります。 (CoInitializeEx() or OleInitialize()) 詳細は、Windows プログラミングの参考資料をご覧ください。

フィルターグラフの構築

DirectShow のフィルターグラフコンポーネントを作成します。

  1. ...
  2. ATL::CComPtr<IGraphBuilder> m_FilterGraph;
  3. ...
  4. HRESULT hRslt = m_FilterGraph.CoCreateInstance(
  5. CLSID_FilterGraph,
  6. 0,
  7. CLSCTX_INPROC_SERVER);
  8. if (FAILED(hRslt)) {
  9. return;
  10. }

ソースフィルターコンポーネントを作成し、フィルターグラフへ登録します。

ここでは、SHCreateStreamOnFileW() 関数を使用して IStream インターフェイスを、 準備しています。その後 AddFilter() メソッドで、フィルターグラフへ登録を行います。

  1. ...
  2. LPCWSTR path;
  3. ...
  4. ATL::CComPtr<IBaseFilter> filter;
  5. {
  6. ATL::CComPtr<IStream> stm;
  7. hRslt = SHCreateStreamOnFileW(
  8. path,
  9. STGM_READ,
  10. &stm);
  11. if (FAILED(hRslt)) {
  12. return;
  13. }
  14. hRslt = QDSA_CreateOggVorbisDecoder_IStream(
  15. stm,
  16. &filter);
  17. if (FAILED(hRslt)) {
  18. return;
  19. }
  20. }
  21. hRslt = m_FilterGraph->AddFilter(
  22. filter,
  23. L"QDSAudio");
  24. if (FAILED(hRslt)) {
  25. return;
  26. }

オーディオレンダラーを作成して、フィルターグラフへ登録します。

ここでは、デフォルト DirectSound レンダラーを作成しています。

  1. ATL::CComPtr<IBaseFilter> rend;
  2. hRslt = rend.CoCreateInstance(
  3. CLSID_DSoundRender,
  4. 0,
  5. CLSCTX_INPROC_SERVER);
  6. if (FAILED(hRslt)) {
  7. return;
  8. }
  9. hRslt = m_FilterGraph->AddFilter(
  10. rend,
  11. L"A-Renderer");
  12. if (FAILED(hRslt)) {
  13. return;
  14. }

ピンの接続を行います。

ソースフィルターについては、Pin 名称が定められているので、FindPin() メソッドで、IPin インターフェイス を取得します。

レンダラーについては、EnumPins() メソッドで、所属 Pin を列挙し、最初に見つかった Pin を使用します。

ConnectDirect() メソッドで、ピンの直接接続を行います。

  1. ATL::CComPtr<IPin> pin;
  2. hRslt = filter->FindPin(L"Audio", &pin);
  3. if (FAILED(hRslt)) {
  4. return;
  5. }
  6. ATL::CComPtr<IEnumPins> e;
  7. hRslt = rend->EnumPins(&e);
  8. if (FAILED(hRslt)) {
  9. return;
  10. }
  11. ATL::CComPtr<IPin> ip;
  12. ULONG c = 0;
  13. hRslt = e->Next(1, &ip, &c);
  14. if (FAILED(hRslt)) {
  15. return;
  16. }
  17. hRslt = m_FilterGraph->ConnectDirect(
  18. pin,
  19. ip,
  20. 0);
  21. if (FAILED(hRslt)) {
  22. return;
  23. }

ここまでで、フィルターグラフの構築は完了です。

フィルターの登録処理をしていれば、IGraphBuilder::RenderFile() メソッドを使用して、 フィルターグラフの自動構築が可能になりますが、エンドユーザー実行環境によっては、意図したものとは異なる フィルターコンポーネントが使用される場合があり、不具合を生じることがあります。

そのため、QDSAudio コンポーネントでは、フィルターコンポーネントの登録を行っていません。

上記のようにフィルターグラフ構築処理が、多少煩雑になりますが、意図しないコンポーネントに 割り込まれることがなくなるので、エンドユーザーに安定した動作を提供することができます。

DirectShow 使用手引き

DirectShow 一般の使用方法については、以下のページを参照ください。

DirectShowUseage

ループ設定

  1. ATL::CComPtr<IBaseFilter> filter;
  2. INT64 sample = 0;
  3. ...
  4. hRslt = QDSA_SetupLoopPoint(filter, sample);
  5. if (FAILED(hRslt)) {
  6. return;
  7. }

ループモードの設定を行うには、以上のようにします。

ループモードでは、ストリーム終端に達したとき、設定したループ位置に戻り再生を続行します。

ループ位置の設定単位は、サンプル数となります。