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

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

[第346回]


●MIDIファイルhitchck.midの解析

前回からの続きです。
前回は「アダムスファミリー」の演奏が終ってもMIDI演奏プログラムが終了しない原因がトラック1の終了コード(FF 2F 00)に演奏時間を大幅に超える時間データが設定されているためだとわかりました、ということについて説明をいたしました。
「ターミネーター2」も同じ症状だったものが、変更後のプログラムでは正しく終了するようになりましたので、「アダムスファミリー」と同じ原因だと思いますが、データの中身については確認していません、と書きました。
しかし、念のために「ターミネーター2」のMIDIファイル(term2.mid)のトラック1についても確認をしてみました。



おお。
全く同じですね。
トラック1の終わりは
8F FF 7F FF 2F 00
になっています。
うーん。
なんだかよくわかりませんが、こういう作法があったのでしょうかねえ。

お話は変わりまして最後に残りました「ヒッチコック劇場」と「スターウォーズ」です。
前回の終わりに書きましたように、この2つは全く演奏してくれませんでした。
おまけにプログラムもハングアップしてしまいます。
そこで「ヒッチコック劇場」のMIDIファイル(hitchck.mid)を解析してみることにいたしました。
E−80(仮称)ミニコンにhitchck.midをロードしてDMコマンドでテータ表示を行なって調べてみましたら。



このファイルもまたトラック1におかしなデータがあることがわかりました。
上のメモリダンプ画像で、アドレス8451H〜8469Hのところです。
ここでは複数回のテンポ設定が行なわれています。
81 F0 60 FF 51 03 0A 67 5A
84 40 FF 51 03 0C B7 35
82 20 FF 51 03 07 90 FB
です。

FF 51 03がテンポ設定のメタイベントコードでそれに続く3バイトがテンポデータです。
FF 51 03の前にあるのは時間データです。
参考までにそれぞれの意味するところを、わかるように換算して示してみます。
なお計算方法につきましては[第338回]を参照願います。

時間データ(可変長表記)81 F0 60を16進数に換算すると7860H、10進数では30316になります。
テンポ0A675AHは10進数に直すと681818(μs)です。
これは4分音符1個の長さです。
これをヘッダートラックの4分音符の分解能00C0H(192)で割ってティックを求めます。
681818/192≒3551μs
そして1分間あたりの4分音符の演奏数は
1/0.681818×60=88
です。

次の時間データ(可変長表記)84 40を16進数に換算すると0240H、10進数では576になります。
テンポ0CB735Hは10進数に直すと833333(μs)です。
これは4分音符1個の長さです。
これをヘッダートラックの4分音符の分解能00C0H(192)で割ってティックを求めます。
833333/192≒4340μs
そして1分間あたりの4分音符の演奏数は
1/0.833333×60=72
です。

次の時間データ(可変長表記)82 20を16進数に換算すると0120H、10進数では288になります。
テンポ0790FBHは10進数に直すと495867(μs)です。
これは4分音符1個の長さです。
これをヘッダートラックの4分音符の分解能00C0H(192)で割ってティックを求めます。
495867/192≒2582μs
そして1分間あたりの4分音符の演奏数は
1/0.495867×60=121
です。

ところでそれぞれのテンポ指定メタイベントコードの前に置かれております時間データを実際の時間に換算するとどのようになるでしょうか?
まず最初の値なのですが、これは10進数で30316でしたからそれにティックの値3.551msを掛けて
3.551×30316=107652ms

おっとっと。
そういうわけにはいかないのですよねえ。
この時間データは最初のテンポ指定メタイベントコードの前に置かれています

そうなのです。
この最初に出てくる時間データは最初のテンポが決定されるよりも前に置かれているのです
テンポが決まらなければティックの値は求まりません。
ということは、この時間データは永久に消化されないことになります。
hitchck.midが全く演奏されず、プログラムがハングアップしてしまったのは、これが原因だったのでした。
おそらく「スターウォーズ」が演奏されないのも同じ理由からだと思います。

しかし。
にもかかわらず、「ヒッチコック劇場」も「スターウォーズ」もWindows7のMedia Playerではまともに演奏されてしまうのです。
なぜだ?

むむ。
ひょっとしたら。
そういうことかも。
ある仮説を思いつきました。

それを確かめるのには妻の協力が必要です。
私ではダメです。
Windows7のMedia Playerで「ヒッチコック劇場」を演奏して、それを妻に聞かせました。

「途中で、ゆっくりになって、それからまたすぐに元の速さに戻っているみたいね」
やっぱりそうか。

ここで時間のデータに戻ります。
最初の時間データは上に書きましたように計算できませんが、2番目と3番目の時間データは計算することができます。
それぞれその前に設定されたテンポデータにより決まるティックを使って
3.551×576=2045.376(ms)
4.340×288=1249.920(ms)
になります。
いずれも短い時間(約2秒および1秒)です。

するとこういうことになります。
演奏開始からある程度の時間はとりあえず速度は不明ですが、それから約2秒間4分音符=88の速さになったあと、約1秒間4分音符=72の速さになって、それから4分音符=121の速さで最後まで演奏されます。

妻によりますと演奏が開始されてから途中でゆっくりになるまでの速さと、ふたたび速くなってから演奏が終るまでの速さは多分同じくらいの速さだといいます。

さて、いくらMedia Playerでもテンポが決まらなければ演奏することはできません。
おそらく何らかの初期値が設定されていて、「ヒッチコック劇場」のように最初のテンポデータが使えないまま演奏を開始しなければならないような場合には、その初期値が使われるのではないかと思われます。

その場合、Media Playerが演奏開始前にトラック1のテンポデータをサーチして、最後のテンポデータを初期値として設定するというのは余りに不自然です。
その最後のテンポデータを見ますと4分音符=121になっています。
ここがたまたま4分音符=121という値だったため、Media Playerがトラック1の最後のテンポデータを最初に読んだ、ように思えてしまうのですが、そういうことではない、と私は思います。

多分4分音符=120というのは、ふつうの速さなのではないでしょうか。
Media Playerでは、テンポの初期値として、ふつうの速さであるところの4分音符=120が設定されているのではないかと思います。
そのように考えると全てのつじつまが合います。

そこでMIDI演奏プログラムにテンポデータの初期値として4分音符=120を設定しました。
そしてそのように変更したMIDI演奏プログラムでhitchck.midを読み込ませて実行してみましたら。
おお。
「ヒッチコック劇場」が、SC−88に接続したアンプ〜スピーカーから流れ出しました。

感動!
でありました。

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

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