Attention! Translated article might be found on my English blog.

2017年10月13日金曜日

[解決] 自作V3 AudioUnitがmacOS 10.13のGarageBandで読み込めなかった

NOTEEnglish article is available.

-- 2017/10/14追記 --
対応方法を自作V3 AudioUnitをin-processに対応させるためのステップに書きました。
-- 2017/10/14追記ここまで --

要約:
GarageBandで自作AUを動かすにはin-processでの読み込みに対応させる必要がありそう。
そのためにはAUの実装を全て自作.frameworkに詰めこむ必要がありそう。


詳細:
macOS 10.13で自作AUの動作確認をしていたところ、GarageBandで正常に読み込めないことがわかりました。
AUの一覧には表示されるものの、選択するとビックリマークが表示されたまま、
クリックしてもビューが表示できないほか、エフェクトとしても機能していませんでした。(下図)


まだ原因は特定できていませんが、自作AUがin-processな読み込みに対応できてないためではないかと考えられます。

自作AUをGarageBandで読み込む際のConsole.appに流れるログを観察すると、
254: Extension <private> advertises loadable bundle <private>, but we couldn't find it
というエラーをGarageBandが出力しているのが確認できました。

このエラーをなんとか解決できないかと思い、ビルド設定やInfo.plist, Sandbox関連の設定を見直したのですが、解決できませんでした。

その後の調査で、+[AVAudioUnit instantiateWithComponentDescription:options:completionHandler:]の第二引数にkAudioComponentInstantiation_LoadInProcessを指定すると、
自作ホストアプリでも同様のエラーが出力されることが分かりました。
どうやらGarageBandはAUをin-processで読み込もうとしているようです。

in-processなロードの対応:
自作AUをin-processな読み込みに対応させるには、自作AUの実装を全て.frameworkとして提供する必要があるようです。
このことはサンプルコードAudioUnitV3ExampleABasicAudioUnitExtensionandHostImplementationの中のFilterDemoExtension.mにコメントとして書かれています。
To facilitate loading in-process and into a separate extension process, the .appx main binary cannot contain any code. Therefore, all the plugin functionality is contained in the FilterDemo.framework and the .appx Info.plist contains an AudioComponentBundle entry specifying the frameworks bundle identifier.
実際、FilterDemoExtension.mにはdummy()という関数しかなく、AUの実装は全てFilterDemoFramework.frameworkに突っ込まれているようです。

今から新しくV3 AudioUnitを作成する場合、このサンプルコードを雛形にするのが良いかもしれません。
サンプルコードのAU(FilterDemo)ならば、GarageBandでも問題なく使用することができました。

あと、このコメントにある通りbundle identifierも少し工夫が必要なようなのですが、
よく分からないので今後調査したいと思います。
このサンプルコード、今回の更新で微妙にbundle identifierを変えたようなので、
そちらもin-processへの対応に必要な作業なのかもしれません。

つづく。

宣伝:
鮭山楽器ではmacOS/iOSアプリ開発のお仕事を募集中です。
詳しくはこちらをご覧ください。