オーディオ形式を検索するには
[このページに関連付けられている機能である Windows Media Format 11 SDK は、レガシ機能です。 これは、ソース リーダーとシンク ライターによって置き換えられます。 ソース リーダーとシンク ライターは、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、Windows Media Format 11 SDK ではなくソース リーダーとシンク ライターを使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]
次のコード例は、指定した条件に一致するオーディオ形式を検索する方法を示しています。 FindAudioFormat 関数は、使用するチャネル数、サンプルごとのビット数、およびサンプル レートを含む WAVEFORMATEX 構造体へのポインターを受け入れます。 関数は、これらの要件に一致し、 dwMaxRate パラメーターを超えない最も高いビット レートを持つ形式を検索します。 fAVSync を TRUE に設定した場合、関数はビデオと同期できる形式のみを検証します。 わかりやすくするために、この関数は 1 パスの CBR 形式でのみ機能します。
// This constant is used to determine if an index was found.
#define INVALID_INDEX 0xFFFF
// The FindAudioFormat function finds a compressed audio format that
// matches the criteria defined by the input parameters.
HRESULT FindAudioFormat(GUID SubType,
WAVEFORMATEX* pWaveLimits,
DWORD dwMaxRate,
BOOL fAVSync,
IWMStreamConfig** ppStreamConfig)
{
HRESULT hr = S_OK;
IWMProfileManager* pProfileMgr = NULL;
IWMCodecInfo3* pCodecInfo = NULL;
IWMStreamConfig* pStreamConfig = NULL;
IWMStreamConfig* pBestMatch = NULL;
IWMMediaProps* pProps = NULL;
WM_MEDIA_TYPE* pType = NULL;
DWORD cbType = 0;
WAVEFORMATEX* pWave = NULL;
DWORD index = 0;
DWORD cEntries = 0;
DWORD dwBestRate = 0;
DWORD PacketsPerSecond = 0;
// This value is beyond the codec indexes
// and will be used to verify success.
DWORD CodecIndex = INVALID_INDEX;
// Instantiate a profile manager object.
hr = WMCreateProfileManager(&pProfileMgr);
GOTO_EXIT_IF_FAILED(hr);
// Get the codec information interface.
hr = pProfileMgr->QueryInterface(IID_IWMCodecInfo3, (void**)&pCodecInfo);
GOTO_EXIT_IF_FAILED(hr);
// Get the number of audio codecs for which there is information.
hr = pCodecInfo->GetCodecInfoCount(WMMEDIATYPE_Audio, &cEntries);
GOTO_EXIT_IF_FAILED(hr);
// Find the index of the codec corresponding to the requested subytpe.
for(index = 0; index < cEntries; index++)
{
// Get the first format for each codec.
hr = pCodecInfo->GetCodecFormat(WMMEDIATYPE_Audio, index, 0, &pStreamConfig);
GOTO_EXIT_IF_FAILED(hr);
// Get the media properties interface.
hr = pStreamConfig->QueryInterface(IID_IWMMediaProps, (void**)&pProps);
GOTO_EXIT_IF_FAILED(hr);
// Get the size required for the media type structure.
hr = pProps->GetMediaType(NULL, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Allocate memory for the media type structure.
pType = (WM_MEDIA_TYPE*) new BYTE[cbType];
if(pType == NULL)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Get the media type structure.
hr = pProps->GetMediaType(pType, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Check this codec against the one requested.
if(pType->subtype == SubType)
CodecIndex = index;
// The subtypes did not match. Clean up for next iteration.
SAFE_RELEASE(pStreamConfig);
SAFE_RELEASE(pProps);
SAFE_ARRAY_DELETE(pType);
// Break now if needed. Placing the break here avoids having to
// release or delete both inside and outside of the loop.
if(CodecIndex != INVALID_INDEX)
break;
} // for index
// The subtype is invalid if no codec was found that matches it.
if(CodecIndex == INVALID_INDEX)
{
hr = E_INVALIDARG;
goto Exit;
}
// Get the number of formats supported for the codec.
hr = pCodecInfo->GetCodecFormatCount(WMMEDIATYPE_Audio,
CodecIndex,
&cEntries);
GOTO_EXIT_IF_FAILED(hr);
// Loop through the formats for the codec, looking for matches.
for(index = 0; index < cEntries; index++)
{
// Get the next format.
hr = pCodecInfo->GetCodecFormat(WMMEDIATYPE_Audio,
CodecIndex,
index,
&pStreamConfig);
GOTO_EXIT_IF_FAILED(hr);
// Get the media properties interface.
hr = pStreamConfig->QueryInterface(IID_IWMMediaProps, (void**)&pProps);
GOTO_EXIT_IF_FAILED(hr);
// Get the size required for the media type structure.
hr = pProps->GetMediaType(NULL, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Allocate memory for the media type structure.
pType = (WM_MEDIA_TYPE*) new BYTE[cbType];
if(pType == NULL)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Get the media type structure.
hr = pProps->GetMediaType(pType, &cbType);
GOTO_EXIT_IF_FAILED(hr);
// Check that the format data is present.
if(pType->cbFormat >= sizeof(WAVEFORMATEX))
pWave = (WAVEFORMATEX*)pType->pbFormat;
else
{
// The returned media type should always have an attached
// WAVEFORMATEX structure.
hr = E_UNEXPECTED;
goto Exit;
}
// Start checking data.
// Do not check particulars unless the bit rate is in range.
if((pWave->nAvgBytesPerSec * 8) > dwBestRate &&
(pWave->nAvgBytesPerSec * 8) <= dwMaxRate)
{
// Check the limits.
if((pWave->nChannels == pWaveLimits->nChannels) &&
(pWave->wBitsPerSample == pWaveLimits->wBitsPerSample) &&
(pWave->nSamplesPerSec == pWaveLimits->nSamplesPerSec))
{
// If audio/video synchronization requested, check the number
// of packets per second (Bps / BlockAlign). The bit rate is
// greater than 3200 bps, this value must be 5.
// Otherwise this value is 3.
// This is an ASF requirement.
if(fAVSync)
{
if((pWave->nAvgBytesPerSec / pWave->nBlockAlign) >=
((pWave->nAvgBytesPerSec >= 4000) ? 5.0 : 3.0))
{
// Release the previous best match.
SAFE_RELEASE(pBestMatch);
// Set this stream configuration as the new best match.
pBestMatch = pStreamConfig;
pStreamConfig->AddRef();
// Set the best bit rate.
dwBestRate = (pWave->nAvgBytesPerSec * 8);
}
} // if fAVSync
else
{
// Release the previous best match.
SAFE_RELEASE(pBestMatch);
// Set this stream configuration as the new best match.
pBestMatch = pStreamConfig;
pStreamConfig->AddRef();
// Set the best bit rate.
dwBestRate = (pWave->nAvgBytesPerSec * 8);
} // else
} // if matching limits
} // if valid bit rate
// Clean up for next iteration.
SAFE_RELEASE(pStreamConfig);
SAFE_RELEASE(pProps);
pWave = NULL;
SAFE_ARRAY_DELETE(pType);
} // for index
// If no match was found, the arguments were not valid for the codec.
if(pBestMatch == NULL)
{
hr = E_INVALIDARG;
goto Exit;
}
// Set the pointer to the stream configuration.
*ppStreamConfig = pBestMatch;
pBestMatch = NULL;
Exit:
SAFE_RELEASE(pProfileMgr);
SAFE_RELEASE(pCodecInfo);
SAFE_RELEASE(pStreamConfig);
SAFE_RELEASE(pBestMatch);
SAFE_RELEASE(pProps);
SAFE_ARRAY_DELETE(pType);
return hr;
}
関連トピック