Extracting Parts and Melodies

This module explains how to extract a part or melody from an existing piece of music.

Rather than manually entering all of the notes of a melody, we can import a musical work into music21 and then return the MIDI note numbers. We can import a work from a file, or from the online music21 corpus.

In this case, we’ll use the song “Life Every Voice and Sing” composed by J. Rosamond Johnson with lyrics by James Weldon Johnson from the music21 corpus:

from music21 import *

my_work = corpus.parse('johnson_j_r/lift_every_voice.mxl')

If we want to view our notation, we can use the following code:

my_work.show()

The notation should appear in the MusicXML reader you specified during the music21 configuration process.

Many musical works consist of more than one part, so we have to specify the part from which we want to extract the melody. We can use music21’s built-in parts property to do this, specifying the part with an index number as we would in a list.

This example pulls the first part from the work as a new variable (using index number 0):

first_part = my_work.parts[0]

If we know how the parts have been labeled, we can also access a part by name:

first_part = my_work.parts['Soprano']

(Index numbers are the most reliable way to access parts. In order to access parts by the label, you must be sure that you know exactly how parts were labeled [i.e. you did it yourself] and the label is spelled correctly. Labels in digital corpora can exhibit irregularities of spelling and convention.)

We can view the excerpted part using the same method as above:

first_part.show()

Finally, if you want to focus on a particular passage within a part, you can specify the passage using the .measures property. For example, this code isolates the first 4 bars of the soprano part as a passage with a unique variable name:

first_excerpt = first_part.measures(1, 4)

first_excerpt.show()

Once our melody is isolated as a variable, we can call it in various contexts to analyze it and apply different transformations and operations. However, you’ll notice that in this case, starting from measure 1 excludes the pick-up bar. If we want to start from the pick-up bar, we’ll have to start from measure “0”:

first_excerpt = first_part.measures(0, 4)

first_excerpt.show()

Using the .show() method is highly recommended to verify that you have extracted the correct part. Also, remember that each time you define a variable it erases however it was previously defined. This means that if you want to select different excerpts, you have to return to “first_part” (not “first_excerpt”), which contains the entire soprano part. Or if you want to select a different part, you have to return to “my work” (not “first_part”), which contains all four parts.

For additional sources for digitized musical examples, see this page.