AUGraph中kAudioUnitProperty_SetRenderCallback回调概率性未触发问题排查
问题背景
用于录音与播放的AUGraph结构如下:
RenderCallback -> C16i_32fConvert -> timePitch -> C32f_16iConvert -> ioUnit -> RecordCallback
每次启动录音播放时执行流程:
AUGraphAddNodeAUGraphOpenAudioUnitSetProperty- 设置
kAudioUnitProperty_SetRenderCallback与kAudioOutputUnitProperty_SetInputCallback AUGraphInitializeAUGraphStart
每次停止时执行流程:
AUGraphStopAUGraphUninitializeAUGraphCloseDisposeAUGraph
在iPhone 8 Plus设备上,多次重复启停操作后,RenderCallback未触发,但RecordCallback正常调用,需排查原因是否为重复创建释放过于频繁导致。
问题分析与解决方案
资源释放不彻底导致回调失效
频繁调用DisposeAUGraph可能存在音频单元回调注册未完全清理的情况。虽然执行了AUGraphUninitialize和AUGraphClose,但RenderCallback的绑定可能没有被彻底移除,多次累积后新注册的回调无法触发。建议在AUGraphUninitialize前,调用AudioUnitSetProperty将RenderCallback设置为NULL,显式移除回调绑定。AUGraph重复创建销毁的资源损耗
每次启停都完整创建和销毁AUGraph,会频繁占用和释放音频硬件资源,iPhone 8 Plus的音频驱动可能无法及时响应这种高频操作,导致输出链路(RenderCallback所在链路)阻塞,但输入链路(RecordCallback)仍能正常工作。最优方案是复用AUGraph:仅在首次启动时完成AUGraphAddNode、AUGraphOpen、回调设置等初始化操作,后续启停仅调用AUGraphStart/AUGraphStop,配合AUGraphInitialize/AUGraphUninitialize即可,避免重复创建销毁带来的资源问题。线程安全问题导致状态混乱
音频操作对线程上下文要求严格,如果启停操作不在同一个串行队列执行,可能导致AUGraph状态异常。比如AUGraphStart未完成就执行AUGraphStop,或初始化与销毁操作交叉执行,都会干扰RenderCallback的触发逻辑。需确保所有AUGraph相关操作都在同一个串行音频队列中执行。
内容的提问来源于stack exchange,提问作者Ken Lee

