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

本文讲述了在使用IAudioClient初始化音频流时遇到AUDCLNT_E_UNSUPPORTED_FORMAT错误的解决方案,重点在于排查WAVEFORMATEX格式问题,调整代码顺序以确保格式支持,并提供相关文档链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

<think>好的,我现在需要解决用户提出的关于TypeError的问题,具体错误是“object.__init__() takes exactly one argument (the instance to initialize)”。首先,我得理解这个错误通常出现在什么情况下,然后找出可能的原因和解决方法。 首先,我应该回忆一下Python中类的初始化方法__init__的基本用法。通常,当我们定义一个类的时候,如果要自定义初始化方法,需要确保__init__方法的第一个参数是self,也就是实例本身。然后,用户可能会在定义子类的时候,尤其是继承自内置对象如object时,可能在调用父类的__init__方法时传入了多余的参数。 比如,用户可能在子类中定义了__init__方法,并尝试调用super().__init__(),但错误地传递了额外的参数。例如,可能错误地写成super().__init__(self, some_arg),这样就会导致传给object.__init__的参数过多,因为object的__init__本身只接受一个参数,也就是实例本身。 接下来,我需要考虑可能的代码示例。例如,用户可能有一个类继承自另一个类,或者直接继承自object,并在其__init__方法中错误地传递参数。比如: class MyClass(object): def __init__(self, arg1): super(MyClass, self).__init__(arg1) 这里,super()会调用object的__init__方法,但用户传入了arg1,而object的__init__只能接受self一个参数,因此会报错。这种情况下,正确的做法是不传递任何额外参数,或者如果父类需要参数的话,确保正确传递。 另一种情况是用户可能在定义__init__方法时,没有正确指定参数,例如忘记添加self,或者参数个数不匹配。例如: class MyClass: def __init__(): pass 这里,__init__方法没有参数,当创建实例时,Python会自动传递self,导致参数不匹配,从而引发错误。不过这种情况通常会报缺少参数,但如果是调用父类的__init__时传递了错误参数,则可能触发用户提到的错误。 还有一种情况是,用户可能错误地覆盖了__init__方法,并且在子类中错误地调用了父类的__init__,而父类实际上是object。例如: class Parent: def __init__(self, a): pass class Child(Parent): def __init__(self): super().__init__() 这里,如果Parent的__init__需要参数a,而Child在调用super().__init__()时没有提供,那么会引发TypeError,但错误信息可能不同。不过如果Parent是object的话,就会导致上述错误,因为object的__init__不接受参数。 不过,更可能的情况是用户在自己的类中,错误地在调用super().__init__时传入了多余的参数。比如: class MyClass(object): def __init__(self, name): super().__init__(name) # 错误,因为object.__init__不需要参数 这里,super()指向的是object,所以调用object.__init__时传入了name,而它只需要self,所以会报错。正确的做法是不传参数,或者如果父类需要参数的话,正确传递。 总结起来,用户的问题通常出现在以下情况: 1. 在子类的__init__方法中,错误地调用了父类(特别是object)的__init__方法,并传递了多余的参数。 2. 父类的__init__方法被错误地覆盖,导致参数传递错误。 解决方法包括: - 检查子类__init__中的super().__init__()调用,确保没有传递不必要的参数。 - 确保父类的__init__方法正确接收参数,特别是当父类是object时,不需要传递额外的参数。 - 检查__init__方法的定义,确保参数正确,包括self的存在。 可能还需要用户检查他们的代码,特别是在继承链中的各个类的__init__方法,是否有不正确的参数传递。例如,如果他们继承了一个自定义类,而该类的__init__需要参数,但在子类中没有正确传递,或者错误地传递到了object的__init__中。 最后,我需要将这些思考整理成一个清晰的解释,并提供示例代码来说明错误和正确的做法,帮助用户理解和解决问题。</think>`TypeError: object.__init__() takes exactly one argument (the instance to initialize)` 是 Python 中常见的错误,通常发生在类的构造函数 `__init__` 调用父类(如 `object`)的构造函数时传递了多余的参数。 --- ### **错误原因** 1. **直接原因** Python 的基类 `object` 的 `__init__` 方法只接受 **实例自身(self)** 一个参数。如果在子类中调用 `super().__init__()` 时传递了额外的参数,就会触发此错误。 2. **典型场景** 当子类继承自 `object`(或未显式继承其他类),但在其 `__init__` 方法中错误地向父类构造函数传递了参数时。例如: ```python class MyClass(object): def __init__(self, name): super().__init__(name) # 错误:object.__init__() 不需要额外参数 ``` --- ### **解决方法** 1. **检查 `super().__init__()` 的调用** 确保调用父类的 `__init__` 时没有传递多余的参数: ```python class MyClass(object): def __init__(self, name): super().__init__() # 正确:不传递额外参数 self.name = name ``` 2. **如果父类需要参数** 若父类(非 `object`)的 `__init__` 需要参数,需显式传递它们: ```python class Parent: def __init__(self, value): self.value = value class Child(Parent): def __init__(self, value): super().__init__(value) # 正确:传递父类需要的参数 ``` 3. **检查 `__init__` 定义** 确保 `__init__` 方法的第一个参数是 `self`,且参数数量匹配: ```python class MyClass: def __init__(self, a, b): # 定义时声明参数 self.a = a self.b = b obj = MyClass(1, 2) # 正确传递参数 ``` --- ### **示例对比** - **错误代码** ```python class Dog: def __init__(self, name): super().__init__(name) # 错误:假设父类是 object,但传入了 name ``` 调用 `Dog("Buddy")` 会触发 `TypeError`。 - **正确代码** ```python class Dog: def __init__(self, name): super().__init__() # 正确:不传递额外参数 self.name = name ``` 调用 `Dog("Buddy")` 正常执行。 --- ### **总结** 此错误的核心在于 **误传了父类构造函数不需要的参数**。检查子类的 `super().__init__()` 调用,确保参数与父类 `__init__` 的要求一致即可解决。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值