ハトネコエ Web がくしゅうちょう

プログラミングとかAndroid

続・SMF ( Standard MIDI File ) Format1 のバイナリを読んでみた

前回の記事の続きです。↓前回の記事

4D 54 68 64 00 00 00 06 00 01 00 02 03 C0 4D 54 
72 6B 00 00 00 17 00 FF 03 00 00 FF 51 03 06 8A 
1B 00 FF 58 04 04 02 18 08 00 FF 2F 00 4D 54 72 
6B 00 00 00 2B 00 FF 03 00 00 FF 21 01 00 00 B0 
79 00 00 B0 00 00 00 B0 20 00 00 C0 28 00 B0 07 
64 9E 00 90 3C 64 9E 00 80 3C 00 9E 00 FF 2F 00

前回の記事では、このバイナリファイルのヘッダーとコンダクタートラックまでを読みました。
3行目の13列目、つまり以下のところまでです。

4D 54 68 64 00 00 00 06 00 01 00 02 03 C0 4D 54 
72 6B 00 00 00 17 00 FF 03 00 00 FF 51 03 06 8A 
1B 00 FF 58 04 04 02 18 08 00 FF 2F 00

今回はその続きを読んでいきましょう。
前回の記事が前提知識となりますので、未読の方は前回の記事を先にお読みください

トラック(演奏トラック)

4D 54 72 
6B 00 00 00 2B 00 FF 03 00 00 FF 21 01 00 00 B0 
79 00 00 B0 00 00 00 B0 20 00 00 C0 28 00 B0 07 
64 9E 00 90 3C 64 9E 00 80 3C 00 9E 00 FF 2F 00

これがひとつの演奏トラックです。
Domino(MIDI編集ソフト)で見ると以下のようになっている箇所です。

f:id:nekonenene:20170225194904p:plain

開始宣言

4D 54 72 6B
これを、ASCIIコード表に沿って直すと MTrk
「ここからトラックについての記述が始まるよー」というサインになります。

トラックの長さ

00 00 00 2B
10進数に直すと 43 です。
「ここから 43 Byte 続くよー」と言ってくれています。

トラックのタイトル

00 FF 03 00
トラック名の指定です。
前回のコンダクタートラック同様、何も名付けていません。

ポート番号の指定

00 FF 21 01 00
ここから前回にはなかった新しい要素、
まずは「ポート番号の指定」です。

「FF 21」で「ポート番号の指定を始めますよー」という合図、
次の「01」が「それに1Byte使うよ」という宣言で、

最後の「00」で「Port A」だと言ってくれています。
Port Bの場合はここが「01」になります。

リセットオールコントローラー (CC#121)

00 B0 79 00

最初の「00」は0Tick経過したところで、の意味。(前回記事参照)
そして次の「B0」、これは「チャンネル1にコントロールチェンジを送るよ」という合図です。

最初の「B」がコントロールチェンジを指すサイン
次の「0」がチャンネル1を表しています。

なので、チャンネル2にコントロールチェンジを送るなら「B1」、
チャンネル16にコントロールチェンジを送るなら「BF」というふうになります。

そして、その次の「79」がコントロールチェンジ番号を表していて、
「79」を10進数に直すと121(7 * 16 + 9 = 121)。
コントロールチェンジ番号121「リセットオールコントローラー」を指します。

この信号でピッチベンドや音色などは初期値にリセットされます。
「79」の次にある「00」はValueで、リセットオールコントローラーの場合は別にどんな値でもいいんですが、通常は「00」としておきます。

バンクセレクトMSB (CC#0)

00 B0 00 00
「チャンネル1にコントロールチェンジ0番を送るよ」という合図になります。

コントロールチェンジ番号0は「バンクセレクトMSB」です。

MIDIの各チャンネルの音色は、
プログラムチェンジ と MSB と LSB の組み合わせ
によって決まります。
それぞれ128種類あり、MIDI音源は最大で 128 * 128 * 128 = 2,097,152 音色持てる計算になります。

今回の場合は、
プログラムチェンジ : 41(バイオリンの音色)
MSB : 0
LSB : 0

で、実際、「B0 00」のあとの最後の値(Value)は「00」です。

バンクセレクトLSB (CC#32)

00 B0 20 00
「チャンネル1にコントロールチェンジ32番を送るよ」という合図になります。

コントロールチェンジ番号32は「バンクセレクトLSB」です。
最後の値は「00」なので、LSB = 0 ということになりますね。

プログラムチェンジ

00 C0 28
チャンネル1にプログラムチェンジを送っています。
コントロールチェンジは「B」でしたが、プログラムチェンジは「C」で始まります。

ですので、チャンネル1にプログラムチェンジを送る合図は「C0」です。
その次の「28」が値(Value)で、10進数に直すと40……なんですけど、
ここの値は「00」(つまり0)から始まる一方、プログラムチェンジは1~128で規定されていますので、ここは41とお考えください。

GM規格ではプログラムチェンジ1~128が規定されており、
1 は Acoustic Piano、41 は Violin の音色です。
このチャンネル1はヴァイオリンの音色で鳴らされます。

ボリューム (CC#7)

00 B0 07 64
チャンネル1のチャンネルボリュームを100に設定しています。

「チャンネル1にコントロールチェンジ7番を送るよ」という合図で、
コントロールチェンジ番号7は「チャンネルボリューム」です。
最後の値(Value)は「64」なので、10進数に直すと100、トラックの音量は100です。
(なお、最大値は127です)

「ド」を鳴らす

9E 00 90 3C 64
設定が続きましたが、ようやく演奏の部分です。

最初の「9E 00」は「3840Tick経過したところで」の意味になります。

詳しくは前回記事のTickの項を読んでもらうとして、
9E - 80 = 1E で、これを10進数に直すと30。
「9E」の次は「00」で、「80」より小さな値ですからTickの値の指定はここまでとわかります。

よってTickは
128 * 30 + 1 * 0 = 3840 Tick と計算できます。

そして続くのが「90 3C 64」の部分。

「90」は「チャンネル1のノートON」を示します。
コントロールチェンジは「B」、
プログラムチェンジは「C」でしたが、
ノートON(音符の開始)は「9」が目印と決まっています。

そして音の高さは「3C」、10進数に直すと60、これはC4。MIDI音源にもよりますが、ト音記号のドの音です。
ヘ音記号のドの音はそこから12小さい48、16進数で表すと「30」の音です。

そして最後の値(Value)の「64」、10進数で表すと100であるこれが、
音の強さ(Velocity)の値を示しています。

「ド」を止める

9E 00 80 3C 00
先ほど鳴らしましたドの音を3840Tick経過したところで停止します。

「9E 00」が「3840Tick経過したところで」の意味、
そして次の「80」は「チャンネル1のノートOFF」を示します。
ノートON(音符の開始)は「9」でしたが、ノートOFF(音符の停止)は「8」というわけです。

で、どこのノートを止めるかというと「3C」の高さの音、
先ほど鳴らしました「ド」の音ですね。

そして最後の値(Value)が「00」です。
ノートOFFの音の強さ(Velocity)、「ノートオフベロシティ」は、
ごくごく一部のMIDI音源がリアルな演奏のために対応しているのですが、
ごくごくまれすぎるため、たいていのMIDI編集ソフトはここを0として処理します。

私がはるか昔に使っていた「Music Studio Producer」なんかは、ノートオフベロシティも編集しやすいようになっていましたね…。

トラックの終わり(End of Track)

9E 00 FF 2F 00
前回のコンダクタートラック同様、トラックの終了宣言をおこないます。

「9E 00」が「3840Tick経過したところで」の意味で、
「FF 2F 00」が「トラック終了(End of Track)」の意味です。

このトラックは4小節目の0Tick目で終了で、解説もこれで終了です。

おわりに

というわけで、2回にわたって続きましたMIDIファイルバイナリの解説、いかがでしたでしょうか!

バイナリって「難しそう」「マニア的なもの」という印象でしたが、
こうして覗いてみると、理路整然としていて思いのほかわかりやすいものであると感じました。(調べるの大変でしたけど…)
この記事を読んでくださった方も同じように感じてくださったのではないでしょうか?

こうなってくると png ファイルとか wav ファイルも気になってきますよね?
wav は読むの大変そうですが、でも気になる……。


最後に、今回参考にしたサイトを以下にまとめておきます。

ここまで読んでくださった方々、どうもありがとうございました!


そして流れを無視して貼っておくアフィリエイトリンク……
(接続部がよくある miniB端子でなく microB端子だからか、この1年くらい使ってるけど抜けにくくてけっこういい感じ)