Shorthand score notation - davidpanderson/Numula GitHub Wiki

The notate_score module lets you specify notes and chords in a compact textual format.

from numula.notate_score import *

As with Numula's other shorthand notations, you can use iteration, substition, and comments.

sh_score(s: str) -> Score

returns a Score specified by the given string.

For example,

sh_score('1/4 c5 d e')

returns a Score object consisting of quarter-note middle C, D and E.

The notation is designed for sequential notes and chords. For pieces with multiple parallel parts, you can notate each part separately, then combine them in parallel.

The notation is as follows:

Durations

1/4, 3/16 etc.

Sets the "current duration" to the given fraction of a 4/4 measure. I.e. 1/4 is a quarter note. In this context, "duration" is both the sounding time of the note and the interval to the next note. You can change the sounding time later using articulation functions.

Suppose there's a repeating rhythmic pattern - say, dotted eighth and sixteenth. You could notate this as

3/16 a 1/16 b 3/16 c 1/16 d

and so on. This is cumbersome. Instead, you can do

<3/16 1/16> a b c d

The <...> construct repeats the given duration sequence until another duration is given.

More generally, you can use a Python iterator to generate a sequence of durations:

dur_iter = iter([1/4, 2/4, 1/4])
ns = sh_score('<durs> a b c <durs> f e d 1/4 c', durs=dur_iter)

The string within <> is the name of a keyword argument passed to sh_score(). If you use an iterator multiple times (as in this example) it will start from the beginning each time. Going past the end of an iterator raises an exception.

Notes: relative pitch

c, c-, c+, -c, ++c

Generates a note of the given pitch class (A to G, but the notation uses lower case). If the pitch name is followed by one or more -'s or +'s, it is flatted or sharped accordingly. The octave is chosen to be closest to the "current pitch" - that is, the pitch of the previous note. In the case of a tritone, the higher pitch is used. This can be overridden by adding -'s or +'s before the pitch name: - means the next instance below the previous pitch, -- means an octave below that, and so forth. At the start of each string, the current pitch is middle C.

Note: iteration is textual; if you say

*4 c c+ *

the notes will keep going up, which is probably not what you want.

Notes: absolute pitch

c5 or c5+

Generate a note with the given pitch, specified by the pitch class (a..g), the octave (5 is the octave that starts at middle C) and optional accidentals as above.

Set the current pitch

#c5

Set the current pitch to the given value (middle C in this case). Don't generate anything.

Rests

.

Generates a rest of the current duration.

Chords

[ ... ]

Generate a chord; the notes specified within [] have the same start time, and the current duration. You can specify a duration within a chord; the following notes have that duration. For example,

1/4 c [d f 1/2 a] g

produces a quarter-note C, a quarter-note D/F/A chord, and a quarter-note G. The A is held for 2 beats, i.e. over the G.

Moving back in time

_

(Underscore): Subtract the current duration from the current time; i.e. back up by that amount. This is useful for cases where notes overlap.

Tags

(tag

Add "tag" to the set of tags added to subsequent notes.

tag)

Remove "tag" from this set.

Octaves

par-12 ... par

For each note specified in the given section, a second note will be created at the given pitch offset (in this case, one octave down). This construct can be nested; e.g. to notate double octaves:

par-12 par-24 par-36 ... par par par

The additional notes don't change the "current pitch".

Sustain pedal

+p ... -p

A "virtual sustain pedal" will be applied to the notes between +p and -p. They will continue to sound (at least) until the time of the -p. This applies only to notes in this sh_score() call. The construct cannot be nested.

Entering long scores

Entering long scores can be tedious and error-prone. Some tips:

  • Break the piece up vertically in a systematic way, and encode each part in a different sh_score() call. For a piano piece this might be the left and right hands. If there's a little non-sequential stuff, use _ (move backward in time) to represent it. If there's a lot (e.g. multiple fugue voices per hand) use multiple sh_score() calls.

  • Use frequent comments marking the measures, e.g. |100 for measure 100. This will make it easier to find problem notes.

  • Break the piece up horizontally into sections, with each section in different sh_score() calls. This is especially useful if there are repeats.

  • As you enter the notes in each section, stop frequently to listen to what you have so far. It's a lot easier to debug this way.

SeeBeethoven op. 57 for examples.

⚠️ **GitHub.com Fallback** ⚠️