Music objects: scales that fit the player
A music object is a passage defined once and applied by name. The definition claims no bars; every application prints the object's bars in the part that applied it, moved to a tonic and — under fit — slid into that player's range. One definition of a one-octave scale becomes fifteen keys on twelve instruments, each in the register that instrument reads.
Define, then apply
scorescript 0.3
score "Two scales, one definition" {
meter 4/4
key open
allstate = {
4C4 8D E F G A B | 4C 8B A G F E D | 1C ||
}
parts {
tpt F#3-C6
tbn E2-Bb4
}
all written fit {
@allstate F
@allstate Bb
}
}Canonical spelling
scorescript 0.3
score "Two scales, one definition" {
meter 4/4
key open
allstate = {
4C4 8D E F G A B | 4C 8B A G F E D | 1C ||
}
parts {
tpt F#3-C6
tbn E2-Bb4
}
all written fit {
@allstate F
@allstate Bb
}
}
allstate = { … } defines the object in C, with its own bar lines and its closing double bar. @allstate F applies it at the tonic F: the object's C becomes F and every other note moves with it. all names every part on the roster; written says the head works on the player's page — the tonic, the range and the printed notes are all what the player reads, and the bars carry the instrument's transposition so the engine never derives them again; fit slides each application by whole octaves to the lowest position on or above the player's floor and refuses one whose top passes the ceiling. The trumpet, held to written F#3–C6, reads F major from F4; the trombone, held to E2–B♭4, reads it from F2. Each application opens with the key it was moved to and a label — F Allstate - 1 octave — derived from the object's name and its compass.
title "Major" on the body's first line is the word the label prints — Bb Major - 2 octaves — where a bare object prints its name (allstate2 → "Allstate2"). A \n or \p line between two applications opens the next object on a new system or page, exactly as the same mark before a measure group does; an All-State sheet is one \n between every scale.
A name is a word: letters, digits, hyphens. A name shaped like a chord symbol (am7, F7) is refused where it is defined, because @am7 would otherwise be ambiguous with the harmony label.
An object may also be moved by an interval (@allstate +P4) or an octave (@allstate F', @allstate F,), and applied inside a single part's body without a head — in which case the part's own range and concert pitch apply.
Choose by what fits
scorescript 0.3
score "What fits" {
meter 4/4
key open
one = {
4C4 8D E F G A B | 4C 8B A G F E D | 1C ||
}
two = {
4C4 8D E F G A B | 4C 8D E F G A B | 4C 8B A G F E D | 4C 8B A G F E D | 1C ||
}
parts {
fl C4-C7
tbn E2-Bb4
}
all written fit {
first { @two C, @one C }
fits { @two G, @one G }
if range contains @two D {
@two D
@one D
} else {
@one D
}
}
}Canonical spelling
scorescript 0.3
score "What fits" {
meter 4/4
key open
one = {
4C4 8D E F G A B | 4C 8B A G F E D | 1C ||
}
two = {
4C4 8D E F G A B | 4C 8D E F G A B | 4C 8B A G F E D | 4C 8B A G F E D | 1C ||
}
parts {
fl C4-C7
tbn E2-Bb4
}
all written fit {
first { @two C, @one C }
fits { @two G, @one G }
if range contains @two D {
@two D
@one D
} else {
@one D
}
}
}
Three doors, one rule. first { @two C, @one C } prints the FIRST object that fits — the flute gets two octaves of C, the trombone (whose written E2–B♭4 holds one octave of C but not two) gets one. fits { @two G, @one G } prints EVERY object that fits, in order: the flute prints both, the trombone the one. if range contains @two D { … } else { … } is the same question asked as logic, for a packet whose branches print different things.
The failure rule is strict. An object that does not fit is not cut short and not swapped for a smaller one: it is omitted and named in an error (object.no-fit) with the range in force, so the packet is never quietly wrong. A first or fits with nothing that fits is the same error.
The range in force is the declared contract (the roster line, a range statement, or bounds on the head — ob written C4-C6 { … }), else the catalog's practical band for the instrument, else nothing constrains the application at all. See declared ranges.
Built-in scales
scorescript 0.3
score "Built in" {
meter 4/4
key open
parts {
cl E3-G6
}
cl written fit {
@scale-major G
@scale-harmonic-minor A
@scale-dorian D
@scale-chromatic
}
}Canonical spelling
scorescript 0.3
score "Built in" {
meter 4/4
key open
parts {
cl E3-G6
}
cl written fit {
@scale-major G
@scale-harmonic-minor A
@scale-dorian D
@scale-chromatic
}
}
The compiler builds in the scales and modes: @scale-major, @scale-minor, @scale-harmonic-minor, @scale-melodic-minor, @scale-dorian, @scale-phrygian, @scale-lydian, @scale-mixolydian, @scale-aeolian, @scale-locrian, @scale-whole-tone, @scale-pentatonic, @scale-minor-pentatonic, @scale-blues, and @scale-chromatic. Each seven-note scale is one octave in the audition pattern — a quarter on the tonic, six eighths, the top tonic, and back — and prints the signature its tonic asks for (a mode prints its parent major's). @scale-chromatic runs from the bottom to the top of the reader's range and back, sharps up and flats down, the last note filling its bar, so it needs a range. scorescript scales prints the whole list with each scale's octave in C; hosts read the same list as the scorescript://catalog/scales resource.
A built-in name cannot be redefined; an authored object of the same name is refused. An unknown @name is object.unknown.
What the expanded score shows
Objects are a desugaring: the analyzer turns every application into ordinary bars before anything downstream sees the score, so a part that applied three scales is a part with three scales' bars, numbered after its last written bar. scorescript format --normalize expand writes that expanded score out, which is how to see — or hand to a tool that knows nothing of objects — exactly what each player was given.