2013.3.9
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第340回]


●MIDIファイルを解析(3)

前回からの続きです。
四季の歌のMIDIファイル(siki−b.mid)のトラック2(楽譜上ではパート1)の実際の音データは904BHから始まります。
下はsiki−b.midのダンプリストの、アドレス9040Hから905FHまでと、トラック2の終り(9228H)の前後です。

9040  00 C0 00 00 B0 07 64 00-B0 0A 40 00 90 48 64 83  .タ..ー.d.ー.@..Hd.
9050  00 90 48 00 60 90 48 64-81 40 90 48 00 30 90 47  ..H.`.Hd.@.H.0.G


9210  42 00 30 90 43 64 81 40-90 43 00 30 90 40 64 8C  B.0.Cd.@.C.0.@d.
9220  00 90 40 00 83 60 FF 2F-00 4D 54 72 6B 00 00 02  ..@..`./.MTrk...
9230  AA 00 B0 00 00 00 B0 20-00 00 C0 00 00 B0 07 64  ェ.ー...ー ..タ..ー.d
9240  00 B0 0A 40 00 90 34 64-81 40 90 34 00 30 90 39  .ー.@..4d.@.4.0.9

●ノートオン(9X XX XX)

最初の音データは
00 90 48 64
です。
9Xはノートオン(音を出す)です。
MIDI音源に送る最も基本的なデータです。
極限すればこのコードさえあれば、とりあえず音源を使ってそれなりに曲を演奏させることができます。

9X aa bb

は、Xで示す音色(楽器)で、aaの高さでbbの強さの音を鳴らすことを音源に指示します。

Xは0〜Fで、チャンネルナンバーを示します。
これはシリアルで送るデータを楽器ごとに振り分けるためのナンバーで、局内電話の内線番号のようなものです。
このナンバーの指定によって、16通りの音色(楽器)に指示を届けることができます。
チャンネルナンバーには、前回説明をしましたバンクセレクトとプログラムチェンジによって、特定の音色(楽器)を割り当てておきます。

音の高さはaaで指定します。
00〜FFの256通りが指定できそうですが、MIDIでは最上位ビットは特別の用途に用いられることが多く、そのルールのために、一般的な数値は7ビットで示されます。
そこで音の高さとしても、00〜7FH(0〜127)が使われます(00が低く7Fが高い)。
各数はそのまま音階に対応していて、ふつうのピアノ(88鍵)の中央のドの高さの音が3CH(60)になります。
もう少し正確にいいますと、音の高さの基準とされている440Hzのラの音が45H(69)になります。

440Hzのラの音が45H(69)ということですと、それでは00Hはどういう高さの音かといいますと、そこから順に下がっていきますと、00Hはドになります。
真ん中のドだとか下のドだとかと言っているのではまるで幼稚園でありますから、一般的には音名を示すABCにオクターブを示す数値をつけてA4とかC4というように表記するようです。
でもA4とかC4では16進数と混同してしまいますので、ここではA、Cというように表記することにいたします。

で。
そのような表記を用いますと上で説明をしました88鍵のピアノの中央付近にあります3CH(60)のドの音はCになります。
また45H(69)のラの音はAになります。
00Hのドの音はC−1になります。
逆に一番高い音7FH(127)はG(オクターブ9のソ)になります。

ちなみに88鍵のピアノの一番低い音(左端のキー)はAのラで、これは15H(21)です。
また右端の一番高い音はCのドで、6CH(108)です。
ということはMIDIでは普通のピアノの音の高さよりもさらに低い音も高い音もそれぞれ約20音も多く出すことができることになります。

なお上のようにオクターブの値をそのままABCにつけるのではなくて、それから−1した値をつけて表記するというルールもあるようです。
その場合には00HのドはC−2になり、3CH(60)のド(オクターブ4)はCになります。
同様にして45H(69)のラ(オクターブ4)はAになります。
7FH(127)のソ(オクターブ9)はGになります。

3バイト目のbbは音の強さを示します。

以上の説明をもとにして、最初の音のデータを見てみます。
最初の音データ
00 90 48 64
は、一番始まりの音ですから時間データが00で、直ちにMIDI音源に送られます。

チヤンネルナンバー0には、前回説明をしましたバンクセレクトとプログラムチェンジによって、バンク0000、プログラムナンバー00の音色(楽器)が割り当てられています。
この楽器はSC−88ではピアノ1ですが、これはおそらくスタンダードでありましょう。

音の高さは48Hで、これはC(オクターブ5のド)です。

その音を64Hの強さで鳴らす、ということになります。
64Hがどのくらいの強さなのかは分かりませんが、7FHがMAXですから、かなり強くということだと思います。

ことはついでということで書いておりますが、このようなことは全く知らなくても、MIDI演奏プログラムを書く上では支障はありません。
しかし、まあ、こうやって解析してみますと、なかなかに興味深いものがあります。

このsiki−b.midは私の妻が地域サークルの仲間と演奏するための楽譜として作成したものをMIDIファイルとして出力したものです。
ですので一般的なMIDIファイルのようにMIDI音源で演奏することを目的にして作成したものではありません。

ふむむむ。
ただの楽譜をMIDIファイルとして出力しただけということだと、音の高さとか音の長さはわかるが、音の強さはどこからもってきているのだろう?
疑問に思ってダンプリストをもう一度しっかりながめてみましたら、音の強さは全部64Hになっておりました。
なるほど。
納得。

●ノートオフ

MIDIの解説書などを読みますと、上で説明しましたノートオン(音を出す)とペアで使うイベントコードとしましてノートオフ(音を止める)が説明されています。
ノートオフは8Xで始まる3バイトです。
しかしsiki−b.midのダンプリストを始めから終わりまで見ましても、そんなコードは出てきません。
音のデータは全て90で始まっています。

実は、本来音を出す(ノートオン)ためのコード9Xが、音を止める(ノートオフ)ためのコードとしても使われておりました。
さきほど説明をしました音の強さのところでは、音の強さは全て64Hになっている、と書きましたが、それは「音を出すためのコード」についてでありまして、「音を止めるためのコード」として使われている9Xの音の強さの値には00が指定されています。

確かに音の強さを0にしてしまえば、何も聞こえないわけですから、実質的に音を止めることと同じである、といえるでしょう。
もともとはノートオフとして8Xが定義され、それが9Xとペアで使われていたのでしょうが、どうも私が調べた限りでは、9Xを使って音の強さを0にすることでノートオフの代用にすることのほうが多いようです。

上で解析しました最初のデータの次のデータ(アドレス9040H〜)
83 00 90 48 00
が、ノートオフの代用です。
最初の2バイトは時間データです。
音の高さ48Hは、その前のデータと同じC(オクターブ5のド)です。
そして3バイト目の音の強さが00になっています。

●音の長さ

ノートオンからノートオフまでの時間が音の長さになります。
MIDIではノートオフの前に付加されている時間データが音の長さを示しています。
最初私が誤解していたことですが、この時間データはMIDI音源には送られません。
これを計算することこそがMIDI演奏プログラムの一番の役目です。
つまりまずノートオンのイベントデータをMIDI音源に送り、それから次のノートオフまでの時間を計算して、実際にその時間が経過したときにノートオフのイベントデータをMIDI音源に送ります。

参考までに音の長さを計算によって求めてみることにいたします。
上のノートオフの時間データは
83 00
です。
時間データは可変長です。
MIDIの可変長につきましては[第338回]で説明をいたしました。

そのルールにしたがって83 00を普通の16進数に直しますと、180H(384)になります。
これはこの曲の最小時間単位(ティック)で384単位の長さであることを示しています。
[第338回]で調べたこの曲のティックは1389μsでした。
そこで実際の時間を求めますと、
1.389×384≒533.376msになります。
ノートオンを送ってから533.376ms後にノートオフを送ることになります。

ところでこの時間は音符の長さでは何音符に相当するのでしょうか?
それはMIDI演奏プログラムを作る上ではどうでもよいことです。
念のためにといいますか、まあ、好奇心です。

音符の長さにつきましても[第338回]で調べました。
この曲の場合、4分音符は1E0H(480)でした(単位はティック)。
あれ?
計算が合わない?

上で確認しましたノートオフまでの時間(=音符の長さ)は180H(384)でした(単位はティック)。
すると、
384/480=0.8
です。
4分音符の8掛け?
5分音符???
むむむむむ?

下はsiki−b.midのもとになりました楽譜の最初の部分です。



おお。
確かに最初の音はC(オクターブ5のド)です。
あれ?
ちゃんと4分音符ですねえ。

MIDIについての解説をしているサイトで、音の長さの指定は、音符の長さそのままではなくて、その8割程度の長さにするほうがよい、と書かれているのをみつけました。
そのままの長さを指定すると、かえって不自然な演奏になってしまうのだそうです。
なるほど。
それで8割の値になっていたわけですな。
納得。

う。
まてまてまて。
それだと、演奏時間も8割になってしまうではないか。

その疑問は、さらにその次の音データを見ることで解消いたしました。
その次のデータは、
60 90 48 64
です。
2番目の音のノートオンです。
音の高さは前の音と同じ(C)です。
が、時間データは00ではなくて60H(96)になっています。
前の音のノートオフのあと、96ティック後にノートオンがMIDI音源に送られることになります。
前の音の長さは本来の4分音符の長さ(480ティック)の8割の長さ(384ティック)でした。
おお。
その値384に96を加えると、480になります。
ちょうど4分音符の長さです。
なるほど。
ここで調節していたわけか。
納得です。

参考までに。
さらにその次のデータを見てみますと。
81 40 90 48 00
音の強さが00ですから、これはノートオフとして使われています。
ノートオフまでの時間は81 40(可変長表記)ですから、これを普通の16進数に直しますと、C0H(192)になります(単位はティック)。
おそらくこれも実際の音符長さの8割と考えて、本来の音符の長さを計算しますと、
192/0.8=240(ティック)
になります。
4分音符の長さが480ティックですから、
おお、確かに。
8分音符です。

しっかりと横道にそれてしまいました。
もうしばらく、このまま脱線が続きます。
次回はいよいよ、バッハに挑戦。
です。

ワンボードマイコンでCP/Mを![第340回]
2013.3.9upload

前へ
次へ
ホームページトップへ戻る