summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Design.md20
-rw-r--r--doc/MML_BNF.md27
-rw-r--r--doc/mcp.md4
3 files changed, 28 insertions, 23 deletions
diff --git a/doc/Design.md b/doc/Design.md
index 525a22e..eab87aa 100644
--- a/doc/Design.md
+++ b/doc/Design.md
@@ -16,7 +16,7 @@ LLMがMML(Music Macro Language)を記述することで、レトロチップ
|---|---|
| **LLMフレンドリ** | LLMが生成しやすいMML構文、明確なエラーメッセージ |
| **2モード対応** | `ppmck`モード(クラシックAPU準拠)と`pyxel`モード(Pyxel準拠)を切り替え可能 |
-| **正確な音源エミュレーション** | レトロAPU 4チャンネルの特性を忠実に再現 |
+| **正確な音源エミュレーション** | NTSC 2A03 timer、段階波形、Noise LFSR、Sweep、非線形ミキサを再現 |
| **拡張性** | 共通AST・IRによりモード別の構文と音声合成を分離 |
| **単一ツール** | `compose_mml` の1ツールで作曲・検証・テンプレート生成を完結 |
@@ -25,7 +25,7 @@ LLMがMML(Music Macro Language)を記述することで、レトロチップ
| 対象 | 内容 |
|---|---|
| 実装範囲 | Pulse1 / Pulse2 / Triangle / Noiseの4ch MML解析、WAV合成、バリデーション、テンプレート生成 |
-| 構文拡張 | Pyxel `@ENV` / `@VIB` / `@GLI`、ppmck `@v` / `@@` / `@MP` / `@EP` / `@EN` / `D` / `s` / `v+` / `v-` / `^` をIRへ保持し、合成未対応のwarningを返す |
+| 構文拡張 | Pyxel `@ENV` / `@VIB` / `@GLI`、ppmck `@v` / `@@` / `@MP` / `@EP` / `@EN` / `D` / `s` / `v+` / `v-` / `^` をIR v2から合成へ反映 |
| 対象外 | GUI / Webフロントエンド、DPCM、NSF出力、未定義のppmck拡張構文 |
### 1.4 技術スタック
@@ -289,16 +289,16 @@ MML文字列
| ゲートタイム | `q`+数値(ppmck 1-8), `Q` + 数値 (pyxel 0-100) | |
| トランスポーズ | `K` + 符号付き整数 (pyxel) | 例: `K-12`, `K+7` |
| ディチューン | `D` + 符号付き整数 (ppmck), `Y` + 符号付き整数 (pyxel) | 例: `D-10`, `Y-25` |
-| 相対音量 | `v+` / `v-` (ppmck) | IR保持のみ |
-| スイープ | `s`+数値,数値 (ppmck) | IR保持のみ |
+| 相対音量 | `v+` / `v-` (ppmck) | 0〜15へクランプして合成 |
+| スイープ | `s`+数値,符号付き数値 (ppmck) | 2A03 Pulse sweepへ反映 |
| タイ | `^` (ppmck), `&` (両モード) | `^`はタイ、`&`はスラー |
| リピート | `[`, `]` + 数値 | ppmckはASTへ保持してwarning、Pyxelは展開 |
-| エンベロープ/LFO | `@v`/`@@`/`@MP`/`@EP`/`@EN` (ppmck), `@ENV`/`@VIB`/`@GLI` (pyxel) | IR保持のみ、合成未対応warning |
+| エンベロープ/LFO | `@v`/`@@`/`@MP`/`@EP`/`@EN` (ppmck), `@ENV`/`@VIB`/`@GLI` (pyxel) | IR v2定義表を参照して合成 |
| 小節線 | `\|` | 視覚用、再生に影響しない |
| トラック識別 | ppmck: `A`/`B`/`T`/`N`/`L`, pyxel: `数字:` | |
| ヘッダー | `#` で始まる行 (ppmck) | |
| コメント | `;` 以降行末 (ppmck) | |
-| 拡張コマンド | `@ENV`/`@VIB`/`@GLI` (pyxel) | 空白区切りの数値引数をIRへ保持、合成未対応warning |
+| 拡張コマンド | `@ENV`/`@VIB`/`@GLI` (pyxel) | 空白区切りの数値引数をIR v2へ保持して合成 |
| 不正文字 | `INVALID` | Parserが構文エラーとして報告 |
### 5.3 Parser(モード別)
@@ -349,7 +349,7 @@ SemanticAnalyzerの責務は**ASTを検証・解釈してNoteSequence IRを生æˆ
- 音量 `V0-V127` → `0-15` 正規化
- ゲートタイム `Q0-Q100` → `0.0-1.0`
- `@` コマンドのチャンネル適合性チェック
-- `@ENV`/`@VIB`/`@GLI` のIR保持と合成未対応warning
+- `@ENV`/`@VIB`/`@GLI` のIR v2定義、選択、解除、合成
- 無限リピートの2回打ち切りwarning
- `&` スラーを前の音符の音長延長として解釈
@@ -631,7 +631,7 @@ class ErrorPhase(Enum):
BNFの各規則は Lexer → AST → IR/診断の一貫経路で検証する。`tests/test_mml_conformance.py`は、音符・休符・コマンド・トラック・ヘッダー・拡張コマンドについて正例、負例、境界値、位置情報を検査する。Hypothesisによる固定seedの生成テストで、有効音列のAST/IR保存と単一トークン破壊の非黙殺も確認する。
-ppmckの将来予約構文は現在の受理言語に含めない。ppmckの `@v`/`@@`/`@MP`/`@EP`/`@EN` および `D`/`s`/`v+`/`v-` は構文解析してIRへ保持し、合成未対応を `SEMANTIC_UNSUPPORTED_FEATURE` でwarningとして返す。Pyxel拡張も同様に空白区切り引数を受理し、AST/IRへ保持したうえで `SEMANTIC_UNSUPPORTED_FEATURE` warningを返す。
+ppmckの将来予約構文は現在の受理言語に含めない。ppmck/pyxelの拡張はIR v2の共有定義表とチャンネル制御イベントへ変換して合成する。ppmckは構文モード名であり、PPMCK/mckcとのドライバ互換は保証しない。
## 9. APU音声合成エンジン
@@ -658,8 +658,8 @@ NoteSequence IRを入力としてPulse1、Pulse2、Triangle、Noiseを合成しã
| **デューティ比** | `@0`〜`@3` で4種(Pulse系のみ) | `@0`〜`@3`(Pulse系のみ有効) |
| **クオンタイズ/ゲート** | `q1`〜`q8`(gate_time = value / 8) | `Q0`〜`Q100`(%) |
| **タイ/スラー** | `^` = タイ、`&` = スラー | `&` = スラー(タイなし) |
-| **ディチューン** | `D-127`〜`D126`(IR保持のみ) | `Y-127`〜`Y127`(セント) |
-| **エンベロープ/LFO** | `@v`/`@@`/`@MP`/`@EP`/`@EN`(IR保持のみ) | `@ENV`/`@VIB`/`@GLI`(IR保持のみ) |
+| **ディチューン** | `D-127`〜`D126`(セント) | `Y-127`〜`Y127`(セント) |
+| **エンベロープ/LFO** | `@v`/`@@`/`@MP`/`@EP`/`@EN`(合成対応) | `@ENV`/`@VIB`/`@GLI`(合成対応) |
| **リピート** | `L`(構文上のループトラック)、`[...]`(AST保持・warning、合成未反映) | `[...]`(回数指定、省略時は2回で打ち切り、ネスト対応) |
---
diff --git a/doc/MML_BNF.md b/doc/MML_BNF.md
index 83a1281..0c3f3b0 100644
--- a/doc/MML_BNF.md
+++ b/doc/MML_BNF.md
@@ -102,7 +102,7 @@
<comment> ::= ";" <string_to_eol>
```
-### 2.3 拡張コマンド(第1段階: IR 保持のみ、合成無視)
+### 2.3 合成拡張コマンド
```bnf
<ppmck_ext_cmd> ::= <relative_volume_cmd>
@@ -127,7 +127,7 @@
| "v-" <number>? /* 1 〜 15 */
<detune_cmd> ::= "D" <signed_number> /* -127 〜 126 */
-<sweep_cmd> ::= "s" <number> "," <number>
+<sweep_cmd> ::= "s" <number> "," <signed_number>
<vol_envelope_def>::= "@v" <number> "=" "{" <number_list> "|" <number_list>? "}"
<vol_envelope_use>::= "@v" <number>
@@ -224,7 +224,7 @@
<tie_cmd> ::= <tie> (<note> | <rest> | <number>)
```
-### 3.3 拡張コマンド(第1段階: IR 保持のみ、合成無視)
+### 3.3 合成拡張コマンド
```bnf
<ext_cmd> ::= <env_cmd> | <vib_cmd> | <gli_cmd>
@@ -261,19 +261,19 @@
| `l` / `L` | 両方 | 1 〜 192 | 4 | |
| `v` | ppmck | 0 〜 15 | 15 | |
| `V` | pyxel | 0 〜 127 | 100 | |
-| `v+` / `v-` | ppmck | 1 〜 15 | 1 | 相対音量(IR保持のみ) |
+| `v+` / `v-` | ppmck | 1 〜 15 | 1 | 相対音量(0〜15へクランプ) |
| `@` | ppmck | 0 〜 3 | 2 | デューティ比(Pulse系のみ) |
| `@` | pyxel | 0 〜 3 | — | デューティ比(Pulse系のみ) |
| `q` | ppmck | 1 〜 8 | 8 | クオンタイズ(gate_time = value / 8) |
| `Q` | pyxel | 0 〜 100 | 80 | ゲートタイム(%) |
| `t` / `T` | 両方 | 1 〜 | 120 | |
-| `D` | ppmck | -127 〜 126 | 0 | ディチューン(IR保持のみ) |
-| `s` | ppmck | 0 〜 15, 0 〜 7 | — | スイープ `s<x>,<y>`(IR保持のみ) |
-| `@v` | ppmck | 0 〜 255 | — | 音量エンベロープ(IR保持のみ) |
-| `@@` | ppmck | 0 〜 255 | — | デューティエンベロープ(IR保持のみ) |
-| `@MP` / `MP` / `MPOF` | ppmck | 0 〜 255 | — | LFO(IR保持のみ) |
-| `@EP` / `EP` / `EPOF` | ppmck | 0 〜 255 | — | ピッチエンベロープ(IR保持のみ) |
-| `@EN` / `EN` / `ENOF` | ppmck | 0 〜 255 | — | ノートエンベロープ(IR保持のみ) |
+| `D` | ppmck | -127 〜 126 | 0 | cent単位ディチューン |
+| `s` | ppmck | speed 0〜7, depth ±1〜±7 | — | Pulseハードウェアスイープ |
+| `@v` | ppmck | 0 〜 255 | — | 48 tick単位の音量エンベロープ |
+| `@@` | ppmck | 0 〜 255 | — | 48 tick単位のデューティエンベロープ |
+| `@MP` / `MP` / `MPOF` | ppmck | 0 〜 255 | — | 三角LFO |
+| `@EP` / `EP` / `EPOF` | ppmck | 0 〜 255 | — | cent単位ピッチエンベロープ |
+| `@EN` / `EN` / `ENOF` | ppmck | 0 〜 255 | — | 絶対半音オフセット列 |
| `K` | pyxel | -127 〜 127 | 0 | トランスポーズ(半音) |
| `Y` | pyxel | -127 〜 127 | 0 | ディチューン(セント) |
@@ -283,8 +283,9 @@
- 本 BNF は `mml-composemusic-mcp` の**サポート範囲**を定義するものであり、オリジナルの PPMCK や Pyxel の全機能を網羅するものではない。
- 第2段階予定コマンドは設計予約として記載するが、現在の受理文法には含めない。
-- ppmck モードの `@v` / `@@` / `@MP` / `@EP` / `@EN`、および `D` / `s` / `v+` / `v-` は構文解析して IR へ保持し、合成には反映しない。未対応を `SEMANTIC_UNSUPPORTED_FEATURE` で警告する。
-- pyxel モードの `@ENV` / `@VIB` / `@GLI` も同様に IR 保持のみで、`SEMANTIC_UNSUPPORTED_FEATURE` 警告を返す。
+- ppmck モード名は構文互換の識別子であり、拡張の挙動は本プロジェクト独自仕様である。PPMCK/mckc互換は保証しない。
+- ppmck の列型エンベロープは1要素48 tickで、`|`以降を反復し、反復がなければ末尾値を保持する。`D`/`@EP`はcent、`@EN`は絶対半音、`@MP`は`delay,period,depth,0`である。
+- pyxel の `@ENV` は`target,duration`組、`@VIB`は`delay,period,depth_cents`、`@GLI`は`initial_offset_cents,duration`である。slot 0は解除を表す。
- コマンド文字は ppmck では小文字、pyxel では大文字を使用する。音符・休符も同じ規則に従う。ただし ppmck の `D`(ディチューン)は大文字のみ受理する(小文字 `d` は音符)。
- `^` は ppmck モード専用のタイ、`&` は両モード共通のスラー(slur)として扱う。
- 詳細な実装アーキテクチャは [Design.md](Design.md) を参照。
diff --git a/doc/mcp.md b/doc/mcp.md
index fbc8dbd..ecdda8e 100644
--- a/doc/mcp.md
+++ b/doc/mcp.md
@@ -52,6 +52,10 @@ MML文字列を解析し、以下のいずれかの処理を実行します。
| `wav_path` | string \| null | 生成されたWAVファイルのパス(失敗時はnull) |
| `duration_sec` | number | 生成された音声の長さ(秒) |
| `note_sequence` | object \| null | 中間表現(IR)のNoteSequence |
+
+`note_sequence`はIR v2で返される。曲全体で共有するエンベロープ/LFO定義は
+`definitions`、選択・解除と演奏イベントは各`channels.*.events`に格納される。
+`ppmck`は構文モード名であり、拡張コマンドのPPMCK/mckc互換を保証しない。
| `validation.errors` | array | エラーのリスト |
| `validation.warnings` | array | 警告のリスト |