name: sakura-mml-composition description: >- Use when the user asks to write, edit, troubleshoot, or explain テキスト音楽サクラ (Sakura MML / csakura v2) notation and .mml files, including text-to-MIDI composition, arrangement, and syntax guidance.
Sakura MML Composition
Overview
テキスト音楽サクラ (Text Music Sakura) is a Music Macro Language (MML) that converts text into Standard MIDI Files. It supports both Japanese ストトン表記 (Sutoton / Do-Re-Mi notation) and Western MML notation (cdefgab). This skill covers the MML notation system.
Reference Guide (When to Open Which File)
- Composition structure, track routing, timing control → references/tracks-channels-time.md
- Control changes, pitch bend, RPN/NRPN, SysEx → references/control-changes.md
- Automatic parameter patterns (
.onNote,.onTime, waves, random/range) → references/advanced-expression.md - Drum programming and
Rhythm{}macros → references/rhythm-mode.md - Variables, functions, loops, conditions, macros → references/scripting.md
- Tempo/timebase/key/system behavior and metadata → references/system-options.md
- GM program numbers and predefined voice constants → references/gm-instruments.md
Quick Reference — Core Commands
| Command | Description | Default | Range |
|---|---|---|---|
c d e f g a b |
Notes (ド レ ミ ファ ソ ラ シ) | — | — |
r |
Rest | — | — |
l |
Note length (n-th note) | 4 | 1,2,4,8,16,32,64 |
o |
Octave | 5 | 0–10 |
v |
Velocity (note strength) | 100 | 0–127 |
q |
Gate time (% of note length sounded) | 80 | 0–100+ |
t |
Timing offset (steps) | 0 | any integer |
h |
Gate reduction (steps subtracted) | 0 | any integer |
^ |
Note-length addition / extension (Sutoton ー equivalent) |
— | — |
& |
Tie/Slur between notes (behavior affected by Slur(...)) |
— | — |
+ / # |
Sharp (after note) | — | — |
- |
Flat (after note) | — | — |
> |
Octave up | — | — |
< |
Octave down | — | — |
` |
Temporary octave up (one note only) | — | — |
" |
Temporary octave down (one note only) | — | — |
Note Length Specification
Two modes for specifying length:
- N-th note mode (default):
l4= quarter,l8= eighth,l2= half,l1= whole - Step mode: Use
%prefix. WithTimeBase(96), quarter = 96 steps.l%96= quarter note in steps!nconverts n-th note to steps inline:c!2= half note in step value
Dotted notes: append . — l4. = dotted quarter.
Length addition: ^ adds default length. c8^^ = c8 + c8 + c8 = dotted quarter.
Pitch tie/slur: & connects notes and can be customized by Slur(type[, value, range]).
Length can follow note directly: c4 d8 e16 (applies only to that note).
Inline Note Parameters
Full note syntax with inline overrides:
note[length][,gate][,velocity][,timing][,octave]
c4,100,127,2 // quarter note, q100, v127, t2
Customizable order via ArgOrder(lqvto).
Chords
Three methods:
'ceg'4 // chord notation
c0e0g4 // zero-length notes (l0 = no time advance)
Sub{ c } Sub{ e } g4 // Sub rewinds time pointer
Tuplets (連符)
Div{cde}4 // triplet in quarter note duration
{cde}4 // shorthand (Div can be omitted)
Nestable: {cde{fg}}4
Loops
[4 cdef] // repeat 4 times
[4 cdef : g] // last iteration exits at ":" → plays "g" instead of remaining
Tracks, Channels & Time
See references/tracks-channels-time.md for details.
Track(1) Channel(1) Voice(1) // Piano on ch1
Track(2) Channel(2) Voice(33) // Bass on ch2
Track(10) Channel(10) // Drums on ch10
Key points:
- MIDI has 16 channels; Channel 10 = drums (GM/GS)
- Sakura track upper bounds are implementation-dependent (e.g., some runtimes support
Track(0)toTrack(999)) TrackSyncsynchronizes all track time pointersTime(measure:beat:step)sets absolute time positionSub{ mml }writes MML then rewinds time pointer
Voice / Program Change
Voice(n) // n = 1–128 (GM instrument)
Voice(n, msb, lsb) // with bank select
@n // shorthand
GM instrument names are predefined: GrandPiano, Violin, Trumpet, AcousticBass, etc.
For the full GM map and constant list, see references/gm-instruments.md.
Control Changes & Effects
See references/control-changes.md for full list.
| Short | Full | CC# | Description |
|---|---|---|---|
P(n) |
Panpot(n) |
10 | Pan (0=L, 64=C, 127=R) |
M(n) |
Modulation(n) |
1 | Vibrato |
V(n) |
MainVolume(n) |
7 | Main volume |
EP(n) |
Expression(n) |
11 | Expression |
REV(n) |
Reverb(n) |
91 | Reverb |
CHO(n) |
Chorus(n) |
93 | Chorus |
Raw CC: y(cc_number),(value)
Pitch bend: PitchBend(n) range -8192–8191, or p(n) simplified 0–63–127.
Advanced Expression (先行指定)
See references/advanced-expression.md for all patterns.
Key patterns — prefix any command (v, q, t, P, M, EP, PitchBend, etc.):
| Pattern | Description |
|---|---|
cmd.onNote(v1,v2,...) |
Cycle values per note-on |
cmd.onTime(low,high,len,...) |
Time-based value transitions |
cmd.onCycle(len,v1,v2,...) |
Repeating time-based cycle |
cmd.onNoteWave(low,high,len,...) |
Per-note linear sweep |
cmd.onNoteWaveEx(low,high,ratio,...) |
Per-note sweep scaled to note length |
cmd.Random(n) |
Add random ±n |
cmd.Range(low,high) |
Clamp output range |
Cancel by assigning a normal value (e.g., v100).
Rhythm Mode
See references/rhythm-mode.md for details.
Track(10) Channel(10)
$b{n36,} // b = bass drum
$s{n38,} // s = snare
$h{n42,} // h = closed hi-hat
Rhythm{
[4 l8 bhhh shhh bhhh shsh]
}
Variables, Functions & Control Structures
See references/scripting.md for details.
Int A = 0; // integer variable
Str S = {cdef}; // string variable (plays as MML)
Array Arr = (1, 2, 3); // array variable
Function MyFunc(Int X=0) { ... } // function definition
#macro = { cdef }; // string macro
Control: If/Else, For, While, Switch/Case, Exit.
Important: Use leading uppercase names for variables/functions to avoid collisions with single-letter lowercase MML commands.
System Options
See references/system-options.md for details.
| Option | Default | Description |
|---|---|---|
Tempo(n) |
120 | BPM (1–500) |
TimeBase(n) |
96 | Ticks per quarter note |
TimeSignature(num,den) |
4,4 | Time signature |
Key(n) |
0 | Transpose n semitones |
KeyFlag+(note) |
— | Set accidentals |
Include(file) |
— | Include external file |
Meta Events
TrackName={"Title"} // track/song name
Copyright={"Author"} // copyright
MetaText={"text"} // arbitrary text
Lyric={"text"} // lyrics
Marker={"text"} // marker
Sound Source Reset
Include(stdmsg.h); // required for reset commands
ResetGM(); // GM reset
ResetGS(); // GS reset
ResetXG(); // XG reset
Complete Example
// === Tempo & Setup ===
Tempo(120)
TimeSignature(4,4)
// === Track 1: Melody (Piano) ===
Track(1) Channel(1) Voice(1)
P(64) v110 q80 o5
l8 cde^ cde^ gedc ded^
// === Track 2: Bass ===
Track(2) Channel(2) Voice(33)
P(64) v90 q90 o3
l4 [2 c c g g]
// === Track 3: Drums ===
Track(3) Channel(10)
$b{n36,} $s{n38,} $h{n42,}
Rhythm{
[2 l8 bhhh shhh bhhh shsh]
}
Key Caveats
- Use leading uppercase names for variables/functions (recommended to avoid command-name collisions)
- Strings use
{ }delimiters, not" " - Hex numbers use
$prefix:$1FFF - Rhythm mode does NOT auto-set Channel 10 — set it explicitly
- Comments:
//(line) and/* */(block, nestable) .onNote/.onTimepatterns repeat until cancelled by setting a normal value- To move time without emitting a rest event, use time arithmetic such as
Time = Time + !n - Most commands are case-insensitive (
Track=TRACK) - String macros start with
#and need no declaration