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 pointers - •
Time(measure:beat:step)sets absolute time position - •
Sub{ 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