Spanners

A common pattern in notation is objects which span between one and another, for example hairpins, slurs, and octave lines. Neoscore supports this through a family of Spanner classes. Most spanners are created in the same way by providing an initial position and parent, and an end position and parent.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
start = Chordrest(Mm(2), staff, ["f"], (1, 4))
Chordrest(Mm(12), staff, ["a"], (1, 4))
end = Chordrest(Mm(22), staff, ["c#'"], (1, 2))
Hairpin((ZERO, staff.unit(6)), start, (ZERO, staff.unit(6)), end)
/_static/rendered_examples/JYWJOYRBHGPIZVV3VQVQMALOXSWXLQBD.png

The ending parent can usually be omitted to make the ending position relative to the initial position.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
start = Chordrest(Mm(2), staff, ["f"], (1, 4))
Hairpin((ZERO, staff.unit(6)), start, (staff.unit(3), ZERO))
/_static/rendered_examples/P6NVWLLU3DPDGSNHSBPPHN6IYUVJGFAV.png

Hairpins

Crescendo and diminuendo Hairpins, demonstrated above, can be configured in several ways. By default the opening points right, but this can be changed with the direction argument. They can also lie at angles and the default opening width can be configured.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
start = Chordrest(Mm(2), staff, ["f"], (1, 4))
Hairpin((ZERO, staff.unit(6)), start, (staff.unit(3), staff.unit(-4)),
    direction=DirectionX.LEFT, width=staff.unit(1))
/_static/rendered_examples/O27FLLMP54F7TUEDXAORVENDRQFSDJ3H.png

Slurs and Ties

Slur and ties are both created with the Slur class. By default they arch upward, but this can be changed with the direction argument.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
start = Chordrest(Mm(2), staff, ["f"], (1, 4))
Chordrest(Mm(12), staff, ["a"], (1, 4))
end = Chordrest(Mm(22), staff, ["c#'"], (1, 2))
Slur((ZERO, staff.unit(-1)), start.stem.end_point, end.extra_attachment_point, end)
/_static/rendered_examples/V2APRY7N64ZEE2GNMNMJ4ZL6E6WREH2Y.png

Ties are just horizontal slurs. (Though we’re open to contributions making this easier)

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
start = Chordrest(Mm(2), staff, ["f"], (1, 4))
Slur(start.extra_attachment_point, start, (Mm(10), ZERO), direction=DirectionY.DOWN)
/_static/rendered_examples/Y7KN27FZUZRFYSIIZYJORN2RN3P5U5KL.png

A reasonable curvature is automatically derived from the spanner length, but this can be overridden with the height and arch_length arguments.

Octave Lines

Cosmetic OctaveLines can be drawn with a variety of common octave indications, but note that they do not automatically transpose the notes under them.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
Chordrest(Mm(2), staff, ["c''"], (1, 4))
Chordrest(Mm(12), staff, ["e''"], (1, 4))
# Note that this transposition is manual
Chordrest(Mm(22), staff, ["g#'"], (1, 2))
OctaveLine((Mm(18), staff.unit(-4)), staff, Mm(15))
/_static/rendered_examples/HA5CUUMJDCEXEPEBRXRQE5562NKUOHLI.png

Repeating Music Text Lines

RepeatingMusicTextLine allows you to repeat some music text over a spanner. This is useful for things like trill lines.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
c = Chordrest(Mm(2), staff, ["c'"], (1, 1))
RepeatingMusicTextLine((ZERO, staff.unit(-1)), c, (Mm(20), ZERO), None, "wiggleTrill")
/_static/rendered_examples/Z7HPGOAZLUC4WBSLQ63OC4ZUSY77CLXU.png

You can optionally provide a glyph to use as a start cap.

staff = Staff(ORIGIN, None, Mm(40))
RepeatingMusicTextLine((ZERO, staff.unit(-1)), staff, (staff.unit(10), ZERO), None,
   "wiggleTrill", "ornamentTrill")
/_static/rendered_examples/VZC7IBR73LL7V67SBGXIXGTJ2QQPSJ2T.png

Similarly you can provide a glyph to use as an end cap.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
start = Chordrest(Mm(2), staff, ["c'"], (1, 1))
end = Chordrest(Mm(25), staff, ["c''"], (1, 4))
RepeatingMusicTextLine((staff.unit(2), ZERO), start.highest_notehead,
   (staff.unit(0), ZERO), end.highest_notehead,
   "wiggleGlissando", None, "wiggleArpeggiatoUpArrow")
/_static/rendered_examples/HZBDJD374CM4MWS2N2BUVGKNVGBMPLHL.png

See SMuFL’s collection of multi-segment line glyphs here for common applications.

Arpeggio Lines

Arpeggio lines can be built with RepeatingMusicTextLine, but for convenience we provide one out of the box with ArpeggioLine.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
c = Chordrest(staff.unit(3), staff, ["c", "g", "eb"], (1, 16))
ArpeggioLine((staff.unit(-2), staff.unit(-1)), c.highest_notehead,
    (staff.unit(-2), staff.unit(2)), c.lowest_notehead, include_arrow=True)
/_static/rendered_examples/25DKKTEZFHCEZKXZF3AIMYZ2UNUXVSYL.png

For chordrests specifically, the dedicated ArpeggioLine.for_chord can automatically work out the line positions for you.

staff = Staff(ORIGIN, None, Mm(40))
Clef(ZERO, staff, 'treble')
c = Chordrest(staff.unit(3), staff, ["c", "g", "eb'"], (1, 16))
ArpeggioLine.for_chord(c, DirectionY.UP)
/_static/rendered_examples/GFUEVIAPAWOX27PPXKR4KI5VXRWEAN6U.png

Other Spanners

Other available spanners include: