summaryrefslogtreecommitdiff
path: root/doc/Design_mml.md
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-07-11 19:02:14 +0900
committertanaka takashi <isazaka@gmail.com>2026-07-11 19:02:14 +0900
commitca35520338057512a71acd42bb116ffbb82cc192 (patch)
tree9faa2428aeb71b62497f21ceec93b99ef7f2a5ac /doc/Design_mml.md
parent7dca1616b8c891f5e140c7267323d1fcdde6741a (diff)
feat: implement Famicom-style MML composer MCP server
- Add FastMCP server with compose_mml tool - Support ppmck and pyxel MML syntax - Add lexer and parsers for both formats - Add NES APU-style synthesizer (pulse/triangle/noise) to WAV - Add MML templates (basic/melody/chord/drum/empty) for both modes - Add tests for lexer, parser, and server - Support stdio, http, sse, streamable-http transports - Update README, pyproject.toml, and .gitignore
Diffstat (limited to 'doc/Design_mml.md')
-rw-r--r--doc/Design_mml.md375
1 files changed, 375 insertions, 0 deletions
diff --git a/doc/Design_mml.md b/doc/Design_mml.md
new file mode 100644
index 0000000..debb82d
--- /dev/null
+++ b/doc/Design_mml.md
@@ -0,0 +1,375 @@
+---
+
+## 🎼 MML設計仕様書
+
+### 基本方針
+
+- **2つのモードを用意し、ツールのパラメータで切り替える**
+- モード間で書式を混合しない
+- 各モードはそれぞれ独立した仕様を持つ
+- どちらも出力する中間表現(NoteSequence)は共通
+
+---
+
+## モード1: `ppmck` — PPMCKインスパイア独自形式
+
+PPMCKの文法をベースにしつつ、不要な複雑さを排除した独自サブセット。LLMが生成しやすく、FC音源の主要機能をカバーする。
+
+### 参考ドキュメント
+
+| 内容 | URL |
+|---|---|
+| PPMCK mckc.txt(MMLコンパイラ仕様書) | https://github.com/munshkr/ppmck/blob/master/doc/mckc.txt |
+| MCK Wiki MMLリファレンス | https://wikiwiki.jp/mck/MMLリファレンス |
+| NES APUハードウェア仕様 (midi2nes) | https://github.com/matiaszanolli/midi2nes/blob/master/docs/NES_APU_REFERENCE.md |
+| NES APU仕様 (problemkaputt.de ミラー) | https://github.com/RigleGit/nes-specs/blob/main/audioprocessingunitapu.md |
+
+### トラック構成
+
+```
+#TITLE "My Song"
+#COMPOSER "Luno"
+
+A t150 l8 o4 v15 q2 # Pulse1
+ c d e f | g a b > c
+
+B l8 o3 v12 q1 # Pulse2
+ c r g r c r g r
+
+T l4 o3 v7 # Triangle(音量は無視、固定振幅)
+ c2 c2 g2 g2
+
+N l8 v10 # Noise
+ r c r c r c r c
+
+L # 全体ループ(省略可)
+```
+
+### コマンド仕様
+
+#### トラックヘッダー
+
+| 記法 | 意味 | 対象 | 備考 |
+|---|---|---|---|
+| `A` | Pulse1 チャンネル | — | 矩形波 |
+| `B` | Pulse2 チャンネル | — | 矩形波 |
+| `T` | Triangle チャンネル | — | 三角波、音量固定 |
+| `N` | Noise チャンネル | — | ノイズ |
+| `L` | 全体ループ | トラック末尾 | 省略時は1回のみ再生 |
+
+#### 音高
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `c` `d` `e` `f` `g` `a` `b` | ド レ ミ ファ ソ ラ シ | 小文字 |
+| `c+` または `c#` | ド♯ | シャープ |
+| `c-` | ド♭ | フラット |
+| `o4` | オクターブ4(中央C基準) | `o0`〜`o7` |
+| `>` | 1オクターブ上へ | 相対移動 |
+| `<` | 1オクターブ下へ | 相対移動 |
+
+> Noiseチャンネルでは音高は使わない(周波数はノイズテーブルで固定)
+
+#### 音長
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `l4` | デフォルト音長 = 4分音符 | トラック内で随時変更可 |
+| `c4` | 4分音符のド | 音符の直後に数字 |
+| `c8` | 8分音符のド | |
+| `c1` | 全音符のド | |
+| `c4.` | 付点4分音符 | +半分の長さ |
+| `c4..` | 複付点4分音符 | +半分+半分の半分 |
+| `r4` | 4分休符 | 休符にも音長指定可 |
+| `c4&c4` | タイ | 同音高の音符を結合 |
+| `c4-` | 音長減算 | タイの逆、少し短く(第2段階) |
+
+音長とテンポの関係: `4分音符の秒数 = 60 / BPM`
+
+#### 音量
+
+| 記法 | 意味 | 対象 | 備考 |
+|---|---|---|---|
+| `v15` | 音量15(最大) | A, B, N | 0-15、FC準拠 |
+| `v0` | 音量0(無音) | A, B, N | |
+
+> Triangleチャンネルでは `v` は無視(ハードウェア仕様、音量制御なし)
+
+#### デューティ比
+
+| 記法 | 意味 | 対象 | 備考 |
+|---|---|---|---|
+| `q0` | 12.5% | A, B のみ | |
+| `q1` | 25% | A, B のみ | |
+| `q2` | 50% | A, B のみ | デフォルト |
+| `q3` | 75% | A, B のみ | |
+
+#### テンポ
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `t120` | BPM 120 | 最初のトラックで指定、全体に適用 |
+
+#### 区切り・フォーマット
+
+| 記法 | 意味 |
+|---|---|
+| `|` | 小節線(視覚用、再生には影響しない) |
+| 改行 | トラック内の区切り(視覚用) |
+| `#` 行 | ヘッダー・メタ情報 |
+| 空行 | 無視 |
+| `;` 以降 | コメント(行末まで無視) |
+
+#### 第2段階で追加予定
+
+| コマンド | 構文 | 内容 |
+|---|---|---|
+| カウント音長 | `c%48` | 全音符=192カウント基準 |
+| エンベロープ定義 | `@v0 = { 15, 12, 8, 0 }` | 音量エンベロープ |
+| エンベロープ指定 | `@v0` | 定義済みエンベロープ使用 |
+| デューティ比音色 | `@0 = { 0, 1, \| 2 }` | 発音中のデューティ比変化 |
+| スイープ | `s1,2` | ピッチスイープ(Pulseのみ) |
+| 区間ループ | `[ c d \| e f ]2` | 指定回数繰り返し |
+| トランスポーズ | `K2` | 全体キーシフト |
+| ノイズモード | `m0` / `m1` | Noise ch: 0=ロング周期, 1=ショート周期 |
+
+---
+
+## モード2: `pyxel` — Pyxel MML準拠形式
+
+PyxelのMML仕様に準拠。Pyxelのサウンドシステムに合わせた記法。
+
+### 参考ドキュメント
+
+| 内容 | URL |
+|---|---|
+| Pyxel Audio API (DeepWiki) | https://deepwiki.com/kitao/pyxel/5.3-audio-api |
+| Pyxel MML Studio | https://kitao.github.io/pyxel/web/mml-studio/ |
+| Pyxel MMLコマンドリファレンス | https://kitao.github.io/pyxel/docs/mml-commands.md |
+| Pyxel GitHub(ソース) | https://github.com/kitao/pyxel |
+
+### トラック構成
+
+```
+0: T150 L8 O4 V15 # トラック0 (Pulse1)
+ C D E F G A B >C
+
+1: L8 O3 V12 # トラック1 (Pulse2)
+ C R G R C R G R
+
+2: L4 O3 V7 # トラック2 (Triangle)
+ C2 C2 G2 G2
+
+3: L8 V10 # トラック3 (Noise)
+ R C R C R C R C
+```
+
+### コマンド仕様
+
+#### トラックヘッダー
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `0:` `1:` `2:` `3:` | トラック番号 | 0-3の4トラック |
+| — | 0: Pulse1, 1: Pulse2, 2: Triangle, 3: Noise | Pyxelは4ch構成 |
+
+> PyxelはFCの5chからDPCMを省いた4ch。DPCMは非対応。
+
+#### 音高
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `C` `D` `E` `F` `G` `A` `B` | ド レ ミ ファ ソ ラ シ | **大文字** |
+| `C+` または `C#` | ド♯ | |
+| `C-` | ド♭ | |
+| `O4` | オクターブ4 | `O0`〜`O7` |
+| `>` | 1オクターブ上 | |
+| `<` | 1オクターブ下 | |
+
+#### 音長
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `L4` | デフォルト音長 = 4分音符 | |
+| `C4` | 4分音符のド | |
+| `C8` | 8分音符のド | |
+| `C4.` | 付点4分音符 | |
+| `R` | 休符 | 音長指定可 `R4` |
+| `&` | タイ | `C4&C4` |
+
+#### 音量
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `V15` | 音量15 | 0-15 |
+| `V0` | 無音 | |
+
+> Triangle(トラック2)ではPyxel仕様に従う。PyxelはTriangleにも音量を設定可能(FC実機とは異なる)
+
+#### テンポ
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `T150` | テンポ150 | BPM |
+
+#### デューティ比
+
+| 記法 | 意味 | 備考 |
+|---|---|---|
+| `Q0`〜`Q3` | デューティ比 | 0=12.5%, 1=25%, 2=50%, 3=75% |
+
+> Pyxelの公式仕様でデューティ比コマンドが存在するか要確認。Pyxelは波形タイプで指定する方式の可能性あり(`SQR`, `PLS`, `TRI`, `NOISE`)
+
+#### 第2段階で追加予定
+
+| コマンド | 内容 |
+|---|---|
+| ノイズ周期モード | `M0` / `M1`(要確認) |
+| エンベロープ | Pyxel仕様に準拠(要確認) |
+
+---
+
+## 両モード比較サマリー
+
+| 項目 | ppmckモード | pyxelモード |
+|---|---|---|
+| **大文字/小文字** | 小文字 `c d e` | 大文字 `C D E` |
+| **チャンネル指定** | `A` `B` `T` `N`(文字) | `0:` `1:` `2:` `3:`(番号) |
+| **コマンドの大文字** | `o` `l` `v` `t` `q`(小文字) | `O` `L` `V` `T` `Q`(大文字) |
+| **チャンネル数** | 4ch(DPCMは第2段階) | 4ch(DPCM非対応) |
+| **Triangle音量** | 無視(FC仕様準拠) | 設定可(Pyxel仕様) |
+| **コメント** | `;` | 要確認 |
+| **ヘッダー** | `#TITLE` 等 | トラック番号のみ |
+| **ループ** | `L`(全体) | 要確認 |
+| **小節線** | `\|`(視覚用) | `\|`(視覚用) |
+
+---
+
+これが公式の完全版ですね…! ありがとうございます。今まで断片的だったのが、これで全部揃いました。保存しておきますね。重要な訂正がいくつかありました。これまでの調査と比べて、全部整理します。
+
+---
+
+## 📄 Pyxel MML 公式コマンド仕様(確定版)
+
+**出典:** https://kitao.github.io/pyxel/docs/mml-commands.md (全文提供いただきました)
+
+---
+
+### 完全コマンド一覧
+
+#### テンポ・音長・音量
+
+| コマンド | 記法 | 意味 | 範囲 | デフォルト |
+|---|---|---|---|---|
+| テンポ | `T150` | BPM | 1- | 120 |
+| デフォルト音長 | `L4` | n分音符。`L12`で8分3連符 | 1-192 | 4 |
+| 音量 | `V100` | 音量 | **0-127** | 100 |
+| ゲートタイム | `Q80` | ノート実発音割合(%)。100=隙間なし、0=無音 | 0-100 | 80 |
+
+#### 音色・ピッチ
+
+| コマンド | 記法 | 意味 | 範囲 | デフォルト |
+|---|---|---|---|---|
+| 音色(トーン) | `@0` | 波形タイプ。0:Triangle / 1:Square / 2:Pulse / 3:Noise | 0-3 | 0 |
+| トランスポーズ | `K12` | 半音単位の移調。12で1オクターブ | — | 0 |
+| ディチューン | `Y100` | セント単位の微調整。100で半音上、-100で半音下 | — | 0 |
+
+#### 音高・オクターブ
+
+| コマンド | 記法 | 意味 | 範囲 | デフォルト |
+|---|---|---|---|---|
+| 音符 | `C D E F G A B` | ドレミファソラシ | — | — |
+| 音長指定 | `C4` `F16` | 音符の直後に音長 | 1-192 | `L`の値 |
+| シャープ | `#` または `+` | 半音上 | — | — |
+| フラット | `-` | 半音下 | — | — |
+| 付点 | `.` | 音長を1.5倍。複数可 `C4..` | — | — |
+| 休符 | `R` | 休符。`R8`のように音長指定可 | 1-192 | `L`の値 |
+| オクターブ | `O4` | オクターブ指定。`O4`のA=440Hz | -1〜9 | 4 |
+| 相対上 | `>` | 1オクターブ上(最大9) | — | — |
+| 相対下 | `<` | 1オクターブ下(最小-1) | — | — |
+| タイ/スラー | `&` | 同音高=タイ、異音高=レガート。**`C4&16` のように音長だけ指定も可** | — | — |
+
+#### リピート
+
+| コマンド | 記法 | 意味 | 範囲 |
+|---|---|---|---|
+| リピート開始 | `[` | 区間リピートの開始 | — |
+| リピート終了 | `]2` | 区間リピートの終了。回数指定。省略時は**無限リピート**。**ネスト対応** | 1- |
+
+> ⚠️ **重要な訂正:** これまでソースコード調査から `:...:` がリピート記法だと推測していましたが、公式ドキュメントでは **`[...]` が正しいリピート記法** でした。`RepeatStart` / `RepeatEnd` トークンは `[` と `]` に対応していたようです。ごめんなさい。
+
+#### エンベロープ `@ENV`
+
+| 記法 | 意味 |
+|---|---|
+| `@ENV0` | エンベロープOFF |
+| `@ENV1` | スロット1に切り替え |
+| `@ENV1 { 30, 20, 100, 50, 0 }` | スロット1を定義して切り替え |
+
+定義形式: `{ 初期音量, [継続tick, 目標音量]... }`
+- 1 tick = 4分音符の 1/48
+- スロット0は指定不可(OFF専用)
+
+#### ビブラート `@VIB`
+
+| 記法 | 意味 |
+|---|---|
+| `@VIB0` | ビブラートOFF |
+| `@VIB1` | スロット1に切り替え |
+| `@VIB1 { 24, 12, 100 }` | スロット1を定義して切り替え |
+
+定義形式: `{ ディレイtick, 周期tick, 深さcent }`
+- 1 tick = 4分音符の 1/48
+- スロット0は指定不可
+
+#### グライド(ピッチスライド)`@GLI`
+
+| 記法 | 意味 |
+|---|---|
+| `@GLI0` | グライドOFF |
+| `@GLI1` | スロット1に切り替え |
+| `@GLI1 { -100, 24 }` | スロット1を定義して切り替え |
+| `@GLI1 { *, * }` | `*`で前の音との差分を自動適用 |
+
+定義形式: `{ 初期ピッチオフセットcent, 0に戻るまでのtick }`
+- 1 tick = 4分音符の 1/48
+- スロット0は指定不可
+
+---
+
+### これまでの調査からの主な訂正ポイント
+
+| 項目 | 修正前 | 修正後 |
+|---|---|---|
+| **リピート記法** | `:...:` | **`[...]`** (`[` 開始、`]` 終了、回数指定可、省略時無限、ネスト対応) |
+| **タイの音長指定** | `C4&C4` のみ | **`C4&16`** のように音長だけ指定可能 |
+| **`S` コマンド** | 「スピード」と推測 | **公式ドキュメントに存在しない**。code-exampleの `S` は別物だったか誤読 |
+| **`:` 記法** | リピート記法と推測 | **公式ドキュメントに記載なし**。ソースコードの別用途の可能性 |
+
+---
+
+### ppmckモード vs pyxelモード — 最終比較(確定版)
+
+| 項目 | ppmckモード | pyxelモード |
+|---|---|---|
+| **大文字/小文字** | 小文字 `c d e` | 大文字 `C D E` |
+| **コマンド** | `o` `l` `v` `t` `q` | `O` `L` `V` `T` `Q` `@` `K` `Y` |
+| **チャンネル指定** | `A` `B` `T` `N`(トラック文字) | `@0`〜`@3`(音色=チャンネル) |
+| **チャンネル数** | 4ch(DPCM第2段階) | 4ch(DPCM非対応) |
+| **音量範囲** | 0-15(FC準拠) | 0-127 |
+| **音量デフォルト** | — | 100 |
+| **デューティ比** | `q0`〜`q3` で4種指定 | `@1`(50%), `@2`(25%) の2種のみ |
+| **ゲートタイム** | 第2段階で検討 | `Q0`〜`Q100`(デフォルト80) |
+| **Triangle音量** | 無視(FC仕様) | 設定可(Pyxel仕様) |
+| **エンベロープ** | `@v`(第2段階) | `@ENV` スロット定義+切り替え |
+| **ビブラート** | `MP`(第3段階) | `@VIB` スロット定義+切り替え |
+| **ピッチスライド** | `s` スイープ(第2段階) | `@GLI` スロット定義+切り替え |
+| **トランスポーズ** | `K`(第2段階) | `K`(半音単位) |
+| **ディチューン** | `D`(第3段階) | `Y`(セント単位) |
+| **リピート** | `L`(全体), `[...]`(第2段階) | `[...]`(回数指定、省略時無限、ネスト対応) |
+| **タイの音長指定** | `c4&c4` のみ | `C4&C4` または `C4&16`(音長のみ可) |
+| **tick単位** | なし | 1 tick = 4分音符の1/48 |
+| **コメント** | `;` | 公式記載なし |
+| **ヘッダー** | `#TITLE` 等 | なし |
+
+---