ピアノロール経験者のためのMML入門

この記事は、[DTMテクニック集 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/dtm-technique-tips)の10日目の記事になります。
前回の記事は、Machiaさんの[腱鞘炎で手首が動かせなくなったときのDTM。](https://machiaworx.net/?p=1879)です。

# MMLって、何？
MMLとはMusic Macro Languageの接頭辞で、その名の通り音楽を記述するためのマクロ言語です。
簡単に言えば「テキストベースで楽譜や音色設定を記述する原語」というものです。

現代の楽曲制作手法の主流ではありませんが、その昔(国産アーキテクチャのPCが元気だった時代)はPCベースで音楽制作といったらMMLという時代もありました。
そういった年代に発展した事から、いわゆる内蔵音源の制御向けに作られている部分があり、現代でもそういった内蔵音源での演奏のために用いられることがあります。(ex. nsd.lib(FC/NES音源)、mml2vgm(FM音源中心の総合ツール)、msxplay(MSX用MGSDRVベースのWebツール)…等)

自分は元々ピアノロールやステップシーケンサーで楽曲製作を開始し、後にトラッカー(説明は割愛します)も使うようになったものの、これらと比較して、完全にテキストベースで制作するMML系の環境は敷居が高い物でした…が、それまで触ってきた環境で不自由を感じたことや、MML系の制作環境で機能的なアドバンテージが得られる状況でもあったことから、MMLの読み書きを習得しました。

# この記事は？
この記事では自分がMMLを理解するために、このような工夫をしました。という事を綴っていきます。
- mml2vgmでXGM形式のデータを作って、MD音源で4chの合成PCM音源を使いたい！(自分の動機です)
- レトロゲーム機向け新作の曲を作らなきゃいけなくなったけど、MML系のドライバ指定になった！
- MMDSP(X68000用のプレイヤー)で自作曲を再生してドヤりたい！
といった壁に当たった際、理解の助けになれば幸いです。

# なぜ人はMMLに挫折するのか
まずは、自分が習得するまでに感じた、挫折しやすいポイントを挙げてみます。

- 環境構築が大変
MML系の環境は、大きく分けてテキストエディタ、コンパイラ、プレイヤーに分けられます。
これらを連携する方法がもちろんあるのですが…間に更新監視ツールを挟んだりとか、パス受け渡したりとか、これがまず大変な事が多いです…。
ただ、この問題はツール単位で解決しつつある面もあります。
今回サンプルに使う、ブラウザで動作する[MSXplay](https://msxplay.com)や、まさに統合開発環境といえる[mml2vgmIDE](https://github.com/kuma4649/mml2vgm)、80年代に登場したドライバがWin向けにGUIを搭載して蘇った[MUCOM88](https://onitama.tv/mucom88/)などで、以前のような複雑な環境整備を行わずとも始められるようになりました。

- 小節線などの区切りが存在しないため、書き方を理解しづらい
どこまで書いた？何小節目？みたいになりがち
複数パートを書いた時、パート間でシーケンスの長さがズレた時などの箇所特定が大変

- サンプルMMLの画面を見ても、初学者は何がどうなっているのか理解が難しい
特にGUIから作編曲を始めた人にとって、ここが一番つらいと思われる
フリーフォーマット故に、書き方が個々人によって異なるので読み方を掴むまで分かりづらい
音符とコマンドが同じ行内に書かれるため、判別ができない段階だと読むだけでも大変

他にも、音色パラメーターの指定が分かりづらいとか、環境によっては音すぐ出ないとか、色々ありますが…
MMLの読み書きという点では、これらの点は多くの環境で共通するのではないでしょうか。

実際、自分もこの点には苦しめられ、複数回に渡る挫折を乗り越えて今に至ります。
ここからは、こういった挫折ポイントに対して自分がどのように対処していったか、Tipsをつづっていきます。

# 人がMMLで挫折しないためのTips
MMLはフリーフォーマットである事が多いので、自分で書き方を制御(制限？)する必要があります。

- サンプル曲を無理に読み解こうとしない
とっかかりがないので最初はサンプル曲を読もうとしがちですが、前述の通りMMLは音符とコマンドが同じ行内に書かれるため、どれが何だか分からない状態でサンプル曲を読み解くのは困難です。
例えばMSXplayのサンプル曲データは非常に高品質ですが、初心者が読み解けるものではないと思います。
最初はとにかく単純なものを自分で書いてみるのが、理解のコツになると思います。

- いきなり長い曲を書こうとしない
特に読み方に慣れていないうちは、小節数が多くなるだけでも読みづらいと絶対感じるので、やめたほうがいいです。
まずは、4小節とか8小節ぐらいの短い曲を書こうという気持ちで取り組んでみましょう。
いきなり長い曲を書こうとすると、思った以上に書き進められずにストレスになる…などの状況が予想されます。

- いきなり複数パートの曲を書こうとしない
最初は1パート書くだけでも十分な進捗です。サンプル曲や公開されているMML系環境での楽曲も、1パートの集合体です。
まずは1パート書ききる事を目指しましょう。段々できるようになれば大丈夫です。
いきなり複数パートを書こうとすると、パート間の小節数ズレを起こして解決できなくなる…などの状況が予想されます。

- 冗長でも可読性重視の書き方をする
最初は1小節1行で書くのをおススメします。
MMLは1行に何小節でも書く事は可能ですが、絶対分からなくなるので最初は1小節=1行で書いた方が挫折しないと思われます。
慣れてきたら複数小節で構成される1フレーズをまとめて1行に書くなどすると見た目がスッキリしますが、最初はやめておきましょう。
慣れないうちにフレーズ1行書きをやろうとすると、休符の入れ忘れ位置が特定できなくなる…などの状況が予想されます。

- 4分音符程度で区切り線を入れる
区切り線がないのなら、自分で入れてしまいましょう。MMLはフリーフォーマットです。大抵コメント行を書けるので、それを使いましょう。
1行1小節で書けば大丈夫では？とも一見思いがちですが…全行詰めて書いてしまうと数えるのも大変になったり、複数パートを書いている場合にどこまで書いたかの理解がしづらくなるので、一定小節ごとに小節番号を書くといいと思います。

- 楽譜の書き方を理解するまでは、安易に音源操作系のコマンドを使おうとしない
楽譜関連のコマンド(例:o, l, <, >)は早くに覚えるべきですが、使用する音源依存のコマンドはいきなり使うのは避けた方がよいと考えます。
MMLは楽譜上に挟み込むような形でコマンドを記述するので、楽譜とコマンドが入り混じる状態になると初学者は絶対に混乱すると思われます…音源操作系コマンドをいきなり使って、翌日に読み返そうとして何が何だか分からなくなるのは、きっと辛いものだと思いますので…。

- 音長の認識に迷ったら全て16分で書く
楽譜の経験がまったくない場合、8分音符や4分音符が混在すると音長で迷う可能性があると思いました。
自分は多少は楽譜を読んだ経験があったため、この書き方はしませんでしたが、MMLとピアノロールの差を埋める方法として提案します。
16分グリッドのピアノロールを使い慣れた人であれば、全て16分で全て書くとグリッドそのままになる。と書くと、「なるほど！」と鳴れる方もいるのではないでしょうか？
もちろん、音長と合計の仕方についてはどこかで覚えたほうがよいと思います。(命令量が減るとデータ量が単純に減り、その分長い曲を書けるMMLドライバも存在する)

自分が意識的に注意した点はこういった部分でした。

# とりあえず「きらきら星」を打ち込んでみよう
ここでは、上のTipsを踏まえながら「きらきら星」のメロディーパートを打ち込む際の、自分の認識と手順を解説してみます。
今回は、Webブラウザ上で簡単に試せるmsxplay向けのデータを書いていきます。

最初に、前準備です。まずは音が出るように準備しなければなりません。
MSXplayの[MML Editor](https://msxplay.com/editor.html)を開き、Sampleから新しいMMLを開いた状態を前提とします。

今回はFM音源(YM2413)の内臓音色を使って演奏していくことにします。
詳細は割愛しますが(右下の「MMLのヘルプ」から詳細を確認できます)、FM音源の1ch目に割り当てられているMMLのパート9に、最低限の設定を書いておきます。
```
9 o5 @1 v15
```
MSXplayは行頭にパート番号、その後に楽譜やコマンドを記述するスタイルです。
上のMMLは、
「パート9(=FM音源のch1)に、オクターブ5、音色番号1番(=FM音源の内臓音色)で、音量15(=この音源の最大値)」
という意味になります。
今回は楽譜の書き方に重点を置きたいため、この辺りの解説は割愛しますが…音色を設定して、音量を設定するというのは基本の一つということは伝えさせていただきます。

また、自分の場合は小節番号が小節の開始地点にあると分かりやすい派なので、
```
;bar1
```
とも書いておきます。これはコメント文で、MMLの処理時には読み飛ばされます。
MSXplayの場合は、セミコロンの後の行の終わりまでがコメントになります。


さて、「きらきら星」の楽譜を用意しました。
![ez8r2fb4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197254/a9698989-05e1-99f6-33be-cd2618581315.png)
([きらきら星 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%81%8D%E3%82%89%E3%81%8D%E3%82%89%E6%98%9F)より引用)
楽譜が読める場合は、～分音符の名前の通り書けば大丈夫です。

この楽譜をピアノロールに起こすと、こうなりますね。
![pianoroll1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197254/228e46bc-cd10-6cc0-03ec-54c8e5fc0e29.png)
ピアノロール上からMMLに起こす場合を考えてみます。

まずは1小節目を拡大してみます。
![pianoroll2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197254/235e9eda-48f6-849d-44a6-066f2b26dc63.png)
グリッド(薄い線)は16分音符(1拍を4つで区切る=1/4beat)にしてあります。
16分音符を基本として考えると、1音目のC5はグリッド4つ分ですね。

音符の長さの名前は、長さを2倍にすると数字が半分になります(16分グリッド上での限定的な解説として…)。
この1音目の長さは、16分音符の2倍の2倍…つまり名前は4分音符になります。
MMLでの音符の長さの指定は、このように楽譜基準の音長表記で行います。(最大は全音符=1分音符=1小節分、です)

ここまでわかったら、これをMMLの表記にしてみましょう。

MMLでは、基本的にどの処理系でも英名の音名を使います。
C=ド、D=レ、E=ミ、F=ファ、G=ソ、A=ラ、B=シ
と対応しています。基本的に、MMLではこれらは全て小文字(cdefgab)で表現します。
♭(半音下げ)は「-」、#(半音上げ)は「+」でそれぞれ表現されます。

上記を踏まえると、きらきら星の1小節目は全て4分音符でドドソソ、なので、MMLでは音名と音長を組み合わせて、
```
9 c4c4g4g4
```
と表記します。頭の9は前準備と同様に、パート番号の指定です。
これで1小節分打ち込むことができました。

2小節目のピアノロールは以下のようになります。
![pianoroll3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197254/bc2767b7-226f-9062-a8a3-f3f58afc3fa7.png)
こちらは頭から2つ目までは1小節目と同じく4分音符で、3音目だけ長くなっています。
こちらは4分音符の2倍の音長であることは、お分かりいただけるかと思います。
1小節目での解説の通り、音符の長さの名前は長さを2倍にすると数字が半分になるので、4分音符の2倍…つまり名前は2分音符になります。
これを踏まえて、2小節目をMMLで表記すると、
```
9 a4a4g2
```
となりますね。案外簡単？と思ってもらえたら嬉しいです。

3、4小節は同じリズムでの音高違いのため、解説は省略して…
```
9 f4f4e4e4
9 d4d4c2
```
となります。1小節ずつ改行を入れています。
ここまでで4小節ほど書いたので、何かしらコメントを書いておくとよいと思います。
自分の場合は小節の開始地点に番号があると見やすい派なので、
```
;bar5
```
と書いておくことにします。

こちらは5～8小節のピアノロールです。
![pianoroll4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197254/ec6ffa77-d860-ac9d-03ef-2e0d2a2fb10f.png)
5、6小節と7、8小節は完全に同じフレーズの繰り返しである事が、お分かりいただけると思います。
まずは5、6小節として、
```
9 g4g4f4f4
9 e4e4d2
```
を書きました。
MMLの利点の一つは、テキストであるためコピペが容易という点です。テキストエディターの許すまま、好きなようにコピペすることが可能です。
よって、7、8小節目はそのままコピーして、
```
9 g4g4f4f4
9 e4e4d2
```
でOKです。もちろんピアノロールでも可能な動作ですが、もっと複雑な制御コマンドを書いた場合にも、そのままコピペできます。
このあたりで

きらきら星は、1～4小節と9～12小節が完全に繰り返しのため、最初に書いた分をそのままコピペして、
```
9 c4c4g4g4
9 a4a4g2
9 f4f4e4e4
9 d4d4c2
```
で問題ありません。これにてきらきら星のメロディーの打ち込みが完了です。
MSXplayでは、Compileボタンをクリックするとその場で再生できます。ぜひぜひ打ち込んだメロディーを聴いてみてください。

今回打ち込んだMMLの全文は以下の通りです。
```
9 o5 @1 v15

;bar1
9 c4c4g4g4
9 a4a4g2
9 f4f4e4e4
9 d4d4c2
;bar5
9 g4g4f4f4
9 e4e4d2
9 g4g4f4f4
9 e4e4d2
;bar9
9 c4c4g4g4
9 a4a4g2
9 f4f4e4e4
9 d4d4c2
```
このままMSXplayのSample→新規MMLにコピペすれば再生可能です。
また、[こちらのリンク](https://f.msxplay.com/54d62acf "MSXplay")を開くと、上のMMLが打ち込まれた状態でMSXplayが開かれます。
(サンプルに付いている未使用の音色を削除してあります)

簡単な楽曲ですが、耳慣れたメロディーが自分の書いたテキストから再生されるというのは、なかなか面白い体験ではないでしょうか？
最初はこのように短め、でも自身が満足感を得られる楽曲に挑戦していくとよいと思います。
自分は最初の頃、練習にGB版テトリスのコロブチカ(コロベイニキ)を耳コピして打ち込んでいました。

# おわりに
自分はMMLに覚えている限りで3度挫折していて、各回で何がダメだったのかを分析しながら挑み続けてようやく扱えるようになりました。
今や需要がある作成スタイルとは決して言えませんが、ゲーム機実機向けの音楽などを作りたいと思った時には、一つの選択肢である事は今も昔も変わりません。
自分の使いたい機能がMMLのツールにしかない、諦めよう…から、この記事をヒントに頑張ってみようとなる人が現れたら、とても嬉しく思います。