Building Chord Progressions using Stacks, Part 2
Photo by Nahir Giorgio on Unsplash
Continuing with my previous post on chord progressions, I am going to play a few more chord progression examples. Remember, I am using the music21 Python library to understand and play the music and I am using this musical stack structure:
from music21 import *
class MusicStack:
def __init__(self):
self.items = stream.Stream()
def push(self, item):
self.items.append(item)
def pop(self):
if self.is_empty():
raise IndexError("Sorry, your stack is empty")
else:
return self.items.pop()
def peek(self):
if self.is_empty():
raise IndexError("Sorry, your stack is empty")
else:
return self.items[-1]
def is_empty(self):
return self.items == []
Thanks for reading Learning Data Structures and Algorithms with Music! Subscribe for free to receive new posts and support my work.
One very recognizable chord progression is in “Don’t Stop Believing” by Journey, due to the prominent piano part. I’ll build this chord progression with the stack.
stack_chords_journey = MusicStack()
# 'Don't Stop Believing' by Journey
chord_data = [
['E3', 'B3', 'E4', 'G#4'], # E major
['B2', 'B3', 'D#4', 'F#4'], # B major
['C#3', 'B3', 'E4', 'G#4'], # C sharp minor over 7
['A2', 'C#4', 'E4', 'A4'], # A major
['E3', 'B3', 'E4', 'G#4'], # E major
['B2', 'B3', 'D#4', 'F#4'], # B major
['G#2', 'B3', 'D#4', 'G#4'], # G sharp minor
['A2', 'C#4', 'E4', 'A4'] # A major
]
for notes in chord_data:
stack_chords_journey.push(chord.Chord(notes, type='whole'))
stack_chords_journey.items.show()
stack_chords_journey.items.show('midi')
Now let’s play it backwards with the pop() function. Note that with this stack structure, I could add a size() function that determines the length of the stack, but I just call it directly here. I like how it sounds!
reverse_journey = MusicStack()
num_items = len(stack_chords_journey.items)
for _ in range(num_items):
reverse_journey.push(stack_chords_journey.pop())
reverse_journey.items.show()
reverse_journey.items.show('midi')
Another song that is pretty popular these days is “Golden” by Huntrix from KPop Demon Hunters. This is the chord progression in the pre-chorus:
# Golden by HUNTRIX, Pre-chorus
stack_chords_golden = MusicStack()
chord_data = [
# pre-chorus
(['C3', 'C4', 'E4', 'G4'], 'whole'), # C major
(['G2', 'B3', 'D4', 'G4'], 'whole'), # G major
(['D3', 'A3', 'D4', 'F#4'], 'whole'), # D major
(['E3', 'B3', 'D3', 'A4'], 'half'), # E major 7 suspended 4th
(['E3', 'B3', 'E3', 'F#4'], 'half'), # E major suspended 2nd
(['C3', 'C4', 'E4', 'G4'], 'whole'), # C major
(['G2', 'B3', 'D4', 'G4'], 'whole'), # G major
(['D3', 'A3', 'D4', 'F#4'], 'whole') # D major
]
for notes, duration in chord_data:
stack_chords_golden.push(chord.Chord(notes, type=duration))
stack_chords_golden.items.show()
stack_chords_golden.items.show('midi')
Now, let’s hear it in reverse. Very interesting!
reverse_golden = MusicStack()
num_items = len(stack_chords_golden.items)
for _ in range(num_items):
reverse_golden.push(stack_chords_golden.pop())
reverse_golden.items.show()
reverse_golden.items.show('midi')
Lastly, let’s hear the chord progression from the chorus of my song, “Past The Pain.”
I’m using the I, V, VI, IV , chord progression, which is very popular in music. Turns out it’s used in “Don’t Stop Believing” by Journey, “Let It Be” by the Beatles, “No Woman, No Cry” by Bob Marley, and countless other songs.
chord_data = [
(['F3', 'A3', 'C3', 'F3'], 'whole'), # F major 7
(['E2', 'G3', 'C3', 'E3'], 'whole'), # C major over E.
(['D3', 'F3', 'A3', 'D3'], 'whole'), # D minor
(['C3', 'E3', 'G3', 'C3'], 'whole'), # C major
(['F3', 'A3', 'C3', 'F3'], 'whole'),
(['E2', 'G3', 'C3', 'E3'], 'whole'),
(['D3', 'F3', 'A3', 'D3'], 'whole'),
(['C3', 'E3', 'G3', 'C3'], 'whole'),
]
for notes, duration in chord_data:
stack_chords_pastthepain.push(chord.Chord(notes, type=duration))
stack_chords_pastthepain.items.show()
stack_chords_pastthepain.items.show('midi')
Now, let’s hear these chord progressions in reverse:
reverse_pastthepain = MusicStack()
num_items = len(stack_chords_pastthepain.items)
for _ in range(num_items):
reverse_pastthepain.push(stack_chords_pastthepain.pop())
reverse_pastthepain.items.show()
reverse_pastthepain.items.show('midi')
Nice, so we can build chord progressions and play chord progressions in reverse using stack data structures. In my next post, I will write about how we can use stacks to solve the valid parentheses problem with MusicXML notation.
Thanks for reading Learning Data Structures and Algorithms with Music! Subscribe for free to receive new posts and support my work.





