LoginSignup
1
0

More than 1 year has passed since last update.

MGSDRVでループすると音がズレる...?

Last updated at Posted at 2022-03-20

MGSDRV用のMMLを作っていると、ループすると音がズレるのでバグではないか?と思うことがあります。
原因は多くの場合、入力ミスなのですが、入力したMMLが一見完璧に思えるのに、演奏すると期待通り発音されないことがあります。

実例

次のMMLを演奏してみましょう。同じフレーズを2回演奏するつもりのMMLです。

#opll_mode 1
#tempo 90

9 v15@10 l4 [ g4>d4<b-4.l8 agb-agf+ad4 r1 ]2
  • MMLはこちらで実際に演奏できます。

同じフレーズが2回演奏されるように見えますが、2回目は、最初のg4>d4< が4分音符ではなく8分音符で演奏されてしまいます。バグっぽいですよね。

原因

MGSDRV 用の MML コンパイラ MGSC には MML の最適化機能がついていているのですが、ループを一切考慮しないで最適化してしまうという問題があります。

最適化とはどういうことが行われるかというと、直前の音長lコマンドで指定したのと同じ音長のノートは、音長を省略したMMLとして扱われます。例えば

l4 c4d4 l8 e8f8

と書いた場合、直前の音長指定コマンドを考慮して

l4 cd l8 ef

と書いたかのようにコンパイルされます。これがなぜ最適化なのかというと、音長付きの c4d4 はコンパイル後に2バイトになるのですが、音長なしの cd は1バイトになるのです。

この最適化は大変ありがたいことなのですが、ループを使うと、問題が起こります。
例えば次のように書いたMMLが

l4 [c4d4 l8 e8f8]2

次のように最適化されます。

l4 [cd l8 ef]2

このMMLのループを展開して考えてみると、

l4 cd l8 ef cd l8 ef

となります。MMLを書いた側からすると、2回目の cd も4分音符で演奏されることが期待なのですが、
8分音符として演奏されてしまうことが分かります。

対策

lコマンドはループの開始点で必ず指定しましょう。

l4 [cd l8 ef]2

ではなく

[l4 cd l8 ef]2

とすれば意図通りに演奏が行われるようになります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0