3月の開発記録 (2022)

早いもので3月が終わろうとしています。2月の終わりから全く世界情勢が安定せず、誰もが落ち着かない雰囲気の中で日々を過ごすことになったと思います。自分も例外ではないところですが、多かれ少なかれ影響を受けつつも、自分の作業は進められるだけ進めておきたいところです。

AAP hosting overhaul

2月からずっとやっていて、今日3/31にようやくmainにマージできた作業です。

2月はAAPのnative (C++) hosting APIの仕切り直しに着手していましたが、3月も引き続き泥沼に入っていました。native hosting APIは現時点では (1) MidiDeviceServiceの実装と (2) aap-juce-plugin-host (JUCE AudioPluginHostの移植)の2つしかなく、aap-juce-plugin-hostは「起動時にインストールされているオーディオプラグインの全てをbindService()で接続する」という割とシビアな実装になっていました。これには当然ながら(?)理由があって、まずBinder APIに基づいてServiceと接続する必要があったため不可避だったのです。が、aap-juceに基づくプラグインの移植は今や↓のように大所帯になっていて(README.mdからのコピペ)、今やこれを全て接続するわけにはいきません:

そういうわけで、native hosting API仕切り直しにあたっては、native APIからServiceのAPI…を操作するAAPのKotlin API…をJNI経由で呼び出してBinderを生成する(そのBinderはJNI経由でネイティブコードに渡されてNative Binderとなるわけで多重に境界を往復するわけですが)…という仕組みを作りました。

fixing JUCE Thread

構想としてはシンプルですが、よくある話ながらAudioPluginHostが実行できるようにコードを書き換えて動作させてみたら全くうまくいきません。まず自分のライブラリのクラスをJNI経由で呼び出そうとしてもClassNotFoundExceptionで堕ちてしまう。JNIのClassNotFoundExceptionはJNIをそれなりに使ったことがある人なら、あるいはJNI経由で他言語とinteropするフレームワーク(XamarinとかReact Nativeとか)のユーザーであれば馴染みがあると思いますが、JUCEでも同じ目に遭いました。

この話は前回ここに書いたネタに繋がってきます:

atsushieno.hatenablog.com

ここにまとめたパッチは、その後この記事の英語版を作成してからJUCEへのPRとして登録したのですが(長らく「contributionは受け付けない」方針だったJUCEが1月にポリシーを変更していたのです)、現状音沙汰なしです(issueにしろPRにしろJUCEはだいたいcontribution体験が悪いのであんましお勧めしないです。JetBrainsとかは割とおすすめ。dotnetもそれなりにいいほうだと思います。)

JUCE AudioPluginHostをいじっている過程でこのパッチを作成したということは先のエントリ(日本語)でも言及している通りで、まずはこの問題を追及してパッチを作る作業でそこそこ時間が溶けました。

async-ify plugin instancing API

スレッディングの問題を片付けたら、いよいろJNI経由でContext.bindService()を呼び出してAudioPluginServiceとbindするコードを実装しました。

bindService()は呼び出してもすぐに返ってくるもので、実際にServiceに接続できたらServiceConnection.onServiceConnected()というメソッドにコールバックが返ってくるようになっています。そのため、JNI経由で呼び出すインスタンス生成のメソッドではkotlinx.coroutines.channels.Channelインスタンスを作って.wait()させておいて、onServiceConnected()のコールバックの中で.send()して続行させるコードを書いていましたが、これがまた案の定うまくいかずにハマりました。AudioPluginHostでaap-juceのjuceaap_plugin_clientモジュール経由でAAPの新しいnative APIプラグイン インスタンスを生成しようとしても、途中で返ってこなくなるのです。

しばらく調べてみると、ServiceConnection.onServiceConnected()は(生成スレッドを問わず)常にmainスレッドで呼び出される仕組みになっていました。JUCEのアプリケーション・ループはmainスレッド上で動作しており、そこから呼び出されるインスタンス生成のネイティブ関数もmainスレッドで動いていたので、ここでブロックされていたわけです。

この問題も別エントリでもうちょっとだけ詳しくまとめようと思いますが、結局この問題を解決するために、AAPのAPIにasyncificationを施すことになりました。"asyncification" というのは一部で使われている非同期API化(あるいは非同期APIの提供)をあらわす俗語です。xxx()メソッドに対応するxxxAsync()を生やすやつです。AAPの場合、同期APIで実装すること自体が無理なので、非同期APIのみで作り直すことになりました。

今まで同期APIで設計していたものを非同期APIで作り直したので、内部的には大幅なコードの書き換えを伴うことになりましたが、差分はAAP本体とaap-juceのモジュールのレベルで吸収しているので、移植したアプリケーションのレベルでは書き換えが必要ないところまで収まりました(別途ヘッダファイルのパスの統一などを施しているので、AAP 0.6.xから0.7.0へのアップグレードでは書き換えが必要になっています)。

GitHub Sponsors set up

これは去年の話なのですが、わたしが一時期アプリ開発をちょっとだけ(本当にちょっとだけ)手伝っていたサンプラーアプリがあって、もともとはその開発者がAAPに興味をもって連絡を受けてやっていました。AAPは当時まだJUCEのエフェクトプラグインの移植が使い物にならなくて、「まだ…その時ではない…」と言っていたのでした。サンプラーでエフェクトプラグインが適用できないんじゃ利用機会が無いですし。

それで今は特に一緒にやっていないのですが、そのコミュニティで開発者にAAPを紹介されたという人がコンタクトしてきて、sponsorさせてほしいと申し出をいただけたので、ありがたい2〜と思いながらやりかけで放置していたGitHub sponsorsを設定していました。スポンサープログラムを始めるといろいろサポートを考えないと…となるところですが、あまり気負わずに運用していこうと思います。donationwareとして始めてしまうと仕事見つけづらくなるかな〜とか考えてしまいますし。

WeMove, ADC21動画鑑賞会

しばらく前からMusic Hackspaceというオンラインセミナーを運営しているところで無料のセミナーがあるとたまに参加しているのですが(最初はAndroid Audioだったような気がする)、最近#WeMoveというWomen in Audioのコミュニティと連携して25回の無料セミナーを毎週のように開催するという狂気のような企画があるので(言い方…!)たまに見ています。off-siteではUKの夕方にやっているのでリアルタイムで見られる人はだいぶ限られると思いますが、録画も上がっているので興味がある人はチェックしてみるといいかもしれません。

musichackspace.org

あと最近ようやく昨年のaudiodevcon 21の動画が上がってきています。1週間に1本みたいな感じでちょろちょろと出ていて、このペースでいつ終わるんだろう…?となっていたのですが、最新の動画を最後まで見ていて、見慣れない他のADC21動画へのリンクが出てきたので「あれ?」と思いながらクリックしたら、何やら非公開リストにすでに大量の動画が上がっているらしいことがわかりましたw そういうわけで、そのへんの動画を見ながら勉強する動画鑑賞会を企画しています。来週1度やってみる予定なので興味のある方はお気軽にどうぞ(2020年にやったMusic Tech Meetupのメンバーの承諾のもとこのグループで公開しています)。

music-tech.connpass.com

その他

2〜3月には他にもちょいちょい試したことがあるのですが、今のところボツネタばかりです。最近のボツネタだとBYODを移植しようとしましたが、全く動いていないです。うまくいかなかったVialFX(謎)とかもあるし、まあそういうこともあるよね〜という感じで草の生えていないgithubを眺めています。

4月の予定

native hosting APIの書き直しがざっくり終わったので、3月に公開されたAndroid 13 DP2Android MIDI APIMIDI 2.0対応でもいじって遊んでみたいという気持ちがあります。AAPのMIDI2対応もテコ入れし直しの機運ですね。

4月にはM3 2022春が開催される予定ですが、今回はサークル申し込みしませんでした。今回は入場規制がないので、まだ安全に開催できるのかちょっと未知数だなと思っていることが正直あります(特に音楽関係はソフトウェア業界と違ってリアル空間で生きている人が多いこともあってかそこそこルーズなので…)。せっかく休みにしているので、この機会(?)にAAPの作業を進めておきたいなと思っています。