次の方法で共有


TV オーディオのプレビュー

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayerIMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]

テレビ オーディオをプレビューするには、クロスバー フィルターの Audio デコーダー ピンを Audio Tuner ピンにルーティングします。 オーディオをミュートにするには、次の図に示すように、Audio デコーダー ピンを -1 にルーティングします。 (クロスバー フィルターについては、「 クロスバーの操作」を参照してください)。

オーディオ デコーダー ピンのルーティング

基本的なアプローチは次のとおりです。

  1. クロスバー フィルターを見つけるには、 ICaptureGraphBuilder2::FindInterface メソッドを使用します。
  2. IAMCrossbar::get_CrossbarPinInfo メソッドを使用して、クロスバー フィルターの入力ピンと出力ピンを列挙します。 オーディオ デコーダー出力ピンとオーディオ チューナー入力ピンを検索します。
  3. 正しいピンが見つかる場合は、 IAMCrossbar::Route を呼び出してピンをルーティングします。 そうでない場合は、アップストリームで別のクロスバーを探し、プロセスを繰り返します。
  4. オーディオをミュートにするには、オーディオ デコーダー ピンを -1 にルーティングします。

ほとんどのテレビチューナは単一のクロスバーフィルタを使用しますが、2つのクロスバーフィルタを使用するものもあります。 したがって、最初のクロスバーが失敗した場合は、2 番目のクロスバーを検索する必要がある場合があります。

注意

あなたが期待するかもしれないものとは対照的に、チューナカードとサウンドカードの間に物理的な接続があるため、オーディオをプレビューするためにオーディオキャプチャフィルタやオーディオレンダラーは必要ありません。

 

次のコードは、これらの手順の詳細を示しています。 まず、指定したピンの種類についてクロスバー フィルターを検索するヘルパー関数を次に示します。

HRESULT FindCrossbarPin(
    IAMCrossbar *pXBar,                 // Pointer to the crossbar.
    PhysicalConnectorType PhysicalType, // Pin type to match.
    PIN_DIRECTION Dir,                  // Pin direction.
    long *pIndex)       // Receives the index of the pin, if found.
{
    BOOL bInput = (Dir == PINDIR_INPUT ? TRUE : FALSE);

    // Find out how many pins the crossbar has.
    long cOut, cIn;
    HRESULT hr = pXBar->get_PinCounts(&cOut, &cIn);
    if (FAILED(hr)) return hr;
    // Enumerate pins and look for a matching pin.
    long count = (bInput ? cIn : cOut);
    for (long i = 0; i < count; i++)
    {
        long iRelated = 0;
        long ThisPhysicalType = 0;
        hr = pXBar->get_CrossbarPinInfo(bInput, i, &iRelated,
            &ThisPhysicalType);
        if (SUCCEEDED(hr) && ThisPhysicalType == PhysicalType)
        {
            // Found a match, return the index.
            *pIndex = i;
            return S_OK;
        }
    }
    // Did not find a matching pin.
    return E_FAIL;
}

次の関数は、 bActivate パラメーターの値に応じて、オーディオのアクティブ化またはミュートを試みます。 指定したクロスバー フィルターで必要なピンを検索します。 見つからない場合は、エラー コードを返します。

HRESULT ConnectAudio(IAMCrossbar *pXBar, BOOL bActivate)
{
    // Look for the Audio Decoder output pin.
    long i = 0;
    HRESULT hr = FindCrossbarPin(pXBar, PhysConn_Audio_AudioDecoder,
        PINDIR_OUTPUT, &i);
    if (SUCCEEDED(hr))
    {
        if (bActivate)  // Activate the audio. 
        {
            // Look for the Audio Tuner input pin.
            long j = 0;
            hr = FindCrossbarPin(pXBar, PhysConn_Audio_Tuner, 
                PINDIR_INPUT, &j);
            if (SUCCEEDED(hr))
            {
                return pXBar->Route(i, j);
            }
        }
        else  // Mute the audio
        {
            return pXBar->Route(i, -1);
        }
    }
    return E_FAIL;
}

次の関数は、フィルター グラフでクロスバー フィルターを検索します。 見つかると、(前の関数を使用して) オーディオのアクティブ化またはミュートを試みます。 その操作が失敗した場合、メソッドはアップストリームで 2 番目のクロスバーを検索し、もう一度試行します。 グラフ内の複数のクロスバー フィルターを管理するためのより一般化されたアプローチについては、AmCap サンプル アプリケーションの CCrossbar クラスを参照してください。

HRESULT ActivateAudio(ICaptureGraphBuilder2 *pBuild, IBaseFilter *pSrc,
  BOOL bActivate)
{
    // Search upstream for a crossbar.
    IAMCrossbar *pXBar1 = NULL;
    HRESULT hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pSrc,
        IID_IAMCrossbar, (void**)&pXBar1);
    if (SUCCEEDED(hr)) 
    {
        hr = ConnectAudio(pXBar1, bActivate);
        if (FAILED(hr))
        {
            // Look for another crossbar.
            IBaseFilter *pF = NULL;
            hr = pXBar1->QueryInterface(IID_IBaseFilter, (void**)&pF);
            if (SUCCEEDED(hr)) 
            {
                // Search upstream for another one.
                IAMCrossbar *pXBar2 = NULL;
                hr = pBuild->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pF,
                    IID_IAMCrossbar, (void**)&pXBar2);
                pF->Release();
                if (SUCCEEDED(hr))
                {
                    hr = ConnectAudio(pXBar2, bActivate);
                    pXBar2->Release();
                }
            }
        }
        pXBar1->Release();
    }
    return hr;
}

次のコードは、これらの関数を呼び出す方法を示しています。

// Build the analog TV graph (not shown).
// Activate the audio.
hr = ActivateAudio(pBuild, pCap, TRUE);
// Later, mute the audio.
hr = ActivateAudio(pBuild, pCap, FALSE);

これらの関数の例では、同じ関数呼び出しの多くが繰り返されることに注意してください。 たとえば、毎回クロスバー ピンを列挙します。 実際のアプリケーションでは、この情報の一部をキャッシュできます。

アナログ テレビ オーディオ

クロスバーの操作