Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin Multiplatformで MIDI 1.0/2.0 ライブラリを作っている話

Atsushi Eno
December 20, 2023

Kotlin Multiplatformで MIDI 1.0/2.0 ライブラリを作っている話

Atsushi Eno

December 20, 2023
Tweet

More Decks by Atsushi Eno

Other Decks in Technology

Transcript

  1. atsushieno/ktmidi (on GitHub) MIDI (musical instrument digital interface) を扱うKotlin Multiplatformライブラリ

    - MidiAccess : プラットフォーム別のMIDIデバイスにアクセス - Midi1Music, Midi2Music : SMF (MIDIファイル) 1.0 / 2.0もどき を読み書き - Midi1Player, Midi2Player : SMF 1.0 / 2.0もどき を演奏 - MIDI 2.0対応機能 - UMP、MIDI-CI(開発中)など MIDI 2.0サポートが特長 そもそもKotlinでMIDIを扱うライブラリが他に存在しない
  2. Kotlin for music apps? 音楽アプリの音声処理にはリアルタイム処理が重要 - no GC pause, no

    locks, no (blocking) syscalls, no unbounded computation ... 音楽制作アプリをKotlinのようなGCやJITありきの言語で作るべきではない  (so as JavaScript, Java, C#, Python, Go, Ruby...)  Swiftも現状では非推奨 - Is Swift really not performant enough for realtime audio? 実際にはオーディオスレッドのコードだけ非GC言語で動かせばOK 例: Bitwig Studio (Java)
  3. Platform MIDI Access API (C/C++/ObjC|Swift) MIDIデバイス: USB, BLE, その他(ソフトウェアMIDIデバイス、RTPなど) MIDIデバイスアクセスはプラットフォーム固有

    - WinMM / UWP MIDI API - CoreMIDI - ALSA - Web MIDI API - Android MIDI API (Java), Android Native MIDI API (C) クロスプラットフォームMIDIライブラリ - rtmidi, portmidi, libremidi (MIDI 2.0対応), ...
  4. MidiAccess: MIDI APIs on Kotlin Multiplatform (KMPの"Multiplatform"はWin/Mac/Linux/...ではない) - Kotlin/JVM: javax.sound.midi

    or JNIで前記C/C++ APIにアクセス - Android: android.media.midi - Kotlin/Native: cinteropで前記C/C++ APIのバインディングを生成 - Kotlin/JS: Web MIDI APIとnode.js用のMIDIライブラリをnpmで参照 - JAZZ-SOFT/JZZ: クロスプラットフォーム MIDIアクセスライブラリ - たぶんKotlin/Wasmもこれになる
  5. Kotlin/JVM実装 - JvmMidiAccess : javax.sound.midi (非推奨) - Java MIDI APIは仮想MIDIデバイスを作成できない

    - Linuxでソフトシンセ等を使えない (alsa-sequencerではなくalsa-rawmidiを使っているため) - このせいでBitwig Studioなどはtimidity, fluidsynth,vmpk等を認識しない - RtMidiAccess : RtMidiバインディング - Win / Mac / Linux, 仮想MIDIデバイス作成も可能 (Windows以外) - AlsaMidiAccess : ALSAバインディング - Linux Kernel 6.5以降ではMIDI 2.0仮想デバイス作成も可能 (CoreMIDI JVMサポートもほしいけどup to dateなものが存在しない…)
  6. Kotlin/JVMに向いているJNIバインディング機構は? JNA + JNAerator 󰢏 native glue codeの生成が不要 󰢄 JNAeratorはメンテされておらず

    arm64未対応 JavaCPP 󰢏 現役 󰢄 native glue codeの自動生成が必要   = Mavenパッケージがplatform / ABIごとに必要 󰢄 gradle-javacppの知見を集めるのは大変 JNI手書き 󰢄 しんどい 󰢏 余計な依存性が無い Panama 󰢏 glue codeは不要 󰢄 stableリリースされていない / Androidでは使えない
  7. Kotlin/Nativeサポート RtMidiNativeAccess : RtMidi APIバインディング (cinterop) - rtmidi-javacppのRtMidiAccessとは別のAPI - サポート対象をデスクトップに限定するため独立したmoduleに切り出し

    - JavadocJarのサポートが厄介 (Kotlin/dokka/issues/3122) - ドキュメントJavadocJarが無いとMaven Centralでリリースできない - jvmターゲットが無いとJavadocJarが生成されない - Gradle 8.0でJavadocJarの扱いが変わってよろしくやってくれなくなった 他のネイティブAPIもcinteropバインディングを作成することになる…? Kotlin/Nativeでやる必要ある…?(多分ある…)
  8. GitHub ActionsからMaven Centralへのリリース rtmidi-javacpp - GitHub Actionsでbuild matrixを設定  (macos13-xlargeを使いたい…) (ktmidiはまだ)

    OSSRH sonatypeへのアップロード - nexus-actions/create-nexus-staging-repoを利用 リリースは手動で承認
  9. MIDI 2.0サポートの実装 MIDI 2.0仕様: 2020年に正式リリース / 2023年6月に大幅に改訂 - MIDI-CI 双方向の通信が可能になったのでデバイスの機能の有無などを確認するプロトコルを実現した

    送信者・受信者のエージェント APIが必要 - UMP 2〜3バイトのMIDIメッセージに代わって 32 / 64 / 128ビットで表現できるようになった バイトデータの解析・生成 APIが大量に必要 / 1.0 / 2.0相互変換処理も必要 - SMF2 UMPに基づくMIDIファイル(現状「クリップファイル」のみ) UMP/SMF2は(基本部分は)バイト配列の処理で済む(MIDI-CIはもう少し複雑)
  10. MIDI 2.0: プラットフォームのサポート まだ全然出揃っていない - 󰢄 MS: Windows MIDI Service

    (Microsoft/midi) - 2024年予定 - 󰢏 Apple: CoreMIDIで数年前から実装(macOS / iOS) - Sonomaまでは安心して使えなかった ? https://www.dtmstation.com/archives/63930.html - ? Linux: Kernel 6.5 / libasound 1.2.10 からサポート - 各種distroの安定版リリースを待つ必要 - ? Android: USB MIDI 2.0のみAndroid 13からサポート 「まだその時ではない」が、やる気があるなら今できなくもない
  11. まとめ - KotlinのMultiplatformでネイティブAPIをサポートするには   (OS = platform) x (実行環境 =

    VMs) の実装が必要 - Kotlin/NativeのみのモジュールのJavadocJarはハマる - Kotlin/NativeのCIビルドはプラットフォーム別のレーンが必要 - atsushieno/ktmidiを使うと最先端のMIDI 2.0アプリ開発もそこそこできる