我们的 Mac 应用程序在 AUGraphInitialize() 中崩溃,并带有来自 gdb 的回溯
(gdb) bt
#0 0x7004dc2f in PowerMeter::PowerMeter ()
#1 0x70073583 in MatrixMixerCore::MatrixMixerCore ()
#2 0x700461ac in AUMatrixMixer::Initialize ()
#3 0x7000541b in AUBase::DoInitialize ()
#4 0x700a333d in AUMethodInitialize ()
#5 0x91e6056c in _AT_AudioUnitInitialize ()
#6 0x91e75072 in AudioUnitNodeInfo::Initialize ()
#7 0x91e76a62 in AudioUnitGraph::Initialize ()
#8 0x91e77ded in AUGraphInitialize ()
#9 0x008908b6 in CMyCoreAudioWrapper::Init (this=0xc800c80) at MyCoreAudioWrapper:829
...
#18 0x0000c9b7 in main (argc=4, argv=0xbffff8c4) at main.h:7
此崩溃仅发生在某些机器上,例如 Mac Pro 2008 年初,Lion,而不发生在其他机器上,例如 Mac Mini 2012 年末,Mountain Lion。但是我们没有资源来测试所有可能的操作环境。
我把这个问题缩小了一点:
我们在图中只有两个节点,一个 MatrixMixer 节点和一个 Output 节点。如果我注册一个回调到 MatrixMixer 节点,会发生崩溃,但如果回调注册到输出节点,则不会崩溃。
回调注册看起来像这样
AURenderCallbackStruct callback = {0};
callback.inputProc = MixerInputProc;
callback.inputProcRefCon = this;
result = AUGraphSetNodeInputCallback(m_Graph, m_matrixMixerNode, 0, &callback );
我还注意到,即使回调 MixerInputProc() 什么都不做,崩溃仍然会发生。
我尝试过但也没有奏效的其他事情:
- 将 AUGraphSetNodeInputCallback() 移动到 AUGraphOpen() 之前或之后、AUGraphConnectNodeInput() 之前或之后、AUGraphAddNode() 调用之前或之后。
- 将调用顺序切换到 AUGraphOpen()、AUGraphAddNode()、AUGraphNodeInfo() 和各种 SetProperty 调用。
- 使用 AudioUnitSetProperty() 来设置音频单元的输入回调,而不是在具有 kAudioOutputUnitProperty_SetInputCallback 类别的节点之上,而不仅仅是 AUGraphSetNodeInputCallback()。
- 将 matrixMixer 节点注册到渲染回调而不是输入回调。尽管它没有崩溃,但它根本没有任何声音。
有谁知道设置回调到节点的怪癖,例如线程或内存要求?我心中的事情:
- 顺序敏感度:我见过很多代码示例,其中初始化序列调用的顺序大致如下所示:NewAUGraph() => AUGraphAddNode(), AUGraphAddNode(), ..., => GraphConnectNodeInput() => AUGraphOpen() => AUGraphNodeInfo(), AUGraphNodeInfo(), ..., 节点上的各种设置属性等, ...AUGraphInitialize()。现在我的问题是:必须绝对尊重这个命令吗?
- 回调注册位置:在上面的序列中,我应该什么时候插入回调注册码?例如,在 AUGraphOpen 之前或之后。
- “输入回调”和“渲染回调”有什么区别?将输入回调注册到矩阵混合器有什么效果,渲染回调又如何?
- API AUGraphAddRenderNotify() 和 AUGraphSetNodeInputCallback()除了分别注册输入/渲染回调(例如线程安全、初始化序列中的顺序等)之外,还有什么区别?
CoreAudioAPI 邮件列表的人似乎完全忽略了我的问题,所以我不得不在这里作为我的最后一根稻草。
任何提示将不胜感激!