Transposition

This module demonstrates how to perform the post-tonal transposition operation on pitches and pitch classes.

There are two ways of thinking about transposition in post-tonal music: as a way of measuring distance between notes, or as an operation that can be applied to notes.

Let’s start with two notes, G4 and C5, given as 67 and 72 in MIDI note numbers. The difference between them is 5 semitones (you can review math in Python if necessary):

72 - 67
> 5

So we could say that to get from G4 to C5, we have to travel up 5 semitones. We call this T5. To get from C5 to G4, we have to travel down 5 semitones (T-5):

67 - 72
> -5

Now let’s apply this to an actual melody. We’ll use the same musical example as in the Pitch and Pitch Class module: Alban Berg’s Violin Concerto (1935). This time, let’s listen to the opening rising-and-falling melody played first on the harp in the first bar (ignore the “Piano” indication in the score), and then played again, differently, on the violin in the second bar (from about 0:12-0:22).

These two melodies sound very similar. It might be interesting to find out if they are related to one another by transposition.

The harp and violin melodies can be given in MIDI notes as follows:

harp_melody = [34, 53, 60, 67, 67, 60, 53, 34]
violin_melody = [55, 62, 69, 76, 76, 69, 62, 55]

We can find the difference between each note in these two melodies by subtracting one from the other. However, we can’t simply subtract one list from another. We have to iterate over both lists simultaneously in order to compare the corresponding note in each melody.

In order to compare two melodies like this, first we have to ensure that they are the same length:

len(harp_melody)
> 8

len(violin_melody)
> 8

If the lengths match, we can use the length as a range for a for loop (using the helpful range function):

for x in range(8):
 print(harp_melody[x] - violin_melody[x])

We step through each of the eight notes in each list, comparing (and printing) the differences as we go.

We can make this a little more efficient by calculating the length in the same line that we establish the for loop:

for x in range(len(harp_melody)):
	print(violin_melody[x] - harp_melody[x])
> 21
> 9
> 9
> 9
> 9
> 9
> 9
> 21

If we deal strictly with pitches, it seems that there’s not a single Tn transposition operation that can be applied to transpose all of the harp’s notes to the violin’s (or vice versa). T9 (transposing all of the harp’s notes up by 9 semitones) would work for most of the notes, but we need T21 for the first and last notes.

But what if we try with pitch classes?

We can use a list comprehension to quickly generate lists of pitch classes:

harp_pc = [x % 12 for x in harp_melody]
violin_pc = [ x % 12 for x in violin_melody]

Now let’s try the same comparison operation as before, but using these new lists:

for x in range(len(harp_pc)):
 print(violin_pc[x] - harp_pc[x])
> -3
> -3
> 9
> -3
> -3
> 9
> -3
> -3

We still don’t have a perfect match. But there’s still hope. Why?

Recall that there are only 12 pitch classes (0-11), and that if we keep rising by semitones past 11, we start over at 0. If we descend, we go straight from 0 back to 11, not -1. Just like how two hours before 1:00 isn’t -1:00, it’s 11:00!

In order to respect this circular structure, we have to apply a final modulo (%) 12 operation to the subtraction. And as soon as we do that:

for x in range(len(harp_pc)):
	print((violin_pc[x] - harp_pc[x]) % 12)
> 9
> 9
> 9
> 9
> 9
> 9
> 9
> 9

Voila! Now we can see that each of the pitch classes of the harp melody are related to the pitch classes of the violin melody by T9.

Put another way, if we add 9 semitones to each note in the harp melody (modulo 12), it will be identical to the violin melody, at least in terms of pitch class.

Let’s prove it:

harp_pc
> [10, 5, 0, 7, 7, 0, 5, 10]

violin_pc
> [7, 2, 9, 4, 4, 9, 2, 7]

for x in harp_pc:
 print((x + 9) % 12)
> 7
> 2
> 9
> 4
> 4
> 9
> 2
> 7

Or more succinctly:

transposed_harp = [(x + 9) % 12 for x in harp_pc]

transposed_harp
> [7, 2, 9, 4, 4, 9, 2, 7]

In fact, if our subtraction operation is modulo 12, we don’t even have to convert the melodies to pitch classes to get the right answer:

for x in range(len(harp_melody)):
	print((violin_melody[x] - harp_melody[x]) % 12)
> 9
> 9
> 9
> ...

To explore building transposition-related functions, try this module.

Extensions

  1. What value n for the transposition operation Tn transforms the violin melody into the harp melody? What is significant about the relationship between this number and the 9 in T9 discussed above?
  2. What generic Python functions above can be replaced with equivalents from the music21 post-tonal toolkit?
  3. Are subsequent statements of the same idea in the Berg Concerto also related by transposition? If so, how do they compare?

Further Reading

For more on this topic, see the Open Music Theory entry.