SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

DirectShowフィルタの作成

オーディオチャンネルを結合する
DirectShowフィルタの作成

複数の入力ピンを持つDirectShowフィルタの作成方法

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルコード (10.1 KB)

フィルタクラスの実装

 早速、フィルタクラスを実装していきましょう。コンストラクタで、入力ピンを2つ、出力ピンを1つ作成します。入力ピンのコンストラクタの引数としてチャンネル番号を渡します。0であればL、1であればRです。これにより、L/Rどちらのチャンネルを受け持っているか入力ピンのインスタンス自身が認識できるようになります。

// 入力ピンのコンストラクタは、次のようになっている。
// ch にチャンネル番号を渡す。
AudioInPin::AudioInPin(LPCTSTR pName, CBaseFilter *pFilter
    , CCritSec *pLock, HRESULT *phr, int ch);

// フィルタクラスのコンストラクタ
AudioChMuxerFilter::AudioChMuxerFilter(LPUNKNOWN pUnk, HRESULT *phr) :
m_FilterLock(),
CBaseFilter(FILTER_NAME, pUnk, 
            &m_FilterLock, __uuidof(AudioChMuxerFilter))
{
    m_InPins[0]=m_InPins[1]=NULL;
    m_OutPin=NULL;
    if(FAILED(*phr))
        return;
    m_InPins[0]=
        new AudioInPin(LIN_PIN_NAME, this, &m_FilterLock, phr, 0);
    if(FAILED(*phr))
        return;
    m_InPins[1]=
        new AudioInPin(RIN_PIN_NAME, this, &m_FilterLock, phr, 1);
    if(FAILED(*phr))
        return;
    m_OutPin=
        new AudioOutPin(this, &m_FilterLock, phr);
}

 AudioChMuxerFilter::GetPinメソッドで、引数のインデックス値に対応したピンを返します。ここではインデックス値が0または1のときは入力ピン、2のときは出力ピンを返すことにします。

CBasePin *AudioChMuxerFilter::GetPin(int n) {
    switch(n) {
        case 0:
            return (CBasePin*)GetInPin(0);
        case 1:
            return (CBasePin*)GetInPin(1);
        case 2:
            return (CBasePin*)GetOutPin();
    }
    return NULL;
}

入力ピンクラスの実装

 入力ピンとアップストリームフィルタの出力ピンを接続できるようにしましょう。今回は入力ピンが2つあるので、単に提示されたメディアタイプを検査するだけでなく、片方の入力ピンが接続済のとき、もう片方の入力ピンは同一メディアタイプでのみ接続できるようにします。こうすると、2つのピンの間で周波数やサンプルあたりのビット数が異なると接続できないようになります。

 それにはAudioInPin::CheckMediaTypeで、入力ピンが接続済かどうか確認し、もし接続済みであれば、どのメディアタイプで接続されているかを取得します。取得したメディアタイプと検査対象のメディアタイプとを比較することにより、同一メディアタイプでのみ接続を許可できます。

HRESULT AudioInPin::CheckMediaType(const CMediaType *pmt) {
    bool connected=false; // 接続済みフラグ
    CMediaType mt; // 接続済のメディアタイプ
    AudioChMuxerFilter *pFilter=(AudioChMuxerFilter*)m_pFilter;
    int idx = m_Channel == 0 ? 1 : 0;
    AudioInPin *pPin=pFilter->GetInPin(idx);
    if(pPin->IsConnected()!=NULL) {
        pPin->ConnectionMediaType(&mt);
        connected=true;
    }
    if (connected && mt!=*pmt) {
        // 同一メディアタイプではない。
    }
    // ピンが接続されていない、または、同一メディアタイプ。
    // 続いてメディアタイプpmtを検査する。
}

出力ピンクラスの実装

 出力ピンとダウンストリームフィルタの入力ピンを接続できるようにしましょう。今回は2つの入力ピンが接続済でない場合は、接続できないようにします。

 それにはAudioOutPin::CheckMediaTypeで、2つの入力ピンが接続済であるか否かを取得し、どちらか一方でも接続されていない場合は接続拒否します。2つとも接続済であれば、メディアタイプを検査して接続可能かどうかを判定します。

HRESULT AudioOutPin::CheckMediaType(const CMediaType *pmt) {
    AudioChMuxerFilter *pFilter=(AudioChMuxerFilter*)m_pFilter;
    AudioInPin *pPin=pFilter->GetInPin(0);
    if(pPin->IsConnected()==NULL) {
        return S_FALSE;
    }
    pPin=pFilter->GetInPin(1);
    if(pPin->IsConnected()==NULL) {
        return S_FALSE;
    }
    // メディアタイプpmtを検査する。
}

次のページ
サンプルの転送

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
DirectShowフィルタの作成連載記事一覧

もっと読む

この記事の著者

syu5()

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3386 2009/01/20 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング