WASAPI: выбор формата волны для эксклюзивного вывода

Я пытаюсь открыть эксклюзивный поток с устройством вывода, используя WASAPI. У меня возникли проблемы с выбором приемлемого формата, поскольку, похоже, нет подсказок относительно того, какие форматы принимаются данным устройством.

В моем случае IAudioClient::GetMixFormat(), который в противном случае возвращал бы формат по умолчанию для устройства, возвращает формат, который нельзя использовать в монопольном режиме (IAudioClient::IsFormatSupported() возвращает AUDCLNT_E_UNSUPPORTED_FORMAT). Я не знаю, куда идти оттуда. Существует смехотворное количество комбинаций параметров формата волны — мне буквально нужно перебирать каждый из них, пока что-то не сработает?


person NmdMystery    schedule 24.03.2014    source источник


Ответы (1)


Ну, я спросил на форумах MSDN, и они дали хороший ответ.

Вам нужно проверить формат устройства по умолчанию через IMMDevice::OpenPropertyStore(), а затем IPropertyStore::GetValue(), а не IAudioClient::GetMixFormat(). Вот код, который извлекает приемлемую структуру WAVEFORMATEX:

//CoInitialize/Enumerate devices

IPropertyStore* store = nullptr;

hr = device->OpenPropertyStore(STGM_READ, &store);

if (FAILED(hr)) {
    ExitProcess(1);
}

PROPVARIANT prop;

hr = store->GetValue(PKEY_AudioEngine_DeviceFormat, &prop);

if (FAILED(hr)) {
    ExitProcess(2);
}

hr = device->Activate (
    __uuidof(IAudioClient), 
    CLSCTX_ALL,
    NULL,
    (void**)&audioClient
);

device->Release();
device = nullptr;

if (FAILED(hr)) {
    ExitProcess(3);
}

hr = audioClient->IsFormatSupported (
    AUDCLNT_SHAREMODE_EXCLUSIVE,
    (PWAVEFORMATEX)prop.blob.pBlobData,
    NULL
);

if (FAILED(hr)) {
    ExitProcess(4);
}

Окончательное значение hr равно S_OK.

person NmdMystery    schedule 26.03.2014
comment
Обычно это работает, но имейте в виду, что это все равно может не сработать. На самом деле я видел, как он терпел неудачу на виртуальном боксе под управлением Windows 7 (т.е. формат устройства не поддерживается устройством =)). ИМХО, единственный действительно надежный способ определить формат - продолжать вызывать IsFormatSupported, пока не найдете то, что вам нравится. - person Sjoerd van Kreel; 27.05.2016