[mml小ネタおぼえがき]

書いた人:SBR (last update:2010/01/31)

Famicompo Vol.6 用のデータ作ってて気が付いた小ネタのメモです。
項目は以下の2つ。

1) テンポずれ対策
2) 三連符未満のシャッフル

特に 1) は基本テクニックの範疇と思われますが、2) のサンプルでも使っている&初心者の助けになるかもしれないのでまとめて文書化しておきます。


1.テンポずれ対策

nsfデータは発声が1フレーム(1/60秒)単位で区切られるため、テンポごとにどうしてもいくつかの「割り切れない音長」が存在する。
こちらの「テンポによる音楽的音長とフレームの関係」参照
何も考えずにこれらの音長を混ぜると、そのパートの以降の発声タイミングがずれてしまう事がある。
 AB t100 v10 q7
 A o4 a8
 B o4 e16.e32

  ↑t100の場合、16分音符=9フレーム、32分音符=4.5フレーム。

   Aチャンネルの「a8」長さは必ず18フレームになるが、
   Bチャンネルの「e16.」と「e32」は少数の切り上げ/切り捨て次第で
   合計が17または19フレームになってしまう恐れがある。

確実な対策は以下の2つ。


 1) すべてのチャンネルを同じ音長に分解する
  A o4 a16.&a32
  B o4 e16. e32
  →全チャンネルに同じ誤差が出るようにしただけなので、曲中にリズムが
   微妙にバラつく可能性がある。(気にするほどではない?)



 2) 音長の減算(~)を使用する
  A o4 a8
  B o4 e8~32 e32 ;←1音目を「8分から32分を引いた長さ」にすることで、合計が8分長になる
  →正確なリズムが保証されるが、音の長さに引き算が混ざるため
   mmlを見てフレーズを思い浮かべにくくなる。




 [おまけ:減算でスラー]

  減算は三度違いまでの音同士をなめらかにつなぐのにも使える。
   A q8 o4 e1 g1
    ↓

   A q8 o4 e1~16  f16~32 g-32  g1

 「接続に使う音長x2」(この場合16分)が「割り切れる音長」なら、三度を超える音同士の接続も可。
   A q8 o4 e1 > d-1
    ↓

   A q8 o4 e1~4 f16~32 g-32  g16~32 a-32  a16~32 b-32  b16~32 >c32 d-1
     ↑「~4」と「16分x4」が等しいため可能。16分が割り切れない場合は誤差が出る。

  (フレーム数を数えてENでつないでしまったほうがソースは見やすいですが、こちらはスロー再生しても
   きれいにつながるのが利点)


2.三連符未満のシャッフル
 ※以下はすべて、この定義が済んでるものとします。
  @v1 = {13,6,0} ; ハイハット
  D t150 q8 o0
8ビート(シャッフル0%)
 D @v1 |:c8 c8:|8

三連符(シャッフル100%)
 D @v1 |:c12 r12 c12:|8

ダンス曲などでは、よく「三連符まではいかない軽いシャッフル」が使用される。
以下はその実装方法。



1) 休符でずらす方法(ベタな方法)

 12分音符による100%シャッフルは、8ビートの偶数番目の音を24分音符ぶん遅らせるのに等しい。
 つまり、8ビートの偶数番目の音を24分音符より短い休符で遅らせてやれば良い。
 96分音符(シャッフル25%)
  D @v1 |:c8 r96 c8~96:|8 ;←前述のように、減算を使えばテンポずれはしない

 48分音符(シャッフル50%)
  D @v1 |:c8 r48 c8~48:|8

 32分音符(シャッフル75%)
  D t@v1 |:c8 r32 c8~32:|8

 →問題点:
   1) 後でシャッフル率を変更したくなった場合に書き換えが面倒。
   2) t150を超えると(誤差のため)苦労して全部書き換えたのに
     変更前と全くリズムが変わらない、というケースも考えられる。


2) フレーム数指定でずらす方法

 「MASAI」でとった方法。シャッフルの前側後側のビートに別々の音量定義を割り当てる。
 1フレーム(シャッフル25%)
  @v101 = {0, 13,6,0} ;← @v1をコピペして頭に無音を1フレーム追加したもの
  D |:@v1c8 @v101c8:|8

 2フレーム(シャッフル50%)
  @v101 = {0,0, 13,6,0} ;← 25%との違いは最初の無音のフレーム数だけ
  D |:@v1c8 @v101c8:|8

 3フレーム(シャッフル75%)
  @v101 = {0,0,0, 13,6,0} ;← 同上
  D |:@v1c8 @v101c8:|8
 同様にすべてのパーカッションに1拍目用と2拍目用の音量定義を用意しておき
 打ち込み時に「その音の開始地点がシャッフルの前側か後側か」を見て使い分ける。
 →音量定義の冒頭の0の数を変更するだけで曲全体のシャッフル率を変えられる。


 →問題点:

  1) フレーム単位の変更なので、テンポを変更した場合に再調整が必要。
     (微調整で一時的にテンポを落として聴く時などにシャッフル率が変わってしまう)
     →1拍目の位置は常に変わらないので、微調整の邪魔になることはまず無いはず。
      とりあえず妥協。


  2) @vの切り替えが大量に発生する
     →元が簡単なフレーズの場合には労力が増えるが、自分の場合もともとパーカッションは
       ハイハット→オープンハット→スネア→オープンハットのようにほぼ毎音切り替えてるので
       問題にならなかった。また、音長の減算をするよりははるかにソースが見やすいはず。



以上。