MIDI 1.0/2.0はどのくらい「現役」の規格なのか?

MIDI 2.0の同人誌を出して、ぼちぼち売れているのですが*1、この本にどういう意義があるのか説明しておいたほうがいいかなと思いました。

みんな「MIDIなんてもう使われていない古い規格じゃないの?」とか「新しいバージョンを出して何の意味があるんだ?」って思うじゃないですか。でも実際には全然使われていないなんてことはなくて、今でもバリバリ現役で使われているし、MIDI 2.0は懐古趣味で作られた規格じゃないし、この本も懐古趣味で書いたわけではないんですよ。2020年に出るに相応しい規格なのです。

MIDIってそもそも何なんだっけ?

MIDI」と一言でいっても実はいろいろな構成要素があります。皆さんが「MIDI」と聞いて思い浮かべるものは、実際にはどれでしょうか?

多くは相互に依存しないので、現代でも役に立つものとそうでないものがありますし、MIDI 2.0としてバージョンアップする価値があるものとそうでないものがあるわけです。そういうわけで、以下ではこれら「MIDI」として扱われている技術要素が今後も存続する価値があるのか、個別に判断・解説していきます。

MIDIキーボード(入力デバイス) : 現役

MIDI規格に基づいて接続できるデバイスMIDIバイスと呼びますが、いま音楽制作の場面でMIDIバイスって使われているんでしょうか? その答えは圧倒的にYESで、たとえば音楽制作のためにDAWを繋いで楽器パートを打ち込む場面ではMIDIキーボードを使う人が多数でしょう*2DAWMIDIキーボードを使わない制作場面があるとしたらこんな感じです:

  • 全部オーディオチャンネルで録音して加工している(打ち込みパートなし)
  • ピアノロールに直接打ち込んでいる(こっちのほうが効率が良い/キーボードを弾けない(!))

…2つしか思いつかなかった。他にもこんな状況が考えられる、というのを思いついた人はコメント欄なりはてぶなりTwitterなりで言及してもらえればと思います。

MIDI音源モジュール(出力デバイス): ほぼ死亡

MIDIキーボードはあくまでMIDI入力」デバイスです。20世紀頃に「MIDIファイル」(SMF)が流行っていた頃はMIDI「音源」というのもあって、これらはMIDI出力」デバイスとしてMIDIメッセージを受け取って音楽を再生できる楽器として機能していました。こちらは、今では日の目を見ない存在です。特にSMFを視聴目的で利用する機会はほぼなくなりました(MIDIファイルの節とGeneral MIDIの節でまた触れます)。MIDIファイルでBGMを鳴らすWebサイトがもう無いのと同じです。音楽を聴くならMP3やFLACなどのPCMデータ一択でしょう。

そういうわけで「MIDI 2.0対応の音源モジュール」が出るとはちょっと考えられないです*3

懐古趣味で古いMIDI楽器を使う場面も考えられなくはないですが*4、昔ポピュラーだったMIDI楽器はだいたいソフトウェア音源として復刻しているので、およそ出番は無くなったと言ってよいでしょう。

もちろんシンセサイザーとしてのキーボードなどでは生演奏のほかにMIDI入力を受け取って音を出す目的で使えますし、人間の演奏入力をパイプラインで通して片方はシンセに流しつつもう片方は映像のコントロールなどに使うこともできるので、用途が無いわけではないです。

MIDIケーブル : だいたい死亡(USB / BLEに置き換え)

2020年現在、PCとMIDIを接続するのにシリアルMIDIケーブルを使う人はいないでしょう*5MIDI楽器同士、あるいはMI.1やmidiglueのような製品を介して古いMIDIバイスをPCと接続する場合には現役です。他にも電子工作方面はMIDIのシリアル接続と親和性が高いので、今でも使う人はいます。ただ一般的とは言い難いでしょう。DTM用途でMIDI楽器とPCを物理的に接続するなら、現在はUSB MIDI一択です。MIDIケーブルは過去のバイスと繋ぐ以外の役割を終えています。MIDIケーブルの新しい規格がMIDI 2.0のために出ることはないでしょう。

USBは1996年に初めて規定されたもので、MIDI音源でサポートしているものはかなり末期のものです(Roland SC-88Proに無くてSC-8850にあるくらい)。USB MIDIの仕様はMIDI 1.0が成立した1983年からだいぶ経ってから成立したものです。USB-MIDIについては昨年末に書きましたが別の同人誌がおすすめです

物理的に接続しない選択肢としては、BLEがあります。MaciOSAndroidではサポートされていますが、LinuxのBLE MIDIはまだ立ち位置が不安定です(一時期Bluezでサポートされていましたが外された模様)。あとBluetooth接続は遅延が問題になるので、USB接続を置き換える存在にはなりません。とはいえ、iOSAndroidのように、物理的に接続用コネクタを持ちようがない端末でもMIDI接続が可能になるポテンシャルは大きいものです。

MIDIメッセージ : 現役

OSIでいうところの物理層からトランスポート層あたりまでの話は時代性もありますが、その上でやり取りされるMIDI 1.0メッセージは、2020年現在でも現役で使われています。ここでは、90h がノートオンで80hがノートオフ、E0hがピッチベンドでF0hF7hがシステムエクスクルーシブ…といった意味付けが規定されています。このMIDIメッセージ仕様は、MIDI楽器とPCの間でやり取りするプロトコルとして用いられているだけでなく、純粋にソフトウェアの世界であるDAWVST/AUなどのオーディオプラグインの間でやり取りする場面でも内部的に使われます。特に音階の表現はMIDIの7ビット128段階の数値が広く一般的に用いられます。

MIDIでやり取りするのはデバイスを楽器として制御するための演奏命令(演奏に関する各種の命令)です。命令には、わかりやすくいえば「鍵盤を押す」ノートオン命令、「鍵盤から指を離す」ノートオフ命令、「音色を切り替える」プログラムチェンジ命令、「音量を変える」「左右の定位置を変える」「リバーブをかけて強さを指定する」などを実現するコントロールチェンジ命令などがあります(もちろん楽器は鍵盤だけではないので、あくまで概念です)。

もう少し具体的にいうと、ノートオン命令には「どのキーを押したか」「どれくらいの強さ(ベロシティ)で押したか」という情報が渡されます。MIDI 1.0の場合はどちらも0〜127で表します。全てのMIDIメッセージの形式が標準化されているので、どのMIDIバイスも命令を正しく伝えることができます。MIDI入力デバイスが今でも使われ続けているのは、どんなDAWでもほぼMIDI入力をサポートしているからです。

現役だけど内容は古い

もっとも、MIDI 1.0で規定された内容だけでは、音楽制作の現場ではだんだん機能不十分であると考えられるようになってきました。たとえば、データ部分が0〜127しか無いメッセージが大半で、この程度では表現力が足りません*6

また、MIDIメッセージには「チャンネル」を指定する部分もあって、これは同時に演奏できる音色の数にもなるのですが、MIDI 1.0では16チャンネルしかありません。現代のDAWを使った音楽制作では100トラック以上使うことがあり*7、16チャンネルでは到底足りません。

他にも、PCとMIDIバイスの間で機能の有無の確認などができればもう少し拡張機能を用意しやすいのですが、MIDI 1.0は単方向のプロトコルなのでそれも不可能です。こういった各種の機能拡大要求が溜まってきたので、MIDI 2.0としてこれまでとは互換性のない仕様を規定する必要が出てきたというわけです。

ちなみにMIDI 1.0の機能がしょぼすぎるということで、SteinbergはVST2からVST3に切り替えるにあたって、「MIDIサポート」を廃止しました。廃止したのにMIDIコントロールから入力を受け付けることができるのは、VSTホスト(DAW)側がMIDI入力を受け取ってVSTAPIによろしく変換してくれているということです。VST3には結局MIDIのノートオンに相当するNoteOnEventなどがあって使われています。

MIDI 2.0 UMPは、このMIDIメッセージ部分に相当する仕様です。今回同人誌としてUMPをターゲットにしたのは、ここがMIDI 2.0の新機能として一番わかりやすかったからでもあります。ちなみにプロトコルは主にMIDI-CIという別の仕様で規定されています。

楽器番号/音色セット(General MIDI): ほぼ死亡

MIDI楽器はプログラムチェンジという命令で「音色」を切り替えることができます。プログラムチェンジで指定できるのは0〜127の番号、あとせいぜい追加の「バンク指定」で0〜127の数字を2つ指定できるだけで、それ以上具体的な、たとえば波形データなどを指定することはできません。MIDI 1.0仕様が前提としているのは、その番号には既に楽器となるデジタル音源データが用意されていることです。これを用意していたのがMIDI音源モジュールであり、MIDI出力デバイスとして機能するキーボードシンセサイザーです。

この音色番号は、General MIDI (GM)という仕様によって、「1番はピアノ、16番はオルガン、24番はギター…」というように決まっていました。決まっていたのはあくまでざっくりとした音色名であり、そこにどんな音があるかは楽器のベンダー次第です。「ピアノ」と言ってもいろんな音があるのと同じです。MIDIデータとして制作し表現する音楽は、ここに限界がありました。

現代の音楽制作で使われているのは一般にはオーディオプラグインと呼ばれるもので、具体的にはSteinbergVSTAppleのAudioUnitといったAPIに基づいて作られたソフトウェアです(Linux方面でもLV2というISCライセンス前提の規格があって、今回技術書典9で同時に公開した「LV2オーディオプラグイン開発ガイド」はこのために書いたものです)。現代のDAWは、プログラムチェンジの音色番号を指定する代わりにこれらのプラグインのIDを指定して、プラグインインスタンスを生成し、そのプラグインのパラメーターを指定したり、よくstateと呼ばれる状態データの復元/保存によって標準的なパラメーターに収まらないデータを楽器のデータとして利用します。

こういう時代になると、音色番号を切り替えるだけで済む時代はおわりました。プログラムチェンジはおよそ死んだも同然です。もっとも、オーディオプラグインの中にはGMに相当する総合音源のようなものもあり*8、これらはプログラムチェンジを送るとプログラムチェンジとして機能することがあります。これらGM相当の総合音源も、単にGM互換だとGMを前提としたMIDIツールが使えるという以上のメリットは特にありません。

音色番号の代わりに楽器の情報を知る方法

オーディオプラグインが制作の中心になっている現在、DAWは複数オーディオプラグイン機構を同時にバラバラにサポートしなければならない状態になっています。楽器プラグインの詳細情報も、それぞれのプラグイン機構のやり方で取得しなければなりません。これを統一的に処理できるJUCEのようなフレームワークもありますが、あくまで私企業の実装であり、標準化されたデータ規約があれば、それに越したことはありません。

この方面では、MIDI 2.0にProperty ExchangeとProfile Configurationという仕様が策定されているのですが、まだ現在進行形です(器だけ決まっていて中身が規定されていない状態)。具体的な情報がまだ少ないので、今回の同人誌でも基本的に対象外のトピックとして、あまり触れていません。

MIDIファイル : ほぼ死亡

かつて音楽データを生のPCMデータでやり取りすることは、ネットワークの帯域の問題やPCの処理速度の問題で事実上不可能でした。MIDIファイルはそういう時代に音楽を表現する形式として有意義だったものです。しかし現在はそういう技術的な制約は消失し、作者が自らの手元で録音した音源をPCMのMP3やFLACなどの形式で配布できるようになりました。MIDIデータは音源次第で聞こえ方が大きく変わるので、細かくこだわって調整しても意味が無くなってしまい、芸術作品としてイマイチです。

そういうわけで、MIDIファイル形式としてのSMFは、もう楽曲の交換に使われることはほぼなくなりました。

データのエクスポート/インポート形式として今も使う場面がある

もっとも、SMFを「使う」場面が無くなったわけではありません。たとえばDAWを乗り換える場合や、細かい打ち込みの詳細情報が無い状態にして、複数環境でやり取りする必要がある場合、SMFでエクスポートしてそれを別の環境でインポートする、といったことは現代でも行われています。楽譜データを配信したり購入者特典にしたりする場合*9も、一般的とは言い難いスコアデータよりは、広く認知されておりツールサポートも一般的で活用しやすいSMFのほうが向いています。

DAWで表現できる音楽の互換性には一定のラインで限界があるので、エクスポート/インポートはあくまで可能な範囲でのみ行われます。SMFにエクスポートするということは、オーディオプラグインに関するデータは全て切り捨てられることになるので、それはインポートしてから制作者が頑張って復元するということになるわけです。アレンジ版の楽曲データを制作するような場合は、これで十分ともいえます。

MIDI 2.0は何が「新しい」のか?

MIDI 2.0 UMPは、MIDI 1.0でいうところのMIDIメッセージの仕様をモダンにしたものです。たとえば…

  • チャンネルが16から256まで拡大されている。ただし単純に4ビットから8ビットにするのではなく「グループ」の概念を導入している(そうしないとMIDI 1.0互換機能が崩壊する)
  • 7ビットの数値が32ビットビットになったりしている
  • ノート別に作用するパラメーターが新設されている
  • ノート命令にアーティキュレーションが追加されている
  • データの可変長要素が全て廃止され32/64/128ビット整数のみになった(sysexと7bit-encoded length, running status)

MIDIのプログラムを組んだことがある人なら、最後の変更点のインパクトが割と大きいことがわかるかもしれません。メッセージの種類に依存した動的なメモリ確保が不要になるのです! リアルタイムオーディオで使われることも多いMIDIメッセージの処理で、動的なメモリの心配をする場面が減るというのは、割と現代的で「わかっている」感じがしませんか??

もちろん新しい仕様には、うれしい新機能だけではなくて、難しい課題が出てくることもあります。先日書いたUMPにおけるノート命令についての解説は今回の同人誌の一部として書いたものですが、だいぶ難しい話題を取り上げています。

あと、SMFの更新はまだ出ていないけど仕様策定中らしいです。

Summary

今後MIDI標準に関連してアップデートされる価値があるやつとないやつを、以下のようなふいんきで一つ一つ解説していきました。

  • MIDIキーボード
  • MIDI音源モジュール
  • MIDIケーブル(電子工作を除く)
  • MIDIメッセージ ← MIDI 2.0 UMPはココ
  • General MIDI
  • MIDIファイル(演奏目的のやつ)

こうやってまとめると「やばい」「炎上要素しか無い」という感じですが、本文に足りない視点があったり有意義な用途を無視している点があったら、コメントなりはてぶなりSNSなりで指摘してもらえればと思います。

*1:お買い上げいただいた皆さんありがとうございます

*2:キーボード以外にもギターや管楽器などがあるんですが、話がややこしくなるのでキーボードとまとめちゃいます

*3:ハードウェア音源は数年に一度くらいごくまれに出る印象がありますが、RolandのSD-50が2010年に「8年ぶりに」出たと考えると、さすがにもう無いかな…と思います

*4:FM音源などはハードウェアのオリジナルに強くこだわるユーザーがちらほらいます

*5:昔はRS-232Cケーブルをモデムと同じ口に繋いだりしていましたが、最近は電話回線に繋ぐことも無いですね…

*6:DAWではMIDIキーボードは人間が演奏したベロシティの値を0〜127で受け取りますが、内部的にはもっと精細な数値(たとえば0〜65535とか、0.0〜1.0とか)で保存することが多いようです

*7:トラックとチャンネルは別々の概念ですが、ここではあいまいにしておきます

*8:たとえばCubaseに付属するHALionやRolandのSound Canvas VAなどがそうです

*9:わたしはPixiv FANBOXで支援しているアーティストが配布しているのをよく見かけます

技術書典9の気になった新刊リスト(その1?)

技術書典9、まだ始まっていないけどどんな本があるかはこれまでと同じくサークルチェック…ならぬ気になった本チェックができるようになっています。

techbookfest.org

というわけで、さっそく新刊を全部チェックして面白そうなものに♡を付けて回っていました。まだ未公表の本がたくさん出てくると思うので、とりあえずその1って書いときますが、その2以降はTwitterで間に合わせるかも。あと技術書典公式の生放送がいろんな本を紹介しているのでそっちも参考になるかと思います。

ホントはTwitterにでも垂れ流そうと思ったのだけど、ずいぶん数があったのでここに書くことにしますた。もともとツイーヨにするつもりで貯めていたのでコメントは短いですすんません。

techbookfest.org

技術書というかアート作品なのか? こういう新しい試み?は同人誌だとやりやすいですね

techbookfest.org

STM32の本なんだけど256ページもあるのヤバい。今まで書いてきたものをくっつけたってことかしら。

techbookfest.org

DeepComposerが入ってるやん

techbookfest.org

Vue.jsデスクトップ開発本だ。さすがにデスクトップというトピックだとこの本くらい?

techbookfest.org

C++ Aggregatesだけで50ページ語るのすげーな??と思ったけど、50ページは確かにいける人はいけそう

techbookfest.org

284ページあるのやばない?? これまで出した本のアンソロジー的な本ってことですかね。

techbookfest.org

KhronosのgITF構造の解説だけで88ページ書いてるのじっくり感ある。こういうの好き(って中身見ずに言うのはあれだけど)。

techbookfest.org

ペーパークラフトを作るためのソフトもいろいろあるんだなー

techbookfest.org

培養肉自作マニュアルやばいw

techbookfest.org

なんか同じカバーの本が2冊登録されている…?と思ったら片方はまさかの英語版だった。確かにオンラインマーケットなら英語版出せるな…うちも出すか…?

techbookfest.org

タイトルのインパクトがすごいw 自宅で出来るとかじゃなくてよかった

新刊のお知らせ2: LV2オーディオプラグイン開発ガイド

昨日に引き続き技術書典9 & M3 2020秋の新刊リリースのお知らせです。2冊目、というか書いた順としては1冊目なのですが、8月に予定として発表した「LV2オーディオプラグイン開発ガイド」です。

techbookfest.org

書籍紹介は序文からのコピペなのですが、ここにもコピペしておきます:

LV2はLinuxを中心に使われている、しかしクロスプラットフォームで利用可能な、オーディオプラグインの仕様です。

LV2はオーディオプラグインとしてはかなり多岐にわたる機能を実現しており、加えてコア部分だけでもなかなか難解な仕様であり、LV2にかかる開発はオーディオ専門職であってもなかなか手を出せない領域です。LV2についてはユーザーガイドと言えるものもなかなか無く、特に日本語情報は非常に少ないので、LV2全般について幅広くまとめたものが必要であろう、と筆者は考えました。

本書ではLV2オーディオプラグインの「使い方」と「作り方」の両方を解説します。通常、ソフトウェア開発のための書籍では「使い方」について説明する必要はないのですが、LV2オーディオプラグインの場合は、まずそもそも使いこなせるようになるところまでの情報が十分ではありません。いくつかの章をまずユーザー用ガイドとして用意し、ある程度理解が整ったところで実際の開発ガイドに進みます。

とはいっても、開発ガイドを「ガチで何でも書ける」レベルまで書ききるのは無理があったので、今回は主に膨大なLV2モジュールを適宜重要度の順くらいで並べ替えて、近いものをグループにまとめて、体系的に説明することに主眼を置いています。細かいことはコードを書く時に調べれば良いですし、まずは参考書として手元に置いてもらえればと思います。LV2開発で一番難しいのは「ガイドとなる資料がないこと」「何を読めばいいのかよくわからないこと」だと思うので。

MIDI 2.0本もこちらも、半分くらい…は盛りすぎなので3割くらい…は「ユーザー」向けの内容になっていて、プログラミングガイドっぽくないところもあるのですが、LV2をサポートするDAWに慣れている人はそうそういないと思うので*1、「使い方」から書いています。スクショがずいぶん入ってます(当社比)。自分で書いたものがそこまで親切なことは無かったので、なんだか新鮮な気持ちです。

LV2開発そのものに興味のない人(VSTとかJUCEが使えれば十分という人)にとっては、この本の内容のうち、LV2開発固有の事情(たとえばTurtleの書き方とか)が役立つことは無いでしょう。LV2は音声処理とUIをしっかり切り分けたり、Atom Sequenceというリアルタイム処理に対応した構造化データを扱えたり、メタデータインスタンス生成前に様々な情報を取得できたりする、といった部分は隣の芝生の話として参考になるかもしれません。LV2が全体的にどんな機能を有しているのか把握できるかと思います。

今回新刊2冊とも表紙は自作なのですが*2、LV2本のほうはスクショをゴニョゴニョいじっただけのものです。本文のほうでも紹介している新進気鋭のLV2をサポートしているDAWZrythmの上でFM音源エミュレーターOPNplugとCarla経由でVST2のCollectiveを動かしている絵です(あれ、よく考えたらaria2webを動かせばよかったのでは…)。

MIDI 2.0本も合わせて昨日入稿したので、問題がなければ紙版も販売できる予定です。紙があってもなくても1000円という価格設定にしてあります。同じ値段なら紙が付いてこないともったいない…!という方には紙+電子版がおすすめです(紙だけ、はありません)。わたしみたいに同人誌を置くスペースが気になってきている人には電子版オンリーがおすすめです。

*1:かくいうわたしも普段DAWをあまり使わないので同じ穴の狢なのですが

*2:いつものイラストの依頼はM3のほうでお願いしてしまったので

新刊のお知らせ(MIDI 2.0 UMPガイドブック)ほか

(8月の作業記録のつもりでまとめ始めたのですが思いのほかMIDI 2.0祭りになってしまったので新刊告知エントリとして生まれ変わりました…!)

MIDI 2.0 UMPガイドブック @ 技術書典9 / M3 2020秋

技術書典9にはサークルとして復活します! 何しろ当日スタッフとして動き回る会場がないからな…!

今回なんと新刊が2冊も出ます。1冊は(改めてエントリを書きますが)7月にはほぼ書き終えていたLV2開発者ガイドです。もう1冊は前回ちらっと言及しましたが、MIDI 2.0に関する本です…!

techbookfest.org

MIDI 2.0 UMPガイドブック」は、2020年2月に正式に公開されたMIDI 2.0仕様のうち、もっとも目を引く内容であるMIDI 2.0 UMP(ユニバーサルMIDIパケット)仕様を中心に、MIDI 2.0をサポートするデバイスやソフトウェアが提供する、あるいは実装する必要がある機能について解説する書籍です。

UMPが何なのかというと、一連のMIDI 2.0関連仕様の中で、MIDI 1.0のときに80hはノートオフ、90hはノートオン、B0はCC、F0〜F7はシステムエクスクルーシブ…といったメッセージを規定していた部分に相当する部分です。「MIDI 2.0で拡張・強化された機能」というと伝わるでしょうか。

本書は、MIDI 2.0というキーワードに関心のあるMIDIのユーザーと開発者のどちらもターゲットとしていますが、MIDI 2.0をサポートするソフトウェアは2020年8月の本書執筆時点で皆無に近いので、本書を実用できる読者はどちらかといえば開発者が多いでしょう。これまでは、MIDI 2.0について詳しく知ろうと思ったら、AMEIまたはMMAで公開されている英語の仕様書の原典にあたるしかありませんでした。本書がその状況を少し切り拓くことになればと思っています。

本書のデジタル版は2020年9月13日からオンラインで開催される技術書典9で、ペーパー版は同イベントでのオンライン販売および2020年10月25日のM3 2020秋にて販売します。サンプルページ等は技術書典9のサイトで書籍データが公開されるようになったら出てくる予定です。

なお、同イベントでは、新刊として並行して執筆した「LV2オーディオプラグイン開発者ガイド」も同時にリリースする予定です。(というか、この本自体はライブラリ開発のついでに書き始めて、LV2開発者ガイドの販促用オマケにするつもりだったのが、なぜか単独で完成してしまったやつだったり…)

本書がどのくらい有用かというと、筆者がこの執筆後に開発に着手した自作のオーディオプラグインフレームワークにLV2を統合する過程でMIDI 2.0をサポートするためのLV2拡張機能MIDI 2.0サポートのCライブラリを自作しているときに、ほとんどの場面で仕様書ではなく本書の内容だけで疑問を解決出来ているレベルです(MIDI 1.0の仕様に該当する部分は基本的に省略しています)。

lv2-midi2

MIDI 2.0 UMPまわりを調べていたのはただの趣味ではなく…いや、趣味の延長ではあるのですが…LV2拡張としてMIDI 2.0をサポートして、これを自作オーディオプラグインフレームワークMIDIメッセージング基盤として使いたいと思ったからでした。

MIDI 2.0サポートを追加するのに必要なフレームワークへの変更は(驚くべきことに)ほぼ皆無で、プラグインが任意のポートの内容種別にMIDI 2.0ストリームであることを指定するだけで足り(現状ここがホスト側ではenumになっているのですが、もしかしたらLV2みたいにURI(D)にしたほうがいいのかも)、ホストがポート情報を取得してMIDI 2.0ポートであればvoid*のバッファにUMPバッファを流すだけなのですが、実際にそれらを処理するLV2とJUCEのブリッジでは実装が必要になります。

というわけで、まずLV2サポートを作っています。LV2にはもちろん標準でMIDI 1.0のサポートがあるのですが、MIDI 2.0のUMPは(上記書籍でも解説しているのですが)MIDI 1.0とは根本的に構造が違うので、ざっくりとLV2拡張のかたちが似ているだけです。

github.com

あと多分MIDI入力ポートが複数並立しているとややこしくなるので(LV2では基本的にすべてのポートがconnect_port()で繋がっていないといけない/複数ポートで競合するようなストリームの処理が未定義動作にならざるを得ない)、UMP対応プラグインでは基本的にポートは1つ、内容種別はextension_data()でホストとの合意に基づいて決定する、というMIDI-CI的なやり方にしました。(MIDI 2.0ではMIDI 1.0プロトコルMIDI 2.0プロトコルを排他的に選択し、MIDI 1.0のメッセージはMIDI 2.0プロトコルでは送信できないようになっています。逆も同様。)

現時点では自作プラグインフレームワークのほうでMIDI 1.0サポートを切り捨てておらず、MIDI 1.0のストリームがMIDI 2.0前提のプラグインに流れ込んでくることが想定されるので、バイトストリームをUMPに変換する作業が必要になります。むしろ一般的にはプラグインがUMPをサポートしていないためUMPをMIDI 1.0のストリームに変換して送信する処理が必要になります。これは実装したのですがまだUMPを送ってくるホストは無い状態です(まあホストも自作しているというか自分のフレームワークではホストはAndroidサービスの受け口なのですぐ作れるわけですが)。

JUCEのほうはLV2が出来たら着手しようかなと思っていますが、そもそも今コーディング作業を勧めているべき段階ではないはずなので(!)、M3 2020秋が終わる10月末までは着手も未定です。上記書籍の肥やしにはもうならなくなっていますし。

cmidi2: allocation-free, header-only MIDI 2.0 UMP library

LV2でUMPサポートを実装するためには、当然UMPを操作するためのライブラリが必要になります。しかし、8月時点では何一つ発見できませんでした。Xcode 12にCoreMIDIでUMPをサポートするAPIがいくつか生えましたが、こっちとしては当然ながらどのプラットフォームでも使える必要がありますし、それは現時点でも皆無です。

lv2-midi2サポートを実装するにあたっては、LV2 AtomのようなAPIが必要になります。LV2はVST3SDKなどとは異なり軽量なheader onlyなCライブラリの集合体で、LV2 AtomAPIもすべての関数がstatic inlineで定義されています。LV2 Atomはオーディオ処理の中で解析・生成されるので、当然ながらメモリアロケーションも許されません。すべて事前に用意されたバッファで処理します。

そういうわけで、まずはLV2 Atomと同様の構成でUMPを操作するためのライブラリを作りました。それがcmidi2です。

github.com

UMPはuint32_tuint64_tuint128_t…という標準型は存在しないのでまあuint64_t * 2ですね*1…で表現できるので、自然とアロケーションフリーで扱いやすい構造です。単なるバッファ処理でしかないので自然とクロスプラットフォームです*2。基本1日で作ったやつですし(ちょくちょく手を加えているので今は500行を超えちゃいましたが)。

名前はさすがにシンプルにmidi-2.0とするわけにもいかないので雑にCを付けました…。おそらく類似のMIDI 2.0 APIを既存のktmidiにも生やすことになると思います。managed-midiには…MicrosoftLinuxデスクトップ開発者をきちんとリスペクトしてLinux向けにVS for Linuxを出すなりかつて存在したMonoDevelopなどをまた使えるようにしたら、やるかもしれません。

lv2-midi2のために作ったライブラリですが、汎用的に使えるはずなので、MIDI 2.0に興味のあるCプログラマーは取り込んでみてください。なおheader onlyなのでCライブラリであってもdlopen()・dlsym()を前提とするFFIにはほぼ向いていません。

ayumi-lv2

7月に作っていたPSG音源AY-3-8910のエミュレーターayumiをLV2で使うためのプラグインayumi-lv2ですが、まともに発音出来るようにMIDIメッセージからのAPI呼び出しを調整できたので、最大3音ですが音が出るようになっています。

本当はこれをlv2vst経由でVST2をサポートしているDAW(Tracktionなど)から使いたいのですが、手元の環境でlv2vstがクラッシュするようになっていてまだ試せていません。調べるよりJUCEプラグインとして作り直したほうが早そう…しかし今やり始めるとまずい…!

ayumi自体はもとのハードウェアのレジスタ類をエミュレートしている音源であって、MIDIノートではなく周波数を設定するかたちになっているので、MIDI 2.0におけるpitch 7.9(前回書いたやつ)も問題なく計算して渡せるでしょう。ホスト側が調整できたらこの辺から動作確認も含めてサンプルとして作り込んでみようと思っています。(しかし今やり始めるとry)

*1:calccrypto/uint128_tなどを使う手もありますがこれはheader onlyではないので…

*2:特定のendiannessにも依存しないようになっているはず…

MIDI 2.0 UMPにおけるノートオン命令について

正式なリリースについてはまだ白紙状態なのですが、いまMIDI 2.0 UMP (Universal MIDI Packet、雑にいえば新しいMIDIメッセージのフォーマット)に関する調べ物をしていたらだんだん同人誌化できそうな感じになってきたので、そのうちまとめて出そうと思っています。既に技術書典9およびM3 2020秋でのリリースを公開しているLV2開発者ガイドと併せて楽しめる読み物にできればと思っています。

とはいえWebにも調査内容をフツーに公開したいので、どんな内容の本になるかという紹介も兼ねて、昨日まとめていたノートオン・ノートオフ命令に関する説明の部分をまるっと公開します。まだドラフトなので最終版は変わるかもしれません。図も今回は仕様書のコピペです。そもそもUMPとは何なのか、MIDI 2.0とは何なのか、みたいな話が無いので読みにくいかもしれませんがそこはご容赦あれ…


ノートオン・ノートオフ命令は、MIDI 1.0のものから何点か機能追加されています。まずはメッセージ構造を見てみましょう。

f:id:atsushieno:20200824151743p:plain
MIDI 2.0ノートオンメッセージのパケット(UMP仕様書より)

note numberの次にattribute typeという見慣れないフィールドがあります。その次はvelocityですが、これはMIDI 1.0の7ビットから16ビットに拡大されています。そして残り16ビットにattribute dataというフィールドが追加されています。

ノートの属性

MIDI 2.0のノート命令で新しいのがこの属性(attribute)です。ノートオン・ノートオフの時点でそのノートにひとつプロパティ値のようなものを指定できます。属性の種類は現時点での仕様では次の3種類のみです。

属性種別 定義
0 なし 値も0が想定されています
1 製造者固有 バイスの製造者(Manufacturer)が意味を定義します
2 プロファイル固有 MIDI-CIプロファイルの策定者が意味を定義します
3 Pitch 7.9 1セント未満の微分音を設定します

製造者固有あるいはプロファイル固有の情報として使うと、いわゆるアーティキュレーションの機能を実現できます。その具体的な効果はMIDIバイスのプログラム(音色)しだいです。MIDI-CIプロファイルは現在具体的な仕様が何一つ存在しないので、現状では無視してよいでしょう。

ピッチ補正

Pitch 7.9というのは、アーティキュレーションとは全く異なる用途になります。これは1セントすなわちMIDIノートの値でいえば1.0(半音階)より小さい値を固定小数点で指定するものです。7.9というのは、整数部分を7ビット、小数部分を9ビットで表現する型であることを意味しています。

MIDI 1.0の時代でも、ピッチ補正を設定できるMIDI音源は存在しました。MMAもMTS(MIDI Tuning Standard)と呼ばれる仕様を策定しており、このシステムエクスクルーシブメッセージを使うとノート別のチューニングを変更できました。

またノート別RPNの3番にはPitch 7.25というより固定小数点精度の高いデータを設定できます。

そして、MIDI 1.0の時代からあるピッチベンドも存在します。ピッチベンドの値の効果は、RPNの0番で規定されているピッチベンド・センシティビティ(感度)の値によって、2セントから24セントまで変わります。MIDI 2.0ではピッチベンドもノート別に指定できるようになっています。

最後に、MIDI 1.0の頃から、RPNの1番と2番にはマスターチューニングというパラメーターが存在します。すべてのノートオンに適用されるピッチ補正です。

ノートのピッチを決定するのに、一体いくつの変数を考慮しなければならないのでしょうか?? MIDI 2.0仕様では、次の任意の組み合わせによって決まる、という説明を加えています。

  • MIDI 1.0と同様のデフォルトピッチ: ノートオンのノート番号
  • ノートオンに継続的に適用されるピッチ補正: MTS, ノート別RPNの3番
  • ノートオンに1度だけ適用されるピッチ補正: ノートオンのPitch 7.9
  • 以上に対して追加で加えられるピッチ補正: マスターチューニング、ノート別ピッチベンド、(チャンネルの)ピッチベンド

もし読者にサンプラーなどを実装する機会があったら、どこかに実装の抜け落ちている部分がないか確認してみましょう。

また、ユーザー(クリエイター)の視点で考えると、これらには他にも利用上の特性の違いがあることがわかります。たとえばPitch 7.9でノートとピッチを指定できるのはノートオンのタイミングのみです。そのノートに対して後からピッチ補正をかけたい場合はノート別ピッチベンド(あるいはピッチベンド)を使うしかありません。

MTSとPitch 7.9の具体的な用途・使い分け

属性種別3を選択した場合、実際に発音される音階はPtch 7.9の7ビット整数部分が示すことになります。このメッセージのnote部分にはそれでは何の意味が残るのかというと、ノートオフやノート別コントロールの対象を示すインデックスとして機能します。そうしないと、同じノート番号で別のPitch 7.9で発音したり、別のノート番号から同じPitch 7.9で消音したりといった謎の状態が生じて混乱することになるでしょう。

そもそもなぜPitch 7.9のような整数値を含むノート構造が必要になるのでしょうか? ファインチューニングしたいだけであれば、小数だけで足りるはずではないでしょうか? …その答えは微分音という音楽表現にあります。

一般的な微分音について説明する前に、もう少し簡単な用例を紹介します。それは純正律と呼ばれるチューニング標準です。

われわれが学校教育等で教わる一般的な音楽理論は12平均律と呼ばれる音階・周波数の配置に基づいています。12平均律の配置は、さまざまなコード(和音)を一定の美しさで聴くことが出来るように最適化された配置です(和音の響きの美しさは各音階がどれだけ離れているか、きれいな比率で倍数になっているか、といった要因で決まります)。

実は、かつては*1純正律と呼ばれる周波数配置に基づいて12音階が定められていました。枝葉末節になるので定義はここでは省略しますが、これは主音が固定された和音を鳴らすとより美しく響き、転調すると美しくないとされています。

作曲家によっては、この純正律をあえて好んで使うので、せっかく機械的に周波数を補正できるのであればそう出来るようにすべき、と考えるのは自然なことでしょう。これがMTSの存在する理由の一つです。もっとも、純正律をサポートするだけであれば、チューニングに整数部分は必要ありません。1セント未満の小さな単位で周波数が補正できれば十分であるはずです。

さて、世の中にはさらに変わった音楽を求めて、12平均律ではないオクターブの分割を探求する人たちがいます。そこでは1オクターブを24分割したり、31分割したり、53分割したりといった実験が行われます。これが微分音(microtonal)といわれるものです。この微分音をDAWMIDIの(互換の)データに基づいて表現しようと思うと、チューニングが小数だけでは足りないのです。1オクターブが24ノートによって成立するとしたら、12ノート目は半オクターブ分しか進んでいないのです。

微分音クリエイターは、表現できるノートの音域を犠牲にしてノートに周波数を割り当てます。この時に使われるのがMTSでした。また、周波数マッピングを任意の数値で可能にするために、Scalaと呼ばれるデータを用いることがあります*2

MIDI 1.0でもMTSで微分音作曲ができていたのであれば、Pitch 7.9は微分音作曲に有意な機能追加となるのでしょうか? その答えは、ピッチ補正は必ずしもコード理論に基づいてノートに対して固定された周波数を適用しなくても使いたい場合がありうる、ということです。MTSやノート別RPNを前提にすると、楽曲の特定箇所の特定のノートだけワンタイムで少しピッチを上下させたい、といった入力は面倒になります。ノート別ピッチを適用することも可能ですが、ピッチベンドは別の目的で使っている可能性もあります。ノートオンに付随して調整できるほうが自然に打ち込めるのです。

アーティキュレーションとノート別コントローラー・NRPNの使い分け

独自の音源ソフトウェアなどを開発している読者であれば、Pitch 7.9ではなく独自のアーティキュレーションとして、何かしらのパラメーターをサポートしたいと読者は考えるかもしれません。しかしひとつ注意してもらいたいのは、属性の値はノートオンのタイミングでしか指定できないということです。現在のMIDI 2.0 UMP仕様では、いったんノートオンを送信した後でそのアーティキュレーションを変更することはできません。

もしパラメーターがノートオンの後でも変更できるようなものにしたい場合は、ノートオンの属性ではなく、ノート別コントローラーやノート別NRPNを活用するとよいでしょう。たとえば歌唱合成ソフトウェアでブレシネス(息の強さ)やオープンネス(口の開き方)などはしばしばアーティキュレーションの類型として説明されますが、もしMIDI 2.0のパラメーターとして実装するのであれば*3、機能によってはノート別コントローラーにしておくほうが無難かもしれません。

ノート別アーティキュレーションはたかだか1つしか指定できない点も注意すべきでしょう。ノート別コントローラーであればいくつでも指定可能です。

ベロシティ0の扱い

MIDI 1.0では、ノートオフメッセージをベロシティ0のノートオンメッセージで代替することが仕様上認められていました。これはMIDI 2.0のノートオンではもはや認められていません。MIDI 2.0でベロシティ0のノートオンメッセージをMIDI 1.0に変換する場合は、ベロシティを1にすべきである、と仕様上明記されています。

逆にMIDI 1.0のノートオンメッセージでベロシティ0のものをMIDI 2.0メッセージに変換する場合については明記されていません。これはノートオフメッセージとして変換することが意図されているのかどうか、対象デバイスを限定しているかどうか等の各種状況に依存するからであろうと筆者は考えています。

MIDIメッセージをサポートするオーディオプラグイン規格によっては、このMIDI 2.0の制約を先んじて規定していたものがあります。Linuxデスクトップで使われているLV2仕様などがそうです。

*1:Wikipediaの記述では、純正律の期限は2世紀に遡るとなっています。平均律は16〜17世紀です。

*2:プログラミング言語Scalaとは全くの別物です。

*3:ここではリアルタイムで歌唱合成できる世界に住んでいると仮定します。

7月の作業記録

ひさしぶりに半ば自分用メモであるところの作業記録を書くわけですが、ここ1ヶ月強の成果を振り返ると、びっくりするくらい何もない…! どうしてこうなった…?と冷静に振り返ってみると、(6月にも書いたのですが)自分のメイン開発マシンであったところのHP Spectre x360のキーボードとタッチパッドが使えなくなる故障がひどくて、先月修理から返ってきてから今度は4回目の修理に出しています。修理から返ってくると正常動作するのに、1週間かそこらでまたすぐ反応しなくなる…の繰り返しで、これが半年弱前からずっと続いているせいで生産性ガタ落ちだったわけですね。(最初の頃はFF7Rとかいろいろゲームで時間をつぶししていたのですが、さすがに飽きました…)

MSI Prestige 15に乗り換え

そんなわけで、さすがにこれ以上泥沼の状態でHP製品を使い続けるのは無理…ということで、否応なく新しいPC環境にしました。今はノートPCだけ持ってふらふら旅に出ながら作業する状況にもならないので、多少重くてもいいだろうと思ってMSIのゲーミング…とはいえなさそうな15.6インチノートPCです。

それでWindowsパーティションは極小化して(完全に消すとメインマシン引退した後でWindowsマシンにするときに入れ直しが面倒なので残します)、Ubuntu 20.04を入れて使っているのですが、今のところトラブルとは完全に無縁で、こんなに安定しているのか…となっています。ただ海外のフォーラムでは指紋認証が使えないみたいな報告もあったので、自分が使っていなくてハマっていないだけ、という可能性はあります。

HP Spectreで使っていたときはOSのアップグレードまわりでおかしくなっていたのか、jackdが使えなくなっていたのですが、MSI環境の方では問題なく動いています。この辺はLinux kernel 5.40.xあたりでいろいろ変更が加えられている部分で、ちょいちょいリグレッションが修正されたりしていたので(わたしもバグレポートしていたのでlaunchpadから「おれもおれも」みたいなコメントをちょいちょい受け取りました)、どうしても困ったらクリーンインストールすると解決する問題かもしれません。

せっかくニューマシンしかも重量級(?)のやつに乗り換えるというので、32GB RAMにしたので、Android Studio 4.2 Canaryのインスタンスが3つくらい立ち上がっても問題なく動作しています。これはMacでは生じない問題なのですが、LinuxではAndroid Studioインスタンスを複数起動できるので(クライアント/サービスの開発ではそのほうが嬉しい)、その分メモリ消費も大きくて困っていました。

一方でタッチスクリーンでなくなったのは、明らかにAndroid UIのテスト体験体験が悪化しているので、本当に改善したくなったらAirBarでも付けてみようかな…とか考えています。あとhome/endが無い(fn必須の)キーボードのレイアウトが完全に好みではないのもしんどいですね(これはHPがベストだと思っている)。とはいえPageUp/PageDownが独立しているだけ他の数多のベンダーよりはずっと良いです。あとバッテリーが弱くなって重量も1.3倍くらいになったのですが(これはHP Spectreが良すぎたという話もある)、冒頭にも書いたとおり持ち歩く機会も減っていますしね。次に買い換える頃にはコロナも収束していてほしいところです(フラグ…?)。

COSCUP 2020のセッション

8/2にリモートでやってきました。スライドはspeakerdeckにおいてあります。

speakerdeck.com

上記のようにメイン作業環境が破滅的な状況だったので、音楽作業用のMacでも最低限の開発ができるようにコードを整理しつつ、リモートセッションが可能になるように環境を構築したりしていました。blackholeでオーディオルーティングしたり、OBS Virtual Cameraをセットアップしたり…(ちょうどこれが可能になった頃に始めたのでラッキーでした)。

配信のやり方がわかってきたので、そのうちオンライン勉強会を開催しても良いかもしれないですね。

スライドの準備とマシントラブルへの対応のせいで、開発そのものはすっかり停滞してしまいました。(Macでできるのはせいぜい既存コードのメンテナンス程度だったので…)

「LV2オーディオプラグイン開発者ガイド」限定公開と査読のおねがい

6月くらいからちょいちょい作業を始めていたのですが、M3 2020秋とたぶん技術書典9に新刊を出すことにしました(技術書典9は参加未確定なので予定)。先日80ページくらいの初稿をすべて書き終えたところです。わたしは締切がなくても執筆作業を始められる人種なんだ…(!)

内容はLinuxデスクトップで普及している(と今なら言えそうな)Lv2オーディオプラグインに関する包括的な開発本です。開発本ですが、たぶん誰もがLV2の「使い方」のレベルで躓くと思うので、そこからケアしています。最新のオーディオプラグイン開発のトレンドなども言及しつつ(たとえばリアルタイムマルチスレッディングの話題とか)、公式のLV2 Bookよりは読み物っぽく書いているところがあります。あと公式のリファレンスは書いてる人も認めているくらい読みにくいので、この本くらいの粒度の解説本が有用だと思っています。

個人的には仕様書をじっくり眺めているうちに不備を見つけてLV2仕様にコントリビュートするというところまでは読んだので、一応それなりにきちんと掘り下げたと思っています(…!?)

これは毎回悩むところなのですが、今回もリポジトリを全部公開にするかどうかしばらく考えました。LV2は情報源が少ないので(情報源の多い原稿をかいたことがあっただろうか…?)、公開しておいたほうが世のためだという気持ちはあるのですが、今回はいちおう紙版を印刷して同人印刷所に生き延びてほしいという気持ちがあるので、昨年のシーケンサーエンジン本と同様、紙版が捌けて一定期間を経るまでは公開しない従来型のモデルで頒布することにしました。サンプル章のフリー公開などである程度公共に資することにしようと思います。

ただ、一方で事前に興味のある人に(もしいたら)読んでもらって何かおかしいことなどがあったら紙に刷る前に指摘をいただいたほうが生産的なので、今は期間限定で公開してあります。もし何かヘンだなと思うようなことがあったらぜひgithub issueで教えてください。9月には非公開に戻すと思いますが、参加いただいた方には引き続きアクセスしていただけるようにします。

https://github.com/atsushieno/lv2-developers-guide/github.com

ちなみにシーケンサーエンジン本はごくたまにTwitterとかに出すたびに数冊売れるので(宣伝だらけになると自分でもうざいのでかなり絞っています)、紙版はそのうちなくなると思います…なくなるといいなあ。

xamaritans.booth.pm

OPNplug(JUCE)とayumi(-lv2)のAndroid

7月にはJUCEが6.0になってLinux VST3も使えるようになったので、これはtracktion_engineもアップグレードすればホストもいける…!ということで去年作っていたaugeneをアップグレードしてVST3でJUCE音源をまたいじるようになりました。

それで、デスクトップで使えてAndroidにも移植できて自分でもそれなりに使えそうな音源ということで、とりあえずADLplugに含まれるOPNplugをAndroidプラグイン化しました(OPNなら自作音色のストックがいくつかあるのです)。ただ音色バンクのフォーマットがよくわからないものなので、MMLで書いていたようなのを直接書けるようにならんもんか…と思っていたらOPN2BankEditorというアプリで変換できることが分かったので、ちょっとだけ開発に協力したりしていました。

それから気づいたのですが、FM音源はOPNplugで再現できたとしても、OPNplugにはSSG音源に相当するものが存在しません。OPNが含まれていたYM-2203にはAY-3-8910というSSG音源が載っていたのですが、これを再現するプラグインが見当たらないのです(少なくともLinuxで動作できるようなものは)。

エミュレーターはいくつかあったので、とりあえず簡単そうなayumiというエミュレーターをベースにayumi-lv2というLV2プラグインを作ってみたのですが、SSG音源にどんな生パラメーターを与えればいいのかまだよくわかっていないのでちゃんとした音が出るかはまだ確認していません(音は出ますが)。サンプル作っておいてほしみ…! LV2プラグインの作りはsfizzなどを参考にしつつシンプルなMIDIトランスレーターにしたので、LV2プラグインのリファレンスコードとしても悪くないと思います…音が意図通りに出ていることさえわかれば(!)

自作LV2プラグインAndroid移植は死ぬほど簡単でした(LV2ヘッダファイルの参照だけ面倒ですが、これはaap-lv2の他のプロジェクトの使い回しで十分なので)。ホストとプラグインを別々にデバッグできるのも状況次第では便利です。HPマシンで開発していたときはjackd依存のホストが全滅でAndroidでしかデバッグできませんでしたし(!?)。

sfizzのAndroid assets対応(進行中)

最近手を出して泥沼化しているのがsfizzのsfzファイルをローカルファイルではなくassetからロードできるようにする変更なのですが、割としんどいやつで今も実のところホントに続けるのかどうかわからないレベルです。sfizz単体ならまだ何とかなるかもしれないのですが、libsndfileにも手を加えてassetをロードできるようにするとなると途端に煩雑になるので…(そもそもlibsndfileはaap-lv2ではビルドしないバイナリ参照だし)。

これに拘っているといつまでも先に進めないので、たぶんwebから落としたやつをローカルファイルでロードするようになると思います。ただこれもAndroid11からはかなりしんどいので、進むも戻るも地獄みたいな感じです。まあ何とかなると思いたい…(?)

8月の予定

8月は、当初の予定ではLV2本の執筆に費やされる予定だったのですが、だいたい終わってしまったので、M3に向けて創作環境を再整備しようと思います。いいかげんMMLコンパイラMIDI仮想キーボードを作り変えないと…。そんなわけでオーディオプラグインからは離れそうな気がします。まあそう言いながら今週もほとんどsfizzのコードをいじって時間が溶けていたりしますが…! ではまた来月(?)

6月の作業記録

このシリーズのタイトル使うのひさしぶりなんですが、先月書いたaria2webも実質的に作業記録みたいなものなんで、掘り起こして復活させた、みたいな感じではありません…。

6月の、と書き出してしまいましたが、前回からの差分だけにしておきます。3週間くらい?

designing Audio Plugin Framework for Android @ COSCUP 2020

台湾の大規模コミュニティカンファレンスCOSCUPで2年ぶりにしゃべることにしました。内容は今開発しているAndroid向けオーディオプラグインフレームワークの設計アプローチについて、ということになります。7月はその準備作業に着手する予定です。

2018年もlanguage server protocolについてのセッションで、かなり.NET色を排除した内容だったのですが(それまではMonoDevelop -> Monoランタイム -> .NET Coreだった)、今回は完全に過去を切り捨ててオーディオの話をします。どっちも単独で引っ張るとまあまあ素人なのですが、複合領域だからな…!

AndroidiOSもなのですが、モバイルOSは実行可能なコードの制約が強く、プロセス分離から逃げられないので、それを踏まえたオーディオプラグイン機構が必要になります(この話題ここではしょっちゅう出してますが)。オーディオはリアルタイム処理も考慮しないといけないので無理ゲーなのでは…!?となってしまいますが、Android 8.1で「Realtime IPC Binderが実装された<折返し>か!?」みたいな状況になっていたりする…など無駄に深入りした話などを交えつつ、基本的にはどういう設計が求められるかという上澄みの話をする予定です。

プラグインUIの仕組みなども実装しておきたいのですが、時間的に厳しそう…(30分しかないし)。実装基盤もガタガタなので、おそらくその辺を強化して終わりでしょう。

ちなみに台湾のカンファレンスのスピーカーといっても、それだけで業務出張になるわけではないので、渡航資格が発生するわけではありません。そんなわけで日本からのオンラインセッションとなる予定です。準備というのはだいたいそっちの練習という感じです。やってみないとわからないですしね。基本的には会場のネットワークに繋いでビデオ通話するだけなのですが、もしかしたら日本からでも見えるようになるかもしれません。現状何もわかっていません。

aap-sfizz

今月の上旬に書きましたが、ARIAのUIをWebViewで表示できるようになって、sfizzとも組み合わせてオーディオプラグインとして使えるようになったので、今度はこれをAndroidで動かそうと思ったわけですが、LV2プラグインの移植はmda-lv2しか実績がなく、その土台を整備する作業が必要になりました。JUCEのプラグインならほぼProjucerのプロジェクトがあるわけですが、LV2プラグインはプロジェクトによる感じです。

sfizzはCMakeのプロジェクトなので、プロジェクトファイルを取り込むという意味では難易度がやや低いのですが、Android用のLV2開発ライブラリをパッケージとして参照解決できる状態にはなっていません。理想を言えば、aarを参照に追加するだけで解決したいところです。

この目的ではAndroid Studio 4.0に新規追加されたPrefabフォーマットのサポート(4月に書いたやつ)が解決することが期待されたのですが、全くうまくいく様子がなく、AGPのソースを追っかけてもそもそもprefabツールがセットアップされる様子もなく、Prefabパッケージの妥当性を検証する機構が全く無いので(こっちはLV2で使われているwafのビルド結果を手作業でバンドルするしかない)、まだまともに動作させるのは無理だという結論になりました。この辺の機能は今のAndroid NDKのプロジェクトリーダーが仕切っているっぽいのですが、どうも中途半端な機能を無理やりリリースにねじ込んでいる感が否めません…

ともあれ、Prefabは使えないので、これまで通りwafとcerberoのビルド結果をaarに取り込みつつ、参照側でもPkgConfigのパスなどをよろしく解決できるhackに頼るという方向性で、sfizzのCMakeLists.txtにパッチを当ててなんとかビルドしました。

sfizzはそれでビルドまではできたのですが、実際にsfzファイルをロードするところまではまだ実現できていません。それほど難しくはないはずなのですが、続く2つのタスクが先だと判断して先送りしています。

aap-lv2モジュールの切り離しとmda-lv2の再構成

sfizzの移植は、当初は独立リポジトリで行っていたのですが、LV2プラグイン移植の依存関係にフレームワーク本体を追加しないといけない状態はしんどいなあ…と考えていました。

また一方で、そもそもプラグインフレームワーク自体にLV2は必須のものではありません。LV2依存部分がビルドの難易度を爆上げしていた側面はあります。(これは実際にはそこまで大したことはなく、当初lv2リポジトリのサンプルプラグインまでビルドしていた関係でlibsndfileやcairoまでビルドしていたことが原因なのですが、それらを除外してもmda-lv2ではlibsndfileが必須でした。)

mda-lv2はもともとLV2プラグインをビルドする際に必須ではないですし、これだけはGPLv3なのでビルドから切り離しておきたかったこともあって、LV2まわりのビルドを根本的に見直すことにしました。最終的には、aap-lv2というリポジトリが誕生し、プラグイン本体はaap-juceを切り離した時のようにスッキリしました。

いったんLV2依存部分を切り離すと、ここにLV2プラグインの移植を放り込むことでビルドスクリプトの負担がかなり下がったので、sfizz移植はここに追加しました。mda-lv2はLV2サポートのリファレンス実装としてモジュールを再整備されています。

いずれprefabが安定的に使えるようになってaarがMaven経由で使える程度に安定化してきたら、単独の移植プロジェクトでフレームワークを参照するのも平易になるでしょう。(aap-lv2リポジトリ自体はLV2バックエンドの開発とdogfoodingのために現状のままが良いですが。)

Guitarixの移植

前述の4月のエントリーでも言及したのですが、sfizzでインストゥルメントプラグインを実現して、Guitarixで実用的なエフェクターを取り入れることができれば(といってもどれだけ実践的なのかは正直サンプル以上のことはわかりませんが)、とりあえず「波形合成のおもちゃ」以上の、まともな音源で作られた楽曲を再生できる期待値は上がります。

そういうわけでいよいよGuitarixを取り込むことにしたのですが、Guitarixもwafを使ってビルドするので、LV2モジュールをAndroidようにビルドする仕組みを再利用できるようにすることにしました。今後LV2プラグインを誰でも移植できるようにするためには、自分で道を作っておかないといけないわけです。

ビルドスクリプトそのものは再利用がそれほど難しいわけではないはずだったのですが、LV2リポジトリのビルドはautowaf、Guitarixは手書きのwafなので(wafはpythonスクリプトなので何でも書けてしまう)、再利用できる部品だけ再利用しました。同じことを移植作業では毎回気にしないといけないことでしょう…

Guitarixの最難関はハードな依存関係です。glibmm、その依存関係にあるlibsigc++、glibなどが基本にあって、さらにlibsndfile, fftw3, eigen、zita-convolver, zita-resamplerといったものをすべてCerberoでビルドできるようにしました(zita-*は必要なかったので無駄足になってしまいましたが…)。

ネイティブライブラリのビルドシステムのオーバーホールの一環として、Cerberoを置き換えることも検討したのですが(何しろこれはGStreamerのためにしかメンテされないので)、Prefab・ndkportsは前述の通り未熟すぎ、vcpkgはLinuxサポートですら建前でしかなく、パッケージのビルドスクリプトWindows対応のことしか考えていないというのがザラだったので(vcpkgがLinuxで使われるようになる日は一生来ないだろうと思いました)、引き続きCerberoを使っています。

ビルドできたGuitarixは、Androidプロジェクトに取り込むにあたってディレクトリ構成を差し替えないといけないのですが(何しろlib/lv2/GxHogehoge.lv2みたいなディレクトリからターゲットアーキテクチャ向けでもない.soファイルをロードすることはできないので)、それらを自動的に再配置するMakefileスクリプトもaap-lv2で追加されています。誰でも(特に「将来の自分」)同じ手順を追えば任意のプラグインを移植できるようにする、というのが重要です。

ともあれ、Guitarixも無事移植できました。数十種類のエフェクトが利用可能なプラグインのリストに追加されるのを見るとアガりますね。

f:id:atsushieno:20200629230048p:plain
guitarix on Android

Mac環境用ビルド

この3ヶ月くらいメイン開発機のHP Spectre x360のキーボードの故障がひどく、キーが入力できなくなってHPに修理依頼しても、帰ってきてしばらくするとまたキーが入力できなくなる…というのを繰り返していて(実のところ今も修理中)、完全に生産性が下がっていて困っています。

さすがにこのままではまずいと思って、打ち込みマスタリング用のMac環境でも何とかこの辺のリポジトリの開発が継続できるようにビルドを整備しました。GitHub ActionsでMacビルドが通るくらいまではきちんとやってあります…あったのですが、GitHub ActionsはAndroid開発環境のアップデートがまともに行われずAndroid API Level 30がいつまでも入ってこなかったので、CIは放置状態でした。モバイル開発で最前線を走るならGitHub Actionsはやめておいたほうがいいのかも…

ちなみにWindowsでもビルドできました。ただしmakeをWSL環境で走らせてからWindowsAndroid Studioで開いて開発を進める必要があります(ASはWSL2でも動くかもしれない)。GitHub Actions上でWSLのbashを呼び出す方法がわからないので、CIは通さないでしょう。

Next Steps:UI統合

Guitarixの個別のプラグインにはまだ謎のクラッシュを起こすものがあるのですが(要個別調査)、多くが何やら動作はできているっぽいので、「DAWあるいはそれに類するシーケンサーで音楽を演奏できる」状態にするために必要な作業は、インストゥルメント(sfizz)まわりの整備とシーケンサーの整備という感じになりました。

プラグインフレームワーク自体にもLV2バックエンドにもまだまだやることはいっぱいあるので、音楽が演奏できるようになっただけでは完結しないのですが、当面の目標はその辺りです。

aria2webはsfizzをKontaktみたいな商用製品っぽく見せるように構成するのとWeb UIを実現するのが目的でしたが、そのUI統合モデルはそのままこのプラグインフレームワークにも敷衍できます。というドキュメントを先日まとめていたので、この辺に着手しつつ、プレゼンテーションの準備をすることになるでしょう。

シーケンサーはtracktion_engineを使い回せれば十分だと思っています。tracktion_engineがAndroidで期待通りに完全動作するかは不明ですが、juce_emscriptenでもStepSequencerDemoが動いているのでまあ大丈夫ではなかろうか…

tracktion_engineはエディタを伴わず、デスクトップ環境で作成した楽曲データはそのままでは再生できないので、プラグイン情報などを適宜マッピングして再生することになるでしょう。楽曲はMIDIファイルからインポートできるので(デスクトップ向けには実績があります)、Android上でも再生できるような楽曲は作成可能であると踏んでいます。sfizzベースのインストゥルメントであれば、複雑な命令を伴わないので十分に可能でしょう。