In this module, we’ll find the pitch class for each pitch of a melody.
In post-tonal music, we draw a distinction between pitch and pitch class. Pitch refers to a specific note in a specific range. Pitch class refers to a class of notes that share the same name, plus enharmonic equivalents. A good analogy is that pitch refers to one of the 88 keys on a piano keyboard, while pitch class refers to all verisons of that same key, in all octaves.
There are twelve notes to the octave, and therefore twelve pitch classes (the classes start over with each octave). Pitch classes are numbered 0 to 11, by convention. Pitch class 0 is equivalent to C (or B-sharp), pitch class 1 is equivalent to C-sharp (or D-flat, or B-double-sharp), and so on.
If we represent pitches as numbers, we can use a simple mathematical operation to convert from pitch to pitch class. (Check out this module if you’re not sure how to convert your melody into MIDI note numbers.)
Middle C on the piano can be represented as the number 60. The pitch class of middle C is 0. The same is true of any C anywhere on the piano: C3 (48), C5 (72), C2 (36), etc. They all have the same pitch class because they all have the same name.
The mathematical operation we use to convert pitches to pitch classes is called modulo. (See this module on basic math in Python.) The modulo operation gives the remainder of a division. Since there are twelve pitch classes, we divide the MIDI note number by 12. But instead of using the division symbol (/), we use the modulo symbol (%):
60 % 12
> 0
If we try a different C, like C3 or C5, we get the same result:
48 % 12
> 0
72 % 12
> 0
Now let’s try a note that’s not a C. If we take C#4, for example, we get pitch class 1:
61 % 12
> 1
You can try this with any note. Now let’s turn to a real-life passage from the fourth movement of Ruth Crawford Seeger’s String Quartet (1931). The passage in question is the third bar, where the second violin, viola, and cello play in a unison eighth-note rhythm, starting at 8:43 in the video below:
The second violin’s part would be represented in MIDI note numbers like this:
violin_ii = [62, 64, 65, 63, 66, 69, 68, 67]
If we wanted to print the pitch class for each pitch in the melody in sequence, we might use a for loop:
for x in violin_ii:
x = x % 12
print(x)
It’s often more readable and convenient to generate a list of results, rather than simply printing them. To generate a new list of pitch classes, we can use a list comprehension:
pitch_classes = [x % 12 for x in violin_ii]
pitch_classes
> [2, 4, 5, 3, 6, 9, 8, 7]
Let’s compare the viola and cello parts:
viola = [50, 52, 53, 51, 54, 57, 56, 55]
cello = [38, 40, 41, 39, 42, 45, 44, 43]
Let’s compare the pitch classes of each of the three parts side by side. Instead of printing each list individually, we can combine multiple print statements into a single for loop that runs once:
for i in range(1):
print([note % 12 for note in violin_ii])
print([note % 12 for note in viola])
print([note % 12 for note in cello])
> [2, 4, 5, 3, 6, 9, 8, 7]
> [2, 4, 5, 3, 6, 9, 8, 7]
> [2, 4, 5, 3, 6, 9, 8, 7]
Sure enough, even though each instrument is playing notes in different registers, the pitch classes are the same. This is also called “octave equivalence.”
Extensions
- Do you notice any patterns between this passage and similar passages in the movement? Or any patterns within this passage?
- What information would we be collecting if we used the / (division) operator instead of the % (modulo) operator?
Further Reading
For a more detailed look at this topic, see the Open Music Theory entry.