読者です 読者をやめる 読者になる 読者になる

すこしふしぎ.

VR/HI系院生による技術ブログ.まったりいきましょ.(友人ズとブログリレー中.さぼったら焼肉おごらなきゃいけない)

midi規格についてしらべた

先日紹介したNSX-1.さっそくいろいろ開発してみたい. ちょこちょこと情報を見た限り,どうやらチップとの通信ではmidi規格による通信が可能らしい.

そこで今回は,midi規格について調査してみた.

what's midi ?

コーラスやってたとき,単純な音で各パートの音を 演奏した音取り用のデータのことをmidiと呼んでいた.自分もdominoとか使ってぽちぽち曲を打ち込んだ記憶がある.

まぁおそらくmidiの本来の意味は違うのだろう. よく"midiキーボード"とか"midi音源"なんて言葉を聞いたりもする. なんとなく抱いているイメージは演奏情報を記録したデータというもの. はたして正しいのだろうか.

まずはwikipediaでなんとなくのイメージをつかむ.曰く.

MIDI(ミディ、Musical Instrument Digital Interface)は、日本のMIDI規格協議会(JMSC、現在の社団法人音楽電子事業協会)と国際団体のMIDI Manufacturers Association (MMA) により策定された、電子楽器の演奏データを機器間でデジタル転送するための世界共通規格。物理的な送受信回路・インタフェース、通信プロトコル、ファイルフォーマットなど複数の規定からなる。

だそうな. ポイントはやはり電子楽器の演奏データを機器間でデジタル転送するための世界共通規格というところかな.

waveファイルとかは演奏された結果として,物理的な振動データを保持している.実際にデータを見ると波形が見えるし,これがwavという名前の由来でもあろう.これを更に圧縮したものがmp3だったりoggだったり.可逆なものであれ不可逆なものであれ,音をそのまま記録してるという点では共通している.

一方のmidiでは演奏情報だけが記録されているため,それだけでは音として鳴らすことができない. そこで必要になるのがmidi音源というもの.演奏情報をもとに実際に音として鳴らすものだ. 昔はハードウェア音源が多かったようだけれど,最近ではソフトウェア音源が主流らしい.

システム

midi規格に乗っ取った通信は,一つのケーブルにおいて一方通行のものらしい. 片方のmidi outから命令が出て,もう片方のmidi inでデータを受け取る構成だ. であるから,機材同士を相互に連携させたければmidiケーブルが2本必要となる. お互いのmidi out/inをつなぐいだものを,1つのシステムとよぶ.

そして,システムには16のチャンネルがある. チャンネルという概念により,1本のケーブルでも最高16種類の楽器を演奏できる. たとえば,チャンネル1はピアノ,チャンネル2はギター,チャンネル3はベース..といった具合だ.

midiケーブルによりつながれた機材同士のデータ通信は,midiメッセージを用いて行われる. midiメッセージは大別するとチャンネルメッセージとシステムメッセージに分かれる. チャンネルメッセージを使うことにより,各チャンネルに対し個別で命令を送れる. 例えば,ピアノはこの音,ギターはあの音,ということが可能になる. システムメッセージを使うと,チャンネルに関係なく全体に命令を送ることができる. クロックの同期などに使われるようだ.

まとめると,送信先が指揮者となり,受信先の各楽器に対し指示を送っているようなものだろう.

通信フォーマット

では,具体的にmidiメッセージを生成するにはどのようにすればよいか.

midi規格では,データは複数のバイト列で表現される. その中でも"ステータスバイト"と"データバイト"に大別されている. 通信の基本は

  1. ステータスバイトにより命令を指定
  2. データバイトにより具体的な値を送信

という形のようだ. 例えば,ステータスバイトで「ch1に音を鳴らす」,データバイトで「C3を127の強さ」という命令を送ることができる.

midi規格では,ステータスバイトとデータバイトの違いを最上位ビットにより表現している.1byte = 8bitのうち,最上位の1bitが1ならばステータスバイト,0ならばデータバイトと判断する. 故に,ステータスバイトは80~FF,データバイトは00~7F(=0~127)を用いることになる.

↓こんな感じ

ステータスバイト:[1][~][~][~][~][~][~][~]:80~FF

データバイト:[0][~][~][~][~][~][~][~]:00~7F

さて,チャンネルメッセージを発行する際は,ステータスバイトにおいて「命令内容」と「対象チャンネル」の双方を指定する必要がある. この場合,最上位1bitでステータスバイトであることを示し,続く3bitで命令内容を,下位4bitで対象チャンネルを指定する. そのため命令内容は23=8通り,チャンネルは24=16通りを指定することが可能となる.

チャンネルメッセージ:[1] (status:1bit) [~][~][~] (event:3bit) [~][~][~][~] (ch:4bit)

用意されているチャンネルメッセージ命令は次の通り.詳細はまたそれぞれ複雑になるので省略. なお表中のnは0~Fの16通りであり,チャンネルを示す.

byte event
8n ノートオフ
9n ノートオン
An ポリフォニックキープレッシャ
Bn コントロールチェンジ
Cn プログラムチェンジ
Dn チャンネルプレッシャ
En ピッチベンドチェンジ
Fn システムメッセージ*

システムメッセージは対象チャンネルをとらず,全体にブロードキャストする. そのため.続くnによりメッセージ内容を表現することができる.

まとめ

midi規格による通信のフォーマットを調べた. 久しぶりにレポートでも書いてる気分だ.

midi規格による通信は,

  • シリアル通信によるバイト列送信
  • ステータスバイトで命令指定.データバイトで値指定

により行われる. それぞれのメッセージでどのような処理を行うのか,はまたいずれ.

とりあえずこのあたりがわかればNSX-1のサンプルプログラムを読むことはできるのではないだろうか.