the generative music blog #02 – generating chord progressions

Abstracting harmony using functions

Harmony is a vast and complicated topic and I don’t want to bore my readers with the technicalities of composing effective harmonic progressions. For today’s experiment we will generate some simple chord progressions using harmonic functions.

Similar in concept to Tonic, Dominant, and Subdominant used in traditional western harmony. We can define our own functions (4 in our case) that will determine the relations and probabilities for harmonic changes within a chord progression. This makes every chord an instance of the harmonic function.

For example, let’s take D, D7, G, A as instances of our four functions. This simple chord progression is basically an extended cadenza, with D7 functioning as a secondary dominant of the subdominant. (Again, I do my best to not make it feel like a harmony lesson).

Our four chords represented using standard western notation.

Probabilities

Now, we can define probabilities for the harmonic changes between the functions.

So let’s define some very simple relations like so:

D has 80% chance to go to G and 20% chance to go to D7

D7 has 80% change to go to G and 20% chance to go to D

G has 50% chance to go to D and 50% chance to go to A

A has 50% chance to go to D and 50% chance to go to D7

With these harmonic probabilities we might get harmonies not dissimilar to 18th century German folksongs.

Ich bin ein junges Weibchen. https://www.volksliederarchiv.de/ich-bin-ein-junges-weibchen-selleriesalat/

It should be noted that changing these probabilities can produce extremely different musical results despite the simplicity of our 4 base chords. Case in point, you will get a very different harmonic world if the D7 had an 80% chance of preceding A, rather than G.

Automating the process

The probabilities can also be represented in a JSON format for fast generation of instances using a python script. The code examples can be found here:
https://codeberg.org/guyoob/generative-music-resources/src/branch/master/chord_progressions

Multiple chords per function

Looking at the folksong mentioned above, we can see a fifth chord – A7. We can treat this A7 as a fifth function or alternatively, as a member of the 4th chord family (corresponding to the 4th function). Within the chord family we can define probabilities as well, so let’s say that A and A7 both have 50% of appearing as the representative member used as the function’s instance.

I have created chord families for all functions, defined their probabilities, ran the script multiple times and got some interesting results:

[['D', 'D7', 'Em7', 'D', 'D7b9', 'G', 'A7'], ['Bm7', 'Em7', 'A7'], ['D', 'G', 'A']]

[['D', 'G', 'A'], ['D7', 'DMaj7', 'D7', 'G', 'A'], ['D7', 'G', 'A']]

[['D', 'G', 'A'], ['D7', 'Bm7', 'Em7', 'A'], ['D', 'G', 'A7']]

[['DMaj7', 'G', 'Bm7', 'G', 'A7'], ['D7', 'G', 'A7'], ['Bm7', 'G', 'D', 'G', 'A7']]

Let’s make some music

To put these chord progressions into practical use, I have created a 5/4 drum beat and employed the chords as the harmonic progression to accompany the beat.

For those curious about why 5/4 in particular – I was inspired (again) by my German folksong research:

Prinz Eugen der edle Ritter. https://www.volksliederarchiv.de/prinz-eugen-der-edle-ritter/

The result has nothing to do with my source of inspiration, but it’s a fun little harmonic experiment nonetheless: https://shufu.bandcamp.com/track/smelly-jobs


Note: In this article I use “German” as a linguistic identifier and not as a national identifier.

Leave a Reply

Your email address will not be published. Required fields are marked *