IAudioClient::Initialize报错AUDCLNT_E_UNSUPPORTED_FORMAT(0x88890008)的解决办法

IAudioClient::Initialize

初始化音频流的时候发生报错AUDCLNT_E_UNSUPPORTED_FORMAT(0x88890008),先上产生了错误的代码:

    WAVEFORMATEX* wfex;
    HRESULT res;
    DWORD flags = AUDCLNT_STREAMFLAGS_NOPERSIST;
    flags |= AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM;

    res = Device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr,
        (void**)&ac);
    if (FAILED(res))
        throw HRError("Failed to activate client context",res);

    res = AudioClient->GetMixFormat(&wfex);
    if (FAILED(res))
        throw HRError("Failed to get mix format",res);

    InitFormat(wfex);

    CoTaskMemFree(wfex);
    
    if (!m_isInputDevice)
        flags |= AUDCLNT_STREAMFLAGS_LOOPBACK;
    else
        flags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
    
    res = ac->Initialize(AUDCLNT_SHAREMODE_SHARED, flags,
        BUFFER_TIME_100NS, 0, wfex, nullptr);
    if (FAILED(res))
        throw HRError("Failed to get initialize audio client",res);
    

解决思路:

首先查阅微软官方文档对该错误的解释:

AUDCLNT_E_UNSUPPORTED_FORMAT

The audio engine (shared mode) or audio endpoint device (exclusive mode) does not support the specified format.

并尝试使用IAudioClient::IsFormatSupported排查问题:

 WAVEFORMATEX* wfex2;
 res = ac->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, wfex, &wfex2);

发现上述代码的报错相同,开始排查WAVEFORMATEX的输入参数是否正确

通过跟代码发现wfex在GetMixFormat()赋值后,wFormatTag被CoTaskMemFree()修改了

GetMixFormat()赋值后的wfex
CoTaskMemFree()执行后的wfex

应该把CoTaskMemFree()放到Initialize()之后,程序正常。

最后贴上正常的代码:

    WAVEFORMATEX* wfex;
    HRESULT res;
    DWORD flags = AUDCLNT_STREAMFLAGS_NOPERSIST;
    flags |= AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM;

    res = Device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, nullptr,
        (void**)&ac);
    if (FAILED(res))
        throw HRError("Failed to activate client context",res);

    res = AudioClient->GetMixFormat(&wfex);
    if (FAILED(res))
        throw HRError("Failed to get mix format",res);

    InitFormat(wfex);

    if (!m_isInputDevice)
        flags |= AUDCLNT_STREAMFLAGS_LOOPBACK;
    else
        flags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
    
    WAVEFORMATEX* wfex2;
    res = ac->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, wfex, &wfex2);
    res = ac->Initialize(AUDCLNT_SHAREMODE_SHARED, flags,
        BUFFER_TIME_100NS, 0, wfex, nullptr);
    if (FAILED(res))
        throw HRError("Failed to get initialize audio client",res);
    
    CoTaskMemFree(wfex);

参考文档:

https://docs.microsoft.com/zh-cn/windows/win32/api/audioclient/nf-audioclient-iaudioclient-initialize

https://docs.microsoft.com/zh-cn/windows/win32/api/audioclient/nf-audioclient-iaudioclient-isformatsupported

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值