summaryrefslogtreecommitdiff
path: root/src/mml_composemusic_mcp
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-07-12 18:50:50 +0900
committertanaka takashi <isazaka@gmail.com>2026-07-12 18:50:50 +0900
commitd83a966199671a1cab6b8f56be448662e79f4a46 (patch)
tree88f1ee34230e5f60411bf988a251b00c3c9fe8ad /src/mml_composemusic_mcp
parent3d06bee12a26bc55cd73b1494e4d008a8098f6f5 (diff)
feat: 合成機能テンプレートの拡充とドキュメントの更新
- ppmck/pyxel向けに表現力のある作曲テンプレートを追加 - エンベロープ、ビブラート、音程変化の使用例を追加 - テンプレートの検証・IR・音声合成テストを追加 - README、設計書、MCP仕様書を現行実装に合わせて更新
Diffstat (limited to 'src/mml_composemusic_mcp')
-rw-r--r--src/mml_composemusic_mcp/server.py4
-rw-r--r--src/mml_composemusic_mcp/templates.py9
2 files changed, 11 insertions, 2 deletions
diff --git a/src/mml_composemusic_mcp/server.py b/src/mml_composemusic_mcp/server.py
index 06520a6..45bae68 100644
--- a/src/mml_composemusic_mcp/server.py
+++ b/src/mml_composemusic_mcp/server.py
@@ -13,7 +13,7 @@ from .parser_pyxel import parse_pyxel
from .semantic_ppmck import analyze_ppmck
from .semantic_pyxel import analyze_pyxel
from .synthesizer import build_channel_summary, synthesize, write_wav
-from .templates import get_template
+from .templates import TEMPLATES, get_template
mcp = FastMCP("mml-composemusic-mcp")
OUTPUT_DIR = Path("./data")
@@ -88,7 +88,7 @@ def compose_mml(
if action == "template":
if mode not in ("ppmck", "pyxel"):
mode = "ppmck"
- if template not in ("basic", "melody", "chord", "drum", "empty"):
+ if template not in TEMPLATES[mode]:
template = "basic"
mml_text, description = get_template(mode, template)
return {"mml": mml_text, "description": description}
diff --git a/src/mml_composemusic_mcp/templates.py b/src/mml_composemusic_mcp/templates.py
index 9872e44..4d71568 100644
--- a/src/mml_composemusic_mcp/templates.py
+++ b/src/mml_composemusic_mcp/templates.py
@@ -7,6 +7,9 @@ TEMPLATES = {
"chord": '#TITLE "Chord Backing"\n#COMPOSER "LLM"\n\nA t120 l4 o4 v12 @2\n c e g c | f a > c f | g b > d g | c e g c\n\nB l4 o4 v12 @1\n e g b e | f a > c f | d g b d | e g b e\n\nT l2 o3 v7\n c2 | f2 | g2 | c2\n\nN l8 v8\n r c r c | r c r c | r c r c | r c r c\n',
"drum": '#TITLE "Drum Beat"\n#COMPOSER "LLM"\n\nA t120 l8 o4 v15 @2\n c r e r | g r e r | c r e r | g r c r\n\nB l8 o3 v12 @1\n e r g r | e r g r | e r g r | e r g r\n\nT l4 o2 v7\n c2 c2 | c2 c2 | c2 c2 | c2 c2\n\nN l16 v10\n c r c r c r c r | c r c r c r c r\n c r c r c r c r | c r c r c r c r\n',
"empty": '#TITLE "Empty Template"\n#COMPOSER "LLM"\n\nA t120 l4 o4 v15 @2\n r1\n\nB l4 o3 v12 @1\n r1\n\nT l4 o3 v7\n r1\n\nN l4 v10\n r1\n',
+ "expressive_lead": '#TITLE "Expressive Lead"\n#COMPOSER "LLM"\n\n; Define reusable volume and duty envelopes before the tracks.\n@v1={15,12,9|7,9}\n@0={2,1|2,3}\n\nA t132 l8 o5 v15 q7 @v1 @@0\n c e g >c | <b g e c | v-3 d f a >d | v+3 <c4 r4\n\nB l8 o4 v10 @1\n c r g r | e r g r | d r a r | e4 r4\n\nT l4 o3 v7\n c2 e2 | d2 c2\n\nN l8 v9\n c r c c | c r c r | c r c c | c r c r\n',
+ "vibrato_lead": '#TITLE "Vibrato Lead"\n#COMPOSER "LLM"\n\n; MP adds cyclic vibrato; EP adds a one-shot upward pitch shape.\n@MP1={12,16,18,0}\n@EP1={40,20,0|10,0}\n\nA t116 l8 o5 v15 @2 D-6 MP1\n c4 e4 | g2 MPOF | EP1 a4 g4 | EPOF D0 e2\n\nB l8 o4 v10 @1 D6\n c e g e | c e g e | f a >c <a | g b >d <b\n\nT l4 o3 v7\n c2 g2 | f2 g2\n\nN l8 v8\n c r c r | c r c r | c r c r | c r c r\n',
+ "pitch_motion": '#TITLE "Pitch Motion"\n#COMPOSER "LLM"\n\n; EN creates a rapid arpeggio; sweep bends Pulse pitch over time.\n@EN1={0,4,7|12,7,4}\n\nA t144 l8 o4 v15 @2 EN1\n c2 g2 | ENOF s2,3 >c2 <g2 | s0,-2 c1\n\nB l8 o3 v11 @1\n c c g g | a a g4 | f f e e | d d c4\n\nT l4 o2 v7\n c2 g2 | a2 f2 | c1\n\nN l8 v10\n c r c c | c r c r | c r c c | c c c r\n',
},
"pyxel": {
"basic": "0: T120 L8 O4 V100 @1\n C D E F | G A B >C\n\n1: L8 O3 V80 @2\n E G B R | E G B R\n\n2: L4 O3 V60\n C2 G2 E2 C2\n\n3: L8 V80\n C R C R | C R C R\n",
@@ -14,6 +17,9 @@ TEMPLATES = {
"chord": "0: T120 L4 O4 V90 @1\n C E G C | F A >C F | G B >D G | C E G C\n\n1: L4 O4 V90 @2\n E G B E | F A >C F | D G B D | E G B E\n\n2: L2 O3 V60\n C2 | F2 | G2 | C2\n\n3: L8 V70\n R C R C | R C R C | R C R C | R C R C\n",
"drum": "0: T120 L8 O4 V100 @1\n C R E R | G R E R | C R E R | G R C R\n\n1: L8 O3 V80 @2\n E R G R | E R G R | E R G R | E R G R\n\n2: L4 O2 V60\n C2 C2 | C2 C2 | C2 C2 | C2 C2\n\n3: L16 V80\n C R C R C R C R | C R C R C R C R\n C R C R C R C R | C R C R C R C R\n",
"empty": "0: T120 L4 O4 V100 @1\n R1\n\n1: L4 O3 V80 @2\n R1\n\n2: L4 O3 V60\n R1\n\n3: L4 V80\n R1\n",
+ "expressive_lead": "0: T132 L8 O5 V110 Q90 @1 @ENV1 110 24 80 24 45 48\n C E G >C | <B G E C | @ENV0 D F A >D | <C4 R4\n\n1: L8 O4 V75 @2\n C R G R | E R G R | D R A R | E4 R4\n\n2: L4 O3 V60\n C2 E2 | D2 C2\n\n3: L8 V75\n C R C C | C R C R | C R C C | C R C R\n",
+ "vibrato_lead": "0: T116 L8 O5 V110 @1 Y-6 @VIB1 12 16 18\n C4 E4 | G2 @VIB0 | @VIB1 A4 G4 | @VIB0 Y0 E2\n\n1: L8 O4 V75 @2 Y6\n C E G E | C E G E | F A >C <A | G B >D <B\n\n2: L4 O3 V60\n C2 G2 | F2 G2\n\n3: L8 V70\n C R C R | C R C R | C R C R | C R C R\n",
+ "pitch_motion": "0: T144 L8 O4 V110 @2 @GLI1 700 48\n C2 G2 | @GLI0 K12 C2 K0 G2 | @GLI1 C1\n\n1: L8 O3 V80 @1\n C C G G | A A G4 | F F E E | D D C4\n\n2: L4 O2 V60\n C2 G2 | A2 F2 | C1\n\n3: L8 V80\n C R C C | C R C R | C R C C | C C C R\n",
},
}
@@ -23,6 +29,9 @@ DESCRIPTIONS = {
"chord": "コード伴奏重視(Pulse2で和音、Triangleでベース)",
"drum": "リズム重視(Noise中心のビートパターン)",
"empty": "各チャンネルのヘッダーのみ(空のテンプレート)",
+ "expressive_lead": "音量・音色エンベロープで表情を付けるリード",
+ "vibrato_lead": "ビブラート・ピッチ変化・デチューンを使うリード",
+ "pitch_motion": "アルペジオ・スイープ・グライドによる大きな音程変化",
}