In this notebook, we discuss some software tools for rendering sheet music. Furthermore, we explain some functionality of the Python library music21
.
The process of sheet music rendering refers to the computerized rendition of a symbolic music format into graphical musical symbols, e.g. modern staff notation. There exist several software tools for sheet music rendering, including text-based programs like LilyPond and Verovio, as well as WYSIWYG sheet music editors like MuseScore and Sibelius.
For rendering sheet music from Python, we recommend to use the package music21
.
For a full introduction, we refer to the documentation of music21
.
It offers various options to feed its internal data structure to a renderer.
One option is to internally convert music21
's data structure to the MusicXML format (for more details, see the MusicXML notebook) and use MuseScore to graphically render the sheet music. With a working Python environment where music21
is installed, three more steps are needed to get it to work.
music21
the path to the MuseScore binary.music21
user environment file.music21
.Those three steps only need to be executed one time.
The following code cell sets up a music21
user environment file:
import os
import music21 as m21
us = m21.environment.UserSettings()
us_path = us.getSettingsPath()
if not os.path.exists(us_path):
us.create()
print('Path to music21 environment', us_path)
print(us)
Next, we give the path to the MuseScore binary. The following code cell gives two typical locations for Linux and Windows environments. Note that this could be different on your system and has to be changed, possibly. Both, setting up the user environment file and the specification of the MuseScore path has to be executed only once.
Note: The following example may not work on Windows yet. The reason for this is a bug in music21
. This was fixed and will be solved in the next version of music21
. However, currently the fix is not included the the latest version.
# for linux
# us['musescoreDirectPNGPath'] = '/usr/bin/mscore'
# us['musicxmlPath'] = '/usr/bin/mscore'
# for windows
# us['musescoreDirectPNGPath'] = r'C:\Program Files (x86)\MuseScore 2\bin\MuseScore.exe'
# us['musicxmlPath'] = r'C:\Program Files (x86)\MuseScore 2\bin\MuseScore.exe'
If the setup is correct, the following code cell should create a music21
Note object and show its graphical rendition via MuseScore:
# n = m21.note.Note('c')
# n.show('ipython.musicxml.png')
Another possibility is to use LilyPond for rendering. Again, we need three steps to get it to work.
music21
user environment file (we already did that above).music21
. The following code cell again gives typical locations for Linux and Windows.# for linux
# us['lilypondPath'] = '/usr/local/bin/lilypond'
# for windows
# us['lilypondPath'] = r'C:\Program Files (x86)\LilyPond\usr\bin\lilypond.exe'
Finally, we are able to render our simple note via Lilypond:
# n.show('ipython.lily.png')
For creating a staff line with multiple notes, we add multiple music21
objects to a music21
Stream.
# s = m21.stream.Stream()
# s.append(m21.key.Key('E-'))
# s.append(m21.meter.TimeSignature('2/4'))
# s.append(m21.note.Rest(quarterLength=0.5))
# s.append(m21.note.Note('g', quarterLength=0.5))
# s.append(m21.note.Note('g', quarterLength=0.5))
# s.append(m21.note.Note('g', quarterLength=0.5))
# s.append(m21.note.Note('e-', quarterLength=2))
# s.show('ipython.musicxml.png')
Instead of writing Python code to create a music21
score, we can also read and display a MusicXML file.
# fn_xml = os.path.join('..', 'data', 'C1', 'FMP_C1_F01_Beethoven_FateMotive_Sibelius.xml')
# s = m21.converter.parse(fn_xml)
# s.show('ipython.musicxml.png')
We can also read in a full orchestral score. Since such a score cannot be rendered on a single page, we can specify the measures that we want to show:
# fn_xml = os.path.join('..', 'data', 'C1', 'FMP_C1_F10_Beethoven_Fifth-MM1-21_Sibelius-Orchestra.xml')
# s = m21.converter.parse(fn_xml)
# s.measures(1, 5).show('ipython.musicxml.png')