GameBoy Music Compiler


img
ゲームボーイの音源を使って音楽を演奏します。
テキストエディタで MML(Music Macro Language)を書き、コンパイラに通すことで
各種プレイヤーで再生可能な GBS ファイルを出力します。

NSF Player や旧バージョンの改良、実機での実験結果を基に新しく作り直しました。
懐かしくも暖かいピコピコサウンドを GB でも楽しめます。





■ MMLコンパイラ

(このページの下の方に「その他注意点」として役に立つ情報を載せています。併せてご覧ください。)

・GameBoy Music Compiler 本体 GBMC_20240108.zip (2024.01.08版)
 サンプル曲とソースコード・チュートリアル付きです。
 .NET Framework が必要です。Windows Update で入手できます。


特徴としては
・KbMedia Player や foobar2000 など各種有名プレイヤーで再生できる GBS フォーマット出力
・GBエミュレータ等でも視覚的に楽しめるビジュアルプレイヤー GBDSP を直接出力可能
・音程/音量/デューティー比/波形メモリ音色/定位それぞれ独立したモジュレーションが定義可能
・高速アルペジオ・ポルタメント・レガート・装飾音符コマンド等々
・PCM 再生(GBDSP のみ・GBS は不可。レートは 4096Hz/4bit)
・物理 4 チャンネルにつき各論理 2 トラックずつ使用可能。下位トラックに優先して上位トラックが再生される。
・配布フリー



コマンドラインからコンパイルします。
成功すると、各種プレイヤーで演奏できる GBS ファイルか、GB エミュレータで実行できる ROM ファイルが出来上がります(#mode 指定による)。
エラーがあると、該当行を表示して終了します。

GB音源の仕様についてある程度知っておくと、より深く使えるかもしれません。
他に良い資料がなかったので、閉鎖された“すずめ愛好会”さんのページを
(勝手に)修正・改変したものを置いておきます。 → GB音源仕様・レジスタマニュアル
GB音源(ニコニコ大百科)も詳しいです。


■ MMLマニュアル

大文字、小文字は基本的に区別されますので注意してください。
どちらでもかまわないものもあります。詳細は各コマンドの説明を参照。

初期状態では最初に v(音量),p(定位),x(波形)を設定しないと音が鳴りません。
波形メモリ音源では波形の登録と @(波形)設定も忘れずに。
ループしない曲では音が鳴りっぱなしになります。最後に休符を入れるとよいでしょう。

処理軽減のためドライバ側でのチェックをかなり省いていますので範囲外のメモリにアクセスして変な音が鳴ったりするかもしれません。
重くなるよりは、まともに鳴るように人力で努力する、というスタンスです。
変なコマンド書いたとしてもせいぜい GB がハングアップする程度なので色々試してみましょう。

GBS を出力するには #MODE 0 を、エミュレータで実行するには #MODE 3(GB カラー)か4(モノクロ GB) を指定すると良いです。

ごちゃごちゃして取っつきにくいと思うので、チュートリアルとして SampleEasy.txt を同梱してあります。
テキストエディタで開いて色々いじってみましょう。

制御コマンド
'A MML
'B MML
'C MML
'D MML
'E MML
'F MML
'G MML
'H MML
トラック指定 A B C D
行頭に記述します。A〜H がそれぞれトラック番号の指定になります。
この後に続けて MML を書くことで、各トラックにコマンドを発行します。
複数指定することも可能で、その場合は同じコマンドが各トラックに発行されます。

GB音源 は 4 音を同時に発音できます。
4音源チャンネルはそれぞれ特徴が異なっており、以下のような仕様です。

・各チャンネルステレオ再生可能(左・中・右の 3段階)
・音源チャンネル A 矩形波再生(デューティ比 4種)音量16段階 スイープ機能&エンベロープ機能
・音源チャンネル B 矩形波再生(デューティ比 4種)音量16段階 エンベロープ機能
・音源チャンネル C 波形メモリ音源 波形は任意(4bit 32ステップ) 音量4段階
・音源チャンネル D ノイズ再生 音量16段階 エンベロープ機能あり

デューティー比とは、矩形波の成分を変えて音色を変化させる機能です。→「x」コマンド参照。
エンベロープとは、音量を徐々に上げ下げする機能のことです。→「k」コマンド参照。
スイープとは、音程を徐々に上げ下げする機能のことです。→「s」コマンド参照。
波形メモリ音源とは、音色をある程度自由に定義できる音源のことです。→「w」コマンド参照。

本コマンドのトラック指定 A〜D と E〜H はこの音源チャンネルにそれぞれ対応しています。
トラック A と E が音源チャンネル A、トラック B と F が音源チャンネル B、以下同です。

音源チャンネル 1つにつき、2トラックあり、通常は ABCD のみを使います。
EFGH を使うと、EFGH で発音している間は ABCD の対応するトラックの発音が無視されます。
1つの音源チャンネルを 2 つのトラックで共有する形になります。
ベースとドラムを混ぜたり、目立たない場所でサブメロを混ぜたり、使い道は色々あります。
昔のゲームなどを注意深く聞いてみると参考になると思います。

このマニュアルの各コマンド右上の ABCD はそのコマンドがどの音源チャンネルで有効かを
表しています。A で有効なものは当然 E でも有効です。
<例>
'A o4v8p3 cde → チャンネル A にドレミの発音コマンド
'AB o4v8c3 cde → チャンネル AB にそれぞれドレミの発音コマンド
         同じ内容を書くのにトラック A,B 2行分書く必要が無い

'A o4v8p3 c1 → トラック A に対してトラック E は上位なので優先され、
'E o4v8p3 g4   4分音符のソが鳴った後ドが付点二分音符だけ発音される
;
(セミコロン)
注釈 A B C D
行頭に「;」でも途中からでもかまいません。
コメントです。コンパイラはこれ以降、改行まで解釈をスキップします。
<例>
;この行はコメント。
'A cde ; fgab → ファソラシ(fgab)の部分は無視される。
/* 〜 */
注釈ブロック A B C D
行頭に指定します。
/* から、*/までの間をコンパイラは読み飛ばします。
<例>
/*
'A o4v8p3 cdecde
*/
'B o4p3v3 fgafga

→ トラック A のがスキップされるのでトラック B だけを聞くことができます
  トラック毎の出音チェックや曲の前半部分をスキップしたりできます
#M番号 MML
#MKILL番号
#MKILLALL
マクロ登録/削除 A B C D
行頭に記述します。番号には 0〜999 が指定できます。
ここで登録したマクロを MML に記述することで登録内容を取り込む事ができ、MML を簡略化できます。
同じ番号のマクロを登録すると、後で登録した内容は追加扱いになります。

#MKILL 番号とすることで、該当番号のマクロ登録内容が削除されます。
#MKILLALL とすると、登録された全てのマクロ内容が削除されます。

ここで登録した内容を実際に MML 中で呼び出すのは以下のコマンドになります。
関連→マクロコマンド「m」
関連→ビルトインマクロコマンド「M」
<例>
#M0 fg m0=ファソ(fg)を登録しておく
'A o4p3v8 cde m0 ab → ドレミファソラシになる

#M0 ab 追加登録なので m0=ファソラシ(fgab)になる
'A o4p3v8 cde m0   →ドレミファソラシになる
#@番号 {$xx,・・・,$xx}波形メモリ音源の音色登録 A B C D
行頭に記述します。番号には 0〜126 が指定できます。
音源チャンネル C の波形をここで最大 127 種類登録できます。
{ }内に $に続けて2桁16進数を16個並べます。

波形は最低一つ登録して、それを使って発音しないと音源チャンネル C の音は鳴りません。
音色が全て 0 で初期化されているためです。

16進数のアルファベット部分は大文字でも小文字でもかまいません。 $da = $DA
2桁でなく1桁でもかまいません。 $01 = $1
","での区切りをせずに16進数を32個並べる形式でも登録できます。
<例>
#@0 {$01,$23,$45,$67,$89,$ab,$cd,$EF,$fe,$dc,$ba,$98,$76,$54,$32,$10}

'C @0 p3v3 cde → @0 で登録した音色でドレミ 三角波で鳴ります

#@1 {0123456789ABCDEFFEDCBA9876543210} ;区切り無しでの音色登録
#F番号 {xx,・・・,xx}ピッチモジュレーション登録 A B C D
行頭に記述します。番号には 0〜127 が指定できます。

同じ番号のものが複数ある場合、後で書いた方が登録されます。
音程を連続的にずらす変化量を記述します。LFO 効果などに使えます。
変化量は -127〜127 までで、データの個数は 256byteまでです(通常使用で問題ないレベル)。
ここで登録したモジュレーションを使用するには MML 中で「zf」コマンドを使用します。

登録した数値を基準音程に加算して音程を相対変化させます。
変化量は GB の音源内部の細かい周波数値なので、「-1」指定でドがシになるわけではありません。

※ "\"と"["〜"]"と"$"コマンドについて

データ中に"\"があると、それ以降モジュレーションは停止します。

データ中に "数値1 ] 数値2" があると <数値1>番目の "[" があるポイントまで<数値2>回ループします。
"["が設定されていないと先頭に戻ります。<数値1>が省略されている場合は直近の"["に戻ります。
<数値2>は省略できません。数値2は 2〜255までです。

本コマンドには無限ループが無いので、もし無限ループさせたい場合は "]2,]2"などと記述することで
擬似的に無限ループにできます。

"]"は実のところループというよりジャンプコマンドであり、"["も単に戻る場所の目印あるいは
しおりのようなもので、数値1はそのしおり番号ということになります。

入れ子はできません。
少しややこしいのですが、ループ回数を覚えておくメモリが1つしかないので、"]255,]2"と書いても
255*2回ループするわけではなく、]2で戻った後、再び "]255"に到達した時点で 2→255に
上書きされてしまいます。結果、255→2→255→2... と無限ループになります。

["と"]"の間にデータが無いと音源ドライバがハングします。

データ中に$があると、速度設定を変更します。
これは MML 中でのモジュレーション呼び出し「zf」コマンドで指定する速度指定を強制的に上書きします。
アタックだけ一瞬の変化で後はゆるやかな変化、といったモジュレーションが可能です。
注意すべきは、zfで指定した速度の上書きなのでそれ以降は上書きされた状態でキーオンされるということです。
上の例では、一旦ゆるやかにしてしまったら次の発音の頭での「一瞬」までもゆるやかになってしまいます。
これを避けるためには、zfで指定する速度値をデータの頭にも埋め込んでおく必要があります。

<例>
#F0 { 0,-1,-2,-1,0,1,2,1,]255 }
'A o4p3v8 zf0,4,24 c1^1  → LFO効果. #F0番をスピード4、ディレイ24フレームで適用
               データには"["が設定されていないので先頭に255回戻る

#F1 { [,0,1,2,3,]4,[,3,2,1,0,]4,1]255 } → ループを使った例
               <数値1>を指定しない"]"は直近の"["に戻る

#F2 { $1,10,$4,[,0,-1,0,1,]255} →速度設定を使った例
'A o4p3v8 zf0,1,24 c1^1     zfの速度設定 1 をmodデータ中にも埋め込んでおく

#V番号 {xx,・・・,xx}音量モジュレーション登録 A B C D
行頭に記述します。番号には 0〜127 が指定できます。
同じ番号のものが複数ある場合、後で書いた方が登録されます。
音量を連続的に上下させる変化量を記述します。
変化量は -15〜15 までで、データの個数は 256byteまでです(通常使用で問題ないレベル)。
音源チャンネル C(波形メモリ音源)で使う場合は変化量は -3〜3 にしてください。
ここで登録したモジュレーションを使用するには MML 中で「zv」コマンドを使用します。

登録した変化量を基準音量に加算して音量を相対変化させます。
GB の仕様で短時間に頻繁に音量を操作すると音が荒れます。
音源チャンネル ABDでは ハードウェアエンベロープ「k」との使い分けを推奨。

#F 同様、データ中で "\"、 "["〜"]"、"$"のコマンドが使えます。
<例>
#V0 {0,-1,-2,-3,-4,-5,-6,\}

'A p3x2o4 v7 zv0,12,0 c1^1
 音量 v7 からだんだん音量が下がっていきます
#X番号 {xx,・・・,xx}
#W番号 {xx,・・・,xx}
デューティー比/波形メモリ音色モジュレーション登録 A B C D
行頭に記述します。番号には 0〜127 が指定できます。
同じ番号のものが複数ある場合、後で書いた方が登録されます。

#X は音源チャンネル A/B で使用するデューティ比のモジュレーションです。
#W は音源チャンネル C(波形メモリ音源)で使用する波形メモリ音色のモジュレーションです。
この2つはドライバ内部では同じなのですが、データの内容が違うので登録コマンドを分けています。

<#X>
データにはデューティ比の数値 0,1,2,3 いずれかを記述します。
0=12.5% 1=25% 2=50% 3=75% の矩形波デューティ比になります。

<#W>
データには波形メモリ音色番号を記述します。この番号は #@ コマンドで登録した 0〜126 の数値です。

#W,#X で登録したモジュレーションを使用するには MML 中で「zw」コマンドを使用します。

内部で同じコマンドなので、#W0 で登録した後 #X0 を登録すると #X0 の方で上書きされてしまいます。
また、MML 中の zw コマンドで呼び出しする際も、波形メモリが使えない音源チャンネルで #W 登録番号が
呼び出せたりしてしまいます。トラブルを避けるため #W と #X で登録番号をずらすなどの対策を推奨。

#F 同様、データ中で "\"、 "["〜"]"、"$"のコマンドが使えます。
<例>
#X0 {0,1,2,3,]2,]2}

'A p3v8o4  zw0,1,0 c1 →デューティ比が 0,1,2,3,0,1,2,3 と高速に切り替わります

#@0 {0000000000000000FFFFFFFFFFFFFFFF}	;矩形波
#@1 {0123456789ABCDEFFEDCBA9876543210}	;三角波

#W10 { 0 ,1 ,]2 ,]2 }
'C p3v3o4 zw10,8,0 c1^1 →矩形波と三角波が交互に切り替わります
#P番号 {xx,・・・,xx}
定位モジュレーション登録 A B C D
行頭に記述します。番号には 0〜127 が指定できます。
同じ番号のものが複数ある場合、後で書いた方が登録されます。
定位(パン)を連続的に変化させます。
データは 0〜4 で、データの個数は 256byteまでです(通常使用で問題ないレベル)。
ここで登録したモジュレーションを使用するには MML 中で「zp」コマンドを使用します。

0=無音,1=左,2=右,3=中央です。
4=ランダムで1〜3のいずれかになります。この乱数値はドライバ側処理なので、毎回違う値になります。
GB 音源の仕様で短時間に頻繁にパンを操作すると音が荒れます。

#F 同様、データ中で "\"、 "["〜"]"、"$"のコマンドが使えます。
<例>
#P0 {1,3,2,]2,]2}

'A p3v8o4  zp0,8,0 c1 →左・中央・右...と切り替わります
#INCLUDE "ファイル名"外部ファイル取り込み A B C D
行頭に記述します。
ファイル名で指定された外部ファイルを取り込みます。
お気に入りの音色セットやよくつかうモジュレーション定義などを外部ファイルにしておくと便利です。
GBMC は実際に曲中で使われた音色や定義しかデータ中に含めないので
データサイズが膨れあがる心配はありません。
<例>
#INCLUDE "tone.txt"
#PCMLOAD
番号,"ファイル名",ループ指定
PCMファイル登録 A B C D
行頭に記述します。番号には 0〜255 が指定できます。
曲中で使用する PCM ファイルを指定します。
PCM ファイルは当サイトの別ページの PCM コンバータで変換した、
4096Hz/4bit/2データ1バイト/16byte 境界揃え/最大サイズ16384byte のものに限ります。
音質が悪いので、使うところは限定されると思います。

PCM 音色を MML 中で指定するのは「@p」コマンド、実際に発音するのは「u」コマンドです。

ループしない場合は、ループ指定に何も書かないか -1 としてください。
ループする場合はループアドレスを 0〜16368 の範囲で指定してください。
16進数で指定する場合は $0〜$3FF0 です。

GBS 出力時は PCM は使用できません(GBDSP のみ)。
<例>
#PCMLOAD 0,"drum1.pcm"
#PCMLOAD 1,"voice.bin",$200  ← ループ指定は16進数でも10進数でも良い

'C p3v3o4 @p0 u8 → @p0で 0 番に登録したPCM を u8 で8分音符で再生します
#TITLE "タイトル"タイトル名登録 A B C D
行頭に記述します。省略可。
GBS / GBDSP で出力する際のタイトル欄を書き込みます。
全角・半角混在可。32バイトまでです。
このコマンドは大文字、小文字どちらでも可です。
<例>
#TITLE "サンプル - sample - "
#AUTHOR "作者"作者名登録 A B C D
行頭に記述します。省略可。
GBS / GBDSP で出力する際の作者欄を書き込みます。
全角・半角混在可。32バイトまでです。
このコマンドは大文字、小文字どちらでも可です。
<例>
#AUTHOR "author"
#COPYRIGHT "著作権者"著作権者名登録 A B C D
行頭に記述します。省略可。
GBS /GBDSP で出力する際の著作権者欄を書き込みます。
全角・半角混在可。32バイトまでです。
このコマンドは大文字、小文字どちらでも可です。
<例>
#COPYRIGHT "test"
#FRQ 数値Ch.D PCM ノイズ周波数指定 A B C D
行頭に記述します。数値は 0〜255 です。
エミュレータと実機、またエミュレータによっても 音源チャンネル D でのPCM再生は
ノイズ周波数の指定値によって聞こえ方がかなり変わります。
この指定で、PCM再生時のノイズ周波数を強制的に指定できます。
省略時は 0 になります。エミュレータは 0、実機では 5 あたりが良いようです。

このコマンドは大文字、小文字どちらでも可です。
<例>
#FRQ 0
#OCTAVE-REVオクターブ指定反転 A B C D
行頭に記述します。
オクターブ相対指定「>」「<」の効き方を逆にします。
「>」でオクターブ下げ、「<」でオクターブ上げになります。

このコマンドは大文字、小文字どちらでも可です。
<例>
#OCTAVE-REV

'A o4 c>c → o4c o3c と展開される
#NOISENOTEノイズ音程指定 A B C D
行頭に記述します。
ノイズチャンネル(Ch.D)のノイズ周波数指定を11オクターブの音階で指定できるようにします。

この指定をしない場合(デフォルト)「cdefgab」の何を書いても「w」コマンドで指定した周波数で
発音しますが、#NOISENOTE を指定すると「w」は無視され「cdefgab」に割り当てられた周波数で
発音するようになります。

割り当てられた音階は xpmck のものと同じです。

このコマンドは大文字、小文字どちらでも可です。
<例>
#NOISENOTE
'D o0 c d e → w$E0c w$A7c w$A7c と展開される. オクターブは o0-o10 まで有効
#MODE 数値GBS出力指定 A B C D
行頭に記述します。数値は 0,1,2,3,4 です。

0 (デフォルト)では GBS フォーマットのファイルを出力します。

1 を指定すると GBS でなく、生のバイナリファイルを書き出します。
 主に開発用にドライバと組み合わせてコンパイルする時の為のコマンドです。

2 を指定すると、バイナリと GBS の両方が出力されます。

3 を指定すると カラーGB用の GBDSP の ROM ファイルを出力します。

4 を指定すると モノクロGB用の GBDSP の ROM ファイルを出力します。

省略時は自動的に GBS 出力(0)になります。

このコマンドは大文字、小文字どちらでも可です。
<例>

#MODE 0
#BANK 数値出力バンク指定 A B C D
行頭に記述します。数値は 1〜255 です。省略可。
通常は指定しないでください。
生バイナリファイルを書き出す際に格納開始バンクを指定するためのコマンドです。
バンク情報は曲オブジェクトに埋め込まれます。
<例>
#BANK 1
#DEFLEN 数値全音長のフレームカウント指定 A B C D
行頭に記述します。数値は 1〜255 です。省略不可。
デフォルトは 192 です。各 X 分音符はこの数値の約数になります。
割り切れない音符を指定した場合はエラーになります。
例. 四分音符=192/4=48カウント

MML コマンドの "C" でも指定できます。
この指定は n 音長には影響せず、あくまで X 分音符指定をフレームカウントに変換する際の計算が変わるだけです。
<例>
#DEFLEN 96
全音符のカウントが 96 になります。テンポがそのままの場合は二倍速になります。
MML コマンド
cdefgab(+/-)数値音程・音長 A B C D
音程を指定します。cdefgabがそれぞれドレミファソラシです。
+をつけると半音上がり-をつけると半音下がります。

音程の後の数値は音長を表します。4が四分音符、16が十六分音符などです。
音長を省略すると「l」(小文字のエル)コマンドで指定した数値が使用されます。

数値は #DEFLEN で指定した数値または MML コマンドの "C" で指定した数値の約数でなければなりません。
未指定の場合は 192 の約数なので、
デフォルトで使えるのは 192 96 64 48 32 24 16 12 8 6 4 3 2 1 (分音符) となります。
(以下、192フレーム=全音符としての説明です)

符点も指定でき「.」(ピリオド)をつけることで前の音長の半分を追加します。
複数の符点も可ですが、前の音長の半分が整数でないとエラーになります。

音長は「n」に続けて指定すると、フレーム数を直接指定できます。
n192を指定すると192フレーム分(=全音符)発音されます。
n指定の時は1〜999までの数値が指定できます。
n指定時も符点はつけられます。

1フレーム=最短音長です。
192/○分音符=nフレーム で導かれます。
コンパイル結果に表示される "xxxx count" の数字は各トラックの総フレーム数を表しています。

オクターブ指定は「o」コマンドを使ってください。

音源チャンネル D(ノイズ)では「#NOISENOTE」指定によって音階モードと非音階モードが
選択できます。音階モードは11オクターブ中の「それっぽい」音階で発音します。
あくまでノイズなので、そう聞こえなくもないレベルです。

非音階モード(デフォルト)は c〜b の内どれを使ってもノイズ発音になります。
この場合の音階(ノイズ周波数)は「w」コマンドを使って指定します。

<例>
'A o4p3v8 c+1.. → c+1c+2c+4と同じ音長になります 音程はオクターブ4 ドの半音上
'A o4p3v8 c+n192.. → 上と同じ音長です 192フレーム+96フレーム+48フレーム
r数値休符 A B C D
休符です。音長指定は音程と同じです。
数値を省略すると「l」コマンドで指定した基準音長になります。
休符にもタイコマンド「^」や「n」での音長指定(マイナスも可)が使えます。

& の後に r(休符) を記述した場合は Q/q のゲート効果発動になります。
「&」の項目も参照してください。
<例>
'A r1 → 全休符
'A rn192 →全休符
'A r2^2 →全休符
^数値タイ A B C D
音長を加算します。
音を延ばしたいときなどに使います。
指定できる音長は音符のものと同じで、192 の約数または nフレーム数です(符点可)。

数値の部分をマイナスにすると、音長を足すのではなく、引いて処理します。
引く数値にも nフレーム数が使えます。
引いた結果音長が 0以下になるとエラーが出ます。
<例>
'A o4p3v8 c1^1^1. → 全音符3つと二分音符一つ分の長さで発音します
'A o4p3v8 c1^n384^n96 → 上と同じ音長です
'A o4p3v8 cn192^-4 → n192(全音符)から四分音符分の音長を引いて付点二分音符で発音
&スラー A B C D
キーオンしたまま次のコマンドに繋げます。
「&」の後の音程コマンドはキーオンしないで発音します。
「&」コマンドは音程系コマンドの直後でないとエラーになります。

キーオンで発音→各種mod、エンベロープ、スイープが初期状態からスタート
キーオンせずに発音→各種mod、エンベロープ、スイープが現状のまま音程だけ変化

という違いがあります。音程が前のものと同じであればタイと一緒です。
弦を弾いた後、押さえた指だけをずらすベンドのような感じです。

音量、エンベロープ、スイープはキーオンしないと反映されない GB 音源の仕様により
& の後にこれらが来た場合 & を無視して強制キーオンになります。
ただし、音源チャンネル C の波形メモリ音源だけはキーオンせずに音量が反映されるため
強制キーオンはしません。

Q/q コマンドでゲートが指定してあり、かつ & の後に r(休符) が来た場合、
r は休符(即時音量 0)ではなく、ゲート発動になります。
Q/q で指定してあるカウント値は無視して r 以降即時発動します。
本来休符として無音になる部分を、徐々に音量が減衰していく効果などを得られます。
<例>
'A o4p3v8 c1&c1 r → 全音符2つの長さで発音します。 c1^1 と同じです
'A o4p3 k8,0,5 l32 b&b-&a&a-&g&g-&f&e&e-&d&d-&c r
         → エンベロープによって音量が下がりつつ音程も下がっていきます

'A o4p3 k8,0,5 l32 b&b-&a&a-&g&g-& v8f &e&e-&d&d-&c r
         → 音量 v は & を無視するため v8f のところで再キーオンになります

#F0 { 0,-16,0,16,]2,]2 }
'A p3v8o5x2 zf0,1,48 c1&g1 → mod を維持したままドからソに変わる
'A p3v8o5x2 zf0,1,48 c1 g1 → &をつけないキーオン時、mod は最初からスタート

'A t64p3x2k$A0o4 L q24,3,0 cn48 gn12&rn48 en12rn48
→ キーオンから24カウント後に音量の減衰が始まる q 設定で
 gの音は休符部分で強制的に減衰が始まる。g自体が12カウントでも&rで発動。

o数値
>
<
オクターブ指定・オクターブ上下 A B C D
音程のオクターブを変えます。 音源チャンネル ABC では数値は 2〜7 までです。
音源チャンネル D では数値は 0〜10 までです。
「>」で現在のオクターブを一つ上げ、「<」で一つ下げます。
数値を指定しないと o4 になります。
発音可能域を超えた音程(o2cより下など)はエラーが出ます。

#OCTAVE-REV を指定している場合「>」「<」の上下が逆になります。

音源チャンネル AB では o4a=440Hz となります。
波形メモリチャンネル C は o5a=440Hz となります。
チャンネル C は、A/B より 1 オクターブ低い音が出せますが、逆に一番高いオクターブが出ません。

本来はチャンネル C でも o4a=440Hz、指定可能範囲 o1〜o6 とすべきですが
プログラムの都合により、チャンネル A/B と合わせています。
<例>
'A v8p3 o4cdefgab>c → ドレミファソラシド
'A v8p3 o2c- → エラーが出ます
'A v8p3 o6>>>c → o9になってしまうのでエラーが出ます
v数値
v+数値
v-数値
v$16進数
音量指定・音量上下 A B C D
音量を変えます。
音源チャンネル ABD では数値は 0〜15 までです。数値省略時は v8 です。
音源チャンネル C では数値は 0〜3 までです。数値省略時は v3 です。
「v+数値」で現在の音量を数値分上げ、「v-数値」で数値分下げます。数値省略は±1。
v+ あるいは v- で音量が最大/最小を超えた場合はそれぞれ最大・最小値となります。

波形メモリ音源チャンネル C は音量が 4 段階しかなく、
v3=100% v2=50% v1=25% v0=0%
の音量になります。

GB のハードウェア仕様として、Ch.ABD で音量を頻繁に変えるとプチノイズが発生します。

v$8B など16進数で指定すると音量と同時にエンベロープの指定も同時に行えます。
音量は上位 4bit が音量、下位4bit がエンベロープ情報なので、
これらを一括して書き込むことが出来、エンベロープコマンドと分けて書く手間が省けます。

以下に16進数での指定値を導くスクリプトを置いておきます。
パラメータの意味についてはエンベロープ「k」コマンドも参照してください。

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 開始音量
上昇 下降
7 6 5 4 3 2 1 0 変化 7=遅い 1=速い 0=なし
16進数の部分は必ず大文字で記述してください(音程と誤って解釈してしまうため)。
桁は1桁でも2桁でもかまいません。
<例>
'A p3o4 v15c → 最大音量でド
'A p3o4 v13 v+5 c → v15c と同じです

'A v$F1 → 下向きエンベロープ・速度1・初期音量15 を指定します
'A v$1cdef → $1C def なのか$01 cdef なのか分からないのでエラーになります
V+数値
V-数値
トラックマスターボリューム A B C D
大文字の V です。
そのトラックの小文字の v で指定される音量すべてに加算する値を指定します。
エンベロープコマンドの初期音量指定にも加算されます。
トラック全体の音量を底上げしたりする際に役に立ちます。
加算した結果 v15 を上回ったり v0 を下回った場合は、それぞれ v15,v0 になります。

※注意
「加算する値」なので、元に戻す場合は V0 にします。
<例>
'A o4p3 V+2v8cv9def → v8はv10、v9はv11相当になります

'A v10 V+5 cde V-5 fga → 元に戻っていない。 v15cde v5cde になってしまう。
'A v10 V+5 cde V0 fga → こちらが正しい
l数値基準音長 A B C D
小文字のエルです。音程の後の数値を省略した時の音長を指定します。
数値省略時は l4(四分音符) になります。
音程と同じく、「n数値」での指定や「^」タイコマンドを使った指定も出来ます。
符点も使えます。
<例>
'A l4cde → 四分音符でドレミ c4d4e4 と同じ。
'A l4c l8de → 四分音符でド 八分音符でレミ c4d8e8 と同じ。
t数値
t+数値
t-数値
テンポ A B C D
曲全体のテンポを設定します。
値の範囲は 1 〜 255 で、省略時は 64 です。値が大きくなるほど速くなります。
テンポはどのトラックに書いても個別ではなく共通の値となります。
プラス・マイナスに続けて数値を書くと、現在のテンポからの相対値が設定されます。

テンポに関しては「テンポについての注意事項」もご覧ください。

参考までに、音楽的テンポ(一分間に四分音符が何回鳴るか)は以下のようにして求められます。

BPM = 75 * (t の値 / 64)

下のフォームに数字を入れて変換ボタンを押すことでで相互に変換できます。

t の値= 音楽的テンポ=
<例>
'A t64 o4p3v8 cdefg → デフォルトのテンポ
'A t128 o4p3v8 cdefg → およそ2倍のテンポ
k数値1,数値2,数値3
k$16進数
エンベロープ A B C D
ハードウェアエンベロープです。音量を連続的に上下します。
音源チャンネル C では使えません。
数値1 : エンベロープ開始時の初期音量 0〜15
数値2 : エンベロープの向き 0/d=下降 1/u=上昇
数値3 : エンベロープの速さ 1=速い〜7=遅い 0=エンベロープなし。

※エンベロープの速さはn/64秒に一段階音量を上下するという意味です。

数値1の初期音量はトラックボリューム V の影響を受けます。
v+/v- で音量を上げ下げすると、エンベロープの初期音量が増減します。

数値2は 0,1 の代わりに d,u も可能です。[d]own,[u]p の意。

3つあるパラメータはそれぞれ省略可能です。省略した場合、前回指定した値が使われます。

k$16進数とすることで、上記 3パラメータを一括設定できます。
この場合 v$16進数と機能も書式も全く同じです。v の項目に簡易スクリプトがあります。
<例>
'A p3o4 k8,0,7 c1 → 減衰エンベロープでドを発音
'A p3o4 k0,1,7 c1 → 上昇エンベロープでド 速度は前回指定した値を使う
'A p3o4 k$0F c1 → 上の上昇エンベロープと同じ

'A p3o4 V+2 k4,0,3 c1  → k6,0,3 相当になります
'A p3o4 k4,0,3 c1 v+2 d1 → d(レ)の方は k6,0,3 になります

'A k7,0,1 c k,,2 d → 2回目の指定は k7,0,2 と補完される
s数値1,数値2,数値3
s$16進数
スイープ A B C D
ハードウェアスイープです。音程を連続的に上下させます。
音源チャンネル A 専用です。
数値1 : スイープの速さ 1=速い〜7=遅い 0=スイープ無し
数値2 : スイープの向き 0/u=上向き 1/d=下向き
数値3 : スイープ変化量 0=大きい〜7=小さい

数値を省略して s だけを指定した場合はスイープをオフにします。
※スイープの速さは n/128 秒に 1 回、現在の周波数にスイープ変化量を与えるという意味です。
※スイープ変化量は現在の周波数を n 回右シフトした値を ± するという意味です。

数値2は 0,1 の代わりに u,d も可能です。[up],[d]own の意。

3つあるパラメータはそれぞれ省略可能です。省略した場合、前回指定した値が使われます。

s$8B など 16進数での指定も出来ます。
3 つのパラメータを一括して書き込むことが出来ます。
bit6-4=速さ bit3=向き bit2-0=変化量 です。
以下に16進数での指定値を導くスクリプトを置いておきます。
7 6 5 4 3 2 1 0 速度 1=速い 7=遅い 0=なし
上昇 下降
7 6 5 4 3 2 1 0 変化量 7=小さい 0=大きい

16進数の部分は必ず大文字で記述してください(音程と誤って解釈してしまうため)。
桁は1桁でも2桁でもかまいません。

なめらかな音程変化を行うのには、ポルタメントコマンド「{}」も有用です。
ポルタメントは Ch.A 以外でも使えます。
<例>
'A p3o4v8 s1,0,7 c1 → 減衰スイープでドを発音。急速に音程が上がります
'A p3o4v8 s1,0,7 c1 s d1 → d(レ)ではスイープはオフになります

'A p3o4v8 s$17 c1 → s1,0,7 と同じ

'A s1,0,1 c s,,2 d → 2回目の指定は s1,0,2 と補完される
x数値デューティー比 A B C D
矩形波チャンネルのデューティー比を指定します。
GB音源チャンネル AB は矩形波を出力しますが、その成分(デューティ比)を決めるのが本コマンドです。
Ch.A/B の音色指定と考えて良いでしょう。

 ̄ ̄|__ = 50%とすると

 ̄|___ = 25%

 ̄ ̄ ̄|_ = 75% となります。

音源チャンネル AB 以外では使えません。数値は 0〜3 です。数値の意味は以下の通り。

0=12.5% 1=25% 2=50% 3=75%

数値を省略すると x2 になります。
25% のデューティ比と 75% は互いに反転した形になるので同じように聞こえます。
50% をプーとすると 25%は ピー、12.5% はビーといった鋭い感じになります。
<例>
'A p3v8o4 x0c1 → 波形デューティ比12.5%でド
w数値
w数値1,数値2,数値3
ノイズ周波数 A B C D
ノイズ周波数を指定します。Ch.D の音色指定と考えて良いでしょう。
1パラメータ版は数値は 0〜255 です。省略時は w0です。16進数指定($00〜$FF)も出来ます。

3パラメータ版は数値1が周波数シフト値(オクターブ的)で 0〜15
数値2は長周期、短周期ノイズの切り替え 0(l),1(s) です。l/sは [l]ong,[s]hort の意。
数値3はノイズ周波数で 0〜7 です。

3パラメータ版は各パラメータをそれぞれ省略可能です。
省略した場合は、前回指定した値が使われます。

デフォルトではノイズチャンネルは非音階モードになっており、
「w」コマンドでノイズ周波数指定、「cdefgab」いずれかで発音という手順です。
この場合、音階とオクターブは何でもかまいません(単なる発音指定のみ)。

#NOISENOTE を指定すると音階モードとなり、cdefgab でノイズ周波数指定と発音を同時に行います。
音階モードではオクターブは o0〜o10、12音階それぞれにノイズ周波数が割り当てられています。
この場合、「w」コマンドは意味がありません。

GB のノイズは LFSR (Linear Feedback Shift Register) という簡易乱数発生アルゴリズムで生成されており、
15bit(長周期)/7bit(短周期)のレジスタの特定のビットを xor 演算+シフトすることでノイズを出力します。
詳しくはハードウェア資料を参照。

<例>
'D p3v8 w5 c1 → 非音階モード ノイズ周波数5で全音符長で発音
'D w7,s,7 c8 w,,0 c8 → 2回目の指定は k7,s,0 と補完される

#NOISENOTE
'D o0 c8 d4 e2 → 音階モード
p数値定位 A B C D
パンポットです。数値は 0〜3。省略時は p3 です。
p0=消音 p1=左 p2=右 p3=両方 から音が出ます。

頻繁に変えるとプチノイズが出ます。
<例>
'A v8p3o4 p1c p3d p2e → 左からド 両方からレ 右からミ
%数値
%-数値
デチューン A B C D
音程周波数を数値分だけずらします。
数値は -128〜127 までです。数値は省略できません。
計算は GB 内部の値を基に行いますが、音程に対する内部値は以下の通り差があります。

o3c = 44(GB内部の値)
o3c+ = 156  → o3c〜o3c+ の半音の差が 112
o8a+ = 2013
o8b = 2015 → o8a+〜o8b の半音の差が 2

低い方の音程は差が大きく、高いほど小さくなります。
本コマンドも音域に合わせた数値でないと、ずれ方に差が出てきます。
ピッチモジュレーションも同様です。

デチューンコマンドを使った状態でピッチモジュレーションを使うと、
両方を加算した結果が正しく音程周波数に反映されます。
<例>
'A p3v8o5 %32 cde → ドレミの各音から32ポイント上げて発音する
i数値
i-数値
移調 A B C D
トランスポーズです。
音源チャンネル ABC の場合、値の範囲は -60〜60 です。
音源チャンネル D の場合、値の範囲は -120〜120 です。

指定した数値分、以降の音階がずれます。
<例>
'A p3v8o5 cde i1 fga → ファソラが1つずつ上に音階が上がって f+g+a+ 相当になる
@v数値1,数値2ハードウェアマスターボリューム A B C D
音源全体の音量を指示します。左右別々に指示できます。
数値1 : 0〜7で左の音量を指示します。
数値2 : 0〜7で右の音量を指示します。

数値はどちらかを省略すると、省略された数値には前回指定された値を使います。

特に指定しなくてもドライバは音源を @v7,7 で初期化します。
本コマンドはどのトラックにあっても、上位・下位トラックに関わらず即時効果適用されます。
<例>
'A @v7,7 p3v3o4 c1 → マスターボリューム最大
y数値1,数値2アドレス指定直接書き込み A B C D
数値1で示したアドレスに数値2を書き込みます。
数値は$に続けて16進数で指定します。
使い方によっては危険なコマンドなので注意してください。

本コマンドはどのトラックにあっても、上位・下位トラックに関わらず即時効果適用されます。

音程(cdefgab)と誤認識してしまうので、
アドレス指定と値指定の16進数は必ず大文字で書いてください。
<例>
'A y$FF12,$F0 → 音源チャンネルAの音量を15にする。
L曲ループポイント A B C D
曲のループポイントを指示します。
MML が最後まで演奏された後、指定ポイントに戻ります。
指定が無い場合はループせず演奏はそこで終了します。
<例>
'A o4p3v8  cde r → ドレミ で終了
'A o4p3v8 Lcde r → ドレミを演奏し続ける
m数値マクロ呼び出し(置換処理) A B C D
数値は0〜999まで、省略不可です。
#M で登録した MML を呼び出します。
コンパイルする際に置換処理を行っているだけです。
チャンネル別に MML の文法が違う場合はエラーが出ます。

始点と終点があるようなコマンドは、マクロ内部で完結させるようにしてください。
混乱とエラーの元になります。(カッコでくくるようなコマンド群)
<例>
#M0 x2 cde
'A p3v8o4 m0 → ドレミ
'C p3v3o4 m0 → デューティ比指定コマンドxは音源チャンネルCで使えないのでエラーになる
M数値1
M数値1,数値2
マクロ呼び出し2 A B C D
数値1は0〜999まで、省略不可です。
#Mで登録した MML を呼び出します。

小文字 m が単なる置換処理(コピペ)なのに対し、大文字 M では一度使用された MML マクロを
後から再利用します。2回目以降は 1回目に使われた場所にジャンプして、
終わったら戻ってくるだけなので容量が抑えられます。

上記の通り、最初にマクロが使われた状態をなぞるだけなので、
相対変化のコマンド(v+/-, <, > 他) やデフォルト値を決めるようなコマンド(l, o, v 他) などは
期待する動作にならない場合があります。マクロ内はマクロ内だけで完結するようにし、
マクロ終端で元に戻すようにするなど工夫が必要です。

また、あるトラックで一度使われたことのある M マクロは別のトラックでは呼び出しできません。

特定のフレーズを容量を抑えつつ使いたい場合などに有効です。

始点と終点があるようなコマンドは、マクロ内部で完結させるようにしてください。
混乱とエラーの元になります。(カッコでくくるようなコマンド群)


数値2 がある場合は他のマクロ呼び出しとは別の動作になります(実質別コマンド)。
マクロ内の MML を数値 2 の音長で演奏します。ただし音長は 255 カウント以下です。

指定 MML 内の総音長が数値 2 より長ければ数値 2 で打ち切り、短ければ足りない分は何もせず待機します。
これにより従来音長別にマクロをつくりわけなければならなかったのが、一つで足りるようになります。

注意点として数値 2 を指定したマクロ内の MML は常に t64 相当(=vsync)で処理されるということです。
マクロの外つまりシーケンスのテンポによらず一定の再生速度になります。
ゲーム音楽で曲によってテンポが違っていても効果音が速くなったり遅くなったりしないのと同じようなものです。

「待機」は本当に何もしないので休符を入れておいた方がいいかもしれません。
音長は n 音長も使えます。

MON/MOFF コマンドと組み合わせることで、M番号1,数値2 を c8 などのように記述できるようになります。
<例>
#M0 cde
'A p3v8 o4 M0 o5 M0 → 2回目のM0はo5でなくo4で演奏されてしまう

#M1 v+1c
'A p3o4 v8M1 v9M1 → 2回目のM1はv10でなくv9で演奏されてしまう

#M2 o4x2l96 v10b v-1a v-1g v-1f v-1e r
'A p3 L M2 r16  → シンセドラムっぽいフレーズを繰り返します

'A p3 L M2,32 M2,32 M2,16 M2,16 M2,4
 → #M2 は総音長が 96分音符 * 6 で八分音符相当だが、呼び出し側で音長を決定できる
MON
MOFF
マクロモード切替 A B C D
M 番号で呼び出されるマクロを音程で記述できるようにするコマンドです。
モードは切り替え出来、MON でオン MOFF でオフになります。

M 番号の(0-)が 12音階×オクターブの音階になります。
ch.ABC では最低音程である o2c が M0 に、c+ が M1、以下同となります。
ch.D では最低音程である o0c が M0 です。

オクターブと音階の許す範囲なので M999 などは当然使えません。ch.ABC で 72 音階、ch.D で 132 音階。
ch.D のノイズチャンネルは #NOISENOTE モード指定する必要はありません。

常に「音長指定付きマクロ」相当になります。
通常の音程と同じく n 音長も使えます。ただし音長は 255 以下でなければなりません。
音長を省略した場合はデフォルト音長 (l) コマンドで指定した値が使われます。
<例>
#M2 o3x2l96 v10b v-1a v-1g v-1f v-1e r o2

'A t64 p3 x2 MON L
'A o2 d32 d32 d16 d16 d4
→シンセドラムっぽいフレーズを繰り返します
 マクロ内 MML で o3 を指定しているので、マクロを抜けたときに o2d(=M2) になるように、
 マクロ末尾に o2 を追加しています

[数値 : ]ループ A B C D
繰り返しコマンドです。数値は2〜255までです。
数値を省略すると 2 になります。
「:」がある場合「:」以降をループの最終回にスキップします。
多重ループも 8重まで可能です。
ループ内では相対変化系のコマンドは意図した動作をしない場合があります。
<例>
'A [2 cde ] → cdecde と同じ 
'A [3 cd : ef] → cdef cdef cd と同じ 最終回は ef をスキップする
'A [2c [3d] e] → c ddd e c ddd e と同じ

'A o3 [3>cde] → o4cde o4cde o4cde となる オクターブはだんだん上がらない
'A v5 [4 cv1-] → v5c v4ccc(だんだん小さくなっていかない)
zf数値1,数値2,数値3ピッチモジュレーション A B C D
音程を変化させるためのモジュレーションです。
数値1 : モジュレーション番号 #F で登録した番号(0〜127)を指定します。
数値2 : スピード スピードをフレーム数(0〜255)で指定します。0=モジュレーションオフです。
数値3 : ディレイ 最初のデータを適用するまで待つフレーム数(0〜255)を指定します。

3つとも省略して「zf」だけの時はオフになります。
また、スピードが 0 の時もモジュレーションはオフになります。
3つあるパラメータはそれぞれ省略可能です。省略した場合は、前回指定した値が使われます。

デチューンコマンド「%」とピッチモジュレーションは加算された値が適用されます。
<例>
#F0 {0,1,2,1,0,-1,-2,-1,]255 }
'A p3o6x2v8 zf0,3,48 L c1d1 r16 → ビブラート効果を与えます
zv数値1,数値2,数値3音量モジュレーション A B C D
音量を変化させるためのモジュレーションです。
数値1 : モジュレーション番号 #V で登録した番号(0〜127)を指定します。
数値2 : スピード スピードをフレーム数(0〜255)で指定します。0=モジュレーションオフです。
数値3 : ディレイ 最初のデータを適用するまで待つフレーム数(0〜255)を指定します。

各数値は省略不可ですが、3つとも省略して「zv」だけの時はオフになります。
また、スピードが 0 の時もモジュレーションはオフになります。
3つあるパラメータはそれぞれ省略可能です。省略した場合は、前回指定した値が使われます。

音量モジュレーションデータ自体は音源チャンネル C とそれ以外の区別がないので
4 段階しか音量のない音源チャンネル C で 16段階のデータを使うと意図しない出音になります。

GBの仕様で、音量レジスタを頻繁に操作するとプチノイズが発生します。
ハードウェアエンベロープを使った方が負荷も軽く綺麗な場合があります。

ゲートタイム「q/Q」でも音のリリース部分に変化を付けることが出来ます。
併せて参照ください。
<例>
#V0 {$4, 3,$32,-5,-6,-7,-8,-9,-10,-11,\} → アタックだけ強く後はゆるやかなエンベロープ
'A p3o6x2 v12 zv0,4,0 c8d16e16f8e16d16c1 r
zw数値1,数値2,数値3デューティー比/波形メモリ音色モジュレーション A B C D
デューティー比または波形メモリ音色を変化させるためのモジュレーションです。
数値1 : モジュレーション番号 #W #X で登録した番号(0〜127)を指定します。
数値2 : スピード スピードをフレーム数(0〜255)で指定します。0=モジュレーションオフです。
数値3 : ディレイ 最初のデータを適用するまで待つフレーム数(0〜255)を指定します。

各数値は省略不可ですが、3つとも省略して「zw」だけの時はオフになります。
また、スピードが 0 の時もモジュレーションはオフになります。
3つあるパラメータはそれぞれ省略可能です。省略した場合は、前回指定した値が使われます。
<例>
#X0 {0,1,2,3,]255,\}
'A p3o6x2 zw0,4,48 c1 → デューティー比が 0,1,2,3... と切り替わります

#@0 {0000000000000000FFFFFFFFFFFFFFFF}
#@1 {77BFC536B775009BB7766FF64235A950}
#W10 {0,1,]255 }
'C p3o5v3 zw10,2,48 c1 r → 波形音色が0,1...と切り替わります
zp数値1,数値2,数値3定位モジュレーション A B C D
パンを変化させるためのモジュレーションです。
数値1 : モジュレーション番号 #P で登録した番号(0〜127)を指定します。
数値2 : スピード スピードをフレーム数(0〜255)で指定します。0=モジュレーションオフです。
数値3 : ディレイ 最初のデータを適用するまで待つフレーム数(0〜255)を指定します。

各数値は省略不可ですが、3つとも省略して「zp」だけの時はオフになります。
また、スピードが 0 の時もモジュレーションはオフになります。
3つあるパラメータはそれぞれ省略可能です。省略した場合は、前回指定した値が使われます。
<例>
#P0 {1,3,2,3,]255,\}
'A o5p3x2v8 L zp0,3,48 c1 r → パンが左・中央・右と切り替わります
q数値1,数値2,数値3
q-数値1,数値2,数値3
ゲートタイム A B C D
ゲートタイムです。
音符コマンドで指定した音長それぞれについて、キーオフのタイミングを指定します。
鍵盤から指を離す動作及びその後の余韻(リリース)をそれっぽくシミュレートします。

数値1 で実際に音をキーオンしているフレーム数を指定します。
(新しい音長 = 数値1、キーオフ期間 = 本来の音長 - 数値1、とする)
ここをマイナス数値にすると、音長の後ろから数えたフレームをキーオフ期間と見なします。
(新しい音長 = 本来の音長 - 数値1、キーオフ期間 = 数値1、とする)

数値1 は省略できません。
ゲートタイムに入ると音量モジュレーションの動作は停止し、ゲートタイム側でリリースの処理に入ります。

数値2 はリリースレートで、指定したフレーム毎に現在の音量を数値3の音量に近づけて行きます。
数値2 に 0 が指定してあると、カウントせずに即時音量が数値3になります。

数値2と数値3はそれぞれ省略可能です。省略すると前回指定した値が使われます。
完全に省略して数値1だけでも有効です。

何も付けずに q 指定あるいは q0 とするとゲートタイムはオフになります。
q だけの時は、内部で記憶している前回使われた数値2,数値3もリセット(=0)します。

「&」や「^」で音符を繋いだ場合、q/Q が効くのは最後尾の音符だけです。
「^」で繋いだ場合、内部的に音長が最適化された上での最後尾になるので、MML の記述とは異なる場合があります。

GBの音源仕様で、音量を頻繁に操作するとプチノイズが発生します。

セルフディレイ「W」と相性が悪いです。q/Q がドライバ側で音長を計算するのに対し、
「W」はコンパイラ側で音長を分割するためです。
<例>
'A p3o4v8l1 q-12,0,0 cde r  → 音の切れ目が分かる
'A p3o4v8l1 q-24,3,2 cde r  → リリースがゆるやかに聞こえる

Q数値1,数値2,数値3ゲートタイム2 A B C D
ゲートタイムその2です。
機能はゲートタイム1と同じですが、音長計算を n/8 とします。
数値1は 0〜8 です。0 と 8 は無効(ゲート機能オフ)です。
数値2,3 は「q」と同じ。省略して数値1だけでも有効です。

何も付けずに Q 指定あるいは Q0 とするとゲートタイムはオフになります。
Q だけの時は、内部で記憶している前回使われた数値2,数値3もリセット(=0)します。

「&」や「^」で音符を繋いだ場合、q/Q が効くのは最後尾の音符だけです。
「^」で繋いだ場合、内部的に音長が最適化された上での最後尾になるので、MML の記述とは異なる場合があります。
<例>
'A p3o4v8l4 Q4 cde r  → 四分音符の音長の半分だけ鳴る

{音程1,音程2}数値ポルタメント A B C D
音程を滑らかに変化させます。
音程1には開始音程を入れます。オクターブ指定も出来ます。
音程2には終了音程を入れます。オクターブ指定も出来ます。

数値には音長が入ります。この音長を使って滑らかに音程が上下します。
数値を省略すると「l」の基準音長が使われます。

ポルタメント音程は、その時点で指定されているデチューン「%」値も反映されます。
%-3を指定してポルタメントを開始すると、開始・終了音程とも-3で計算します。

ポルタメント後のオクターブは音程2のものを引き継ぎます。

スイープコマンド「s」と似た効果ですが、音源チャンネル A 以外でも使えます。
処理としてはこちらの方がはるかに重いです。
<例>
'A p3v8 o3{c,>c}1 → オクターブ3のドからオクターブ4のドまで
'A p3v8 {o6c,o3c}1^1. → オクターブ6のドからオクターブ3のドまで
_数値
_音程
_数値音程
レガート A B C D
一つ前の音程から次の音程へ滑らかに変化させます。

数値は音程をつなぐ音長です。255 音長カウント以下である必要があります。
レガートコマンドはポルタメントコマンドに読み替えられるので、ポルタメント部分の音長ということになります。

数値を指定した場合は、デフォルト値として以降のレガートで同じ音長が使われます。
数値が省略され、続いて音程を記述した場合はデフォルトのレガート音長値が使われます。
数値と音長をその都度指定してもかまいません。

音程は、ポルタメントに読み替えられる部分の音長を引かれた音長になります。
引かれた結果マイナスになる場合はレガートは発動しません。

o3c_n8o4c4 とすると、o3c {o3c,o4c}n8& cn40 というように読み替えられます。

副作用として、多用するとデータサイズが肥大化します。
<例>
'A t64 p3 x2 k$A0 o4 L l8 o3c_n4d_e_f_g_a_b r
→ 音符間がなめらかに繋がって聞こえる
(音程)数値高速アルペジオ A B C D
()内の音程を最短音長で繰り返し、指定した音長分鳴らします。
()内の音程の数は最大で 4 個までです。
()内はオクターブと音程以外不可です。音量や定位コマンドは入れられません。
音量や定位を変化させる場合は zv,zp モジュレーションまたはハードウェアエンベロープを使ってください。

数値は音長です。他の音程系コマンドと同じ指定方法です。
数値を省略すると「l」の基準音長が使われます。

アルペジオ後のオクターブ音程は、アルペジオ内で指定した最後の値を引き継ぎます。
<例>
'A o4p3v8 (ceg>c)1 → ドミソドを高速に全音符で鳴らす
~数値1,数値2,数値3装飾音符 A B C D
"〜"チルダです。
音程コマンド(cdefgab)の前に装飾音符を付けるコマンドです。

数値1は -12〜12 で、元の音程との半音単位の差を表します。-1 で半音下の音を装飾音符として使います。
数値2は装飾音符の長さで 1〜8 です。元の音長と分割されます。
数値3は装飾音符と元の音符を「&」で繋げるかどうかを指定します。0=繋げない 1=繋げるです。

ゲートタイム q/Q が指定されていると、「&」が付いていない音符は音長分割の対象になってしまうので
装飾音符にもゲートタイムが効いてしまいます。数値3 のスイッチはそれを防ぐためのものです。
q/Q を使っていなければ「&」を付けなくても良いかもしれません。

ポルタメントとアルペジオには装飾音符は付きません。
<例>
'A ~-1,2,1 def → cn2&d^-n2 d+n2&e^-n2 en2&f^-n2 と展開される
W数値1,数値2,数値3,数値4セルフディレイ A B C D
セルフディレイを付加します。
数値1で何音前の音をディレイに使用するかを指定します。範囲は 0〜2。
数値2でディレイ時の元の音に対する相対音量を指定します。範囲は -15〜15。
数値3でディレイ音長を指定します。マイナスを指定すると分割元の音の後ろからカウントします。-255〜255。
数値4でディレイ時のパンポットを指定します。0〜4。0で元の音のまま、4 で 1〜3 のランダムになります。

オプション指定なし「W」だけの場合、セルフディレイはオフになります。


説明のために 1 音前の音をディレイするとして・・・前音符、当音符、次音符と呼びます。

セルフディレイは、ディレイを付ける当音符の音長をコンパイラ側で分割します。
数値3 がプラスの時は数値3を当音符の音長、残りをディレイに割り当てます。
数値3 がマイナスの時は数値3をディレイ、残りを当音符に割り当てます。後ろからカウントというイメージ。

ディレイは音色(@,x)が変わっていても前音符のものを復元します。次音符には影響しません。
音量は前音符のもの+数値2のものをディレイ音量として使います。
エンベロープが有効だった場合も反映されます。これも次音符には影響しません。
パンポットは 0 を指定すると前音符のものを使います。これも次音符には影響しません。
1〜3 あるいは 4 を指定すると、ディレイ音符を指定した定位で処理します。

<例>
'A o4p3 v$F3 W0,-8,-12,0 cdefg r → 音が追いかけて聞こえる
@数値1,数値2波形メモリ音色指定 A B C D
波形メモリ音源チャンネルの音色を指定します。
#@ で定義した音色番号(0〜126)を数値1に指定します。

数値2 でマイナス音量(0,-1 〜 -16)を設定できます。

数値2 は省略可(初期値は 0)。省略すると前回指定した値が継承されます。zw にも継承。
波形モーフィングには適用されません(0=元音色として動作)。
波形の 8 に収束する用に数値2 の半分を足し引きする動作になります。

詳しくはサンプルの wavvol.txt を参照。
<例>
#@0 {$01,$23,$45,$67,$89,$AB,$CD,$EF,$FE,$DC,$BA,$98,$76,$54,$32,$10}
'C o4p3v3 @0 c1 → 音色番号0で発音

'C o4p3v3 @0,-2 c1 → 音色番号0を波形の8を中心に上下を-1して設定する
@S数値1,数値2波形モーフィング動作指定 A B C D
@@ で始動する波形モーフィングの動作を指定します。
数値1は動作の指定(0/1)。
0 の場合波形モーフィングの動作をキーオン非同期にします。
1 の場合波形モーフィングの動作をキーオン同期にします。

数値2は動作速度(1-128)。何回毎にモーフィング変化をするかを指定します。
キーオン非同期の場合、ステップカウントを指定します。
キーオン同期の場合、キーオンの回数を指定します。

詳しくはサンプルの morph.txt を参照。
<例>
'C o4p3v3 @1cde @S1,1 @@2 defgab → @1 から @2 にキーオン同期で1音毎にモーフィング変化

@@数値1波形モーフィング始動 A B C D
@S で指定した条件で波形モーフィングを実行します。
数値1は変化"先"の音色番号。
変化"元"は現在の音色番号です。

音色のマイナス音量指定や zw は強制的に解除されます。
モーフィング中の新規の音色設定や zw でモーフィングは解除されます。
変化は 15 回で完了(変化先と一致)します。
キーオン同期の場合、最短で15音
キーオン非同期の場合、最短で15ステップカウントで完了

詳しくはサンプルの morph.txt を参照。
<例>
'C o4p3v3 @1cde @S1,1 @@2 defgab → @1 から @2 にキーオン同期で1音毎にモーフィング変化

*MML スキップ A B C D
MML 中で最初に * が現れるところまで演奏をスキップします。
* が現れるまでのすべてのエフェクトや音色は反映されます。
内部的には高速に演奏を進める動作を行います。gbs での制作過程の補助に便利です。

複数書いても良いですが、最初に発見した * 以外は無視します。
<例>
'A o4p3l4v10x0 cdef
'A * gab
→ gab の所から o4p3l4v10x0 の設定を反映して演奏が開始されます
@p数値PCM音色指定 A B C D
PCM再生する音色を指定します。
#PCMLOAD で指定した番号(0〜255)を指定します。
PCMは排他使用なので、どのトラックで発音しても同時に 1 つしか鳴りません。

GBS 出力時は PCM は使用できません(GBDSP のみ)。
<例>
#pcmload 0,"drum.pcm",-1
'C @p0 u1 → 登録したドラム音色を全音符で鳴らす
u音長PCM発音 A B C D
PCM再生します。
PCM に音階は無いので、cdefgab の代わりの発音コマンドです。

PCMは排他使用なので、どのトラックで発音しても同時に 1 つしか鳴りません。
PCM再生時は各種MODはオフになります。

GBS 出力時は PCM は使用できません(GBDSP のみ)。
<例>
#pcmload 0,"drum.pcm",-1
'C @p0 u1 → 登録したドラム音色を全音符で鳴らす
C数値全音長のフレームカウント指定 A B C D
数値は 1〜255 です。省略不可。
デフォルトは 192 です。各 X 分音符はこの数値の約数になります。
割り切れない音符を指定した場合はエラーになります。
例. 四分音符=192/4=48カウント

#DEFLEN でも指定できます。
この指定は n 音長には影響せず、あくまで X 分音符指定をフレームカウントに変換する際の計算が変わるだけです。
<例>
'A C96 l4 c
'A l4 C96 c
[注意] この二つは別の動作になる可能性があります。
l4 が音長省略時のフレームカウントを決定するので C コマンドの前か後かで動作が変わってきます。




■ その他注意点

GBS フォーマットを聞く場合、nezplug++ (http://offgao.net/program/nezplug++.html) 付属の nezplay がコンパクトで便利です。
nezplay.exe と npnez.dll があれば起動でき、プレイヤーに GBS ファイルをドラッグドロップすると演奏開始します。




容量はPCMを除く曲データ全部で最大 16KB(16384byte)です。
GBDSP を使う場合はさらに 96バイト少なくなります。
PCM データは 1音につき最大 16KB(16384byte)です。

PCM データは別のページの PCM コンバータを使ってください。
その際、「16byte境界にする」「4096Hzにする」「1バイト2データにする」の3点が必須です。
コンパイラ側ではチェックしませんのでご注意ください。



ノイズ周波数を求めやすくするためのプログラム(noisetest.gb)を添付しました。GB/GBC 両対応です。
A ボタンで発音/消音、B ボタンでエンベロープありで発音、セレクトでエンベロープの向き変更(トグル動作)です。
左上の SHORT/LONG は短周期/長周期ノイズを表しています。十字キーで動かしながら出音を確認できます。
右上の16進数が w コマンドで使用する値となります。




・GBDSP の操作について

GBMC のコンパイルオプション #mode でモノクロ GB 用、カラー GB 用いずれかが出力されます。
エミュレータのオプションで機種を合わせないと起動しない場合があります。

上下左右でカーソルが順に動きます。A ボタンを押すとカーソル位置に応じた動作をします。
最下行は左から「演奏開始」「演奏停止」「一時停止(再開)」「フェードアウト」で、
その上は各チャンネルのミュートになっています。もういちど押すと解除。

TEMPO のところで押すと、MML 中で t で指示したテンポと音楽的テンポの表示を切り替えます。音楽的テンポは♪マークがつきます。

START ボタンを押すと画面上部の色が変わります。音源ドライバの処理負荷を表しています。もう一度押すと解除。

・GBDSP のパレット変更について



GBC 版では SELECT ボタンを押すとパレット変更モードになります。GB 版は SELECT ボタンを押す毎に色が変わります(全24パターン)。
START+SELECT を押すと全ての変更がデフォルトに戻ります。

以下、GBC 版の説明。
変更はセーブされ次回以降の起動に自動的に反映されます。
まず、左側のアイコン部分1〜4(上図)の部位を選びます。ここでカーソルを上下に移動すると右側の数値が変わるはずです。
右側の数値は、各1〜4からさらに変更できるパーツの箇所を意味します(横に並んだ RGB ひとくくりで最大四カ所)。
それぞれの変更可能箇所は上から順に以下のようになっています。

1.下画面の曲情報の背景色
2.白鍵/黒鍵
3.上画面の背景色/文字影・波形表示・小アイコン背景/文字色・小アイコンの中身・曲情報の文字色
4.鍵盤の押された部分の色

変更したい箇所にカーソルを持って行き、B+上下で各 RGB 値の変更ができます。
もう一度 SELECT を押すと曲情報画面に戻ります。

・複数の曲を一本の GBDSP の ROM に入れる(アルバム化)について

同梱の AlbumGBDSP を使うと、一曲につき一本の ROM ができあがる GBDSP を複数まとめることができます。
GBMC.EXE と同様、コマンドプロンプトから
> AlbumGBDSP TARGET.GBC APPEND.GBC
とすると、APPEND GBC に入っている曲が TARGET.GBC に追加されます(モノクロ GB の場合は GBC を GB に変えてください)。
どちらも GBDSP の ROM でなければならないのと、最新の GBMC でコンパイルしたものでないとダメです。最大 240 曲。

今入っている曲リストを表示するには以下のようにします。
> AlbumGBDSP TARGET.GBC -l
タイトル情報を羅列します。小文字のエルです。

削除したい曲がある場合は、上のリストで出てきた曲の番号を覚えておいて、以下のようにします。
> AlbumGBDSP TARGET.GBC -d num
num のところに曲番号を入れてください。省略すると一番最後の曲を削除します。

アルバム化した際の選曲ですが、GBDSP で B ボタンを押しながら左右で曲番号が変わります。
B ボタンを放すと曲情報が切り替わります。そこで演奏開始アイコンで A ボタンを押すと選択した曲の演奏を開始します。
B + SELECT で元の演奏中の曲情報に戻ります。

・通信ケーブルでつないだ別の GB の GBDSP に演奏指示を送る

演奏開始アイコン上で A ボタンを押すと、通信ケーブルでつないだ GBDSP も同時に演奏開始します。
一台の PC 上のエミュレータでこれを再現するには以下のようにします。BGB を使用するものとします。

BGB を二つ起動し、両方にそれぞれ演奏したい曲の入った GBDSP を読み込ませます。
片方の BGB 上で右クリックし、Option -> Listen を選択、ポート番号を聞かれるので(たぶん 8765 がデフォルト)OK を押します。
このときファイアウォールが通信許可を求めてくるかもしれませんので許可します。
もう片方の BGB 上で Option -> Connect で IP アドレスを聞かれるので(127.0.0.1 がデフォルト)Ok を押します。
これで同一 PC 上で互いの BGB で通信できる状態になります。

あとは演奏開始アイコン上で A ボタンを押すと、同時に演奏が開始されます。同期するのは開始だけで停止などは個別です(手抜き)。

・テンポについての注意事項

テンポは vblank 同期、つまり最小音長単位(192分音符 = 1 カウント) は約 1/60 秒です。
この音源ドライバの仕様上、音欠けが発生する場合があるので補足しておきます。


上の図は t64 つまり 1カウントを 1vsync でぴったり行った場合の進行です。vsync 8 回分。音楽的テンポは tempo=75 になります。
この場合すべての音符は確実に発音されます。

ではテンポを 2 倍にするとどうなるかというと、下の図のようになります。vsync 4 回分。
2 カウント分が 1vsync で処理されるため、赤で塗った部分しか発音されません。
つまり、このエンベロープの特徴的なアタックの強い部分(v15)が飛ばされてしまうということになります。これが音欠けです。

これを避けるには、t64 のまま音長を半分にする(この場合は v15c v9c v6c v2c のようなエンベロープに変える)などの工夫が必要になります。
あるいは、音長付きマクロを使うとマクロ内の MML テンポだけが vsync 同期=t64 に強制されるので、マクロ外では t128 かつ音長カウント 8 のまま、
マクロ内の音長は t64 であるものとして演奏できます(ただしマクロ内 MML では先頭から音長カウント 4 までしか演奏されない)。
このエンベロープのためだけに他のトラック音長を四分音符→八分音符のように変える手間が省けるため便利です。
(ゲーム音楽で曲によってテンポが違っていても効果音が速くなったり遅くなったりしないのと同じようなものです)

#M0 v15cn1 v10cn1 v7cn1 v3cn1 v1cn1 cn1 cn1 cn1

'D t128 M0,n8

なお、各種 mod、高速アルペジオは最小変化単位が元から vsync ベースなので音欠けは発生しません。
t64 でも t128 でも mod の定義数値列のパラメータが飛ばされたりアルペジオの聞こえ方が変わることはありません。
敢えて手動でエンベロープなどを記述した場合の注意点となります。

・配布について
GBS/GBDSP に曲を組み込んで営利・非営利問わず配布できます。連絡等も不要です。
ただし、このサイトの自由な活動の障害となる場合を除きます。


■ 更新履歴

・2024.01.08
+ MML スキップ(早送り)コマンド"*"を追加。制作支援。
+ 波形メモリ音源の音色指定"@"にマイナス音量を指定できるようにした。
+ 波形メモリ音源のモーフィングコマンド"@S","@@"を実装。
+ RGBDS v0.7.0 対応
・2019.07.04
+ rgbasm の新しいバージョンでコンパイルできるようにした。
+ & で音程をつないだ後の modv/p が効かない場合があったのを修正。
+ & や ^ で音程をつないだ後にゲートが効くべきでないところで効いてしまう場合があったのを修正。
+ PCM 関係で暴走の可能性がいくつかあったのを修正。
+ 割り込み源に timer を使うのは無理があったので vblank に戻した。それに伴い gbs での PCM サポートは廃止。
+ 上位トラックが動いている最中に下位トラックのエフェクト関係やポルタメント処理などが動いていなかったバグを修正。
+ 音長指定できるマクロを拡張。ノイズチャンネルの複雑なマクロなどを音長別に設定する必要がなくなった。
+ 音長指定マクロのみ timebase 基準でなく vsync で処理するようにした。テンポが変わっても鳴り方が変わらないように。
+ マクロを M0=o2c など音程で読み替えできるようにするトグルスイッチを新設。音長指定マクロと組み合わせることで c8 c16 などの指定ができるように。
+ PCM の pan が効かない不具合を修正。
+ 矩形波チャンネル ch1.2 で PCM が鳴らない場合があるのを修正。
+ テンポ 64 をデフォルトにするようにした。BPM で言うところの t298 まで可能になった。
+ &r とした場合、休符として扱うのでなくゲートを即時発動するようにした。
+ 相対テンポコマンド実装。
+ レガートコマンド実装。
+ テンポの vsync 一本化に伴い T コマンドを廃止。
+ [GBDSP] 一部の操作をオートリピート対応にした。
+ [GBDSP] カラーセットを START+SELECT でデフォルトに戻せるようにした。
+ [GBDSP] 負荷メーター実装。vblank 開始時に背景色を赤にしておいて、処理が終わった時点でパレットを元に戻す。
+ [GBDSP] 波形メモリ音源の休符表示がうまくいっていなかったのを修正。
+ [GBDSP] チャンネルミュート時、ミュート状態がわかりやすいようにアイコンの色を変更。
+ [GBDSP] カラーセットをセーブするようにした。
+ [GBDSP] 演奏時間表示を実装。
+ [GBDSP] フェードアウト実装。GB のマスターボリュームは 0 でも結構な音量なので無いよりマシ程度。
+ [GBDSP] 通信ケーブルで繋がっている別の GB 上の GBDSP に演奏開始を指示できるようにした。実機では未確認。
+ [GBDSP] テンポ表示を SYNC 値と音楽的テンポ値で切り替えられるようにした。
+ [GBDSP] 複数曲選択(アルバム化)に対応。
・2019.07.07
+ 曲情報のフォントを NAGA10 から M+BITMAP FONTS に切り替え。あわせて配布について追記。
・2019.10.02
+ q- コマンドのカウントの仕方がおかしかったのを修正。Q/q 全て vsync から timebase に変更した。Thanks MM1!
・2019.10.03
+ #DEFLEN と C コマンドを追加。全音符のカウントを指定できるようになった。



■ 反 省

5 年くらい放置していました。

■ 謝 辞

ノイズ音階に関して xpmck のソースを参考にさせていただきました。


▲ TOP