串流音訊轉譯器

串流音訊轉譯器 (SAR) 是轉譯音訊的媒體接收。 SAR 的每個實例都會轉譯單一音訊資料流程。 若要轉譯多個資料流程,請使用 SAR 的多個實例。

若要建立 SAR,請呼叫下列其中一個函式:

如果您要播放受保護的內容,則傳回啟用物件的第二個函式是必要的,因為啟用物件必須序列化為受保護的進程。 如需清楚的內容,您可以使用任一函式。

SAR 可以接收 PCM 或 IEEE 浮點格式的未壓縮音訊。 如果播放速率比 1 快或慢 1×,SAR 會自動調整音調。

設定音訊轉譯器

SAR 支援數個組態屬性。 設定這些屬性的機制取決於您呼叫哪個函式來建立 SAR。 如果您使用 MFCreateAudioRenderer 函 式,請執行下列動作:

  1. 呼叫 MFCreateAttributes來建立新的屬性存放區。
  2. 將屬性新增至屬性存放區。
  3. 將屬性存放區傳遞至pAudioAttributes參數中的MFCreateAudioRenderer 函式。

如果您使用MFCreateAudioRendererActivate函式,此函式會傳回ppActivate參數中IMFAttributes介面的指標。 使用此指標來新增屬性。

如需組態屬性的清單,請參閱 音訊轉譯器屬性

選取音訊端點裝置

音訊端點裝置是可轉譯或擷取音訊的硬體裝置。 範例包括喇叭、耳機、麥克風和 CD 播放機。 SAR 一律使用音訊轉譯裝置。 有兩種方式可以選取裝置。

第一種方法是使用 IMMDeviceEnumerator 介面來列舉系統上的音訊轉譯裝置。 此介面記載于核心音訊 API 檔中。

  1. 建立裝置列舉值物件。
  2. 使用裝置列舉值來列舉音訊轉譯裝置。 每個裝置都是以 IMMDevice 介面的指標表示。
  3. 根據裝置屬性或使用者的選取專案,選取裝置。
  4. 呼叫 IMMDevice::GetId 以取得裝置識別碼。
  5. 將裝置識別碼設定為 MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID 屬性的值。

您可以依其 角色指定音訊裝置,而不是列舉裝置。 音訊角色會識別使用方式的一般類別。 例如, 主控台 角色是針對遊戲和系統通知所定義,而 多媒體 角色則是針對音樂和電影所定義。 每個角色都有一個指派給它的音訊轉譯裝置,而且使用者可以變更這些指派。 如果您指定裝置角色,SAR 會使用該角色指派的任何音訊裝置。 若要指定裝置角色,請設定 MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE 屬性。

本節所列的兩個屬性互斥。 如果您未設定其中一個,SAR 會使用指派給 eConsole 角色的音訊裝置。

下列程式碼會列舉音訊轉譯裝置,並將清單中的第一個裝置指派給 SAR。 此範例會使用 MFCreateAudioRenderer 函 式來建立 SAR。

#include <mmdeviceapi.h>

HRESULT hr = S_OK;

IMMDeviceEnumerator *pEnum = NULL;      // Audio device enumerator.
IMMDeviceCollection *pDevices = NULL;   // Audio device collection.
IMMDevice *pDevice = NULL;              // An audio device.
IMFAttributes *pAttributes = NULL;      // Attribute store.
IMFMediaSink *pSink = NULL;             // Streaming audio renderer (SAR)

LPWSTR wstrID = NULL;                   // Device ID.

// Create the device enumerator.
hr = CoCreateInstance(
    __uuidof(MMDeviceEnumerator), 
    NULL,
    CLSCTX_ALL, 
    __uuidof(IMMDeviceEnumerator), 
    (void**)&pEnum
    );

// Enumerate the rendering devices.
if (SUCCEEDED(hr))
{
    hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);
}

// Get ID of the first device in the list.
if (SUCCEEDED(hr))
{
    hr = pDevices->Item(0, &pDevice);
}

if (SUCCEEDED(hr))
{
    hr = pDevice->GetId(&wstrID);
}

// Create an attribute store and set the device ID attribute.
if (SUCCEEDED(hr))
{
    hr = MFCreateAttributes(&pAttributes, 2);
}

if (SUCCEEDED(hr))
{
    hr = pAttributes->SetString(
        MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, 
        wstrID
        );
}

// Create the audio renderer.
if (SUCCEEDED(hr))
{
    hr = MFCreateAudioRenderer(pAttributes, &pSink);    
}

SAFE_RELEASE(pEnum);
SAFE_RELEASE(pDevices);
SAFE_RELEASE(pDevice); 
SAFE_RELEASE(pAttributes);
CoTaskMemFree(wstrID);

若要建立 SAR 的啟用物件,請將呼叫 IMMDevice::GetId 之後出現的程式碼變更為下列內容:

IMFActivate *pActivate = NULL;          // Activation object.

if (SUCCEEDED(hr))
{
    hr = MFCreateAudioRendererActivate(&pActivate);    
}

if (SUCCEEDED(hr))
{
    hr = pActivate->SetString(
        MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, 
        wstrID
        );
}

SAFE_RELEASE(pActivate);

選取音訊會話

音訊會話是應用程式可以共同管理的相關音訊串流群組。 應用程式可以控制每個會話的磁片區層級和靜音狀態。 會話是由 GUID 識別。 若要指定 SAR 的音訊會話,請使用 MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID 屬性。 如果您未設定此屬性,SAR 會加入該程式的預設會話, 由GUID_Null識別。

根據預設,音訊會話是進程特定的,這表示它只包含來自呼叫進程的資料流程。 若要加入跨進程會話,請使用值MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS_CROSSPROCESS設定MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS屬性。

建立 SAR 之後,您可以使用 IMFAudioPolicy 介面將會話加入會話群組,這些會話全都由控制台中的相同磁片區控制項控制。 您也可以使用此介面來設定顯示在磁片區控制項中的顯示名稱和圖示。

控制磁片區層級

若要控制 SAR 音訊會話中所有串流的主要音量層級,請使用 IMFSimpleAudioVolume 介面。 若要控制個別資料流程的磁片區,或控制資料流程內個別通道的磁片區,請使用 IMFAudioStreamVolume 介面。 這兩個介面都是藉由呼叫 IMFGetService::GetService 來取得。 您可以直接在 SAR 上呼叫 GetService ,或在媒體會話上呼叫它。 磁片區層級會以衰減值表示。 針對每個通道,衰減等級是主要磁片區和通道磁片區的乘積。

音訊/視訊播放