Music Notation
Grid models can hold music. A score is an ordinary value: you write it as notation text, calculate with it, and see it engraved, played and edited in the Score surface. Scores exchange with…
Music Notation
Grid models can hold music. A score is an ordinary value: you write it as notation text, calculate with it, and see it engraved, played and edited in the Score surface. Scores exchange with Sibelius, Finale, Dorico and MuseScore through MusicXML.
# Inputs
input melody = raw"""key: G
time: 3/4
tempo: 116
| \mf d5/4( g4/8 a b c5) | d5/4 g4-. g4-. |]"""
input transpose_by = 0 VALIDATE BETWEEN -12 AND 12
# Derived calculations
tune = MUSIC_SCORE(melody)
performance = MUSIC_TRANSPOSE(tune, transpose_by)
# Final outputs
playing_seconds = MUSIC_DURATION(performance)
musicxml_export = MUSIC_TO_MUSICXML(performance)
See the complete example.
Score values
A score is a value of type music. IS music accepts it and its
representation root is object. It holds a title block and parts. Each part is
one staff of measures, and each measure holds notes, chords and rests with
their durations, ties, slurs, tuplets, articulations, dynamics, lyrics and
chord symbols.
Create a score in one of four ways:
| Source | Use |
|---|---|
music"…" or <music>…</music> |
Notation written directly in the model. |
MUSIC_SCORE(text) |
Notation held in another cell or an input. |
MUSIC_FROM_NOTES(table, …) |
A table of pitches and durations. |
MUSIC_FROM_MUSICXML(xml) |
A score exported from other notation software. |
The literal forms are shorthand for MUSIC_SCORE. Use <music>…</music> for
notation that spans several lines or contains double quotes. Hold notation that
people edit in an input, and use raw"""…""" so backslash dynamics stay
verbatim.
Every function that takes a score also accepts notation text, so
MUSIC_DURATION("| c4/4 d e f |") works without a separate parse.
Notation text
Notation text has a header, then one or more parts.
title: Night Song
composer: A. Composer
key: e minor
time: 6/8
tempo: 1/8=132 "Andante"
part Flute abbr "Fl." clef treble
| b4/8 e5 f#5 g5/4. | f#5/8 e5 d#5 e5/4. |]
part Cello clef bass program 42
| e3/4. b2/4. | c3/4. b2/4. |]
Header
| Line | Meaning |
|---|---|
title: subtitle: composer: lyricist: copyright: |
Title block. |
key: G, key: e minor, key: Bb major, key: F#m |
Opening key signature. |
time: 3/4, time: common, time: cut |
Opening time signature. |
tempo: 120, tempo: 1/8=144 "Allegro" |
Metronome mark, with an optional marking. |
clef: bass |
Default clef for parts that do not name one. |
swing: triplet, swing: 62%, swing: 2:1, swing: off |
Play pairs of eighth notes long-short. light, triplet and hard are named feels; a percentage is the share of each beat taken by its first half. Swing applies where the beat is a quarter or half note. |
Parts
part <name> starts a staff. It accepts clef (treble, bass, alto,
tenor, percussion, treble8vb, bass8vb, tab), abbr for the name on
later systems, group to brace staves together, and program for a MIDI
program.
Two parts with the same name, such as a piano's two staves, are braced
automatically.
A part named after an instrument takes that instrument's clef, abbreviation,
playback sound, playable range and transposition. "Clarinet in Bb",
"Violin 1" and "Horn 2 in F" all match, and instrument names the preset when
the part name does not. Anything written explicitly wins over the preset.
duet = MUSIC_SCORE("key: F
part Clarinet in Bb
| f4/4 a4 c5 bb4 | a4/1 |]
part Solo instrument cello
| f2/2 c3/2 | f2/1 |]")
The presets cover the orchestra, wind band, saxophones, keyboards, tuned percussion, guitars and choir voices.
Transposing instruments
Scores are always stored at sounding (concert) pitch, so every calculation,
playback and MUSIC_TRANSPOSE works on the notes you hear. A transposing part
also publishes its written pitch and written key: the clarinet above is
written in G major, a tone higher than it sounds. Use transpose <semitones> [steps] on a part for an instrument without a preset; transpose -2 is a
B-flat instrument, and the diatonic steps default to the usual spelling.
MusicXML keeps the same convention: export writes written pitch with a
<transpose> element, and import reads one back to sounding pitch.
Notes and rests
A note is a letter, an optional accidental, an octave and a value:
c4/4 is middle C as a quarter note.
| Written | Meaning |
|---|---|
c d … b |
Pitch letter. |
# ## b bb n |
Sharp, double sharp, flat, double flat, natural. |
4 |
Scientific octave. C4 is middle C. |
/1 /2 /4 /8 /16 /32 /64 /0 |
Whole to 64th note; /0 is a breve. |
. after the value |
Augmentation dot. c4/4. is a dotted quarter. |
r/4 |
Rest. |
R |
Rest for the whole measure. |
[c4 e4 g4]/2 |
Chord. |
Octave and value carry forward: c4/8 d e f is four eighths. Pitches are
written as they sound; the 8vb clefs place them an octave higher on the staff.
Accidentals are written as heard. The engraver shows or cancels them against
the key signature and earlier notes in the measure.
Marks
| Written | Meaning |
|---|---|
c4/4~ c4/4 |
Tie. |
c4/8( d e f) |
Slur from the note before ( to the note before ). |
-. -> -- -^ -! |
Staccato, accent, tenuto, marcato, staccatissimo. |
-fermata -trill -mordent -turn |
Fermata and ornaments. Playback plays a trill with the note above in the key, a mordent with the note below, and a turn around the note. |
-trem1 -trem2 -trem3 |
Tremolo strokes: repeated eighths, sixteenths or thirty-seconds. |
[c4 e4 g4]/2-arp |
Rolled chord, played from the bottom up. |
\8va \8vb \15ma \15mb then \loco |
Ottava line from the next note until \loco. Pitches stay as they sound; the staff shows them an octave (or two) away under the line. |
\ped then \* |
Sustain pedal pressed at the next note and released at the note after \*. A second \ped while the pedal is down retakes it. Notes ring until the release. |
c4/2 \gliss g4/2 |
Glissando line from the note before \gliss to the next note. |
cue{ c5/8 d e f } |
Cue notes: written small and not played. |
\p \mf \ff \sfz |
Dynamic on the next note. |
\< \> then \! |
Crescendo or diminuendo wedge from the next note, ending at the note after \! or at the next dynamic. Playback ramps the loudness to that dynamic, or by one level when none follows. |
"Glo-" after a note |
Lyric syllable; a trailing - joins it to the next syllable, and a trailing _ holds it with an extender line under the notes that follow. |
%G7 %F#m7/A |
Chord symbol on the next note. |
^"dolce" |
Text above the next note. |
3{ c4/8 d e } |
Triplet. 5:4{ … } gives an explicit ratio. |
g{ d5/16 } |
Grace note before the next note. |
Measures and changes
| separates measures. || is a double barline, |] a final barline, |:
and :| repeat signs, and :|: a back-to-back repeat. key, time, clef and
tempo inside a measure change the signature from that measure on:
| c4/1 | key Eb major time 3/4 eb4/4 f g | clef bass c3/2. |
break system or break page inside a measure forces a new system or page
after it. Without one, the Score surface breaks systems where they fill.
Drum kits and tablature
A part named Drums or Drum Set (or any part with clef percussion) is a
drum kit. Write each instrument at its staff position, as if in treble clef;
cymbals and hi-hats get cross noteheads, and playback uses the kit's sounds:
| Position | Instrument | Position | Instrument |
|---|---|---|---|
f4 |
Bass drum | g5 |
Closed hi-hat |
c5 |
Snare drum | b5 |
Open hi-hat |
a4 |
Floor tom | d4 |
Pedal hi-hat |
d5 |
Mid tom | f5 |
Ride cymbal |
e5 |
High tom | a5 |
Crash cymbal |
part Drums
| [f4 g5]/8 g5 [c5 g5] g5 [f4 g5] g5 [c5 g5] g5 |
clef tab writes a fretted part as tablature. Write the pitches as they
sound; Grid chooses the string and fret for each note in the lowest position,
and gives chord notes separate strings. Guitar and bass guitar use standard
tuning; tuning lists other open strings from lowest to highest:
part Guitar clef tab
| [c3 e3 g3 c4 e4]/2 e2/4 g3 |
part Bass Guitar clef tab tuning b0 e1 a1 d2 g2
| b0/2 e1 |
-s and a string number plays a note higher up the neck: e4/4-s2 is the
open first string's E fretted on the second string, and -s3 on the third.
String 1 is the highest. On a chord the number places the highest note, and
the notes below it take the next strings down:
part Guitar clef tab
| e4/4 e4/4-s2 [c4 e4]/2-s2 |
A note too low for the chosen string moves to the next string that reaches it. A position that is not part of the kit, or a pitch the strings cannot reach, is reported as a finding. MusicXML export writes the tuning and each note's string and fret, and import keeps a tuning that is not standard and any note placed away from the lowest position.
Voices
// starts the next voice of the same measure, up to four voices on one
staff. Each voice fills the measure on its own, and ties and slurs stay within
their voice. The first and third voices are stemmed up and the second and
fourth down:
| e5/4 d5/8 c5 d5/4 e5 // c5/4 b4/8 a4 b4/2 |
Lines starting with # are comments.
Findings
Notation errors, such as an unknown token or an unclosed chord, make
MUSIC_SCORE return #VALUE! with the line and column. Measures that are
too long or short, parts of different lengths, pitches outside the MIDI
range, and notes outside an instrument's playable range are warnings. The Score surface lists them, and MUSIC_CHECK returns
them as a table, including errors in text that does not parse:
findings = MUSIC_CHECK(melody)
Functions
The complete signatures are in the function catalog.
| Function | Returns |
|---|---|
MUSIC_SCORE(text) |
A score parsed from notation text. |
MUSIC_FROM_NOTES(notes, [time], [key], [tempo], [title]) |
A score from rows of pitch, quarters, lyric and part. Notes crossing a barline are split and tied. |
MUSIC_FROM_MUSICXML(xml) |
A score imported from MusicXML. |
MUSIC_TRANSPOSE(score, semitones, [part]) |
The score transposed with correct spelling, key signatures and chord symbols. |
MUSIC_PART(score, part) |
One part, by name or number. |
MUSIC_MEASURES(score, from, [to]) |
An excerpt, keeping the key, time, clef and tempo in force. |
MUSIC_CONCAT(score, …) |
Scores joined end to end; parts match by name. |
MUSIC_SET_TEMPO(score, bpm, [beat_unit]) |
The score with a new opening metronome mark. |
MUSIC_TEXT(score) |
Canonical notation text. |
MUSIC_TO_MUSICXML(score) |
A MusicXML 4.0 document. |
MUSIC_NOTES(score) |
A table of sounding notes: part, measure, beat, pitch, MIDI number, length, start and lyric. |
MUSIC_MIDI_EVENTS(score) |
A table of MIDI note events with timing in seconds and velocity. |
MUSIC_CHECK(score) |
A table of findings. |
MUSIC_DURATION(score) |
Playing time in seconds. |
MUSIC_MEASURE_COUNT(score) |
Number of measures. |
MUSIC_PARTS(score) |
Part names. |
MUSIC_KEY(score, [measure]) |
Key in force, such as G major. |
MUSIC_TIME_SIGNATURE(score, [measure]) |
Time signature in force, such as 3/4. |
MUSIC_TEMPO(score, [measure]) |
Metronome mark in force. |
MUSIC_TITLE(score) |
Title. |
MUSIC_RANGE(score, [part]) |
Lowest and highest pitch. |
Note tables feed ordinary analysis. For example, count the pitches that sound in the first measure:
notes = MUSIC_NOTES(tune)
opening_bar_notes = COUNTIF(CHOOSECOLS(DROP(notes, 1, 0), 2), 1)
MusicXML import keeps up to four voices on each staff and splits a multi-staff part, such as a piano, into braced staves. It warns when it skips a fifth voice. Export writes every part and voice, with grand-staff braces.
The Score surface
Create a Score surface and point [source].bind at a cell that holds a
score. It engraves publication-style notation: shared proportional spacing
across the system, beams grouped by beat, key-aware accidentals, ledger lines,
ties, slurs, tuplets, grace notes, articulations, dynamics, lyrics, chord
symbols, tempo marks, repeat barlines, braces and brackets.
[source]
bind = "minuet" # cell holding the score
edit = "melody" # optional: the notation-text input to edit
[layout]
view = "page" # page | panorama
zoom = 100
[playback]
enabled = true
audio = "renders/minuet.wav" # optional: where Render audio writes
soundfont = "sounds/orchestra.sf2" # optional: a sample library for Render audio
- Page view breaks systems onto pages with a title block. Panorama lays the whole score on one line.
- Play previews the score with the browser's audio from the selected measure, following tempo marks, swing, dynamics and hairpins, ties, articulations, ornaments, tremolos, rolled chords and the sustain pedal. The preview plays the same notes at the same moments as rendered audio and exported MIDI. The playhead follows the music. Choose a slower or faster playback tempo without changing the score.
- Mixer opens a strip for each part with a volume slider, Mute and Solo. The preview follows it at once, and Render audio applies the same mix to the file.
- Parts shows the full score or one part.
- Concert pitch appears when a part transposes. Transposing parts are shown at written pitch by default; the toggle shows every part as it sounds. Instruments that transpose only by octaves, such as piccolo, guitar and double bass, keep their written octave in both views.
- Notes outside an instrument's playable range are drawn in red.
- When one part is shown, runs of empty measures become multi-measure rests
with the count above.
[layout].multireststurns that on or off, and[layout].spacing(0.5 to 2.5) tightens or loosens the horizontal spacing. - Scores of up to 200,000 notes and rests are engraved. A long score draws only the pages near the part you are looking at, so scrolling stays quick.
Document setup
The page view lays the music out for a sheet of paper. Without any setup it is A4 portrait with a 7 mm staff and 14 mm side margins:
[layout]
page = "a4" /* a4 | a3 | letter | legal | tabloid */
orientation = "portrait" /* portrait | landscape */
staff_size = 5 /* staff height in millimetres, 3 to 10 */
margin = 12 /* side margin in millimetres, 5 to 40 */
hide_empty_staves = true
A smaller staff puts more measures on a system and more systems on a page,
which is how a full score fits its staves; parts usually keep 7 mm. With
hide_empty_staves, every system after the first leaves out the staves that
only rest in it, as a conductor's score does. The two staves of a piano, harp
or organ stay together, and a staff stays when a tie, slur or line continues
into the system.
Rendered audio and the Media surface
Render audio turns the performance into a WAV file in the model's Files,
at [playback].audio or renders/<cell>.wav. Grid renders it on the runtime:
repeats and endings, tempo changes, dynamics, ties, grace notes and
articulations, with each part voiced by its instrument family and placed across
the stereo field. The file is 16-bit PCM at 44.1 kHz stereo; scores longer than
about six minutes step down to mono and then to 22.05 kHz so the file stays
within the Media surface's 64 MiB limit, and scores longer than 25 minutes are
refused. Rendering an unchanged score again leaves the file untouched, and
overwriting a different file asks first.
Sample libraries
Rendered audio can play recorded instruments instead of the built-in sounds.
Put a SoundFont 2 file (.sf2) in the model's Files and name it in
[playback].soundfont; Render audio then plays each part with the
library's samples for its instrument, and the drum kit with the library's kit.
A part whose instrument the library lacks keeps the built-in sound, and the
status line names those parts. The mixer, the stereo placement of the parts
and the hall reverb apply either way, and the same score, mix and library
always produce the same file.
Grid reads the library's samples, loops, key and velocity splits, tuning, volume envelopes, panning and hi-hat cut-offs. It does not apply a library's filters, modulators or vibrato settings, so a library that depends on those sounds brighter and plainer than in a full sampler. Libraries up to 512 MiB are read; compressed (SF3) libraries are refused. The browser preview always uses its own synthesizer, so use Sound: Rendered audio to hear the library.
Export MIDI writes a Standard MIDI File beside it (renders/<cell>.mid):
a conductor track with the title, tempo, time and key signatures, then one track
per part with its name, instrument program and notes, repeats written out and
hairpins and accents in the velocities. Percussion-clef parts use MIDI channel
10. Open it in a sequencer or another notation program.
After rendering, Sound chooses between the quick browser preview and the rendered file; the rendered file plays at the written tempo. When the score, the mix or the sample library changes, the surface says the rendering is out of date until you render again. The surface remembers the file it rendered: after a reload Sound offers it again while the music still matches.
Bind a Media surface to the same file for its waveform, spectrum, annotations and selection inputs:
kind = "media"
[source]
asset = "renders/minuet.wav"
The two surfaces follow each other. While the Media surface plays that file, the Score surface follows it with its playhead, and choosing a note moves the Media playback to that measure. While the Score surface plays the rendered file, the Media surface's cursor follows and its own player stays silent, so the file is never heard twice. The link stays in the browser; playback position is never written to the model.
Keyboard note entry
When edit names the writable input the score is parsed from, click a note
and type. Each change rewrites that note's notation and the model recalculates.
| Key | Action |
|---|---|
A–G |
Insert a note after the selection, in the nearest octave. On a transposing part the letter is read at the pitch shown. |
↑ ↓ |
Move the note by a step in the key. |
⌘/Ctrl + ↑ ↓ |
Move the note by an octave. |
Alt + ↑ ↓ |
On tablature, move the note to the next string up or down at the same pitch. |
1–8 |
64th, 32nd, 16th, eighth, quarter, half, whole, breve. |
. |
Toggle a dot. |
+ - N |
Sharp, flat, natural. |
T |
Toggle a tie to the next note. |
S > |
Toggle staccato or accent. |
R or 0 |
Insert a rest. |
Delete |
Turn a note into a rest, or remove a rest. |
← → |
Select the previous or next note. |
Shift + ← →, or Shift-click |
Extend the selection to a range within one part. |
⌘/Ctrl + A |
Select the whole part. |
⌘/Ctrl + C X V |
Copy, cut or paste. |
Esc |
Leave note input, then clear the selection. |
Space |
Play or pause. |
With a range selected, the step, octave, string, accidental, value, dot, tie and
articulation keys change every note in it in one write, and Delete turns the
notes into rests so the rhythm stays. Copy puts the selection on the clipboard
as notation with every value written out; tuplets, grace notes and cue notes
keep their groups. Paste inserts it after the selection, or in place of an
empty measure. Cut leaves rests. Only notation is accepted from the clipboard.
Mouse note entry
Note input turns clicks on the staff into notes. Choose a Value (and the dot), then:
- Click a rest to write a note of that value at the height you click. What is left of the rest is filled with rests; in an empty measure a quarter note is followed by a quarter and a half rest.
- Click a note to move it to the clicked line or space. In a chord the nearest note moves.
- Shift-click a note to add a chord note at that height, or to remove the one already there.
The pitch takes the key signature's accidental and is read as shown: written pitch on a transposing part, and the displaced octave under an ottava line.
Import MusicXML loads a score from other notation software into the
notation input. Choose a .musicxml, .xml or compressed .mxl file; Grid
stores it under imports/ in the model's Files, converts it to notation text,
and shows the title, parts and measures before anything changes. Load
replaces the input's text, after which the score is edited like any other.
Voices, ties, tuplets, grace notes, dynamics, hairpins, repeats and endings,
lyrics, chord symbols, transposing instruments, ottava lines, pedal marks,
glissandi, tremolos, cue notes, system and page breaks, and tablature tunings
and string choices carry over; other layout and engraving details from the
other program do not.
Editing needs the score to come directly from the input: bind
MUSIC_SCORE(melody) or an excerpt of it with MUSIC_PART or
MUSIC_MEASURES. A transposed or imported score is shown read-only, with the
reason.
In Grid Views
A score placed in a Grid View shows through the Score surface:
SURFACE Practice
Score minuet edit melody
show performance
END
Score accepts edit, view, zoom, playback, audio, soundfont,
multirests, spacing, page, orientation, staff size, margin and
hide empty staves phrases.