n2kc MML マニュアル
この文書では N2KD FM Driver 付属の MML コンパイラである N2KC が受け付けるMML の記法について説明します。
概要と基本事項
ここでは、MML 全体に関わる事項について説明します。
MML全般に関わる項目
本ドライバの MML の命令は以下の3つに分かれます。コンパイルの処理も 1 → 2 → 3 の順に分割されて行われます。よって、例えば、演奏命令より下に音色の定義を記述したとしても、コンパイル結果への影響はありません。
- 全体設定命令
- 音色定義命令
- パート指定・演奏命令
数値を記述できる箇所において、数値を 0x で始めて16進数の数値を、また 0b で始めて2進数の数値をそれぞれ記述することが可能です。
コメント開始文字は ; です。 ; 以降、行末までの範囲はコメントとして扱われます。
「空白文字」といった場合、スペースとタブ文字を指します。
現時点ではドラムモードに対応する MML 命令はありません。レジスタに直接値を書き込む命令はあるため、それを駆使してドラムモードで演奏させることは不可能ではないですが、大変な作業になると思われます。
演奏命令の処理のタイミング
各パートに記述する演奏命令は、その命令が実際に処理されるタイミングで以下の2種類に分かれます
- コンパイル時に処理されるもの
- MML のコンパイル時に処理され、出力された曲データには表れない命令
- 演奏時に処理されるもの
- 出力された曲データに含まれ、演奏時に処理される命令
タイ命令の手前に発音命令以外の命令を配置する場合は、これらの分類を考慮する必要があります。詳細はタイ命令の説明の際に述べます。
曲データの重さ
ドライバの演奏処理は速度に気を遣って実装しているつもりですが、計算機の性能と曲データによっては演奏時に処理落ちして本来より遅いテンポで演奏されてしまう場合があります。
低速な CPU の環境でも楽曲の演奏の再現性を維持したい場合は、曲データがあまり重くならないよう以下のような工夫をする必要があるかもしれません。
- 同時に発音するパート数を減らす
- 全音符のクロック数を 96 や 48 にする
- 曲のテンポを遅くする
- テンポを遅くしても割込頻度が下がって処理落ちしにくくなります
- ソフトウェア LFO を軽くする
- 使うソフトウェア LFO のチャンネル数を減らす
- ソフトウェア LFO の単位変化毎の待機時間を長くする
- ポルタメントの利用を避ける
全体設定命令
ここでは、全体設定命令について説明します。全体設定命令は、曲データ全体に関わるパラメータを設定するのに使います。全体に対する設定のため、同じ全体設定命令を複数記述して、途中からコンパイルの挙動を変更することはできません。命令の大文字小文字は区別されます。
全体設定命令の一覧は以下の通りです。
| 命令 | 機能 |
|---|---|
#Title | 楽曲タイトル文字列指定 |
#Composer | 作曲者名文字列指定 |
#Arranger | 編曲者名文字列指定 |
#Comment | コメント文字列指定 |
#WNClock | 全音符のクロック数指定 |
#Use | 音源番号と対応する音源の指定 |
#VoiceDef | 音色定義開始 |
#EndVoiceDef | 音色定義終了 |
#Include | 別ファイルの読み込み |
#OctSwap | オクターブ変更命令(<, >)の反転の指定 |
#QReso | Q 命令の分解能の指定 |
#PortaOpt | ポルタメント命令のコンパイルオプションの指定 |
#Title : タイトル文字列設定
曲のタイトルを設定します。命令の後、最初に出現した空白でない文字~行末までの範囲が設定されます。また、この命令の行中でコメントを使うことはできません。
; 例: タイトルを「N2KD のテスト」にする
#Title N2KD のテスト#Composer : 作曲者名文字列設定
作曲者の名前の文字列を設定します。命令の後、最初に出現した空白でない文字~行末までの範囲が設定されます。また、この命令の行中でコメントを使うことはできません。
; 例: 作曲者名を「test 太郎」にする
#Composer test 太郎#Arranger : 編曲者名文字列設定
編曲者の名前の文字列を設定します。命令の後、最初に出現した空白でない文字~行末までの範囲が設定されます。また、この命令の行中でコメントを使うことはできません。
; 例: 編曲者名を「test 次郎」にする
#Arranger test 次郎#Comment : コメント文字列指定
曲データ内に格納されるコメント文字列を定義します。命令の後、最初に出現した空白でない文字~行末までの範囲が設定されます。また、この命令の行中でコメントを使うことはできません。
; 例: コメント文字列を「これはコメントです。」にする
#Comment これはコメントです。#WNClock : 全音符のクロック数指定
全音符のクロック数を指定します。1~255 の値を指定できます。初期値は 192 です。
; 例: 全音符のクロック数を96にする
#WNClock 96#Use : 音源番号と使用する音源の指定
作成する曲データが対象とする音源の種類と、その音源の番号を指定します。 #Use 命令を複数回使うことで複数の音源を用いる曲データを作成できます。
音源の番号は、MML 中でパートの指定が必要になった際に、そのパートがどの音源のものかも併せて指定するために必要になる値です。音源番号には 0~255 の値を指定できます。既に指定済みの音源番号を重複して指定するとエラーとなります。
音源の種類には現在下記の1種類が指定可能です。
- OPL3
; 例: 音源番号0の OPL3 と音源番号10の OPL3 を使って曲データを記述する
#Use 0, OPL3
#Use 10, OPL3#VoiceDef, #EndVoiceDef : 音色定義の開始と終了
指定した音源番号の音源で使う音色定義の開始及び終了を示します。 #VoiceDef を記述する前に定義した音色は無視されます。 #EndVoiceDef を記述した後に定義した音色は無視されます。
#VoiceDef に続けて記載する音源番号はカンマ区切りで複数指定できます。 #EncVoiceDef の代わりに #VoiceDef を書いて、音色定義を継続して記述することができます。
#VoiceDef から #EndVoiceDef の間に音色定義とコメント以外の MML 命令を記述した場合の挙動は未定義です。
#Use 0, OPL3
#Use 1, OPL3
; 0番の OPL3 で使う音色の定義を開始する
#VoiceDef 0
@... ; 音色定義(省略)
; 1番の OPL3 で使う音色の定義を開始する
#VoiceDef 1
@... ; 音色定義(省略)
; 0番と1番の OPL3 で使う音色の定義を開始する
#VoiceDef 0,1
@... ; 音色定義(省略)
; 音色定義の終了
#EndVoiceDef#Include : 別のファイルの読み込み
別のファイルを #Include が書かれている位置に読み込みます。
; 例: voices.mmlを読み込む
#Include voices.mml
指定されたファイル名のパスは、コンパイル対象の MML ファイルがあるディレクトリからの相対パスとなります。例えば、上述の例のような #Include を記述して、「n2kc.exe music\test.mml music\test.n2m」というようにコンパイラを実行すると music\voices.mml を読み込もうとします。
#OctSwap : オクターブ変化方向の交換
<, > 命令によるオクターブの変化の上下方向を逆にするか設定します。 1 を指定すると逆になります。 0 を指定するとデフォルトのままにします。
; 例: 逆にする
#OctSwap 1#QReso : Q 命令の分解能の設定
Q 命令の分解能を設定します。 8 または 16 を設定できます。デフォルトは 16 です。
; 例: Q 命令で指定するゲートタイムを1/8単位とする
#QReso 8#PortaOpt : ポルタメント命令のコンパイルオプションの指定
ポルタメント命令(~ 命令)のコンパイルオプションを指定します。引数に渡す数値の各ビットの説明は以下の通りです。
- bit 7~1
- 未使用です。指定した数値は無視されます。
- bit 0
- 変化先の音程指定のオクターブ記述を後続の MML 命令に継続させないようにする場合1を指定します。
- 例えば
o3 c~>>g dと書くと、bit 0 が0の場合 d は o5 のオクターブで発音されますが、 bit 0 が1の場合 d は o3 のオクターブで発音されます。
; 例: ~ 命令の移動先音程のオクターブ指定を継続させないようにする
#PortaOpt 1音色定義命令
2OP モード用の音色または 4OP モード用の音色を定義することができます。 2OP モード用の音色は最大 256 個まで定義できます。ただし、4OP モード用の音色は、1 個定義するのに 2OP モード用音色 2 個分の領域を占有するため、定義できる数は最大 128 個となります。
音色定義の書式を以下に示します。数値同士は 1 個以上の空白文字またはカンマで区切られている必要があります。
; 2OP モード用音色定義
@NUM CNT FB
AR1 DR1 SR1 RR1 SL1 TL1 KSL1 KSR1 ML1 WS1 AM1 VIB1
AR2 DR2 SR2 RR2 SL2 TL2 KSL2 KSR2 ML2 WS2 AM2 VIB2; 4OP モード用音色定義
@NUM CNT FB
AR1 DR1 SR1 RR1 SL1 TL1 KSL1 KSR1 ML1 WS1 AM1 VIB1
AR2 DR2 SR2 RR2 SL2 TL2 KSL2 KSR2 ML2 WS2 AM2 VIB2
AR3 DR3 SR3 RR3 SL3 TL3 KSL3 KSR3 ML3 WS3 AM3 VIB3
AR4 DR4 SR4 RR4 SL4 TL4 KSL4 KSR4 ML4 WS4 AM4 VIB4
各数値の役割と意味、取りうる値の範囲を以下に示します。
- NUM: 音色番号 (0~255)
- CNT: Connection (2OP: 0~1, 4OP: 0~3)
- FB: Feedback (0~7)
- AR: Attack rate (0~15)
- DR: Decay rate (0~15)
- SR: Sustain rate (0~15)
- RR: Release rate (0~15)
- SL: Sustain level (0~15)
- TL: Total level (0~63)
- KSL: Key scale level (0~3)
- KSR: Key scale rate (0~1)
- ML: Multiple (0~15)
- WS: Wave select (0~7)
- AM: Amplitude modulation (0~1)
- VIB: Vibrato (0~1)
SR と RR の両方を指定するのは、キーオン時とキーオフ時に EGT(Envelope type) を切り替える処理を行っているためです。キーオン時は (RR,EGT)=(指定したSRの値,0) が、キーオフ時は (RR,EGT)=(指定したRRの値,1) がそれぞれレジスタに書き込まれます。
2OP 時の CNT 指定は以下の通りです。
・CNT=0: [1]→[2]→
・CNT=1: [1]┬→
[2]┘
4OP 時の CNT 指定は、CNT の bit 1 が CNT(Cn+3)、 bit 0 が CNT(Cn) となります。例えば、CNT(Cn+3)=1 かつ CNT(Cn)=0 としたい場合は CNT に 2 を指定します。
・CNT=0: [1]→[2]→[3]→[4]→
・CNT=1: [1]─────┬→
[2]→[3]→[4]┘
・CNT=2: [1]→[2]┬→
[3]→[4]┘
・CNT=3: [1]-──┬→
[2]→[3]┤
[4]-──┘マクロの定義と展開
マクロを定義しておくことで、各パートの演奏命令の記述内において、マクロの内容として定義した文字列を展開することができます。
最大64個のマクロを定義できます。マクロ名の最初の文字は A~Z または a~z の英字でなくてはなりません。マクロ名とマクロ内容の文字数に制限はありません。マクロ内でのマクロ呼び出しは7回までできます。
マクロ定義の書式と例を以下に示します。マクロ名とマクロ内容は1個以上の空白文字で区切られている必要があります。また、マクロ定義と同じ行にコメントを記述した場合、コメントの部分はマクロの内容には含まれません。
; 書式: $[マクロ名] [マクロ内容]
; 例: マクロ「bassdrum」「cymbal」を定義する
$bassdrum @10 v13 D-10 o3 c ; バスドラムのマクロです
$cymbal @11 v15 D0 o5 a ; シンバルのマクロです
各パートの演奏命令の記述中でマクロを展開する場合も $ を使います。指定した名前のマクロが定義されていなかった場合、エラーとなります。演奏命令の記述方法については後述の「各パートの演奏命令記述」を参照してください。
; 例: マクロ「hoge」を展開する
0A $hoge
マクロの利用例としてはドラムパートの記述があります。
; ドラムマクロ(bd: バスドラム, sd: スネアドラム)の定義例
$bd @10 v13 D0 o2 g
$sd @11 v12 D5 o3 c
; マクロの利用
;「@10v13D0o2g @11v12D5o3c @10v13D0o2g @11v12D5o3c8 @10v13D0o2g8」相当になる
0A l4 $bd$sd$bd$sd8$bd8
マクロの境界が数値や複数文字の命令の途中を跨ぐことはできません。例えば、内容が D1 であるマクロ $m があった時、 $m0 と書き、この部分を D10 としてコンパイルすることはできません。
各パートの演奏命令記述
各パートの演奏命令は以下のように記述します。パート指定の部分は行頭から始まっている必要があり、また、パート指定と演奏命令の間は 1 個以上の空白文字で区切られている必要があります。
; パートの指定とそのパートにおける演奏命令の記述方法
[パート指定] [演奏命令]
[パート指定]の部分には、音源番号と、その音源の各チャンネルに対応した文字を書きます。
OPL3 では大文字アルファベット A, B, ..., R の18文字を用いてパートを指定します。 OPL3 の FM1, 2, ..., 18 チャンネルがそれぞれ A, B, ..., R パートに対応しています。
同一の音源に含まれるパートに対しては、パート文字を複数連続して書いて複数のパートに同じ演奏命令を記述することが可能です。また、A-F のように - を使ってパート文字を結び、範囲で複数パートを指定することもできます。パート指定文字として * を書くと、全パートでコンパイルされます。
音源番号が異なる音源中のパートに対して、同一の演奏命令を記述する際は、パート指定をカンマで区切って書きます。複数のパート指定を区切るカンマの前後に空白文字を置くことはできません。
; 例: 音源番号0の OPL3 の FM1 と FM10 チャンネルでドレミファソラシと演奏する
#Use 0, OPL3
0AJ cdefgab; 例: 音源番号0の OPL3 の FM4 ~ FM9 チャンネルでドレミファソラシと演奏する
#Use 0, OPL3
0D-I cdefgab; 例: 音源番号0の OPL3 の全パートでスケールの設定を行う
#Use 0, OPL3
0* @=(f+,c+,g+); 例: 1個目の OPL3 の FM1 チャンネルと2個目の OPL3 の FM1,2 チャンネルで
; ドレミファソラシと演奏する
#Use 0, OPL3
#Use 1, OPL3
0A,1AB cdefgab
1 箇所のパート指定に同じチャンネルに対応する文字を複数書いてもエラーにはなりませんが、それ以降に続く MML のコンパイルは 1 回しか行われません。
; 例: 1回しか演奏されない(ドレミファドレミファにはならない)
0AA cdef
行頭がパート指定記述でない場合、演奏命令のコンパイル処理において、その行は無視されます。
MML 命令
ここでは、パート指定に続けて記述する各種命令について説明します。
MML 命令の一覧は以下の通りです。
| 命令 | 機能 |
|---|---|
@ | 音色指定 |
c d e f g a b | 音名指定による発音 |
+ - # _ = | 半音の音程変化指定及び臨時記号 |
HS H | FNum, BLK 直接指定発音 |
r | 休符 |
o < > | オクターブ指定及び変更 |
l | デフォルト音価指定 |
^ | 音価の加減算 |
& | タイ及びスラー |
Q q | ゲートタイム指定 |
v V ( ) | 音量指定及び音量相対変化 |
p | パン指定 |
D DF | デチューン及び細かいデチューン |
~ | ポルタメント及びグリッサンド |
~S | ポルタメント及びグリッサンド設定 |
M MW MO | ソフトウェア LFO 設定 |
MS | ソフトウェア LFO スイッチ |
MH | ハードウェア LFO 設定 |
qR | RR 上書き |
@=(..., ...) | スケール指定 |
[ : ] | 繰り返し制御 |
L | ループ開始位置指定 |
t T tn | テンポ指定 |
y | データ直接出力 |
| | コンパイル対象パート指定 |
` | 複数行コメント |
@ : 音色指定 (演奏時処理)
音色定義で指定した音色番号を用いて、パートで使う音色を指定します。
; 例: A パートの音色を音色番号20の音色にする
0A @20
4OP 音色の指定は A, B, C, J, K, L パートのみで行うことができます。これらのパートで 4OP 音色を指定すると、その時点で自動的に、対応する D, E, F, M, N, O パートと組になって 4OP モードになります。
4OP モード中の D, E, F, M, N, O パートで 2OP 音色を指定しても無視されます。 D, E, F, M, N, O パートで 2OP 音色を指定する前に、 A, B, C, J, K, L パートで 2OP 音色を指定して 2OP モードにしておく必要があります。
4OP モードから 2OP モードに変更した時、4OP モードに組み込まれていたパート(例えば A パートに対する D パート)の音色の状態は未定義としています。 A パートを 4OP から 2OP モードに変更した後、2OP の D パートで演奏を行う場合には D パートで発音命令を記述する前に音色指定命令を記述するようにしてください。
各パートの演奏処理は A パートから R パートへ向かって順に処理されます。例えば、4OP モードの A パートで 2OP 音色を設定する命令と D パートで 2OP 音色を設定する命令を同一タイミングで実行するような MML を記述しても、各 2OP 音色は問題なく設定されます。
4OP モード中の D, E, F, M, N, O パートの発音命令は休符と同様に扱われます。また、4OP モードになった後も D, E, F, M, N, O パートの処理は進みます。 2OP モードに戻す場合等は 4OP モードにしている期間分の休符を置く必要があります。
; 例: 2OPモードと4OPモードの切り替え
; @0, @1が2OP音色、@10が4OP音色とする
0A l4 @0 cdef @10 gfed @0 cdef
0D l4 @1 cdef r1 @1 cdefc d e f g a b : 音名を指定しての発音 (演奏時処理)
発音する音の高さを音名で指定します。オクターブはその時の設定値に従います。音名の後には任意で音程の変化と音価の指定の記述を行うことができます。
音程の変化の記述は、楽譜における臨時記号に相当する指定と、半音単位での上下の直接の指定ができます。
臨時記号に相当する指定では #, =, _ の文字がそれぞれシャープ、ナチュラル、フラットに対応します。 2回続く # と _ はダブルシャープ及びダブルフラットとして扱われます。楽譜の読み方と同様に、これらの記号によるり音程の変化が指定されるとスケール指定命令の指定値は無視されます。事前にスケールを設定する方法については、スケール指定命令の解説を参照してください。さらにそれに続いて任意で + 及び - を続けて音程を半音単位で上げ下げすることができます。 + と - は複数個続ける事が可能です。また、n2kc の MML 文法では小節の概念がないため、臨時記号は付与した音符にのみ効果があります。
; 例: ミのフラットを発音する
0A e_
; 例: ファから3半音上がった音を発音する
0A f+++
; 例: シのシャープから2半音下がった音を発音する
0A @=(b-) ; スケール指定
0A b#--
音名と任意の音程変化の記述に続いて数値を続けて音価を指定できます。音価は音符長とクロック数による指定が可能です。記述可能な値の範囲はどちらも 1~255 です。音価を省略すると、音価にはその時点でのデフォルトの音価が使われます。
音価は数値 n を置くことで指定し、n 分音符として解釈されます。 n は全音符のクロック数を割り切れる数である必要があります。また、音符長に . を続けると付点音符として解釈されます。付点は複数連続させることができますが、付点を付けた音符のクロック数が奇数の場合(2 で割り切れない場合)はエラーとなります。直接クロック数を指定する場合は、数値の前に % を置きます。
; 例: ドを付点4分音符の長さで発音する
0A c4.
; 例: レのナチュラルを48クロックの長さで発音する
0A d=%48HS H : FNum, BLK 直接指定発音 (演奏時処理)
直接指定された FNum と BLK をレジスタに書き込んでキーオンします。 FNum と BLK の値を指定する命令と発音を行う命令に分かれています。
FNum と BLK の指定には HS を使います。 FNum と BLK の値は4種類設定できます。設定先は a, b, c, d の4つの内から選ぶことができます。設定先指定の後に Fnum と BLK の数値をカンマ区切りで記述します。
; 例: 設定 b に FNum=500, BLK=5 を設定する
0A HSb500,5
設定した FNum と BLK の値で発音するには H を使います。発音する際の FNum と BLK をどの設定先から読み出すかを指定する必要があります。さらに任意で音価の指定を記述できます。音価の指定方法は発音命令や休符の命令と同様です。
; 例: 設定 a に記録された FNum, BLK の値で付点8分音符の長さで発音する
0A Ha8.r : 休符 (演奏時処理)
休符を配置します。
r の後ろに任意で音価を続けて休符の長さを指定できます。音価の記法及び省略した場合の挙動は発音命令と同様です。
o < > : オクターブの指定と変更 (コンパイル時処理)
オクターブを指定及び変更します。
o はオクターブの高さとして 1~8 の数値を直接指定できます。 < は1オクターブ下げます。 > は1オクターブ上げます。 < 及び > の結果オクターブの範囲が 1~8 に収まらない場合エラーになります。
オクターブの高さの初期値は 4 です。全体設定命令 #OctSwap により <, > で変化するオクターブの上下方向を逆にすることができます。
; 例: 5オクターブの高さのミから下がる音階を発音する
0A o5 edc<bagfl : デフォルト音価指定 (コンパイル時処理)
発音及び休符の命令で音価の指定を省略した時に使われるデフォルトの音価を指定します。音符長での指定とクロック数での指定が可能です。記述できる値の範囲は 1~255 です。エラーになる条件は発音命令と同様です。
; 例: デフォルト音価を付点8分音符にする
0A l8.
; 例: デフォルト音価を36クロックにする
0A l%36
デフォルト音価指定の初期値は 4 分音符相当のクロック数で全音符のクロック数を 4 で割った値となります。この初期値計算時は全音符のクロック数が 4 で割り切れなくてもエラーにはなりません。割り切れない場合、除算結果の小数点以下を切り捨てた値が初期値となります。
^ : 音価の加減算 (コンパイル時処理)
発音及び休符の命令の後に続けて記述してその音符の音価を加減算します。音価のみを記述すると加算が行われ、音価の前に - を記述すると音価の減算が行われます。
; 例: ドを2分音符に8分音符を加えた長さで発音する
0A c2^8
; 例: ミのフラットを4分音符から8クロック減じた長さで発音する
0A e_4^-%8
加減算の結果、加減算対象の音符のクロック数が 1 未満または 255 より大きくなった場合はエラーとなります。長い期間発音を続ける場合はタイ命令 & を使用します。
ポルタメント命令を跨いで記述することはできません。
; 例: コンパイルできない
0A c2~g^8& : タイ・スラー (演奏時処理)
直前の発音命令のキーオフを行わないようにします。 & の後には音価を示す数値または音名指定による発音命令を記述できます。音価が指定された場合は、音程は変化しません。発音命令が指定された場合は、キーオフが行われずに音程が変わります。
; 例: 手前の c1 から次の c1 に移る際にキーオフをしない (全音符2個分音を伸ばす)
; 下記の2つはどちらでも同じ挙動になる
0A c1&c1
0A c1&1
; 例: c4 から d2 に音程が変わる際にキーオフをしない
0A c4&d2
直前の発音命令との間に別の命令を配置することができます。これにより音を伸ばしている途中に何らかの操作を行うことができます。ただし、このような操作を行えるのはコンパイル後にデータに命令が現れる演奏時処理命令に限ります。
; 例: 発音しながらタイマ B の値を変更する
0A l4 t120 c t110 &c t100 &c t90 &c t120
繰り返し制御命令を跨いで & を使った場合の挙動は未定義です。
; 例: 次のような MML はどのような演奏になるか定義されていない
0A c[&cdef]4 &f ; 繰り返しから抜けたところでタイを使う
0A [cd:&dc]de ; 繰り返しからの脱出命令直後でタイを使う
休符を & で繋ぐことはできません。
; 例: 休符をタイで繋ぐことはできない (下記の MML は全てエラーとなる)
0A c4&r4
0A r4&d8
0A r2&r16Q q : ゲートタイム指定 (演奏時処理)
Q は音価の 1/16 単位でのゲートタイムを指定します。 0~16 が指定できます。本来の音価の末尾から(1/16 × 指定の数値)だけ手前の位置でキーオフします。 #QReso で分解能を設定して 1/8 単位にすることも可能です。
q はクロック数でゲートタイムを指定します。 0~255 が指定できます。本来の音価の末尾から q クロックだけ手前の位置でキーオフします。
Q と q の両方を指定した場合は、両方を加味した位置でキーオフします。 Q と q の計算の結果、発音される音価が 1 クロック未満になった場合は、1クロックだけ発音します。
Q と q ともに初期値は 0 です。
v V : 音量指定 (演奏時処理)
音量を指定します。 v で大雑把に、V で細かく指定できます。 v には 0 から 16 を指定でき、V には 0 から 63 を指定できます。値が大きいほうが音量が大きくなります。 V の 0~63 は、TL の 63~0 に対応しています。初期値は V0 (最小音量)です。
v と V の対応を次の表に示します。
+---++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| v || 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| 13| 14| 15| 16|
+---++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| V || 20| 23| 26| 28| 31| 34| 36| 39| 42| 44| 47| 50| 52| 55| 58| 60| 63|
+---++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+( ) : 音量相対変化 (演奏時処理)
音量を現在の値から相対的に変化させます。 ( は相対的に音量を下げ、) は相対的に音量を上げます。
v 及び V と同様に、この命令にも音量の変化量が大雑把な場合と細かい場合にそれぞれ対応した記法があります。変化量の値は、大雑把な場合は 0~63 が、細かい場合には 0~127 が指定できます。変化量を省略した場合は 1 が指定されたものと見なします。
大雑把に変化させる場合は、( または ) の後に直接数値を記述します。実際の細かい変化量(TL の変化量)は指定した数値の 2 倍の値になります。細かく変化させる場合は、( または ) と数値の間に % を入れます。
v, V の説明で掲載した v と V の対応表のとおり v の1の差は V の差で等間隔になっているわけではありません。そのため、( と ) で音量調節した場合の変化量と、 v で音量調節した場合の変化量に差が出ることがあります。
; 例
0A c )2 c ; 大雑把に音量を2上げる(TL が4下がる)
0A d ( d ; 大雑把に音量を1下げる(TL が2上がる)
0A e )%10 e ; 細かく音量を10上げる(TL が10下がる)
0A f (% f ; 細かく音量を1下げる(TL が1上がる)
この命令は演奏時に処理される命令なので以下のように記述して、だんだんと音量を変化させることが可能です。
; 例
0A l4 [e(]4 ; だんだん小さくなるミp : パン指定 (演奏時処理)
そのチャンネルのパンを指定します。指定できる値は 0~3 となります。値と動作の対応は以下のとおりです。初期値は 3 です。
; パン命令に指定する数値とその動作
0A p0 ; L,Rch ともに発音しない
0B p1 ; Lch からのみ発音
0C p2 ; Rch からのみ発音
0D p3 ; L,Rch 両方から発音D : デチューン (演奏時処理)
そのチャンネルでのデチューン量を指定します。指定できる値は -32768 から 32767 です。具体的な挙動としては、FM 音源のレジスタに書かれる F-Number の値を増減させます。
デチューンとソフトウェア音程 LFO の挙動については、 DF の説明により詳しい記述があります。
DF : 細かいデチューン (演奏時処理)
そのチャンネルでの細かいデチューン量を指定します。指定できる値は -32768 から 32767 です。
細かいデチューン量は F-Number を直接増減させる値ではなく、 1 オクターブの 1/1024 の音程を単位として、音程をずらす量を表します。これは対数的な量のため、細かいデチューン量が同じ値であれば、もとの音程によらず音程のずれる量は同程度になります。ただし、1 オクターブ分の F-Number の分解能が 1024 よりも低い音源では、 DF の値を少し変えただけでは発音される音程に変化がない場合があります。
また、ソフトウェア音程 LFO の値も1オクターブの 1/1024 の音程を単位としています。
デチューンとソフトウェア音程 LFO の動作の概要を以下に示します。
- 発音する音程に対応する F-Number と Block を求める。
- ソフトウェア音程 LFO の値と細かいデチューンの設定値を足して、得られた値を 1 オクターブの 1/1024 の音程でのずらす量とする。
- ステップ 2 で求めた値の分だけずらした F-Number を求める。
- ステップ 3 で求めた F-Number にデチューンの設定値を足して、レジスタに書き込む F-Number の値とする。
上記処理で求められる音程の範囲には制約があります。ステップ 2 でデチューン量が大きいために発音される音程が o1c より低くなった場合は o1c に補正されます。逆に最も高い音程は o9c より僅かに低い音になります。また、ステップ 3 で求められる値の最大値と最小値は音源のレジスタに書き込める最大値及び最小値となるほか、ステップ 2 以降で Block の値は変わりません。
~ : ポルタメント・グリッサンド (演奏時処理)
直前の発音命令の音程から別の音程へ滑らかに移動します。この命令で指定できるのは変化先の音程だけであり、音程が変化するのにかかる時間は直前の発音命令の長さになります。そのため、ピッチベンド命令の後に記述できるのは、オクターブ指定命令と発音命令のみです。
; 例: 4分音符の時間をかけて c から e に滑らかに移動する
0A c4~e
タイ命令で発音命令を分割することで、ある音を発音した後に、その途中から音程を変化させることができます。この際、音価加減算命令 ^ でなくタイ命令 & で繋ぐ必要があるのは、 MML コンパイラに分割した発音命令を別々の命令として解釈させるためです。
; 例: c の4部音符の末尾16部音符の部分で1オクターブ下の a に滑らかに移動する
0A l16 c8.&c~<a &a4~S : ポルタメント及びグリッサンド設定 (演奏時処理)
ポルタメント及びグリッサンドの動作を設定します。設定可能な項目は以下の通りです。
- キーオフ後もポルタメントによる音程変化を継続して行うかどうか。
- 0 を与えると、キーオフ後にポルタメントの音程変化は発生しません。
- 1を与えると、キーオフ後もポルタメントの音程変化が継続します。
デフォルトでは 0 が与えられたのと同じ状態になっています。
; 例: キーオフ後もポルタメントの音程変化が継続するようにする
0A ~S1M : ソフトウェア LFO パラメータ設定 (演奏時処理)
ソフトウェア LFO の変化量などのパラメータを設定します。デチューンとソフトウェア音程 LFO の挙動については、 DF の説明により詳しい記述があります。
設定できるのは以下の5項目です。これらの項目をカンマで区切って指定します。
- 設定対象の LFO
- 各パートは a, b, c の3つの LFO を持っています
- LFO の動作開始から実際に効き始めるまでの待機時間(0~255 クロック)
- 「l」で始めて音価指定も可能(例:
l8で 8 分音符の長さ待機する)
- 「l」で始めて音価指定も可能(例:
- LFO の値の単位変化毎の待機時間(1~255)
- クロック数で指定する
- LFO の値の単位変化量(-127~127)
- LFO の振幅に到達するまでの単位変化回数(1~255)
- LFO の波形
- このパラメータの指定は省略することもできます
- 波形の初期値は 0 (三角波)です
指定できる LFO の波形は以下の2種類です。
- 0: 三角波
- 1: ワンショット
LFO 動作中にこの命令を使うと、設定が行われた LFO は停止します。
; 例: A チャンネルの LFO b を
; 待機時間=付点8部音符、単位変化毎の待機時間=3クロック、単位変化量=2、
; 振幅に到達する変化回数=5回、波形=三角波
; となるように設定する
0A Mal8.,3,2,5,0
三角波 LFO の動作と設定した数値の関係を以下に示します。三角波 LFO は振幅に到達すると折り返します。
LFO の値
↑
A|___________________
| /\
| / | \
|LFO ON / | \
| ↓ / | \
+―+―――+―――-+-―――\――――――――/―→ t
| | | \ /
|←―→|←―-→| \ /
t0 t1 \ /
\/
- t0 = LFO が ON になってからの待機時間
- t1 = 三角波の周期の 1/4 = 単位変化毎の待機時間×振幅に到達する変化回数
- A = 三角波の振幅 = 単位変化量×振幅に到達する変化回数
例えば Mal8.,3,2,5,0 という設定を行った場合は次のようになります。
- 波形 = 0(三角波)
- t0 = 付点8部音符相当のクロック数
- t1 = 3×5 = 15クロック
- A = 2×5 = 10
ワンショット LFO の動作と設定した数値の関係を以下に示します。ワンショット LFO の値は振幅に到達するとそれ以降変化しません。
LFOの値
↑
A|_________________ ______________
| /
| / |
|LFO ON / |
| ↓ / |
+―+―――+―――-+-――――――――――――――→ t
| | |
|←―→|←―-→|
t0 t1
- t0 = LFO が ON になってからの待機時間
- t1 = LFO の変化が止まるまでにかかる時間 = 単位変化毎の待機時間×振幅に到達する変化回数
- A = LFO の変化が止まるときの累計の変化量 = 単位変化量×振幅に到達する変化回数
例えば Ma10,1,-20,100,1 という設定を行った場合は次のようになります。
- 波形 = 1(ワンショット)
- t0 = 10クロック
- t1 = 1×100 = 100クロック
- A = -20×100 = -2000
MW : ソフトウェア LFO 波形設定 (演奏時処理)
ソフトウェア LFO の波形を指定します。 M から LFO の ID(a, b, c) の指定と波形の指定だけ取り出したものです。
LFO 動作中にこの命令を使うと、設定が行われた LFO は停止します。
; 例: A チャンネルの LFO a の波形ををワンショットにする
0A MWa1MS : ソフトウェア LFO スイッチ (演奏時処理)
ソフトウェア LFO の動作を切り替えます。 LFO の ID(a, b, c) と LFO の動作モードを指定します。動作モードは 6 ビットの値で指定し、各ビットの意味は以下の通りです。
- bit 7, 6
- 未使用です。0にします。
- bit 5, 4
- LFO の停止タイミングを指定します。
- bit 5 が 1 の場合キーオフのタイミングで LFO が停止します。
- bit 4 が 1 の場合キーオンのタイミングで LFO が停止します。
- bit 3, 2
- LFO の開始タイミングを指定します。
- bit 3 が1の場合キーオフに同期して LFO が開始します。
- bit 2 が1の場合キーオンに同期して LFO が開始します。
- 両方のビットを 0 にした場合、キーオンとキーオフには同期せず、
MS命令の記述時点で LFO の動作を開始します。
- bit 1, 0
- LFO の対象を選択します。
- bit 1 が 1 の場合、音量に対する LFO として動作します。
- bit 0 が 1 の場合、音程に対する LFO として動作します。
- 両方のビットを0にした場合、 LFO は OFF になり、 bit 5~2 の指定内容はすべて無視されます。
; 例: Aチャンネルの LFO を以下のように操作する
; LFO a: 発音に同期して開始してキーオフで停止する音程 LFO をスタート
; LFO b: 発音に同期せず開始して終了せずに続く音量 LFO をスタート
; LFO c: 停止
0A MSa0b100101 MSb2 MSc0
タイまたはスラーで繋がれた次の音符に進む時には、キーオン及びキーオフに同期した LFO の開始または停止は行われません。
MO : ソフトウェア LFO 対象オペレータ指定 (演奏時処理)
ソフトウェア LFO の対象となるオペレータを指定します。 LFOのID(a, b, c) と対象となるオペレータを示すビット集合を指定します。
チャンネル番号を n としたとき、ビット集合は以下のように指定します。各ビットの値を 1 にしたスロットがソフトウェア LFO の対象となります。
(MSB) 0000_**** (LSB)
|||`- bit0: スロット (n)
||`-- bit1: スロット (n+3)
|`--- bit2: スロット (n+6), 4OP 時のみ有効
`---- bit3: スロット (n+9), 4OP 時のみ有効
ビット集合が0の場合は、現在の音色で音声出力を担当しているオペレータがソフトウェア LFO の対象となります。
この命令を使って対象となるオペレータを選択できるのは音量 LFO のみです。オペレータ指定ビット集合の値は音程 LFO に影響を与えません。
; 例: スロット (n) と (n+6) をソフトウェア音量 LFO(ID=a) の対象にする
0A MOa5MH : ハードウェア LFO 設定 (演奏時処理)
ハードウェア LFO の設定を行うレジスタに値を書き込みます。
OPL3 のパートでは 2 bit 幅の値で DAM、DAV レジスタの値を指定します。 bit 0 が DAV、bit 1 が DAM の値になります。
; 例: DAM=1,DAV=0 にする
0A MH2qR : RR 上書き (演奏時処理)
発音中の音符の残クロック数が指定された値になった時、当該チャンネルの全スロットの RR を指定された値で上書きします。 RR を上書する値の記述は省略でき、省略した場合は 15 で上書きされます。
; 例: 発音中の音符が残り 3 クロックになったら RR を 13 で上書きする
0A qR3,13
; 例: 発音中の音符が残り 1 クロックになったら RR を 15 で上書きする
0A qR1
残クロック数に 0 を指定すると、RR 上書き機能は働きません。
; 例: RR 上書きを行わないようにする
0A qR0@=(..., ...) : スケール指定 (コンパイル時処理)
MML 中で音名が記述された際に、その音名の音階を自動的に半音単位で上下させる量を指定します。 @= に続けて括弧内に音名と変化量をカンマ区切りで記述します。
変化量は =, +, - の記号で指定します。 = を記述すると音程の変化を 0 にします。 + を記述すると自動的に変化させる量を 1 半音分高くします。 - を記述すると自動的に変化させる量を 1 半音分低くします。
+ と - の後に音程の変化量を示す数値を続けて記述することができます。省略すると変化量は 1 半音として取り扱われます。
同じ音名に対する指定を複数回行った場合、一番最後の指定が有効です。また、指定のない音名については、音階を上下させる量は変化しません。
; 例: b, e, a の音名が書かれた時に半音下げるようにする
; (Eb メジャーまたは C マイナー)
0A @=(b-,e-,a-)
; 例: b, e, a の変化量を0にして f が書かれた時に半音上げるようにする
; (Eb メジャーまたは C マイナー -> G メジャーまたは E マイナー)
0A @=(b=,e=,a=,f+)
; 例: b を2半音下げて f を3半音上げる(c の変化量は0になります)
0A @=(c+,b-2,f+3,c=)[ : ] : 繰り返し制御 (演奏時処理)
[ は繰り返し範囲の開始、] は繰り返し範囲の終了を意味します。 ] は後ろに 1~255 の数字を続けて繰り返しの回数を指定できます。 ] の後続の数字を省略すると繰り返し回数は 2 回になります。
最後の繰り返しで : に到達するとその部分でループ範囲から離脱します。
繰り返し回数に 1 を指定した場合、その繰り返し範囲については、初めから最後の繰り返しを演奏している状態となります。
繰り返し命令の内部に繰り返し命令を記述して入れ子にできます。入れ子にできる回数は 8 回までです。
; 例: cdef を4回繰り返す
0A [cdef]4
; 例: cdef を8回繰り返す
0A [[cdef]4]
; 例: cdef cdgb と演奏される
0A [cd:ef]gbL : ループ開始位置指定 (演奏時処理)
そのパートの演奏が末尾に到達した場合に戻ってくる位置を指定します。複数記述した場合は、最後に使われた位置に戻ります。ループで戻っても、音量等の設定値は MML 末尾での値を引き継ぎます。
この命令から MML 末尾までの間に発音命令または休符が無い場合は演奏処理で無限ループが発生するため、コンパイル時にエラーとなります。
; 例: ドレミの後、ファソラシを繰り返す
0A cde L fgab; 例: ループ命令の後に発音命令または休符が無いためエラーとなる
0A cdef cdef Lt T tn : テンポ指定 (演奏時処理)
t では 48 クロック時間を単位とした BPM で曲の演奏速度を設定します。 tn では 1 分間の 4 分音符の個数を用いて曲のテンポを設定します。どちらも指定できる数値の範囲は 1~255 です。 t と tn の指定値は OPN(A) の Timer B に設定する値に換算されます。そのため、指定したテンポと演奏の速度が厳密に一致しない場合があります。
t に同じ値を指定しても、全音符のクロック数が異なると演奏の速度は異なります。一方、tn は全音符のクロック数の影響を受けません。
; 例: 1分に4608(=48*96)クロック程度の演奏速度にする
0A t96
; 例: 「4分音符=128」程度の演奏速度にする
0A tn128
T では OPN(A) の Timer B に設定する値を直接指定します。指定できる数値の範囲は 0~255 です。
; 例: Timer B の設定値を 150 とする
0A T150
初期値は tn で120です。
y : データ直接出力 (演奏時処理)
y[アドレス],[データ] と指定して音源のレジスタに直接値を書き込みます。 OPL3 では A, B, C, D, E, F, G, H, I パートで使うと表レジスタに J, K, L, M, N, O, P, Q, R パートで使うと裏レジスタに書き込みます。
; 例: 表レジスタのアドレス 0x82 (FM3ch の OP1 の SL, RR) に 0x5c を書き込む
0A y0x80, 0x5c| : コンパイル対象パート指定 (コンパイル時処理)
特定のパートに対してのみ MML のコンパイルを行います。
| の後に、その後のコンパイル処理を行いたいパートを指定します。 | とパート指定の間には空白があってはいけません。パート指定とその後の演奏命令の記述の間には1個以上の空白文字が必要です。パート指定を解除するには | または |* を記述します。
; 例: 0AB パートに異なった音量を設定し、また、0B パートのみパンを指定する
0AB @0 l8 q2 |0A v13 |0B p1 v10
; 例: 2回目の cdef の部分で 0C と 0E パートのみ演奏を行う
0CDE l8 cdef |0CE cdef |0D r2 | cdef
; 例: D がデチューン命令として解釈されるのでエラーとなる
0CD cdef |0C D cdef` : 複数行コメント (コンパイル時処理)
複数行にわたるコメントを行います。この命令は行頭のみで使うことができます。
複数行コメントを終了する際も、この命令を使用します。ただし、実際のコメント範囲の末尾は、コメント範囲の終了のためにこの命令を記述した行の行末までとなります。
` 例: この行からコメントが始まる
0A @10 l4 v10 Q4 ; ここもコメント
0A [cdef cdef]4 ; ここもコメント
` この行末までがコメント