Отрисовщик потоковой передачи звука

Отрисовщик потокового звука (SAR) — это приемник мультимедиа, который отрисовывает звук. Каждый экземпляр SAR отрисовывает один аудиопоток. Для отрисовки нескольких потоков используйте несколько экземпляров SAR.

Чтобы создать SAR, вызовите следующую функцию:

  • MFCreateAudioRenderer. Возвращает указатель на SAR.
  • MFCreateAudioRendererActivate. Возвращает указатель на объект активации, который можно использовать для создания SAR.

Вторая функция, возвращающая объект активации, является обязательной при воспроизведении защищенного содержимого, так как объект активации должен быть сериализован в защищенный процесс. Для очистки содержимого можно использовать обе функции.

Sar может получать несжатый звук в формате PCM или IEEE с плавающей запятой. Если скорость воспроизведения быстрее или медленнее 1×, sar автоматически настраивает шаг.

Настройка отрисовщика звука

SAR поддерживает несколько атрибутов конфигурации. Механизм настройки этих атрибутов зависит от того, какая функция вызывается для создания SAR. Если вы используете функцию MFCreateAudioRenderer , сделайте следующее:

  1. Создайте новое хранилище атрибутов, вызвав MFCreateAttributes.
  2. Добавьте атрибуты в хранилище атрибутов.
  3. Передайте хранилище атрибутов в функцию MFCreateAudioRenderer в параметре pAudioAttributes .

При использовании функции MFCreateAudioRendererActivate функция возвращает указатель на интерфейс IMFAttributes в параметре ppActivate . Используйте этот указатель для добавления атрибутов.

Список атрибутов конфигурации см. в разделе Атрибуты отрисовщика звука.

Выбор конечного устройства аудио

Устройство конечной точки звука — это аппаратное устройство, которое выполняет отрисовку или запись звука. Примерами могут быть динамики, наушники, микрофоны и 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 значение MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS_CROSSPROCESS.

После создания SAR вы используете интерфейс IMFAudioPolicy для присоединения сеанса к группе сеансов, все из которых управляются тем же контролем громкости на панели управления. Этот интерфейс также можно использовать для задания отображаемого имени и значка, которые отображаются в элементе управления громкости.

Управление уровнями громкости

Для управления уровнем громкости master всех потоков в аудиосеансе SAR используйте интерфейс IMFSimpleAudioVolume. Для управления объемом отдельного потока или для управления объемом отдельных каналов в потоке используйте интерфейс IMFAudioStreamVolume . Оба интерфейса получаются путем вызова IMFGetService::GetService. Вы можете вызвать GetService непосредственно в SAR или в сеансе мультимедиа. Уровни громкости выражаются в виде значений затухания. Для каждого канала уровень затухания — это произведение тома master и тома канала.

Воспроизведение звука/видео