TL;DR 今までJUCE non-GUIアプリケーションしかheadlessでビルド/実行できなかったけど、JUCEプラグインも新たにheadlessでビルド/実行できるようになったらしいよ(プラグインホストはまだだよ)/ただ実際にはどうかな
今回は軽めの話題として、JUCEの次期masterブランチに入ってくるであろうdevelopブランチの様子をお伝えします。JUCE 9.0ではUMPをサポートする新しいAudioProcessorやCLAPサポートが入ってくる予定で、次のバージョンがJUCE 9.0になる様子はありませんが、本稿執筆時点でのJUCEのdevelopブランチでは、JUCEモジュールの再編成が行われているようです。
developブランチでは新しくjuce_audio_processor_headlessというモジュールが追加されています。これまでjuce_audio_processorモジュールで実装されていた多くのクラスが、このモジュールに移動したようです。このheadlessモジュールは、プラグインを実装するAudioProcessorをheadlessにできるということでしょうか? そもそもheadlessとは何を意味しているのでしょうか?
JUCE6のheadlessサポート
JUCEはバージョン6.0でheadlessサポートを追加しています("Added support for running headlessly on Linux")。正確にはLinuxでの実行のサポートの話ですが、WindowsとmacOSでheadlessサポートはあまり意味が無いでしょう。JUCE6ではCMakeサポートが追加されており、ProjucerをCI環境でビルドして --resave することなくプロジェクト本体をビルドできるようになりました。
ただ、これは「CI環境でProjucerを実行する必要がなくなった」という以上のものにはなっていません。2020年にJUCEチームがRaw Material Software社として買収された当時はheadless modeについてもう少し期待していたところがありますが、これはオーディオプラグインやホストがheadlessで動くようになるという性質のものではありませんでした(ただこのエントリを書いた当時はそもそもjuce_eventsに依存していると全てX11依存になると思っていたようで、期待の内容のほうも妥当とは言い難いところがあります)。とはいえ、juce_audio_basicsやjuce_audio_devicesくらいしか使用しないアプリケーションでは、Xは不要になっているはずです。
今回headlessモジュールが追加されて構成が変わったjuce_audio_processorは、ホスト側ではなくプラグイン側のモジュールであり、ホスト側のAPIであるjuce_audio_plugin_clientは本稿執筆時点ではheadlessになっていません。CI環境でプラグインホストアプリケーションを実行してプラグインを適用するやり方は2021年に書いていますが、これが変わることにはならないといえます。
https://atsushieno.hatenablog.com/entry/2021/12/07/214945
juce_audio_processors_headlessとjuce_audio_processorsの棲み分け
juce_audio_processors_headlessは、juce_audio_processorsから何をheadlessとして切り離したのでしょうか? これはむしろjuce_audio_processorsには何が残ったか、という確認の仕方がより妥当そうです(残ったほうが少ないので)。以下のコードは引き続きjuce_audio_processorsにあります:
format_types:AudioPluginFormat::createPluginInstance()の実装 (overrides)processors:AudioProcessorEditorとGenericAudioProcessorEditorscanning:PluginListComponentとその依存関係(KnownPluginListなど。これらについては上記2021年のエントリーに詳しく書いてあります)utilities: APVTS (AudioProcessorValueTreeState),ParameterAttachment,PluginHostTypeなど(このクラスについては去年のAdvent Calendarで解説しています)
juce_audio_processors_headlessの意義
プラグインのAudioProcessor単体であれば、headlessでも十分にテストできる環境が整理されたといえそうです。
JUCEでGUIサポートを必要とするモジュールはjuce_gui_basicsであり、これはjuce_audio_processors_headlessでは依存モジュールとなっていません。
一方、juce_audio_processorsは引き続きjuce_gui_extrasに依存しており、これはjuce_gui_basicsに依存しているので、こちらはGUI環境が無いとビルドできません。またjuce_audio_plugin_clientはjuce_audio_processorsに依存しているので、こちらもGUI環境が必須です。
プラグインのビルドにはX11 dev packagesが(まだ)必要
これはプラグインに限らずJUCE 6.0以来のアプリケーション全般についても当てはまることですが、現状では(?)、headlessモードのサポートとは、アプリケーションの実行時にX11が不要であることを意味する程度です。ビルド時にX11が存在しない環境でもビルドが通るようになったというわけではありません。CMakeで普通にビルドするときに、依存パッケージが不在であればそのモジュールのビルドをスキップする、といった調整は行われません。CMakeLists.txtでjuce_generate_juce_header()を呼び出しても条件付きで取り込まれるようになるわけではありません(この関数を使うのは推奨されませんし)。
自分で#include <juce_audio_processors/juce_audio_processors.hを指定するなら、このヘッダー自体は依存パッケージの有無で内容をスキップするようには(まだ?)作られていないので、自分でheadlessビルドかどうかを判別しなければならないことになりますが、そのための仕組みが現状では用意されていません。少なくともJUCEのCMake APIドキュメントにはありません。
そういうわけで、headless実行がサポートされているとしても、まだまだX11 devパッケージのインストールは必要になるでしょう。
プラグインをホストするには結局xvfb-runが必要では…?
ビルドには引き続きX11 devパッケージが必要だとしても、プラグインを実行する環境では不要になっていることでしょう。果たして実際にはどうでしょうか。…ここでわれわれは別の問題にぶち当たります。standalone exeとは異なり、プラグインのテストにはホストが必要になります。headlessで動作するプラグインをロードできる、headlessで動作するホストは存在するのでしょうか? juce_audio_plugin_clientのheadless版は(何度か言及している通り)まだ(?)存在しません。
ターミナルレンダラーとしてはVST2の頃にはMrsWatsonというツールがありましたが、もう開発が終了しています。Reaperにもターミナルだけで完結するモードがあるようですが、ReaperはOSSではないのでパブリックなCIサーバー上にセットアップできません(プライベートなセルフホストで良いのであれば、必ずしもheadlessな環境で動かさなくても良いように思います)。筆者も独自のプラグインホストのライブラリを開発しているのですが、headlessは優先度が低く、この記事のためだけに手を出すのは無理でした。
…というわけで、筆者の執筆時点での所見としては、「今後headlessなホストが出現すれば役に立つかもしれないけど、今はまだその時ではない」というものですが、もしheadlessに使えるホストがある、という情報をお持ちの方がいたら教えてもらえればと思います。
もちろん、プラグインとして実行できないとしても、standalone exeとしてheadlessにビルドできるようになれば、プラグインのプロジェクトとしてテスト実行できるわけで、その意味では価値があるといえるでしょう。もっとも、この意味では、DSPはもともとテストできるように(できればJUCEに依存しないかたちで)構成しておくほうがよいともいえます(そうすればJUCEがサポートしていないフォーマットに持ち込む場合にも有用です)。それはおそらくすでに単独でテスト可能なライブラリの体裁をとっていることでしょう。
まとめ
juce_audio_processorsからGUI依存部分を取り除いたjuce_audio_processors_headlessというモジュールが開発されつつあって、これが正式にmasterブランチに入ってくると、今後はCI環境等でxvfb-runを使わなくてもプラグインプロジェクトをビルド…はできないにしても、テストできるようになる…かもしれません。今後に期待しましょう。