私たちの Mac アプリは、gdb からのこのバックトレースで AUGraphInitialize() でクラッシュします
(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 Early 2008、Lion など) でのみ発生し、他のマシン (Mac Mini late 2012、Mountain Lion など) では発生しません。しかし、考えられるすべての動作環境をテストするためのリソースはありません。
この問題をもう少し絞り込みました。
グラフには、MatrixMixer ノードと Output ノードの 2 つのノードしかありません。MatrixMixer ノードにコールバックを登録するとクラッシュしますが、コールバックを Output ノードに登録するとクラッシュしません。
コールバック登録はこんな感じ
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() を使用して、AUGraphSetNodeInputCallback() の代わりにカテゴリ kAudioOutputUnitProperty_SetInputCallback を使用して、オーディオ ユニットの代わりに、またはノードの上に入力コールバックを設定します。
- および入力コールバックの代わりに、render コールバックに matrixMixer ノードを登録します。これは、クラッシュしなかったにもかかわらず、まったく音を立てませんでした。
スレッドやメモリ要件など、ノードへのコールバックの設定に関する癖を知っている人はいますか? 私の心にあること:
- 順序の区別: 初期化シーケンス呼び出しが次のような順序で配置されているコード サンプルをかなりの数見てきました。 => AUGraphOpen() => AUGraphNodeInfo()、AUGraphNodeInfo()、...、ノードなどのさまざまな設定プロパティ、...AUGraphInitialize()。ここで私の質問: この順序は絶対に尊重されなければなりませんか??
- コールバック登録場所: 上記のシーケンスで、いつコールバック登録コードを挿入する必要がありますか? たとえば、AUGraphOpen の前または後。
- 「入力コールバック」と「レンダリング コールバック」の違いは何ですか? 入力コールバックをマトリックス ミキサーに登録すると、どのような影響がありますか? また、レンダー コールバックはどうなりますか?
- API AUGraphAddRenderNotify() と AUGraphSetNodeInputCallback() の違いは、入力/レンダリング コールバックをそれぞれ登録するという事実以外には何ですか? たとえば、スレッド セーフ、init シーケンスの順序など。
CoreAudioAPI メーリングリストの人々は私の質問を完全に無視しているようです。
ヒントをいただければ幸いです。