【iOSDC2024 #LT】1. MIDIの規格について
この記事はiOSDC2024で発表したLTのセッション、我が家に電子ピアノがやってきたので、ピアノと連携するアプリを作ってみた!の発表のうち、MIDIについてまとめたものです
この記事ではMIDI規格やそれをSwiftから利用するCoreMIDIについて概要を紹介します
MIDIとは?
MIDI(ミディ、 Musical Instruments Digital Interfaceの略)とは電子デバイスと電子ピアノなどのデジタル音楽機器間で音楽情報をやり取りするための規格です
基本的にはメーカーを問わず、横断して利用することができ、どのデバイスに対しても共通したフォーマットで入出力を管理できます
今回の発表では、電子ピアノとiPhoneやiPad、VisionProなどのデバイスを接続しています
なおMIDI規格は音源ではないので、MIDI規格に対応したからといって、直接iPhoneなどで音を鳴らすことはできません(iPhoneで音を鳴らすためには、音源を取り入れることが必要です)
接続方式は、デバイスと音楽機器を直接有線で接続する方法もあれば、Bluetoothやネットワーク経由での接続も可能です
ただしこれらの接続方法は、デバイスや音楽機器側がその機能をサポートしている必要があります
ちなみに我が家にやってきた電子ピアノ、YAMAHAのClavinova CVP-905でBluetooth経由でのMIDI通史員をしたいとYAMAHAのサポートに確認したところ、MD-BT01ならできると教えてもらい、実際にこれを使用して通信できることを確認しています
また電子ピアノを持ち出せない外部でアプリで、実際に音を出して動作確認をしたい場合、ネットワーク経由でMacと接続し、MacのGarageBandアプリを電子ピアノの代わりに利用することができます
接続方法については、Appleのドキュメントを参照してください
MacのGarageBandでピアノの鍵盤を利用する方法はこちらを参考にしてください
MIDIで取得できるイベント
MIDIでは様々なイベントを取得することができますが、このアプリでは以下の種類のイベントを利用してます
- 接続・切断のイベント
- 鍵盤の打鍵時のイベント
- タイムスタンプ
- 鍵盤を押した or 離した
- 音の強さ(鍵盤を叩く強さ)
- Note番号(音名/弾いた鍵盤の位置)
打鍵時のイベントは、タイムスタンプ以外は3Byteの情報の中に格納されていて、その中から取得することができます
Note番号というのは、電子ピアノの場合、どの鍵盤を叩いたかを判定するために利用する値です
0~127の値で取得でき、一般的な電子ピアノの場合、中央の鍵盤(真ん中のド/第4オクターブのド/C4)は60の番号が該当します
なお中央の鍵盤をC4として扱うメーカーと、C3として扱うメーカーがあり、デバイス側の定義と異なる場合は、オクターブシフトなどで設定を揃える必要があります(参考情報)
Core MIDIとは?
Core MIDIとは、上記のMIDIをApple Platform上で利用できるようにするframeworkです
これを利用することで、iPhoneなどのAppleデバイスと、我が家にある電子ピアノのような電子楽器などを接続することができます
Swiftでも実装できるのですが、Core MIDIは元々C言語ベースで実装されており、低レイヤーのAPIであるため、一部でポインターやスレッドの管理が必要です
例えば以下のコードのように、UnsafePointerの実装が必要になる場合もあります
func MIDIReadProc(pktList: UnsafePointer<MIDIPacketList>, srcConnRefCon: UnsafeMutableRawPointer?) {
let packetList: MIDIPacketList = pktList.pointee
var packet: MIDIPacket = packetList.packet
for _ in 0..<packetList.numPackets {
let data = packet.data
// Analysis data
packet = MIDIPacketNext(&packet).pointee
}
}
低レイヤーのAPIの操作に慣れていない人にとっては、実装が難しく感じることがあると思います(自分もそうです)
その場合、3rdParty製のCoreMIDIのラッパーのMIDIKitを利用するのを検討するのもいいかなと思います
MIDIKitとは?
MIDIKitとは、SwiftでCore MIDIを扱うためのモダンなラッパーライブラリで、MIDI 1.0とMIDI 2.0の両方に対応しています
このライブラリは、Core MIDI APIをシンプルかつ使いやすい形で提供しており、複雑な低レベルの操作を抽象化することで、開発者が効率的にMIDIデバイスとのやり取りを行えるように設計されています
他に以下のような特徴があります
- マルチプラットフォーム対応
- MIDIKitはmacOS、iOS、そして新たにvisionOSにも対応しています。これにより、複数のAppleデバイス間で一貫したMIDI機能を提供できます。
- MIDI 2.0のサポート
- ライブラリは、自動的にプラットフォームの適切なCore MIDI APIを使用し、MIDI 2.0をサポートする環境ではそれをデフォルトで使用するようになっています。これにより、最新のMIDI規格を活用した開発が可能です。
- 強力な型安全性
- MIDIKitは、MIDIイベントを厳密に型指定して扱うことで、MIDI 1.0とMIDI 2.0の間の相互運用性をシームレスにサポートしています。
- ユーザーフレンドリーなI/O
- ライブラリは、MIDIエンドポイントの接続管理を自動化し、デバイスの接続状態の永続性を維持するための機能も備えています。これにより、開発者は複雑な接続管理を気にせず、MIDIデバイスとの通信に集中できます。
- Swift Playgrounds対応
- iPadやmacOS上のSwift Playgroundsでも使用可能で、学習やプロトタイピングが容易になっています。
またSwiftUIでデバイスの接続を管理するためのViewやObservableObjectも用意されており、またDooC製の詳細なドキュメントも用意されているため、それらを考慮しても、そして特にSwiftUIでUIを実装する場合は、MIDIKitを利用した方がMIDIデバイスとの接続機能を実装するのは容易かもしれないです
またサンプルアプリも数多く用意されているため、実装方法に困った場合はそれらを参考にすれば解決することが多いです
MIDIKit Documentation
まとめ
この記事ではMIDIの規格のことやCoreMIDIについて、その概要をまとめました
詳細を確認したい方は、MIDIやCoreMIDIのドキュメントを確認いただければと思います
次の記事は、「2. Core MIDIを使って、電子ピアノと連携したアプリを作る」です