TV オーディオのプレビュー
[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、および Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayer、IMFMediaEngine、Audio/Video Capture を使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
テレビ オーディオをプレビューするには、クロスバー フィルターの Audio デコーダー ピンを Audio Tuner ピンにルーティングします。 オーディオをミュートにするには、次の図に示すように、Audio デコーダー ピンを -1 にルーティングします。 (クロスバー フィルターについては、「 クロスバーの操作」を参照してください)。
基本的なアプローチは次のとおりです。
- クロスバー フィルターを見つけるには、 ICaptureGraphBuilder2::FindInterface メソッドを使用します。
- IAMCrossbar::get_CrossbarPinInfo メソッドを使用して、クロスバー フィルターの入力ピンと出力ピンを列挙します。 オーディオ デコーダー出力ピンとオーディオ チューナー入力ピンを検索します。
- 正しいピンが見つかる場合は、 IAMCrossbar::Route を呼び出してピンをルーティングします。 そうでない場合は、アップストリームで別のクロスバーを探し、プロセスを繰り返します。
- オーディオをミュートにするには、オーディオ デコーダー ピンを -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);
これらの関数の例では、同じ関数呼び出しの多くが繰り返されることに注意してください。 たとえば、毎回クロスバー ピンを列挙します。 実際のアプリケーションでは、この情報の一部をキャッシュできます。
関連トピック