6月の開発記録 (2025)

日本では7月になったみたいですが、今ゆえあってバーゼルにいて、これを書いているのは現地時間の21時です。

midicci

atsushieno/uapmdをもう少しMIDI 2.0デバイスらしくしたいと思っていて、それならAllCtrlListとかProgramListを実装するのが良いだろうと思っているのですが(この辺は先月書いたMIDI 2.0アーキテクチャガイドブックにも書いている話です)、そのためにはC++で統合できるMIDI-CI実装が必要です。現状まともな実装はjuce_midi_ciくらいしか無く(ni-midi2は中途半端に作って放り出されている)、JUCEに依存してAGPLにするつもりは無いので、実装を用意する必要があります。ktmidiはKotlin/Nativeでもビルドできるので、最終手段としては使えなくはないですが、MIDI-CIの多様な機能にアクセスできる幅広いpublic APIが必要になるので、多分これは「使いたいAPI」にはならないでしょう。

しばらく「どうしたもんかな」と思っていたのですが、もしかして最近流行りのagentic AI codingで何とかなるんじゃないかと思って、試しにDevinにktmidiのktmidi-ci-toolをQtに移植させてみたら、もう完全にGUIコーディングのパラダイムが違うはずなのに、1発でそれなりにそれっぽく見えるGUIを提示してきたので、もしかして割といけるのでは…と(その時は)思って、しばらくDevinで遊んで移植を進めていました。Qtには無いMutableState<T>MutableStateList<T>みたいなやつは最初に作っておいて、それを使わせている程度で、あとは何も設計を与えずにチャットだけで指示しています。

ただktmidi-ci-toolは割と複雑なMutableStateの使い方に依存していて、だんだんDevinではまともに処理できなくなってきました。やはりQtでは無理か…と思って、もうFlutterやReact + Electronで作り直させてみよう、とやってみたのですが(人間にはとてもやらせられないし自分もやりたくない)、やはり言語ランタイムの壁を超えるのはまともに実装してもらえませんでした。

Devinはいちいち金がかかるしこれ以上やらせたくない…と思ってClaude Codeに切り替えてやらせてみましたが、やはりClaude Codeでも無理でした。しかしふと「Claude CodeならDevinではできなかったQt版の状態管理が実装できるのではないか」と思い立ってやらせてみたら、ちゃんとやってくれたので、Devinは捨ててClaude Codeに切り替えて今は進めています。

肝心の「何ができるようになったか」ですが、MIDI-CIクライアントとしてはSend Discoveryを送って返ってきた応答をもとにプロパティのリストを取得してプロパティの値を変更したり変更通知を受け取ってGUIに反映する程度のことが出来ています。ここまでできる実装はjuce_midi_ciとktmidiとこのC++移植版しかありません。initiatorとしてはだいぶできることが多いので、次はrecipientの実装を埋めるフェーズです。ただClaude Codeでもそろそろ無理かも…という状態にはなってきています。最近は人間(自分)が手をいれてばかりです。そんなことをしている場合ではないので、多分進捗は悪くなります。

github.com

LAC 2025

今月は25日から4日間リヨンで行われたLAC = Linux Audio Conferenceに参加していました。

jimlac25.inria.fr

2019年以来、6年ぶりの開催だったようですが、今まで一度も参加したことはなく、知り合いがいたわけでもなく、一度くらい参加してみようという感じで雑に参加しました。完全に無料のコミュニティイベントで、INRIAとINSAとGrameの支援で実現したようですが、次回はどうなるかわかりません(決められなかった)。実際にはフランス語で行われたJIMというカンファレンスとくっつけてJIMLACとまとめられていましたが、わたしはフランス語はサッパリなのでLACのみの参加です。25日はBBQだけだったので実際には3日間です。他の参加者にはJIMから参加していたという現地人も多く、25日はすでに仲良くなっている参加者の群れに翌日から参加の誰も知らない自分が飛び込んで話さないといけないというコミュ力を使い果たすイベントから始まりました…

LACはLinuxガチ勢のハードコアなイベント…といえばそうなのですが、100%というわけでもなく、そもそもキーノートはWebAudioの話だったし、LACセッションの後には毎日2時間くらいライブイベントがあって、そのための応募も受け付けていて、Linux Audioは何も知らんという人も来ていました。家族連れてきていた台湾人と話すようになったのですが、electroacousticsのライブをやりに来た、普段はDAWでやってる、Linuxは使ってない、みたいな感じでした。

あとLinuxのイベントのはずなのになぜかAndroidのセッションがいくつかあって、なぜ…と思ったのですが、1つはrooted Android 2.3以降でALSAをフルに使うみたいなやつで、1つはいろんなセンサーを使って(これもrootedだった気がする)Androidペリフェラル的に使おうという感じのやつでした。

もちろんLinuxオーディオガチ勢向けのセッションがメインで、Ardourスクリプティングをx42(開発者の片割れ)が解説したり、Yoshimiの設計や使い方を開発者が解説したりといったワークショップもあり、Studio OneのLinuxサポートを実装した開発者がLinuxX11ベースのオーディオプラグインをWaylandで使うための方法を解説していたりと、期待通りの話題もいろいろありました。

ちなみに会場は、セッションの部屋(1トラックしかない)はACが効いているのに、休憩時間はACどころか扇風機も無い部屋でホットコーヒーと常温のジュースが置いてある、そこにみんな集まって雑談する、みたいな感じの地獄だったので、後半はあんまし人がいない感じでした。そうでなければもっとしゃべったかもしれない。まあそれでもいろんな開発者とやり取りできて満足しました。

7月以降の予定

7月にやることではないのですが、8月に台湾のCOSCUP 2025で、9月にDroidKaigi 2025で、それぞれセッション応募が採用されたので、しばらく登壇準備しなければならなくなりました。どっちかは不採用かな〜と思っていたので、ちょっと忙しい気分になっています。8月のやつはideal-plugin-bookの話をするだけなのでそんなに緊張感はないのですが、9月のやつは「Androidはまあまあわかってるけどオーディオは基本知らん」というオーディエンスが多いであろう中でどこまで説明できるのか手探りの必要がありそうです。まあメッセージは明確なので、これもそんなに迷わないでしょう(慢心)。どっちも英語セッションですが、興味のある方は是非どうぞ。今年のCOSCUPはRubyConf Taiwanと共同らしいです。

5月の開発記録 (2025)

6/1に技術書典18があったこともあって、すっかり月末に書き忘れていたatsushienoです。いやそんな言うほど31日にやることはなかったのですが、時差ボケと天気痛で完全にやられていたり…

MIDI 2.0アーキテクチャガイドブック@技術書典18

5月は前回書いたMIDI 2.0アーキテクチャガイドブックの執筆で最初の1週間を費やしました。これ自体はもう書いたから書くことがないです。

MIDI 2.0について入門的に読める本として用意したこともあって、技術書典18オフライン当日はこれとUMP本とMIDI-CI本の位置付けを明確にして紹介・販売できたので、良い効果があったと思います。どちらかというとMIDI-CI本の特異ぶりが際立ったような気もしなくはないですが…(!?)

今回ブースでお客さんとやり取りしていた範囲では、MIDI 1.0アプリの開発もやってみたけどよくわからなかった、MIDI 1.0は仕様を勉強したけどアプリ開発でやりたかったこととあんまし関係なかった…みたいな感じで、MIDI 1.0での体験がどうだったかをいろいろ教えてもらえたので(どれも「わかる〜」という感じでした)、MIDI 2.0の学習パスの設計が必要な人に指針を示せるようになればと思います。幸い今回の新刊ではクライアントアプリ開発、デバイス開発、オーディオプラグイン開発といった諸方面でMIDI 2.0のユースケースをいろいろ示せているはずなので、それぞれの目的に沿ったコーディングガイドがあれば良いということになるといえるでしょう。

あとこれは完全に失念していたのですが、事前の既刊送付以外はほぼ事前準備なしで参加していたので「これいくらですか?」と訊かれるまで何も価格表示するものがない、というやらかしがありました…さすがに準備しなさすぎた()

package publication migration to sonatype portal

今月はほとんどまともなコード開発作業が出来ていないのですが、最大の原因はMaven Centralにほぼ唯一的にOSSパッケージを発行する出口となっているSonatype PortalがOSSRHを6月に閉鎖するという問題のせいです。われわれは強制的にGradle公式のmaven-publishプラグインがサポートするOSSRHから、非標準で公式サポートが何も存在しないPortal publisher APIに移行させられることになっていて、その移行コストは全面的にパッケージ発行者が負うことになっています。

Sonatype Nexusでのパッケージ発行については去年KotlinFestのセッションで話した内容と重複する部分が多いので、ここで繰り返すことはありません。ただKotlin/multiplatform-library-templateは去年いちど抜本的な修正が加えられた結果、シンプルになったけどきちんとパッケージ発行まで通らなくなってしまったので、修正を適用しないとパッケージ発行はできません。やはりjcenterレベルのものが出て健全な競争が発生してSonatypeがまともなDXを提供するようになってこないとKotlinのエコシステムはそうそう成長しなさそう…

このマイグレーション作業でさらに時間が溶けました。compose-audio-controls, aap-core, libremidi-panama, ktmidi, mugene-ng, missing-dotと、それぞれパッケージ発行設定が(リポジトリとプロジェクトの性格によって)異なるので、全部シンプルに置き換えられるわけではない感じです。

KotlinConf 2025

今年は割とスケジュール的に行けそうだったので、ふらっとコペンハーゲンのKotlinConfに参加してきました。

kotlinconf.com

たまたま…というわけでもないですがJetBrainsのKotlinチームの知人がいて、現地で1人で何も出来ずに過ごすみたいなことにはならないだろう…という公算ありきです。行ってみたら日本人クラスタみたいなものもあったので、そういう意味では困ることはありませんでした。

Kotlinについてはそんなに自分のほうに強いコミットメントがなくて、展示ブースで開発者とダイレクトにやり取りできるといってもそんなに相談することが無かったのですが、Kotlinにフルコミットしている人にはいい機会が提供されているな、と思いました。わたしの場合は、Amperの様子を訊きに行ったりはしていましたが、そもそもカスタムタスク設計機構がこれからという話を聞いて、この分だとGradleの置き換えには(まだ?)ならないだろうなあという感想を得て帰ってきました。ちゃんとパンドラの箱を開けないとGradleの問題を克服できているとは言えないわけで…

そういうのでなければ、テクニカルセッションを聴き倒すことになると思いますが、文法設計でもツールチェインでもディープな内容のセッションが多く、その意味での満足度は非常に高かったです。2024年の動画は1ヶ月以内くらいに出ていたようなので、今年のセッションも近いうちに動画が出はじめると思います。ADCのセッション動画は忘れた頃にしか出てこないのでほとんど紹介しませんが、KotlinConfのほうはいろいろblueskyのほうで言及すると思います。

あとKotlin FoundationがブースでLT大会を企画していたのですが応募が多くなかったので、ちょろっと飛び込んでktmidiやcompose-audio-controlsやmissing-dotの話を10分くらいしてきました(時間は全然足りなかった…)。大した内容ではありませんがスライドは公開してあります:

speakerdeck.com

コペンハーゲンも初めてだったのですが、6月もちょっとカンファレンスで未踏の地に足を運ぶ予定で、今年は妙に外に飛び出す用事が多くて行く前からHPとMPの蓄えが懸念事項です(?)

「MIDI 2.0 アーキテクチャ ガイドブック」刊行によせて

Intro

6/1のオフライン開催を含め、5/31からの技術書典18が近づいてきて、M3 2025春が終わった頃から「オーディオプラグイン研究所の新刊を用意するか…」と考えていました。前回は各オーディオプラグインフォーマットのAPIの良し悪しを徹底比較するという内容で、一応これが初めてオーディオプラグインのメインストリームであるところのVST3やAudioUnitに深く踏み込んだ初めての書籍だったので、これでatsushienoはニッチプラグインフォーマットにしか詳しくない奴呼ばわりはさせないぞ1とコンプレックスを解消 オーディオプラグインの話題はひとまず満足しました。

そういうわけで(?)、5月に入ってからMIDI 2.0の新しい解説書を書き始めて、技術書典18に新刊登録して販売する準備ができました。

表紙

techbookfest.org

MIDI 2.0ほげほげガイドブック」はこれでUMP、MIDI-CIと合わせて3冊目になるのですが、これは民法でいうところの「総則」…といっても伝わらないと思うので、技術標準仕様書によくある「Primer」に相当する内容を目指しています。MIDI 2.0だとOverviewという仕様書(M2-100-U)があるのですが、これは実質10ページも無く、読んでもほとんど何も伝わらないでしょう。この本はそれに代わり、DAW等においてMIDI 2.0が必要になる技術領域でどのように適用されるかを、56ページでみっちり解説します(!)2

この本の目的は前書きからコピペします。

本書は主にMIDI 2.0 のシステムおよびアプリケーションの開発者が、オーディオアプリケーションが動作するプラットフォームにおいて、MIDI 2.0 をサポートするために必要になる技術スタックの全体像を説明し、本書執筆時点ですでに存在する、あるいは今後必要になるソフトウェア構成要素を総合的に解説するものです。特に次のような疑問を解消できることを目的としています。

  • MIDI が現在の楽曲制作ワークフローのどこで使われているのかわからない
  • MIDI 2.0 が現在の楽曲制作ワークフローの何を具体的に改善できるのか見えてこない
  • MIDI 2.0 の何がすでに実現していて、何が実現しそうで、何が単なる願望なのかわからない

章立てのレベルではこんな感じです:

  1. MIDI システムの全体像とMIDI 2.0
  2. プラットフォームのMIDI システム設計
  3. MIDI アプリケーションの開発基盤
  4. DAW とオーディオプラグインMIDI 2.0 統合
  5. MIDI 2.0 デバイスの作成

ちょうどこの本をほとんど書き終えた頃3にDTMstationにMIDI 2.0の現状に関するレポート記事が上がってきたのですが(インタビューの質問も回答も現状が伝わりやすくて良い内容)、

www.dtmstation.com

--一言でMIDI 2.0といっても、いろいろな内容があって、すべてを網羅しているわけではないのが難しくも感じてしまいます。

**確かにMIDI 2.0の規格は非常に多岐にわたるため、すべてを網羅するというのは簡単ではありません。

本書ではこれをシステム(OSプラットフォーム)とDAWアーキテクチャについて概ね「すべてを網羅した」と思います。(もちろんUMPやMIDI-CIの細かいプロファイルやプロパティの仕様は「既刊を参照」で済ませています。)

当初は「MIDI 2.0エコシステム構築術 v2.0」だった

最近は裏稼業でMIDI 2.0システムの設計のヘルプなどをやっているのですが、先月書いたような感じで、そもそもMIDI 2.0サポートがこの方面での技術開発のhot topicのひとつであるということを「伝える」だけで精一杯、みたいなところがありました。「MIDI 2.0は使われるようになる」っていうメッセージは本当なの? という疑問に、このエントリーだと「JUCEでもいま実装している」という話をしていて、これは有効ではあるけど対人論証でしかない(!)わけです。

これはMIDI 2.0が「どこで」「どのように」「なぜ」使われているかを誰も伝えようとしていない(あと全部やっているというのはいない)というのが原因なので、じゃあ今回はその辺りをじっくり解説する本にしよう、と思い至りました。ただ、実はすでに自分は2021年4月にこれと似たようなことを「MIDI 2.0エコシステム構築術」という既刊でやっていたんですね。

techbookfest.org

追記: 今回の新刊公開に合わせて、こちらは過去の参考情報として無料ダウンロードできるようにしました。

2021年がこの業界でどういう年だったかというと、MIDI 2.0デバイスを接続できたのはCoreMIDIだけ、CLAPの正式版リリースが2022年、MIDI 2.0関連仕様の全面的なアップデートが2023年、2021年当時にはUMPを処理できるライブラリが自作のcmidi2ktmidiしか無く(しかもktmidiにMIDI 2.0サポートを追加したのがこの頃)、アプリケーションもMIDIバイスも皆無でした。この本はどういうスタンスで書かれていたかというと、「MIDI 2.0をサポートするDAWフルスクラッチで作るのは大変だし、まずはMIDI 2.0プレイヤーとか仮想MIDI 2.0キーボードとか仮想MIDI 2.0音源デバイスとか、できるところからMIDI 2.0をサポートしていってみよう」みたいな感じでした。

これは当時のスタンスとしては妥当だったと思いますが、2025年にはさまざまな技術的な状況が変わってきていて、仕様の前提も違えばライブラリの充実度も違うわけです(まあ今でもそんなに充実しているとは言えないけど)。この本の内容は「古い」…よしこれをアップデートしよう、そうすれば新刊になるじゃろ…と考えました。

フルスクラッチで「アーキテクチャ本」として書くことに

完全に甘い見通しでした。当時はそもそもMIDIバイスアクセスのAPIがCoreMIDIを除いてできていなかったので(クローズドソースのmacOSの内容は当然知る由もなく)、今回はその辺も言及することになりました。最近はMIDIシステム設計を手伝っていることもあって、そもそもクライアントAPIの使い方だけじゃなくて、プラットフォーム側はMIDI 2.0をサポートするために何をやっているのか、いやそもそもMIDIシステムってどうやってできているのか説明したほうが良い…みたいなことを考え始め、最終的にMIDIシステムだけで独立した章が出来上がりました(第2章)。

先のインタビュー記事にもありましたが、プラットフォームのサポートなども含め一朝一夕にできることではなく、特に2023年のアップデートは割とインパクト大で、これに対応したものと考えると、仕様が出てからまだほんの2年です。VST3の最初のリリースは何年だったでしょうか? 2007年です(しかも2018年にSteinbergがVST2 SDKのライセンスを停止しコピー配布を禁止して回るまで誰も使っていませんでした)。そんなにすぐに使われるわけはないのです。CLAPなんかが3年でここまで採用が進んでいるのは奇跡的なのです。まあそれはさておき。

この部分には、MIDIバイスってどうやって認識されているのか、仮想MIDIバイスって何なのか、みたいな話から、Android 13で追加されたMIDI 2.0デバイスアクセスはALSAじゃなくてJava言語で実装されている(!?)みたいな無駄話まで入っています(これは第3章)。まだリリースされていないWindows MIDI Servicesの解説もちょろっと入っています。

アプリケーション開発で使えるMIDIライブラリについては、自分の中では比較的アップデートが小さい領域なのですが、それでもそもそもMIDIバイスアクセスが可能になっているのでlibremidiなども説明したり、MIDI協会メンバーだからという理由でだいぶフィーチャーされているni-midi2にも言及したり(SysExも解析できない程度であんまし機能的には充実していないけど一応)、MIDI-CI本でも言及したjuce_midi_ciとかも入ってきて、ライブラリの紹介はそこそこ充実したと思います。何より自家撞着で(自作ライブラリの話だけで)終わりにならないのが良い…! MIDIプレイヤーやMMLの話は完全に脇役にしました。DAWサポートの下地ができつつある現在の状況としてマジョリティ向けの話が書けるようになったので…!

DAWプラグインの章は、たぶん多くの人が知らないであろう領域で、「プラグインを使うのにMIDIなんて関係ないじゃん」から「プラグインを演奏させるのはMIDIメッセージなんでしょ」あたりまで、さまざまな誤解の余地があると思います(こんな感じの解像度の理解だと概ね誤解です)。そして(JUCEプラグインなどを開発していれば自明ですが)プラグインではDAWプラグインフォーマットのイベントに変換されたメッセージがまたMIDIに戻される、みたいなことも解説しています。

第4章のサンプル

MIDI 2.0デバイスの章は、第2章を踏まえて仮想MIDIバイスを常駐させて使用するやり方で、この辺は「エコシステム」本と基本的には同じですが、当時は単なるMIDI 1.0デバイスのアップグレード版としての可能性を追求していただけでした。これではユーザビリティとパフォーマンスの観点でDAWの代わりにはならないので(音源側)、DAWに近づくにはどういう仮想MIDIバイスアーキテクチャが必要になるか(!?)といった部分まで踏み込んで解説しています。まあ仮想MIDI 2.0音源の部分はまだ(?)現実化していない、だいぶ野心的な内容です。

「エコシステム」本はMIDI 2.0のプラットフォームAPIも無い頃からMIDI 2.0プレイヤーやMMLによる楽曲データ生成、仮想MIDIバイスなど、だいぶニッチなところからスタートしましたが、今回はこれだけ客観的に実装されたMIDI 2.0技術のエコシステムについてまとめたのであれば、エコシステム「構築術」を中心に論ずるフェーズではないし、シンプルに「システムとアプリケーションのアーキテクチャ」の解説で良いだろうと考えて、最終的に今回のタイトルになりました。

Outro

「エコシステム」本のバージョンアップとして既刊購入者の方が無料でDLできるようにしたほうがいいかな、とも考えましたが、内容の流用すらしていないレベルの、目的意識だけが同じ書籍なので、完全な新刊として出すことにしました。まあ500円の本でしたし、納得感はあるかと思います。

そして「ガイドブック」の1冊としてこのシリーズに加えることにしました。「エコシステム」本とは異なり、本書はMIDI 2.0仕様の解説と同じくらいMIDI 2.0の「王道」を征く解説書であり、客観的に説得力のある内容がほとんどのはず、という自負のあらわれです。あとはプログラミングガイドあたりが出来たら「MIDI 2.0(完全)ガイドブック」として完成する日も遠くはないでしょう(さすがにそれは商業ベースのほうがいいと思いますが)。

今回は印刷版を用意していく予定です。ねんがんの「前から印刷」をやるぞ…! 技術書典18オフラインでは「う-11」でお待ちしています。


  1. そんなことを言われたことは一度も無い
  2. もしかしたら民法総則ではなく債権総論だったかもしれん…すまんな…(伝わりにくい)
  3. https://bsky.app/profile/atsushieno.bsky.social/post/3logllyn24c2u

4月の開発記録 (2025)

手持ちのUSDを半分売り捨ててだいぶ気持ちがすっきりしたatsushienoです(時候の挨拶)。

AAP 0.9.1 and co.

今月はM3 2025春に出展することもあって、現状で安定的に動かせるAAPをリリースしておく必要がありました(まあそれは自分のお気持ち次第ですが)。今回は先月実用化できたAAP APK Installerがあったので、ここからインストールして挙動を確認できることをマイルストーンとしてパッケージをリリースしています。Android SDK APIのPackageInstallerではインストールするパッケージについてさまざまなチェックが入るので、これを全プラグインパッケージについて確認するのはそれなりの作業になります。AIの雑な仕事が当てにならない領域でもあります。

最初はv0.10.0にするつもりだったのですが、本体の実装の改善はほぼ無く、Kotlin 2.0対応くらいしかしていなくて、ABIへの影響も無いはずなのでv0.9.1と控え目にしました。ABIが破壊的に変更されたKotlin 2.1にアップデートするときにはv0.10.xになるでしょう。

github.com

今回のリリースに合わせて、1年前に途中までやっつけたaap-airwindowsも、基本的に動作していそうなところまで進めてリリースに含めてあります。単にパラメーター処理まわりの実装が足りていなくて挙動が怪しかっただけでした。LV2経由でもJUCE経由でもないプラグイン移植は貴重なサンプルケースなので、今後も状況に応じて活用していく予定です。まあ1パッケージに448本もプラグインがあると邪魔なのは多少StandaloneアプリUIに手を加えた今でも変わらないのですが…!

some tech. sessions and lightning talks

今月はちょっと企業内ワークショップで講演依頼を受けていたので、モバイルプラットフォームオーディオフレームワークの開発者向けに、近年のオーディオ開発のトレンドを絡めたAAPみたいなプラグインフレームワーク開発の解説という割とウルトラC級のコンボを決めてきました。その2つ、基本的に交わらないじゃん…!?

speakerdeck.com

わたしはそもそもオーディオ開発のトレンドのポピュラーなところの最先端に波乗りするタイプではないので(たとえばAI技術の話とかはほとんどしない)、去年COSCUPでしゃべってきたときもその肥やしとなる資料をまとめていたときも(1 2 3 4)、その妥当性は常に条件的ではあった(ある)わけです。とはいえ、先日開催されていたJUCE meetup TokyoではJUCEチームのメンバーから次のメジャーバージョンではMIDI 2.0 in AudioProcessorやCLAPサポートが来るという話をしていて、少なくとも「JUCEチームもこの方面ではアツシエノと同じことを言っている」(この辺の情報自体は年初あたりの予告で既知だけど、わざわざ講演でも言及する)くらいの状況にはなったな、と思っています。

今月はついでにこのスライドの中で軽く言及していたSurfaceControlViewHostの話をmobile dev. meetupで5分でしゃべってきました(当日空いてたから滑り込んだ)。iOSのApp Extensionの代替を実現するにはどうすればいいか、という視点にしただけで、技術的目新しさは無いです。といってもSurfaceControlViewHostなんてここをよく見ている人でもなければほとんど知らないと思いますが。

speakerdeck.com

uapmd

振り返ってみるとどうやら去年の9月あたりからコードを書き始めてはいたらしい独自プラグインホストですが、その目的は10月には書いていた通りで「ソフトウェアMIDI 2.0デバイスを任意のオーディオプラグインで作る」というものでした(この時点ではソース未公開)。VST3、AU、LV2のプラグイン列挙とごく簡単なオーディオ処理とパラメーターのサポートを実現してからは、ほぼWebView UIの実験場となり、その後は多忙になって全然いじる暇がなかったのですが、↑の講演が終わってようやくひと息つけた && 3月にjavacppからpanamaへの移行を済ませられたので、ようやくこっちに戻って来られました。

AAPではなくこっちに戻ってきたのは、M3の展示物として新しいものを出しておきたいという気持ちがあったからですが、そもそもMIDI 2.0仮想デバイスの構想は、ktmidiアプリであるところのkmdspMIDI 2.0対応の楽曲で演奏できるようにしたい(きちんと動くことを確認したい)という動機によるものでした。MIDI 2.0音源が存在しなければ、MIDI 2.0プレイヤーがあっても試せないわけです。AAPではもう出来ている機能ですが、デスクトップでもMIDI 2.0ツールが開発できるようになってほしいところです。SMF2 Container Formatが完成すれば、標準技術にちょっとした上モノをプロジェクトファイルとしてかぶせるだけで、オーディオプラグイン+DAWに相当する創作環境が実現できる…というのを目指したいところです。オーディオプラグインによるバベルの塔崩壊(現在)の次の世代をこの辺の技術で実現したい…といった展望です。

ともあれ、ひさしぶりすぎてどこから手を付けたものか迷ったのですが、プラグインホストのデバッグがいまいち開発体験の悪いWebView経由のルートしか無くて、進捗が悪化していました。それで、プラグインホストの機能を追求するより、まずはPoCでごくプリミティブなレベルでもいいから、UMPでメッセージを送れる仮想MIDI 2.0デバイスを作れるようにすることが先決だろうと考えて、いったんプラグインホストの現状は放置して仮想デバイスとして動作させる部分に注力しました。

プラグインホスト部分も、とりあえずノートオン・オフと(上手くいくやつは)パラメータ設定までは出来ています。JUCE実装でも動くように作るか…とも思ったのですが、ライブラリとモジュールのパラダイムが違いすぎて、とりあえず思いつかなかったことにしました。このコードはJUCEみたいな異端ではなく各種プロジェクトで使えるまともなライブラリとして構成したいところです。

コードは12月には公開してあったのですが、README.mdの内容も全体的にHTMLコメント化して隠してあったので、全容が把握できるようになったのは今月からという感じです。

github.com

まだ実装済みのAPIすらいろいろ動かない機能だらけで、当然プラグインとの相性問題もあり、実用に耐えるプラグインは少ないかもしれません。今週からCLAP対応も追加しているのですが、5月は他のタスクに取り掛からなければならず(もともとM3までの予定だったし)、続きはしばらく先になりそうです。

3月の開発記録 (2025)

3月は何の因果か自分の時間が取れる日がここ数ヶ月よりはあったので、溜まっていたコーディングタスクを少し片付けました。(原稿執筆などのタスクに少ししわ寄せが行っているのですが、そもそも原稿が最優先タスクになるのもおかしい話ですし…?)

AAP APK InstallerとJava API for GitHub 2.0に至る改善

AAPは技術的課題が山積みのまま他のタスクに追いやられて手が付けられない状態が何ヶ月も続いているのですが、今月はリリースされたAndroid API Level 36での動作を確認しようと、AAP APK Installerでプラグインをインストールして試そうとしたのですが、正常にインストールできるものが限られていて調査本編どころではなかったので、このままイマイチ体験を放置し続けられないと思い、重い腰を上げてインストーラーそのものをいろいろ改善していました。インストールの失敗はアプリ上のログで見られるようになり、インストール状況も目視できるようになったりと、最低限の改善を施しています。

それよりも大きいのは、公開当初から問題だったAPKのダウンロードがきちんとストリーミング処理で行えるようになったことです。これは、このアプリで使っているJava API for GitHubというライブラリの実装がダウンロード処理をバッファリングしていたために、100MBもいかないうちにOOM Killerによって殺されていたという問題に対処したものです。これでどのアプリケーションも、少なくともダウンロードを完了してPackageInstallerに制御を渡すところまでは完遂できるようになりました。

GH4Jの開発元(昔はJenkinsのひとがつくっていたのですが今はノータッチ)ではデスクトップ中心で使われていたのか、この辺の問題を解決すべきとは思っていなかったようで(記録はされていて反応もしているのに対処がなかった)、こちらから自分のコードで使っているHTTPクライアントのカスタム実装を教えたら、本体に取り込みたいという話になって、いつの間にか全体的にバッファリング処理が削られていって新バージョン公開(予定)という流れになっています。

AAP: NDK r18 fixes、OB-X-AEとaap-juce-ob-x-ae

aap-coreをAPI Level 36やNDK r18でビルドして更新する作業も必要になっていて、NDK r18には実際にNdkBinderが削除されてビルドが壊れるという大問題が発生して、結局Androidチームに報告してビルドできるようになった && 対処してもらうことにしたりと、まあまあ面倒がありました。

それがひと段落したので、aap-lv2までひと通り更新をかけた後、aap-juceにもアップデートの修正をかけていたのですが、OB-XdやVitalといったProjucerベースのプロジェクトが面倒になって、今回はついにOB-XdはOB-X-AEとして(ADLplug-AEみたいなもん)自前でCMake化してビルドするアプローチに変更することにしました。CMake化したのでついでにCLAP版もビルドしています。

github.com

OB-Xdの場合は、本家の更新が3年以上止まっているのと、Linux版jucerみたいなのがあって面倒だったことがあり、CMake化は改善しかなかったといえるでしょう。ただこれをAAP化したaap-juce-ob-x-aeはまだCIビルドが通っていないようです(途中でこっちどころではなくなってしまった)。気が向いたら直して続けると思います。

ちなみに自分がこの辺をいじっていた頃、なぜかTAPコミュニティでもOB-Xd のforkが同時に複数本生えたりしてして(たぶん偶然)、fork開発者同士で相互に話題になっていました。OB-Xd に一体何が起こったのか…w

ktmidi 0.11.0とlibremidi-panama

先月も書いているのですが、AAPより喫緊の課題をかかえているのはMIDIバイスアクセスに根本的な問題のあるktmidiのほうで、JavaCPPを捨ててPanamaに移行するタスクを早めに終わらせる必要がありました。今月Java 24がリリースされて、jextractのほうもそんなに変わっていなそうだったのと、Jarにきちんとネイティブライブラリをバンドルしてロードできるものとして実績があるプロジェクトとしてJNEというライブラリを発見したので、改めてlibremidi-panamaを使ってLibreMidiAccessのAPIを実装することにしました。

このバインディングの対象となるlibremidiが実にトリッキーなライブラリで、anonymous struct / unionがjextractのコード生成の失敗に繋がるのですが、jextractも本当は処理できるはずなのに古いLLVM実装に固執して新しいLLVMでは失敗し続けるという問題があって、一筋縄ではいかず、最終的には組み込んでいるlibremidiのAPIを変更してバインディングを自動生成しているのですが、一応動くようにはなりました。

そこからさらにFFMのAPIで実装するところでいろいろハマったのですが、この辺は多分FFMに慣れれば何とかなるのでしょう。FFMは意外とメモリ境界をちゃんと把握していて、アクセスできない領域のチェックはしっかりしているんだなあと思わされました。

ちなみにjextractがバギーなコード生成しかしないなら、Panamaバインディング生成程度はもうAIコーディングできるんじゃね?とか思いながら試しにRoocode + Mistralとかで書かせてみたりしたのですが、やはりPanamaまわりの知見は浅く、コンパイルさえ通れば実行時にどうなっても知らんみたいなコードしか生成されないので、あきらめました。多分他のAIコーディングプロバイダーで試しても同じだろうなと思います(未検証)。

libremidi-panamaでktmidi-ci-toolとkmdspkmmkcompose-audio-controlsが問題なくLibreMidiAccessで使えることがわかったので(MIDI 2.0サポートはこれらのアプリ次第ですが)、libremidi-javacppからlibremidi-panamaに差し替えてktmidi 0.11.0をリリースしました。PanamaはJava 22以降が必要になるのですが、まあこれは致し方ないでしょう。

0.11.0に合わせてKotlinも2.1.20に更新しようかと思ったのですが、Kotlin 2.1へのアップグレードは大幅なABIの破壊的変更になりますし、Kotlin 2.1で警告から禁止になるようなpattern matchに依存しているGradleプラグインが壊れて動かなくなる事例も観測されたので、まだ時期尚早とみて見送っています。既にkotlinx-coroutines 1.10.xなどはKotlin 2.1 ABIに移行してしまっているので、Kotlin 1.8時代のABIを維持するためにKotlin 2.0.xを使い続けることができるかどうかは、エコシステム全体の動向次第と言わざるを得ないでしょう。同じような話をKotlin Fest 2024でやったなあ…

何はともあれ、LibreMidiAccessが安定することは、MIDI 2.0方面の開発ひいてはAAPの開発そのものにも大きな影響があります。LibreMidiAccessで実現できるMIDI 2.0プレイヤーのためにソフトウェアMIDI 2.0音源の仕組みを作る意義があり(uapmd)、デスクトップでのMIDI 2.0アプリケーションの動きをAAPに…というフィードバックループの構造になっているわけです。AAP本体の開発が進んでいるように見えなくても、自分の中ではこれらはマイルストーンが繋がっています。

Compose Multiplatformのデスクトップpointerイベントの追従

ktmidiのアップデートに合わせてcompose-audio-controlsも各種依存パッケージを最新版に更新していて、そこで気づいたのですが、Compose for Desktop (JVM) のマウスイベントの扱いが開発当時と変わっていて、カーソルが領域内に入っただけでノートオンになってしまうような使い物にならない挙動になっていたので、コードを見直してまともに動作するようにしました。compose-audio-controlsもデスクトップ上ではkmdspでの表示用コンポーネントとしてしか使っていないので、CMPのどのバージョンから挙動が変わっていたのかは確認もしていませんが。

Compose Multiplatformはまだこういう破壊的な挙動の変更が出てくるので油断ならないところです。現状だとkmdspがwasmで表示されない問題があるのですが、これもWasmビルドのパッケージングに破壊的変更があったということでしょう(こっちはalphaなので破壊的変更が十分想定されるべきもの)。Wasm版はまだIMEもサポートされていないレベルなので、今後どう収拾をつけるつもりなのか、まだ(悪い意味で?)目が話せません。まあこれはオーディオアプリケーションのC++ GUIあるある案件でもあります(先月も書きましたがVitalAudio/visageなんかもそう)。

2月の開発記録 (2025)

台独万歳! (228の時候のあいさつ)

1月はいろいろな予定が積み重なってテンパっていたのですが、2月はある程度余裕が出来たので主に原稿書きや雑事を片付けていました。コードは公開部分では結果的に全然増えてないところです。そんなわけで短いです。

DTMの世界に触れてみよう(ハンズオン)

1月にもちらっと書いたのですが、2時間のDTMの超入門講義をやってきました。超入門ということで、基本的に有償製品を避け、使うのにユーザー登録が必要なソフトもなるべく避け…という感じで、教材の選択でめっさ難儀しましたが、一応「とにかく音を出す」「音符を置いて鳴らす」「総合音源とシンセとドラム音源を紹介する」は出来たようです。超入門と言いつつも、開発コミュニティ向けだったので、プログラミングのタームを使って説明できるというアドバンテージはだいぶ大きかったように思います。

スライドは特に非公開にする理由もないので公開してあります:

speakerdeck.com

どんな感じだったかは当日の参加レポートを書いていただいてます(ありがたいです…!)

2323-code.hatenablog.com

自作やっつけ総合音源(USF2Plugin)は作りかけのまま放置してあります。今月はVitalAudio/visageが公開されたので、試しに組み込んでみようかなと思ったのですが、DPFのUIの根本的な方向性がちょっと性に合わないな…と思ってそのままにしてあります。やるならGUI統合部分など完全にforkプロジェクトとして進めたほうがよさそう。まああとVisageIMEサポートがまだアレなのでこのプラグインには向いていないところがありますね。プリセット名とか検索できるようにしたいし。

そんなわけで講義では総合音源には(USF2Pluginの代わりに)SforzandoとGeneralUser-GS.sf2を使って乗り切りました。今月は世間では無料音源は使うな!みたいな話が話題になったりしていましたが、入門者講義で取っ掛かりから有償音源に誘導するのはあり得ないので、この辺の選択肢は(知識として)確保しておきたいところです。Linuxで使える音源なんかも無料のものが多いので、話題としてはかぶってきます。この同人誌を書いたのももう3年くらい前ですね:

techbookfest.org

ktmidiのJVMプラットフォームバインディング再考

ktmidiでプラットフォームMIDI APIアクセスはめちゃくちゃ大変で、Kotlin/JVM用にJNIを、Kotlin/Native用にcinteropを、Kotlin/JS用にNPMを、Kotlin/Wasm用にWebMIDIのDOMバインディングを(当時Kotlin/Wasm自体にnodeサポートが無かった)それぞれ作らざるを得ない状態なのですが、現状JVMまわりが特にパッケージ参照をまともに解決できない困った状態になっていて、中長期的な解決策を探しているところです。現状javacppを使っているのですが、このGradle統合がjavacpp的には本筋ではなく(mvnを使っているため)、gradle-javacppを使ってきちんとパッケージ発行まで漕ぎ着けたプロジェクトは何一つ存在せず、どうもまともに動くものではない(そして開発者もやる気がない)という詰んだ状態です。

自分が手を加えて生きながらえさせることも考えましたが、javacppは今さら使う必要のないJNIベースのプロジェクトなので、Kotlin/JVMではもうPanamaベースのプロジェクトに移行したほうが良いかなと思っています。ただjavacppは実行時に自動的にネイティブライブラリをロードしてくれる仕組みがあって、これはPanamaやjextractではOracleは全然手当する気がない(そしてコミュニティもそれを当然と思っている)ので、その辺をどう埋めるべきか迷っているところです。Panamaでも、だいたいどのサンプルもライブラリを同梱する必要がないlibcとかcurlとかzlibみたいなやつばかりで、ちゃんと現実の課題に取り組んでいる様子が無いんですよね…

あとPanama jextractの仕組みはイケてないのでプラットフォーム中立のバインディングをきちんと作れる仕組みにしよう、というvproxy-tools/panama-native-interfaceというプロジェクトも発見していて、これもいいかもなあ…とか考えています。実際libremidi-panamaを作ったときは、プラットフォーム固有のバインディングが生成されたりして、それは手動で取り除いていたりします。取り除いているというか、そもそもビルド時にjextractを走らせて自動生成する仕組みは避けているので(ksp1で痛い目を見ているので…)、jextractを有効にしたビルドで生成されたものの一部だけを取り込んでいる感じですが。

この辺はそのうちPanamaですっきりさせることになると思います。ktmidiはAndroidではAndroid MIDI APIを直接使えてJNI不要なので、あまり心配せずにPanamaに移行できるのはいい話といえます(?)。

1月の開発記録 (2025)

2025年最初の開発記録です。このフォーマットもそろそろやめてもいい気がしていますが、とりあえず継続しておきます。1月は裏稼業がそこそこしんどかったのと勉強会(後述)の下準備と親族の相続まわりなどで他のことは何もかも止まっていましたが…

USF2Plugin

DPF + WebUIの実験を兼ねて雑なGM音源のプラグイン作っていました(過去形?)。

次の週末にちょっとクローズドなDTM入門講義をやらないといけないのですが、まずはいろんな楽器に触れるのが良いかな…シンセはシンセで触れるとして総合音源があったほうがいいよな…でも今General MIDI音源みたいなやつでカジュアルにダウンロードして使えるやつが無いな…と考えていました。いろいろ選択肢を検討したのですが、どの案もイマイチなんですよね…

  • Komplete Start に入っているKontakt 8 Player + Kontakt Factory Selection : たぶん音源としては申し分無い。ただしユーザー登録 + インストーラー経由でKontakt 8を入れるややオーバーキルな手順。Linux版は無い。
  • Sforzando : SF2を別途ダウンロードしてロードする必要がある(そもそもSF2は主な用途ではない)。Linux版はまだ無い。
  • JuicySFPlugin : SF2を別途ダウンロードする必要がある(デフォルトで何も使えない)。GUIが使いにくい。macOSビルドがnotorizationかかっていないのでVST3が一生ロードできない(これはしょうがないんだけど)
  • x42-gmsynth : 最初から音源が固定で入っていてセットアップ不要なのは良いが、GUIもプリセットも無く音色変更にプログラムチェンジの送信が必要なので、DAWGUIから指定するのが困難

そういうわけで「自作しちゃえば早いんじゃね?」と雑なことを考えて、DPFでとりあえずx42-gmsynth相当のもの + プリセットでGM音色を選択できるものを作りました。サウンドフォントのエンジンとしては、当初はx42-gmsynth同様Fluidsynthを使うつもりだったのですが、せっかくGPLv3フリーなDPFを選択しておきながらこっちでGPLv2に拘束されるというのはイマイチだと思って、今回は選択肢から外しました。最初はsf2hppを使っていたのですが、さすがにCCがほぼ手つかずなのは実用上困るな…となってTinySoundFontを使っています。

ただ、DSP側はすぐ作れたのですが、DPFのWeb UIの方向性がかなりイマイチということがわかり(secure contextの問題が十分に理解されていないし、Web UIを設計するために必要なJSあるいはJS APIが何も公開されていない)、今回の締切がある短期決戦には間に合わなそうです。そしたらこれ作る意味ほぼ無くね?とも思うのですが、まあ今後AAPその他で使い回せるかもしれないので、継続する可能性はそこそこあります。

augene-ng環境の復元

DTM講義でデモとして提示できる楽曲データとして、昔Tracktionプロジェクトとして作成した打ち込みデータを現在手元にある + 商用音源も出せるmacOS環境でロードできるようにしたかったのですが、これが一筋縄ではいかず、いろいろ苦労しました。以前はUbuntuGitHub Actions環境ですらレンダリングできたやつなのですが…(!)

まずTracktionデータを「生成した」augene-ngというMML to MIDI 2.0 to Tracktionなツールを「生き返らせる」作業が立ちはだかりました。これにはXMLリアライザとなるコードを自動生成するKSPの自作コードが含まれており、半年くらい前にはKotlinが2.0化する過程でksp2がきちんと動作する世界線が存在しない…という状況にあって、その状況で放置されていました。

これが何とか動くようになると、次はTracktionプロジェクトを再生するJUCEベースのプレイヤーがmacOS上で動作しないという問題が出てきました(これはLinuxでしか動作しなかった)。これを開発した当時はJUCEにLV2サポートが無く、またホスト側の機能が必要だったのでDISTRHO/JUCEではなくjlv2を使っていたのですが、これが引っ張ってくるpuglのmacOS実装が雑なのかイベントループが適切に初期化されない…みたいな問題にぶち当たり…その辺は原因追及せずtracktion_engineとJUCEを最新にして依存関係をまるっと切り捨てることで解決しました。

このプロジェクトではオーディオプラグインとトラックの関連付けにJUCEのAudioPluginHostのセーブデータを使っていて、そのためのプリセットデータも大量に作成されているのですが、プラグインのインストールパスが環境依存になる問題に対する解決策が不在で、今回も未解決で終わりそうです。解決策のひとつとしてStudioRackを使おうとしたのですが、先月修正したsfizzのPRも開発者不在で放置されていて(これは先月書いたやつ)、すなわちStudioRack経由でインストールされるsfizzは動作しないバージョンということになるので、今回も諦めました。そもそもプラットフォーム別にプリセットファイルを調整しないといけないはずですし、別のアプローチが必要そうです。この辺はそもそも最近は自分でプラグインホスティング機能を開発していることも考えると、JUCE AudioPluginHostより相応しいマッピングファイルを策定するのが正しい姿という気もしています。