Open3

RTP-MIDIとAppleMidiの仕様書を読む会

okuokuokuoku

RTP-MIDIとAppleMidi

いわゆるTCP/IPネットワークを介してMIDIメッセージを送受信する方法としてデファクトスタンダードとなっている感のあるAppleのRTP-MIDI実装は2つの仕様で構成されている。

RFC6295 https://tools.ietf.org/html/rfc6295 で規定されている、RTP(UDP)パケットにMIDIメッセージを格納する方法および欠落したメッセージを補うための"ジャーナル"形式。

Apple独自仕様のセッションプロトコル https://developer.apple.com/library/archive/documentation/Audio/Conceptual/MIDINetworkDriverProtocol/MIDI/MIDI.html 。デバイス名の送出やレイテンシ検出のような重要な仕様がこちらで実装されている。

プロトコルの役割分担

機能 プロトコル 備考
デバイスの発見 AppleMidi Bonjourを使用
MIDIメッセージの送信 RTP-MIDI RTPヘッダを使用
受信済メッセージ番号の通知 AppleMidi
欠落パケットからの回復 RTP-MIDI AppleMidiは一部実装を省略
切断の検出 AppleMidi 1分おきの時刻同期を規定

よって両方無いと機能しない。

okuokuokuoku

RTP-MIDIの欠落メッセージ補完の仕組み

UDP上のプロトコルの宿命として、 1) パケットが欠落した場合 2) パケットがout-of-orderで到着した場合の考察が必要になる。これについて、RTP-MIDIではRFCの4章 "Recovery Journal System" で説明している。

シーケンス番号

RTPでは全てのパケットに16bitのシーケンス番号を付与している。これが順番に届かなかったり、飛ばされたりした場合に、システムはパケットが消失したと判断できる。

欠落の分類

RFCでは、MIDIメッセージが欠落した場合の被害を以下の2種類に分類している:

  1. Transient artifacts 。NoteOn(鍵盤の押し下げ)の欠落のように、無くなっても気付きづらい問題(どうせ次の発音がそのうち行われるため)。
  2. Indefinite artifacts 。NoteOff(鍵盤離し)の欠落や音色変更要求の欠落のように、無くなるとずっと耳ざわりな音になってしまう問題。

RTP-MIDIにおけるRecovery Journalは、後者のindefinite artifactsを防止するために実装されている。

Recovery Journal

Recovery JournalはIndefinite artifactsに結びついてしまうような重要なMIDIメッセージのログで、要するに重要なメッセージは送りづつけることでパケットの脱落に備えるものと言える。

ただ単純にJournalを追加していくだけだとどんどんとパケットが膨張していくことになる。不要になったJournalをクリアするために、 checkpoint の概念が存在する。checkpointの具体的な表現方法はRTP-MIDI側では規定されず、 AppleMidi側に実装されている

AppleMidiでは、定期的に受信側が正常に受信できたパケットのシーケンス番号を通知するとだけ定めている。

Recovery Journalは記録の効率化のために、ほぼ全てのケースでタイミング情報を捨てており、かつ、メッセージを "chapter" に分類している。 Appleの実装はその全てに対応しているわけではない

okuokuokuoku

AppleMidi

仕様書 はあるものの、ちょっと誤植と欠落がある。例えば:

正しくは high / low (いわゆるビッグエンディアン)になる。

AppleMidiでは、UDPポートを2つ使用する。 control port はリアルタイム性が不要なメッセージに使用し、 MIDI communication port はリアルタイムメッセージとなる。control portは独自のセッションプロトコルのみが使用されるが、 MIDI communication portではセッションプロトコルとRTP-MIDIの両方が混在することになる。

セッションプロトコル

セッションプロトコルのメッセージはASCII 2文字で識別される。

コード ポート コマンド 内容
IN C+M Invitation セッション確立コマンド
OK C+M Invitation accept セッション受理
NO C+M Invitation reject セッション拒否
BY C? Exit セッション終了
CK M Timestamp 時刻同期
RS C Feedback 受信したシーケンス番号の通知
RL ?? Receive Limit (仕様書には記述が無い)

(C = Control portで使用される M = MIDI communication portで使用される C+M = 両方)

サポートしているジャーナル

Appleの実装はジャーナルを一部しかサポートしない。

... 仕様書の年代が古いので現状でもそうなのかは何とも言えないが、とにかくジャーナルをサポートしていなさそうなメッセージは避けるのが賢明と考えられる。