2024年03月23日
【ツール制作】MMLコンパイラ(通常版) 第2回
MMLコンパイラ(通常版) 第2回です。
さて、「MMLコンパイラ(通常版)」で「T」(テンポ)コマンドが扱えるようにします。
MSXに限らず「音楽演奏ルーチン」を制作する時、必ず問題になる「テンポずれ」。
過去に制作した「MMLコンパイラ(高機能版)」でも相当悩みましたので、よく覚えています。
今更ながら、テンポは1分間に4分音符を何回鳴らすかの設定です。
1分間の走査線割込み発生回数(60分の1秒ごとに発生するので、1分間で3,600回。)をテンポで割った時に小数点以下が発生します。
しかし当然割り算ですので、割り切れない場合が存在します。
この時の割り切れない端数が「テンポずれ」の原因です。
具体的に説明しますと…、
小数点以下の処理は、小数点以下だけを足していき1を超えたところで音長に1加える等で、音長を調整します。
例えば「T40」の16分音符の音長は「22.5」となります。
それを2回鳴らす際、小数点以下は切り捨てられるので調整しないと「22」・「22」となります。
そこで、別途小数点以下をワークで足していき(「0.5」・「0.5+0.5」)、1を超えた2音目の音長に「1」を足して、「22」・「23」とします。
ただ、割り算の商がBASICで扱える小数点以下の桁(確か15桁)を超えるテンポが指定された場合に、加算しても小数点以下15桁目以降がおかしくなります。
例えば「T41」の32分音符の音長は「21.951219512195・・・」と割り切れない音長となり、2回加算しても正確な値にはなりません。
これが「テンポずれ」となります。
この「テンポずれ」を、何らかの方法で調整しなければなりません。
「MuSICA」をはじめ、各種音楽演奏ルーチンは、当然なんらかの処理を行っています。
例えば1分間の総音長を音符側で算出し、1分演奏したらその時残っている端数と総音長で調整する。など、方法はいくつか考えられます。
しかし、元々私は「T」コマンドがなぜあんなに細かく設定できるのか不思議でした。
1テンポの違いを聴き比べずに感じ取れる人がどれだけいるのだろう…。
…と、いう事で「MMLコンパイラ(通常版)」では、テンポずれが発生しないテンポ(64分音符が小数点以下15桁までに割り切れるテンポ)に強制的に調整します。
例えば、「T41」と指定したら、一番近いテンポずれしない「T40」にデータ上強制的に変更します。
過去に制作した「MMLコンパイラ(高機能版)」もこの方式でした。
高機能版は、コンパイラもマシン語でした。
参考までに、マシン語での小数点以下の扱いは下図になります。
バイト数を増やせば増やすほど、より「1」に近づける事が出来ます。
「MMLコンパイラ(高機能版)」では、少数点以下の計算は確か3バイトでやっていたかと記憶しています。