MIDIについて

MIDI規格の基礎部分の階層

MIDI規格はもともと、「異なるメーカの電子楽器同士を接続して音楽演奏 情報を伝達できる」というために規定されました。そのもっとも基礎となる ハードウェア部分の規約は、

 ・コネクタは5ピンのDINコネクタで、ピン番号も指定されている
 ・UARTの出力からオープンコレクタで5mA電流ループ出力する(MIDI OUT)
 ・高速フォトカプラで入力し、電気的に分離してUARTに入力する(MIDI IN)
 ・MIDI入力を上記のように入力して出力するスルー出力(MIDI THRU)

となっています。データ形式の階層では、

 ・非同期シリアル通信のため8251のようなUSARTを使う
 ・スタート1ビット、データ8ビット、ストップ1ビット
 ・データ速度は31.25Kbps

となっています。つまり、1バイトの情報を転送するのに、およそ320マイクロ 秒、分かりやすく「1ミリ秒で最大3バイト」の転送量があります。これは 最近のコンピュータシステムから考えると相当に遅い通信ですが、1983年 から変わっていないもので、人間の音楽演奏情報の転送としては、まずまず 普通には問題なく「使える」ものなのです。

この電気的規約の階層の上にあるのが、ソフトウェア的な規約の階層です。 データ形式としては、8ビットの「素の」データの最上位ビット(MSB)で 大きく意味が分かれて、MSBが1のデータを「ステータス・バイト」、 MSBがゼロのデータを「データ・バイト」と言います。また、MIDIでは 同時に16種類の異なる楽器の演奏情報を伝達するために、これを区別 する4ビットの「チャンネル」という概念があり、これをステータスバイト の下4ビットに割り当てています。たとえば「発音開始」というステータス バイトには「第*チャンネルの」というチャンネル情報が添えられて いるので、音源では異なったチャンネルが間違って発音することは ありません。

MIDIメッセージの階層

このように「ステータス」と「データ」を組み合わせて、複数バイトで ある音楽的な意味を規定した「塊」を「MIDIメッセージ」と言います。 MIDIは非同期信号ですから、あるメッセージを構成する一連のデータ が揃って到達するとは限りません。たとえば、「発音第1チャンネルの 中央"C#"の音階の音が強度100で演奏された発音開始」という情報は 3バイトからなるメッセージですが、これが一気に1ミリ秒の間に 揃って到達しても、3バイトがそれぞれ10秒ずつの間隔で届いても、 MIDI受信側ではその情報を保存しておいて、メッセージとして完結 した瞬間に発音しなければならないのです。 代表的な「ボイス・メッセージ」と呼ばれるMIDIメッセージには以下の ような種類があります。

-------------------------------------------------------
status byte   meaning        data bytes
-------------------------------------------------------
0x80-0x8f     note off       2 - 1 byte pitch, followed by 1 byte velocity
0x90-0x9f     note on        2 - 1 byte pitch, followed by 1 byte velocity
0xa0-0xaf     key pressure   2 - 1 byte pitch, 1 byte after-touch
0xb0-0xbf     parameter      2 - 1 byte parameter number, 1 byte setting
0xc0-0xcf     program        1 byte program selected
0xd0-0xdf     after touch    1 byte channel pressure
0xe0-0xef     pitch wheel    2 bytes gives a 14 bit value
-------------------------------------------------------

この意味は、たとえば16進で「90」というステータスで始まるメッセージは、 ステータスバイトの下4ビット、つまり「0」から第1チャンネルの情報で、 これに続く2バイトのデータバイトで音高(pitch)と強度(velocity)を 表した「ノートオン」(発音開始)という音楽演奏情報を意味する、という ものです。

全てのボイス・メッセージが3バイトで構成されているわけではなく、 たとえば音色の切り替えに使われる「プログラム・チェンジ」は2バイト構成 ですから、MIDI受信のプログラムは、ステータス・バイトの上位4ビットの 内容に応じて、あと何バイトのデータでメッセージが完結するのか、を 判定する必要があります。

また、7ビットのデータ(128段階)では表現できない微妙なピッチを表現 するための「ピッチ・ベンド」というメッセージでは、2バイトのデータ幅 を使って14ビット精度の表現を伝達するようになっています。

各種のパラメータを転送するための「コントロール・チェンジ」という メッセージの部分には、MIDI演奏する音源の動作モードを規定するなど 複雑な規定があります。

また、多量の音楽演奏情報を高速に伝達するための工夫として、 「ランニング・ステータス」という規定があります。これは、「同じ ステータス・バイトに続くデータ・バイトの組であれば、ステータス・ バイトを省略して送信してもよい」というものです。送信側は省略しても しなくてもいいのですから、受信側はどちらであっても確実に判定 して処理しなければなりません。MIDIの受信というのは、たとえば 「発音開始」を受けて音を鳴らしたのに「発音終了」を正しく解釈 できなければ、「音が鳴り続いて止まらない」という、音楽にとって 致命的な誤動作となりますから、送信側よりも受信側の方が重大な 責任があるのです。

ステータス・バイトの上位4ビットが全て1、つまり「f*」となっている部分 には、さらに以下のような「システム・メッセージ」「リアルタイム・ メッセージ」と呼ばれる複雑な広がりを持つグループがあります。

SYSTEM MESSAGES
-------------------------------------------------------
byte    purpose              data bytes
-------------------------------------------------------
0xf0    system exclusive     variable length
0xf1    time code            variable length
0xf2    song position        2 - 14 bit value
0xf3    song select          1 - song number
0xf4    undefined
0xf5    undefined
0xf6    tune request         0
0xf7    EOX (terminator)     0
-------------------------------------------------------

REAL TIME MESSAGES
-------------------------------------------------------
0xf8   timing clock
0xf9   undefined
0xfa   start
0xfb   continue
0xfc   stop
0xfd   undefined
0xfe   active sensing
0xff   system reset
-------------------------------------------------------

これらの特別なメッセージは、それ以外のボイス・メッセージが完結していない 途中に「割り込む」ことが可能です。つまり、受信側は割り込まれた情報が あとで再開する、ということまで保持しておかなければならないのです。

「ノート・オン」と「ノート・オフ」

ボイス・メッセージのうち、

-------------------------------------------------------
0x80-0x8f     note off       2 - 1 byte pitch, followed by 1 byte velocity
0x90-0x9f     note on        2 - 1 byte pitch, followed by 1 byte velocity
-------------------------------------------------------

で表現されるものが、MIDIによる音楽演奏情報のもっとも基本となるもの です。これは「ノート・オン」と「ノート・オフ」で、2バイト目はその pitch(音高)で、ノート・ナンバと言い、以下のように規定されています。

-------------------------------------------------------
Octave||                     Note Numbers
   #  || C   | C#  | D   | D#  | E   | F   | F#  | G   | G#  | A   | A#  | B
-------------------------------------------------------
   0  ||   0 |   1 |   2 |   3 |   4 |   5 |   6 |   7 |   8 |   9 |  10 |  11
   1  ||  12 |  13 |  14 |  15 |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23
   2  ||  24 |  25 |  26 |  27 |  28 |  29 |  30 |  31 |  32 |  33 |  34 |  35
   3  ||  36 |  37 |  38 |  39 |  40 |  41 |  42 |  43 |  44 |  45 |  46 |  47
   4  ||  48 |  49 |  50 |  51 |  52 |  53 |  54 |  55 |  56 |  57 |  58 |  59
   5  ||  60 |  61 |  62 |  63 |  64 |  65 |  66 |  67 |  68 |  69 |  70 |  71
   6  ||  72 |  73 |  74 |  75 |  76 |  77 |  78 |  79 |  80 |  81 |  82 |  83
   7  ||  84 |  85 |  86 |  87 |  88 |  89 |  90 |  91 |  92 |  93 |  94 |  95
   8  ||  96 |  97 |  98 |  99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107
   9  || 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119
  10  || 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 |
-------------------------------------------------------

いわゆるピアノの「中央C」というのが10進で60となりますが、楽器という のは音色によっても音域によってもオクターブの表現は異なりますから、 実際の周波数として必ずしも同じになるとは限りません。

また、3バイト目のデータは個々の発音の音量に相当する「ベロシティ」と いう値で、鍵盤楽器の鍵盤を打鍵した速度から検出するので、この名前が 付いています。「ノート・オフ」におけるベロシティは、「鍵盤から指を 離す速度」とでもいうべきものですが、これに対応した電子楽器はほとんど 存在していません。

そして、ランニングステータスのルールで情報を効率よく転送するために、 「ノート・オフという情報には[ノート・オンでベロシティがゼロ]という 表現を用いる」ことが、きわめて一般的に行われています。たとえば、普通に 「中央Cを強度64で弾いて、その後発音を停止した」という演奏情報の場合、 MIDIチャンネルを第一チャンネルすなわち「0」とすると、

  90 3C 64 ----- 80 3C 64

というメッセージとなります。ところがランニングを使うと、

  90 3C 64 ----- 3C 00

と、データ量が少なくて済むわけです。受信側では、この両方について 正しく対応しなければなりません。

チャンネル・ボイス・メッセージ

ここで、MIDIメッセージの定義を詳細にまとめると、次のようになります。 ここでは、ステータス・バイトの下4ビットの「cccc」がMIDIチャンネルです。

まず、個々のMIDIチャンネルごとの情報である、「チャンネル・ボイス・ メッセージ」の部分です。ただし、個々の詳しい内容については省略します。

-------------------------------------------------------
Status       Data Byte(s)     Description
D7----D0     D7----D0
-------------------------------------------------------
1000cccc     0nnnnnnn         ノート・オフ
             0vvvvvvv         (nnnnnnn) is the note number.
                              (vvvvvvv) is the velocity.

1001cccc     0nnnnnnn         ノート・オン
             0vvvvvvv         (nnnnnnn) is the note number.
                              (vvvvvvv) is the velocity.

1010cccc     0nnnnnnn         ポリフォニックのアフター・タッチ
             0vvvvvvv         (鍵盤を弾いたあとで押し込む圧力)
                              (nnnnnnn) is the note number.
                              (vvvvvvv) is the pressure..

1011cccc     0ccccccc         コントロール・チェンジ
             0vvvvvvv         (各種のコントローラの情報[後述])
                              (ccccccc) is the controller number.
                              (vvvvvvv) is the new value.

1100cccc     0ppppppp         プログラム・チェンジ
                              (ppppppp) is the new program number.

1101nnnn     0ccccccc         アフター・タッチ
                              (ccccccc) is the channel number.

1110nnnn     0lllllll         ピッチ・ベンド
             0mmmmmmm         (14ビット形式での微調整データ)
                              (llllll) are the least significant 7 bits.
                              (mmmmmm) are the most significant 7 bits.
-------------------------------------------------------

以下は、上の「コントロール・チェンジ」の一部を使って特別に定義されている 「チャンネル・モード・メッセージ」の部分です。

-------------------------------------------------------
Status       Data Byte(s)     Description
D7----D0     D7----D0
-------------------------------------------------------
1011nnnn     0ccccccc         ローカル・コントロール
             0vvvvvvv         (音源が独立するかどうかのスイッチ)
                              c = 122, v =   0: Local Control Off
                              c = 122, v = 127: Local Control On

                              オール・ノート・オフ(非常用発音停止)
                              c = 123, v =   0: All Notes Off

                              発音モードの設定(詳細は省略)
                              c = 124, v =   0: Omni Mode Off
                              c = 125, v =   0: Omni Mode On
                              c = 126, v =   M: Mono Mode On (Poly Off)
                              c = 127, v =   0: Poly Mode On (Mono Off)
-------------------------------------------------------

コントロール・チェンジ

上で述べた「B*」で始まるコントロール・チェンジについては、2バイト目 で指定される「コントロール番号」によって、以下のような規定があります。

-------------------------------------------------------
    2nd Byte Value |              Function                  |  3rd Byte
  Binary  |Hex|Dec |                                        | Value  |  Use
-------------------------------------------------------
 00000000= 00=   0 | Continuous controller #0               | 0-127  |  MSB
 00000001= 01=   1 | Modulation wheel                       | 0-127  |  MSB
 00000010= 02=   2 | Breath control                         | 0-127  |  MSB
 00000011= 03=   3 | Continuous controller #3               | 0-127  |  MSB
 00000100= 04=   4 | Foot controller                        | 0-127  |  MSB
 00000101= 05=   5 | Portamento time                        | 0-127  |  MSB
 00000110= 06=   6 | Data Entry                             | 0-127  |  MSB
 00000111= 07=   7 | Main Volume                            | 0-127  |  MSB
 00001000= 08=   8 | Continuous controller #8               | 0-127  |  MSB
 00001001= 09=   9 | Continuous controller #9               | 0-127  |  MSB
 00001010= 0A=  10 | Continuous controller #10              | 0-127  |  MSB
 00001011= 0B=  11 | Continuous controller #11              | 0-127  |  MSB
 00001100= 0C=  12 | Continuous controller #12              | 0-127  |  MSB
 00001101= 0D=  13 | Continuous controller #13              | 0-127  |  MSB
 00001110= 0E=  14 | Continuous controller #14              | 0-127  |  MSB
 00001111= 0F=  15 | Continuous controller #15              | 0-127  |  MSB
 00010000= 10=  16 | Continuous controller #16              | 0-127  |  MSB
 00010001= 11=  17 | Continuous controller #17              | 0-127  |  MSB
 00010010= 12=  18 | Continuous controller #18              | 0-127  |  MSB
 00010011= 13=  19 | Continuous controller #19              | 0-127  |  MSB
 00010100= 14=  20 | Continuous controller #20              | 0-127  |  MSB
 00010101= 15=  21 | Continuous controller #21              | 0-127  |  MSB
 00010110= 16=  22 | Continuous controller #22              | 0-127  |  MSB
 00010111= 17=  23 | Continuous controller #23              | 0-127  |  MSB
 00011000= 18=  24 | Continuous controller #24              | 0-127  |  MSB
 00011001= 19=  25 | Continuous controller #25              | 0-127  |  MSB
 00011010= 1A=  26 | Continuous controller #26              | 0-127  |  MSB
 00011011= 1B=  27 | Continuous controller #27              | 0-127  |  MSB
 00011100= 1C=  28 | Continuous controller #28              | 0-127  |  MSB
 00011101= 1D=  29 | Continuous controller #29              | 0-127  |  MSB
 00011110= 1E=  30 | Continuous controller #30              | 0-127  |  MSB
 00011111= 1F=  31 | Continuous controller #31              | 0-127  |  MSB
 00100000= 20=  32 | Continuous controller #0               | 0-127  |  LSB
 00100001= 21=  33 | Modulation wheel                       | 0-127  |  LSB
 00100010= 22=  34 | Breath control                         | 0-127  |  LSB
 00100011= 23=  35 | Continuous controller #3               | 0-127  |  LSB
 00100100= 24=  36 | Foot controller                        | 0-127  |  LSB
 00100101= 25=  37 | Portamento time                        | 0-127  |  LSB
 00100110= 26=  38 | Data entry                             | 0-127  |  LSB
 00100111= 27=  39 | Main volume                            | 0-127  |  LSB
 00101000= 28=  40 | Continuous controller #8               | 0-127  |  LSB
 00101001= 29=  41 | Continuous controller #9               | 0-127  |  LSB
 00101010= 2A=  42 | Continuous controller #10              | 0-127  |  LSB
 00101011= 2B=  43 | Continuous controller #11              | 0-127  |  LSB
 00101100= 2C=  44 | Continuous controller #12              | 0-127  |  LSB
 00101101= 2D=  45 | Continuous controller #13              | 0-127  |  LSB
 00101110= 2E=  46 | Continuous controller #14              | 0-127  |  LSB
 00101111= 2F=  47 | Continuous controller #15              | 0-127  |  LSB
 00110000= 30=  48 | Continuous controller #16              | 0-127  |  LSB
 00110001= 31=  49 | Continuous controller #17              | 0-127  |  LSB
 00110010= 32=  50 | Continuous controller #18              | 0-127  |  LSB
 00110011= 33=  51 | Continuous controller #19              | 0-127  |  LSB
 00110100= 34=  52 | Continuous controller #20              | 0-127  |  LSB
 00110101= 35=  53 | Continuous controller #21              | 0-127  |  LSB
 00110110= 36=  54 | Continuous controller #22              | 0-127  |  LSB
 00110111= 37=  55 | Continuous controller #23              | 0-127  |  LSB
 00111000= 38=  56 | Continuous controller #24              | 0-127  |  LSB
 00111001= 39=  57 | Continuous controller #25              | 0-127  |  LSB
 00111010= 3A=  58 | Continuous controller #26              | 0-127  |  LSB
 00111011= 3B=  59 | Continuous controller #27              | 0-127  |  LSB
 00111100= 3C=  60 | Continuous controller #28              | 0-127  |  LSB
 00111101= 3D=  61 | Continuous controller #29              | 0-127  |  LSB
 00111110= 3E=  62 | Continuous controller #30              | 0-127  |  LSB
 00111111= 3F=  63 | Continuous controller #31              | 0-127  |  LSB
 01000000= 40=  64 | Damper pedal on/off (Sustain)          | 0=off  | 127=on
 01000001= 41=  65 | Portamento on/off                      | 0=off  | 127=on
 01000010= 42=  66 | Sustenuto on/off                       | 0=off  | 127=on
 01000011= 43=  67 | Soft pedal on/off                      | 0=off  | 127=on
 01000100= 44=  68 | Undefined on/off                       | 0=off  | 127=on
    ..........     |     (この間はまだ未定義)             |  ...   |  ...
 01011111= 5F=  95 | Undefined on/off                       | 0=off  | 127=on
 01100000= 60=  96 | Data entry +1                          |       127
 01100001= 61=  97 | Data entry -1                          |       127
 01100010= 62=  98 | Undefined                              |        ?
    ..........     |     (この間はまだ未定義)             |    ..........
 01111001= 79= 121 | Undefined                              |        ?
-------------------------------------------------------

システム・メッセージ

次は、「システム・コモン・メッセージ」の部分です。 まず最初は、メーカごとにまったく独自の情報規約を設けてよい、という 「エクスクルーシブ・メッセージ」です。これは、最初が「F0」、次の データがメーカごとに指定されている「ID」になり、あとは各社が 全体のデータ長まで含めてまったく独自に定義してよい、というもの です。このデータは最後が「F7」で終わることになっていますから、 基本的にはMIDIの受信側では「F0からF7までは無視する」というルール で対応します。

-------------------------------------------------------
Status       Data Byte(s)     Description
D7----D0     D7----D0
-------------------------------------------------------
11110000     0iiiiiii         System Exclusive.
             0ddddddd         This message makes up for all that MIDI
                ..            doesn't support.  (iiiiiii) is a seven
                ..            bit Manufacturer's I.D. code.  If the
             0ddddddd         synthesizer recognizes the I.D. code as
             11110111         its own, it will listen to the rest of
                              the message (ddddddd).  Otherwise, the
                              message will be ignored.  System Exclusive
                              is used to send bulk dumps such as patch
                              parameters and other non-spec data.
-------------------------------------------------------

基本的にメーカ独自に規定する、という筈のエクスクルーシブの例外と して、サンプラー音源のサンプリング波形データをこのエクスクルーシブの 部分を使ってダンプする、という以下の規定があります。

まず、ヘッダ部分では以下のような情報を送ります。

-------------------------------------------------------
F0 7E cc 01 ss ss ee ff ff ff gg gg gg hh hh hh ii ii ii jj F7

cc       =     channel number
ss ss    =     sample number (LSB first)
ee       =     sample format (number of significant bits; 8->28)
ff ff ff =     sample period (1/sample rate) in nanoseconds (LSB first)
gg gg gg =     sample length, in words
hh hh hh =     sustain loop start point (word number) (LSB first)
ii ii ii =     sustain loop end point (word number) (LSB first)
jj       =     loop type (00:forwards only; 01:alternating)
-------------------------------------------------------

そして、これに続いてサンプリング波形データのパケットを、以下のように 送ります。パケットは127バイトずつになります。それぞれにチェックサムを とって信頼性を上げています。

-------------------------------------------------------
F0 7E cc 02 kk [120 bytes] mm F7

cc       =     channel number
kk       =     running packet count (00->7F)
mm       =     checksum (XOR of 7E, cc, 02, kk [120 bytes])
-------------------------------------------------------

また、コンピュータとサンプラーとがハンドシェークによってダンプするため の通信プロトコルも、以下のように規定されています。 まず、ダンプをリクエストするには、

-------------------------------------------------------
F0 7E cc 03 ss ss F7

cc       =     channel number
ss ss    =     sample number requested (LSB first)
-------------------------------------------------------

を送ります。ハンドシェイクのメッセージとしては、

cc = channel number
pp = packet number

という定義に対して、

-------------------------------------------------------
     ACK :     F0 7E cc 7F pp F7
     NAK :     F0 7E cc 7E pp F7
     CANCEL :  F0 7E cc 7D pp F7
     WAIT   :  F0 7E cc 7C pp F7
-------------------------------------------------------

が定義されていて、処理能力の異なる機器の間でも同期して通信できます。 ここでは、ハンドシェイクの詳しい通信プロトコルの規定については省略します。

次に「F1」で始まるのは、「タイム・コード」の領域です。これは、MIDI 機器と映像機器との同期をとるために定義されたもので、マルチメディア のスタジオでは一般的に利用されています。

タイム・コードの規定には、いくつかの種類があります。 まず「クォーター・フレーム・メッセージ」の場合には、

-------------------------------------------------------
F1 0nnn dddd

               dddd = 4 bits of binary data for this Message Type
               nnn =  Message Type:
                    0 = Frame count LS nibble
                    1 = Frame count MS nibble
                    2 = Seconds count LS nibble
                    3 = Seconds count MS nibble
                    4 = Minutes count LS nibble
                    5 = Minutes count MS nibble
                    6 = Hours count LS nibble
                    7 = Hours count MS nibble and SMPTE Type
-------------------------------------------------------

という2バイトで定義します。ここでは、映像機器に関する個々の用語の説明 は省略します。上記のデータのさらに詳しい形式としては、

-------------------------------------------------------
FRAME COUNT:  xxx yyyyy
               xxx = undefined and reserved for future use.  Transmitter
                    must set these bits to 0 and receiver should ignore!
               yyyyy = Frame number (0-29)

SECONDS COUNT:  xx yyyyyy
               xx = undefined and reserved for future use.  Transmitter
                     must set these bits to 0 and receiver should ignore!
               yyyyyy = Seconds Count  (0-59)

MINUTES COUNT:  xx yyyyyy
               xx = undefined and reserved for future use.  Transmitter
                     must set these bits to 0 and receiver should ignore!
               yyyyyy = Minutes Count  (0-59)

HOURS COUNT:  x yy zzzzz
               x = undefined and reserved for future use.  Transmitter
                     must set this bit to 0 and receiver should ignore!
               yy = Time Code Type:
                    0 = 24 Frames/Second
                    1 = 25 Frames/Second
                    2 = 30 Frames/Second (Drop-Frame)
                    3 = 30 Frames/Second (Non-Drop)
               zzzzz = Hours Count  (0-23)
-------------------------------------------------------

などと決められています。 そして、「フル・メッセージ」としての定義としては、

-------------------------------------------------------
F0 7F [chan] 01 [sub-ID 2] hr mn sc fr F7

          F0 7F = Real Time Universal System Exclusive Header
          [chan] = 7F (message intended for entire system)
          01 = [sub-ID 1], 'MIDI Time Code'
          [sub-ID 2] = 01, Full Time Code Message
          hr = hours and type: 0 yy zzzzz
               yy = type:
                    00 = 24 Frames/Second
                    01 = 25 Frames/Second
                    10 = 30 Frames/Second (drop frame)
                    11 = 30 Frames/Second (non-drop frame)
               zzzzz = Hours (00->23)
          mn = Minutes (00->59)
          sc = Seconds (00->59)
          fr = Frames (00->29)
          F7 = EOX
-------------------------------------------------------

というように10バイト形式の表現も規定されています。また、この他にユーザ 独自のタイムコードを規定できる形式も定義されていますが、ここでは省略 します。

また、SMPTEタイムコードに準拠した映像機器のセッティングに関する メッセージも、以下のように規定されています。ここでも、それぞれの 用語ごとの定義については省略します。

-------------------------------------------------------
F0 7E [chan] 04 [sub-ID 2] hr mn sc fr ff sl sm [add. info] F7

          F0 7E = Non-Real Time Universal System Exclusive Header
          [chan] = Channel number
          04 = [sub-ID 1], MIDI Time Code
          [sub-ID 2] = Set-Up Type
               00 = Special
               01 = Punch In points
               02 = Punch Out points
               03 = Delete Punch In point
               04 = Delete Punch Out point
               05 = Event Start points
               06 = Event Stop points
               07 = Event Start points with additional info.
               08 = Event Stop points with additional info.
               09 = Delete Event Start point
               0A = Delete Event Stop point
               0B = Cue points
               0C = Cue points with additional info
               0D = Delete Cue point
               0E = Event Name in additional info
          hr = hours and type: 0 yy zzzzz
               yy = type:
                    00 = 24 Frames/Second
                    01 = 25 Frames/Second
                    10 = 30 Frames/Second drop frame
                    11 = 30 Frames/Second non-drop frame
               zzzzz = Hours (00-23)
          mn = Minutes (00-59)
          sc = Seconds (00-59)
          fr = Frames (00-29)
          ff = Fractional Frames (00-99)
          sl, sm = Event Number (LSB first)
          [add. info.]
          F7 = EOX
-------------------------------------------------------

この他のシステム・コモン・メッセージとしては、以下のものがあります。

-------------------------------------------------------
11110010     0lllllll         ソング・ポジション・ポインタ
             0mmmmmmm         (曲データのどの部分かを指定)

11110011     0sssssss         ソング・セレクト

11110110                      チューニングのリクエスト

11110111                      エクスクルーシブの終わり
-------------------------------------------------------

そして最後に、時間的同期のための「システム・リアルタイム・メッセージ」 として、以下のものがあります。これは全て1バイトで、規約の上では サンプルダンプを含むエクスクルーシブ・メッセージの中にでも、突然に 埋め込まれても正しく認識されるべきである、と規定されています。

-------------------------------------------------------
11111000                      タイミング・クロック

11111010                      シーケンサのスタート

11111011                      シーケンサの続行

11111100                      シーケンサのストップ

11111110                      MIDIケーブルの断線チェック

11111111                      システムリセット(一般には使ってはいけない)
-------------------------------------------------------

MIDI規格とSMF規格

MIDI規格とは、基本的に「ある音」「ある制御」「あるイベント」という個別 の情報までしか規定していませんから、「MIDI情報が時間的に次々に送られる」 という「楽曲」の情報は、いっさい定義できません。そこで規定されたのが、 「標準MIDIファイル(SMF)」というファイル形式で、この定義に従ったデータで あれば、どのようなシーケンサ(自動演奏)ソフトでも装置でも、同じ ようなMIDI演奏を「再生」できるものです。

ここには、「時間をどう定義するか」「曲の構造をどう定義するか」 「ファイルとしてどうデータをまとめるか」などの複雑な検討が必要と なります。SMFはあくまで「自動演奏として再生する」という目的の ためのものである、ということになります。

SMFの概念と用語の定義

ここでは、SMFで必要な、いくつかの用語について簡単に定義しておきます。

[Sequence]シーケンス

時間的情報とともに一連のMIDI情報を並べたデータのことで、このデータ に従って自動再生すると元の音楽演奏が再現されます。たとえば、楽譜で 「一つの音符」と記述されている音楽演奏情報は、「ノートオン、一定の時間、 ノートオフ」という3つの情報のシーケンスと等価というわけです。

[Track]トラック

楽曲というのは単一のパートから構成されていることはほとんどなく、 メロディーと伴奏、あるいはピアノとベースとドラム、あるいはオーケストラ のように、複数のパートが同時に演奏されます。そこでこの各パートの かたまりを、トラックという概念で複数にわたって処理します。

[Chunk]チャンク

SMFのファイル構造を定義するために、シーケンスを構成する要素として 「チャンク」という概念を用いています。シーケンスファイルは、ヘッダの チャンクと、複数のトラックに応じたデータを持つトラックチャンクから、

-------------------------------------------------------
MThd  [length of header data]
[header data]
MTrk  [length of track data]
[track data]
MTrk  [length of track data]
[track data]
 ...
-------------------------------------------------------

という標準化された構造で構成されています。ここで「MThd」とか「MTrk」 という4バイトのキャラクタデータは、予約されたSMF独自の規定で、これに 続くデータ長は32ビットと決められています。このデータ長により、それぞれ のチャンクのデータは必要に応じた可変長データとなります。このあたりは Javaのバイトコードでも踏襲されています。

[デルタタイム]

MIDI規約では、「それぞれのMIDIイベントの間の相対時間」あるいは 「起点から各MIDIイベントまでの絶対時間」という、MIDIイベントの集合 から実際の楽曲を構成するための「時間」の概念がありません。そこで SMFでは、「次のMIDIイベントまでの相対時間」を定義するために、デルタ タイムという概念を使用します。これは、システムに固有のペースで刻まれる クロック数でいくつ、というカウント値として使用します。

時間データは、「同時」を表す最小クロックから「数分」以上にまで 幅広いダイナミックレンジを持っているために、あるビット幅のデータと して定義すると、小さい時間に対して無駄があまりにも大きいために、 以下のような可変長形式の定義を用いています。これがデルタタイムです。

デルタタイムは、まず相対時間差データが7ビットで表現できる場合 には、そのまま1バイトで済みます。そしてこれを超える場合には、 MSBを繰り上げた形式で、7ビットだけを使用してデータを表現します。 表現できる相対時間差の最大データは「0FFFFFFF」ですが、これは最小 単位クロックが96分音符として「毎分500」という超高速指定でも「4日」 にあたるので、現実的な音楽データとしては十分です。デルタタイムと 相対時間差データとの対応は、以下のようになります。(16進)

-------------------------------------------------------
       相対時間差      SMFでのデルタタイム表現
-------------------------------------------------------
        00000000        00
        00000040        40
        0000007F        7F
        00000080        81 00
        00002000        C0 00
        00003FFF        FF 7F
        00004000        81 80 00
        00100000        C0 80 00
        001FFFFF        FF FF 7F
        00200000        81 80 80 00
        08000000        C0 80 80 00
        0FFFFFFF        FF FF FF 7F
-------------------------------------------------------

SMFのトラックデータの形式」

トラックデータの定義も構造的に標準化されています。シンタックスとしては 以下のようになっています。

-------------------------------------------------------
[track data] = [MTrk event]+

[MTrk event] = [delta-time] [event]

[event] = [MIDI event] | [sysex event] | [meta-event]
-------------------------------------------------------

つまり、トラックデータは「トラックイベント」が連結されて構成され、 トラックイベントは「デルタタイム」と「イベント」から成ります。 イベントは、「MIDIイベント」「エクスクルーシブ・イベント」「メタイベント」 のいずれかから成ります。

「MIDIイベント」は、MIDI規格で規定されている「生の」情報そのもの となっています。つまり、SMFはMIDI規格の上にできているわけです。 デルタタイムで切り離されたイベントをまたいでランニングステータスの ルールも有効ですから、このMIDIイベントの部分にはMSBの立たないデータ だけがある、という場合もあります。

「エクスクルーシブ・イベント」の部分では、

-------------------------------------------------------
        F0 [length] [bytes to be transmitted after F0]
        F7 [length] [all bytes to be transmitted]
-------------------------------------------------------

という形式で、MIDIのエクスクルーシブで規定するデータパケットを 定義することができます。

「メタイベント」の部分は、

-------------------------------------------------------
        FF [type] [length] [bytes]
-------------------------------------------------------

という形式で、MIDIで表現できないイベント情報を扱います。 たとえば、以下のようなものが定義されていますが、ここでは個々の内容の 詳細については省略します。(楽譜のルール[楽典]を知っている人に とっては必須の概念ばかりです)

-------------------------------------------------------
FF  00  02   ssss             Sequence Number
FF  01  len  text             Text Event
FF  02  len  text             Copyright Notice
FF  03  len  text             Sequence/Track Name
FF  04  len  text             Instrument Name
FF  05  len  text             Lyric
FF  06  len  text             Marker
FF  07  len  text             Cue Point
FF  2F  00                    End of Track
FF  51  03   tttttt           Set Tempo
FF  54  05   hr mn se fr ff   SMPTE Offset
FF  58  04   nn dd cc bb      Time Signature
FF  59  02   sf mi  Key Signature
                       sf = -7:  7 flats
                       sf = -1:  1 flat
                       sf = 0:  key of C
                       sf = 1:  1 sharp
                       sf = 7: 7 sharps
                       mi = 0:  major key
                       mi = 1:  minor key
FF  7F  len  data             Sequencer-Specific Meta-Event
-------------------------------------------------------

SMFのヘッダーチャンク

ヘッダーチャンクは楽曲データ全体を表現するための情報ブロックで、

-------------------------------------------------------
        [chunk type] [length] [format] [ntrks] [division]
-------------------------------------------------------

という形式をしています。最初のデータのチャンクタイプには、

-------------------------------------------------------
   0   マルチチャンネルのトラックがただ一つだけある
   1   同時に演奏される複数のトラックがある
   2   別々の複数のトラックがある(メドレーのようなイメージ)
-------------------------------------------------------

の3種類がありますが、インターネットなどで一般的に使われるのは 「フォーマット0」のタイプのSMFがほとんどです。