Open In Colab

Ch. 9 - Music analysis

This is a very simple demonstration of several built-in analytical functions in music21. We carry out a reduction of Bach chorale, analysis of harmony using Roman numerals and add Lerdahl and Jackendof type of metrical hierarchy.

Install Music21 (in Colab)

Important

The first code segment is to install music21 and other elements needed to run the environment. In Colab, press play and wait for all commands to be executed - this initial command might take some time as it needs to build the musi21 environment.

Install Music21 and Musescore in local machine

Important

For instructions of how to get music21 and Musescore working on a local machine, see Installation guidelines from music21.

Note

The script below uses a workaround where the excerpts are first written to a xml file and then converted to png image.

Harmonic and metrical analysis

Harmonic and metrical analysis of an example excerpt bach/bwv30.6 using music21.

Harmonic analysis – Reduction

First get a Bach chorale.

from music21 import *                     # activate library

### 1 Select one example from Bach chorales
bwv30_6 = corpus.parse('bach/bwv30.6.xml')# Take an example
#bwv30_6.measures(1, 3).show()             # Display 3 bars
bwv30_6.measures(1, 3).write('xml', fp='output.xml')
!mscore output.xml -o images/score1.png --trim-image 0
zsh:1: command not found: mscore

Harmonic analysis

Analyse chords using Roman numerals.

bChords = bwv30_6.chordify()              # Slice the chords
for c in bChords.recurse().getElementsByClass('Chord'):
    c.closedPosition(forceOctave=4, inPlace=True)
# Run analysis and add Roman numerals as lyrics
for c in bChords.recurse().getElementsByClass('Chord'):
    rn = roman.romanNumeralFromChord(c, key.Key('A'))
    c.addLyric(str(rn.figure))
bChords.measures(0, 3).show()             # Display the result
bChords.measures(0, 3).write('xml', fp='output.xml')
!mscore output.xml -o images/score2.png --trim-image 0
zsh:1: command not found: mscore

Metrical analysis

Carry out metrical analysis.

bass = bwv30_6.getElementById('Bass')    # Get the bass part
excerpt = bass.measures(1,3)             # Bar 1 through 3
analysis.metrical.labelBeatDepth(excerpt)# Metrical analysis
#excerpt.show()                           # Display the results
excerpt.write('xml', fp='output.xml')
!mscore output.xml -o images/score3.png --trim-image 0
!rm output.xml
zsh:1: command not found: mscore

Back to top