diff options
| author | tanaka takashi <isazaka@gmail.com> | 2026-07-12 18:28:50 +0900 |
|---|---|---|
| committer | tanaka takashi <isazaka@gmail.com> | 2026-07-12 18:28:50 +0900 |
| commit | 3d06bee12a26bc55cd73b1494e4d008a8098f6f5 (patch) | |
| tree | dd13a8f3fcd9d6dbf74d6406bfaa8894895af0ce /src/mml_composemusic_mcp/ir.py | |
| parent | bf36a773918959eeb6ffe7dae2fb8b0874438eb4 (diff) | |
feat: MML拡張合成とNTSC 2A03準拠のIR v2音源を実装
- エンベロープ、LFO、ビブラート、グライドのグローバル定義表を追加
- ppmckおよびPyxelの拡張コマンドを音声合成へ反映
- 2A03のPulseデューティ列、Triangle DAC、Noise LFSR、Sweepを実装
- APUタイマーに基づく周波数量子化と非線形ミキサを追加
- 途中テンポ変更、拡張コマンドの検証、トラック外定義に対応
- APU規格、拡張合成、IR v2のテストを追加
- プロジェクト独自のppmck拡張仕様と対応範囲を文書化
Diffstat (limited to 'src/mml_composemusic_mcp/ir.py')
| -rw-r--r-- | src/mml_composemusic_mcp/ir.py | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/mml_composemusic_mcp/ir.py b/src/mml_composemusic_mcp/ir.py index 4dd7978..d9a2f93 100644 --- a/src/mml_composemusic_mcp/ir.py +++ b/src/mml_composemusic_mcp/ir.py @@ -44,6 +44,7 @@ class ErrorCode(Enum): SEMANTIC_EMPTY_TRACK = "SEMANTIC_EMPTY_TRACK" SEMANTIC_OUTSIDE_TRACK = "SEMANTIC_OUTSIDE_TRACK" SEMANTIC_UNDEFINED_REFERENCE = "SEMANTIC_UNDEFINED_REFERENCE" + SEMANTIC_DUPLICATE_DEFINITION = "SEMANTIC_DUPLICATE_DEFINITION" SEMANTIC_UNSUPPORTED_FEATURE = "SEMANTIC_UNSUPPORTED_FEATURE" # --- Runtime errors (Synthesizer phase) --- @@ -279,9 +280,22 @@ class ChannelSequence: @dataclass class NoteSequence: - version: str = "1.0" + version: str = "2.0" bpm: int = 120 ticks_per_quarter: int = 192 + mode: str = "ppmck" + definitions: dict[str, dict[int, Any]] = field( + default_factory=lambda: { + "volume_envelopes": {}, + "duty_envelopes": {}, + "pitch_envelopes": {}, + "note_envelopes": {}, + "lfos": {}, + "envelopes": {}, + "vibratos": {}, + "glides": {}, + } + ) channels: dict[str, ChannelSequence] = field( default_factory=lambda: { "Pulse1": ChannelSequence("pulse"), @@ -296,6 +310,8 @@ class NoteSequence: "version": self.version, "bpm": self.bpm, "ticks_per_quarter": self.ticks_per_quarter, + "mode": self.mode, + "definitions": self.definitions, "channels": {k: v.to_dict() for k, v in self.channels.items()}, } |
