One emitter, four target formats, two uses.
ARR-SPEC(+ meta.upstream.lyrics 的歌词)
↓ mc-symbolic-score
├─→ ABC → YuE2 的 abc= 输入(★ 让规格被"执行"而不是"提示");大模型的母语
├─→ MusicXML → 记谱软件 / 交接给乐手(领奏谱:旋律、和弦、歌词、段落、力度、换气)
├─→ MIDI → DAW + 音源,确定性渲染
└─→ ChordPro → 吉他手、排练(段落、和弦、歌词)
Why the same emitter: ABC ↔ MusicXML ↔ MIDI are interconvertible, ChordPro is a subset of the first three, all four carry the same set of information (pitch, duration, measures, key signature, time signature, dynamics, chords, lyrics). Splitting into four skills would make the same spec produce four inconsistent scores. The spelling of the spec sheet's executable fields is defined according to these four formats (schema §1.3.1, §4); the emitter does not need to translate symbols.
Which sections to read by task
| Task | Read |
|---|---|
| Supply a score to YuE2 | §3 ABC + §7 |
| Output MIDI to a DAW | §5 |
| Output MusicXML to hand to a player | §4 |
| Want a deterministic baseline for AB | §2.2 |
| Degree to letter | §3.3 |
| How expression/dynamics are written into MIDI | §5.2 |
| How to verify after emitting | §8 |
Boundaries
| Not covered here | Where it belongs |
|---|---|
| Prompts, section tags, backend selection | mc-render-compile |
| The content of melody/harmony/counterpoint itself | L1 skills |
| What sound source to use, sample library selection, keyswitch | Not covered by this package (which sound source to use is determined by the production environment); the meaning of MIDI CC in orchestration belongs to mc-orchestration reference §5 |
| The meaning of MIDI CC in orchestration | mc-orchestration reference §5 |
| Quantization, velocity'sgroovedesign | mc-rhythm-section |
| The complete specification of notation (slurs, ornament notation) | reference.md |
1. Must-fill before starting
| Required | How to ask |
|---|---|
| ① Target format | ABC / MusicXML / MIDI / ChordPro。What they can carry differs(§6);meta.deliverable emit only what is listed in |
| ② Number of parts | Only lead melody + chords? Or the full score? |
| ③ Who reads it | YuE2 / DAW / human.Determines the level of detail |
| ④ Is this a baseline run | If yesall randomness must be turned off |
2. Why take the symbolic path
2.1 It is the only path that lets the spec be "executed"
All other backends can only "suggest". YuE2's synthesis stepdirectly consumes ABC——
form[].harmony_letters / meta.key / meta.meter / meta.tempo
After compiling to ABC,they are no longer suggestions。
bypass the model's own symbolic planning stepentirely, and feed our ABC directly into the synthesis step. Any carrier that supports YuE2 can be connected this way (see
mc-render-compile§8.2); how to wire it up is a matter for the user's environment.
2.2 It is the only fully reproducible output
The same spec always renders identically.
This makes it the control-variable baseline for AB experiments: to find out "how much difference changing this one field actually makes", render two versions via the symbolic path, and the difference comes 100% from that field. Generative backends cannot do this (even with a fixed seed, changing the prompt changes other things too).
2.3 The Japanese-style 打ち込み workflow was originally this form
LLM directly outputs MIDI/MusicXML, goes into the DAW, and is paired with sound sources. ★ This path has no vocals, and vocals must be connected separately (or use the generation backend for vocals and the symbolic path for accompaniment).
3. ABC mapping
3.1 Header
| ABC field | From | Example |
|---|---|---|
X: |
Fixed 1 | X:1 |
T: |
meta.title |
T:Night Drive |
M: |
meta.meter |
M:4/4 |
L: |
Default unit note value (usually 1/8 or 1/16) | L:1/8 |
Q: |
meta.tempo |
Q:1/4=112 |
K: |
meta.key |
K:D |
★ tempo_map When there are multiple items:Q: take the first item, and write subsequent tempo changes as inline fields within the measure [Q:...] .
3.2 Body
| Content | From | Notation |
|---|---|---|
| Bar line | form[].bars / start_bar |
` |
| Section marker | form[].id + name |
★ Written as a comment % or [P:A1] section marker, see §7.2 |
| Chord | form[].harmony_letters |
"F#m7" placed in quotes before the note |
| Melody | Melody written by L1 | Standard ABC pitch notation |
| Repeat | Section repeat | ` |
3.3 ★ Degree → letter
In ARR-SPEC, harmony is the degree,harmony_letters is the letter, and the two are doubly notated.
When emitting ABC, use the letter, but the two must be validated to be consistent.
Validation action: convert harmony_letters back to a degree according to meta.key ,
and compare chord by chord with harmony .If they do not match, there is a typo in the spec——
this is the practical use of the ARR-SPEC dual-notation convention, not just for readability.
For the transposition table, see mc-progressions reference.md §8。
3.4 ★ The trap of repeat signs
ABC's |: :| makesboth passes exactly the same.
But lint #16 of this library requiresthe chorus to vary from pass to pass——
so in most cases do not use repeat signs; write out each pass explicitly.
★ Exception: sections that are indeed exactly the same (for example, a purely instrumental vamp) may use repeats. Butthe chorus is always written out explicitly。
4. MusicXML
Purpose: to hand over to notation software and to musicians.
What it can carry more than ABC:
- Complete staff layout and part assignment
- Performance markings (bowings, slurs, articulation)
- Dynamic markings (p / mf / f and crescendo/decrescendo)
- Lyrics (syllable-by-syllable alignment)
What it can carry more than MIDI:Notation intent(for the same pitch and duration, whether it is a sharp or a flat, whether it is a triplet or dotted).
★ When it must be used:mc-orchestration when the output is to be given to a real person to perform.
Neither ABC nor MIDI can express bowings and parts.
5. MIDI
5.1 Basic mapping
| Content | From |
|---|---|
| Note | Melody and harmony |
| Track/channel | arrangement.roster[], one track per instrument |
| Sound source mapping | roster[].midi({program, bank, channel}, GM number, drum kit channel 10);render.midi.instrument_map only put remarks such as VST names |
| Tempo | meta.tempo / tempo_map |
5.2 ★ Expression: velocity and CC
MIDI's biggest advantage over ABC is that it can write continuous control.
| From ARR-SPEC | write as |
|---|---|
arrangement.energy_curve |
CC11 (expression) curves + velocity layers |
vocal.dynamics_by_section |
CC11 for the vocal track (if there is a vocal sound source) |
groove.push_pull |
★ the actual offset of note positions(this is the only path that can execute push_pull precisely) |
groove.quantize_policy |
the degree of quantization per track |
roster[].synth_params |
sound source parameters or CC74 (brightness), etc. |
★ The division of labor between CC7 and CC11 must not be mixed up(→ mc-orchestration reference §5.1):
- CC7 determines this track'sposition
- CC11 determineshow this phrase breathes
The result of mixing them is "you pushed the fader but the phrase is still dead."
5.3 ★ On the symbolic path, push_pull is exact
backends.yaml in the symbolic backend, the groove related items are exact——
because note positions can be written precisely.
This is the only reliable means of verifying "whether push_pull is actually useful":
the same score, one version aligned to the grid, one version offset according to push_pull, compared directly.
6. What the four formats can carry
| ABC | MusicXML | MIDI | ChordPro | |
|---|---|---|---|---|
| pitch/duration/measure | ✅ | ✅ | ✅ | ❌ only sections |
| key signature/time signature/tempo | ✅ | ✅ | ✅ | ✅ header directives |
| chord symbols | ✅ | ✅ | ⚠ only as text events | ✅ |
| lyrics | ✅ basic | ✅ complete | ⚠ only as text events | ✅ |
| notation intent(sharps/flats, triplet spelling) | partial | ✅ | ❌ | ❌ |
| articulation marks(bowing, articulation) | ❌ | ✅ | ⚠ can only be approximated via CC/keyswitch | ❌ |
| continuous control(CC curves) | ❌ | ❌ | ✅ | ❌ |
| micro-timing offset(push_pull) | ❌ | ❌ | ✅ | ❌ |
| YuE2 takes directly | ✅ | ❌ | ❌ | ❌ |
★ Conclusion:
- Want YuE2 to execute → ABC
- Want to hand it to a person → MusicXML
- Want expression and groove → MIDI
- Want to give it to a guitarist and rehearse → ChordPro
- If you want several, send several, butsend them from the same spec, don't write each one separately
6b. YuE2 dialect: the four rules measured in practice (2026-09-17)
The same score compiled from ARR-SPEC, fed into YuE2's abc port in three spellings, produced wildly different results:L:1/16 single-voice produced 2:18 (the score says 4:00, the model stopped early), deleting the section comments made it even shorter (1:58),changing it to L:1/32 ran the full 3:56. So give YuE2 ABC that looks the way it writes scores itself:
-
L:1/32: all durations are counted in thirty-second notes, a quarter note is written 8, a dotted half is written 24, a full-measure restz32. WithL:1/16it treats the score as half as long and ends early. ⚠ But changing only this one rule is not enough: the same score changed toL:1/32After running the full duration, whisper can't recognize a single word (76% for the direct-output version, 65% for the model's self-written score, 2% for this version). The reason lies in the melody itself: each character's duration is too long, there are too few notes, and the register is an octave lower than the model's self-written score. The vocal line given to YuE2 should be like what it writes itself: lowercase note-name range (around c to a), four to six notes per measure, and a single character rarely exceeding one beat. Measured: raising the same score up an octave overall into the lowercase note-name range takes whisper's recognition rate from 2% to 47%; adding a w: lyric line brings it to 56% (direct output is 76%). This is where items 5 and 6 come from: -
with
w:lyric line (see item 6). -
Write the voice header as
V: Vocal clef=treble name="Vocal Melody" snm="Vocal", annotate sections with% intro/% verse/% pre-chorus/% chorus/% bridge/% outro; its self-written score also has aV: Insvoice for instrumental phrases, and a single voice can also run the full duration. -
Title line
T:can be empty; callingK:Dand similar standard notation, the model tends toward the relative minor when writing itself (for the same piece it writesK:Dm), which doesn't matter. -
Write the vocal line in the lowercase note-name range(ABC's c to a, i.e. around C5 to A5); in the uppercase range it sings indistinct vowels; this has nothing to do with human vocal range, it's the model's habit.
-
with
w:lyric line(one character per note, with the character count equal to the note count line by line) gives a higher recognition rate than only giving words at the lyrics slot; include the w: line as usual, and also give the lyrics slot as usual. -
To do: melody density. The compiler currently gives each character a long note (dotted half note, whole note), while the model's self-written score has four to six notes per measure and a single character rarely exceeds one beat; most of the remaining gap in recognition rate is here.
Spec fields that ABC cannot express (subtractive events, reverb cutoff, per-instrument entry and exit) can only rely on style text, see mc-render-compile。
7. Practical operation of supplying scores to YuE2
7.1 Connection method
[我们的 ABC] ──→ YuE2GenerateMusic ──→ 音频
↑
(YuE2GenerateABC 被旁路掉)
This skill only handles the left cell: compiling ARR-SPEC into ABC text.
Why the right line should be connected, why after connecting the spec is no longer just a "prompt",
and what carrier (official script, ComfyUI node) to use for the wiring, see mc-render-compile §8.2。
7.2 The dialect is already figured out
YuE2GenerateMusic 's abc input end eats what, §6b has already been fixed based on measurements: annotate sections with % , use standard spelling in quotes for chords ("F#m7"),V: Vocal plus optional V: Ins both voices can run. The only thing still uncertain is that one cut of melody density (§6b item 7).
7.3 Upstream has an official skill
The official YuE2 repository comes with skills/yue2-music/(SKILL.md format, including "check musical invariants").
★ Do not rewrite it. We write the ARR-SPEC→ABC adapter, and reference theirs for knowledge of model operation. Its musical invariants should be aligned or complementary with our 20 self-checks aligned or complementary——
8. ★ Verification loop after emission
Do not send unverified scores into the synthesizer. Three steps:
| # | Check | How to do it |
|---|---|---|
| 1 | Syntax | ABC → run it through a parser; MusicXML → schema validation; MIDI → read it back to see track count and duration |
| 2 | Consistent with spec | ★ total measures == Σ form[].bars; key signature, time signature, and tempo match;letter chords reverse-inferred degree == harmony |
| 3 | Listen once to the simplest rendering | Render quickly with any sound source,only listen to whether the structure is right, not the timbre |
★ The bar-count check in step 2 is the most valuable— the most common bug in the emitter is miscalculating section boundaries, and that error shows up in the audio as "the structure is messed up", which is easily misjudged as the backend not obeying.
These three steps can be checked with your eyes。
One path that has been tested in practice (2026-09): ABC written in this skill's style (including w: lines, quoted chords,% section comments,V: header) parses with zero warnings in music21, and can be directly converted to MIDI and MusicXML. MIDI with any GM timbre is the simplest rendering for step 3, without going through a generative model; wrong characters and melodic density can be heard at this step. Two cautions: music21 does not read w: lines, so the MusicXML handed to the player must use a converter that can read w: (such as abc2xml, abcm2ps) or be manually pasted back according to "one syllable per note"; quoted chords do not sound by default, so if you want to hear a harmonic pad you must expand them yourself into a piano part.
9. Field correspondence with ARR-SPEC (four export targets)
Every field in the spec sheet has a destination (schema §4). Executable fields map to the four formats according to the table below; this skill is responsible for the emission rules among them.
| ARR-SPEC field | ABC | MusicXML | MIDI | ChordPro | This skill |
|---|---|---|---|---|---|
meta.title |
T: |
work-title | Track name | {title} |
§3.1 |
meta.key / mode |
K:(K:Ddor) |
key's fifths + mode | Key signature meta | {key} |
§3.1 |
meta.meter / meter_map |
M:, inline meter change |
time, bar by bar | Time signature meta | {time} |
§3.1 |
meta.tempo / tempo_map |
Q: |
metronome / sound tempo | set_tempo | {tempo} |
§3.1 |
form[].id / name |
P: or % comment |
rehearsal mark + words | marker | {start_of_verse} etc. |
§3.2 |
form[].bars / start_bar |
Barline | measure number | tick | §3.2; §8 step 2 | |
form[].harmony_letters |
"F#m7" |
harmony's root / kind / bass, mapping see schema §1.3.1 | Chord track or marker text | [F#m7] |
§3.3 |
material.motif_abc / arrangement_hook.abc |
Embedded as-is | Actual notes | Actual notes | §3 | |
roster[].id / midi |
V: name |
part-name + midi-instrument | Track name + program change | §5.1 | |
roster[].entry / exit、form[].events |
Before section Z multi-bar rest |
Multi-bar rest | Track content range | §5.1 | |
energy_curve、vocal.dynamics_by_section |
!p! !f! dynamic mark |
dynamics (mapping see schema §1.5) | Velocity scaling / cc11 | §5.2 | |
groove.push_pull |
None | None | tick offset (★ the only exact path) | §5.3 | |
vocal.breath_points |
!breath! |
breath-mark | None | §4 | |
mix_intent.sound_stage[].pan |
None | midi-instrument's pan | cc10 | §5.1 | |
depth_map |
None | None | cc91 | §5.2 | |
meta.upstream.lyrics.sections[].lines |
w: line |
lyric, syllabic=single, one Chinese character per syllable | None | Lyric line | §3 |
render.yue.abc |
Body | §7 | |||
render.musicxml / render.midi / render.chordpro |
Target switch | Target switch | Target switch | §4 §5 |
Intent-only blocks (intent、material text,mix_intent and vocal mostly) travel with the file as a whole block of text: ABC uses % comments, MusicXML uses miscellaneous, MIDI uses a text event in the first bar. For who gets what in each of the four targets, and what they carry, see schema §4.
10. Must pass after emission
- The target format is chosen according to §6, not habitually MIDI
- Total number of measures ==
Σ form[].bars - Key signature, time signature, tempo, and
metaare consistent - ★ Derive the degree from the letter chord, and match
harmonychord by chord - Each chorus repetition is written out in full, without using repeat signs (lint #16)
- In the MIDI, CC7 and CC11 have the correct division of roles
- To verify push_pull,two versions were made: an aligned version and an offset version
- Before sending to the synthesizer,ran the three steps of §8
- When supplying the score to YuE2, a confirmed subset of the ABC dialect was used
Appendix: Sources
- The three-step verification in §8 is manual; among them, the two items "total number of measures" and "chord degree derivation" are pure data checks and do not require listening.
- ⚠ Unconfirmed: YuE2's ABC dialect (§7.2)
- Notation details, ABC syntax quick reference, and GM instrument table are in reference.md。