Project: Music Generator

November 29, 2020
Music generator sketch
Sketch of the core music generator methods.

In my last post I talked about generating a Csound score with Tracery. That was a rewarding exercise, but Tracery isn't an ideal language to continue developing a music generator with. I decided to reimplement the music generator entirely in Python in order to take advantage of handy things like lists, conditional statements, functions, and classes. It all came together quicker than I expected, and I was even able to release an album of tracks showcasing the system.

How It Works

While my Python music generator works in almost the same way under the hood as my Tracery music generator, I was able to add so much more functionality and sophistication to the Python generator that it's hard to compare the two systems. The Python generator is a major leap forward in terms of the complexity and diversity of the output. Here's an overview of the components that make it work.

Classes

I was most excited to see how using classes and objects in Python would allow me to do more advanced things with the generator. Here are the classes I'm using for now, but these will probably evolve as I continue development.

Rule System

You can think of rules as transformations that are applied to one or more Voices at different times throughout the piece. The really fascinating thing about the rule system is that the rules overlap and interact in unpredictable ways. My goal is that these rules make the output dynamic, surprising, and musically interesting. Here's a closer look at the properties of the Rule class, which will give you a sense for how the rules work.

Sketch of the chord change function.

Here are the rules that currently exist.

Csound Orchestra

I'm using the same Csound orchestra from the Tracery version. The output of the Python generator is a long text string formatted as a Csound score, and this score is then performed by the Csound orchestra. The instruments include plucked string (for both melody and bass), pipe organ, Hammond B3 organ, Rhodes electric piano, marimba, and samples of several vintage drum machines. There's also some reverb sprinkled in.

Output

It took about five weeks to build this music generator in Python. There's much more work to be done on it. Endless work in fact because new rules and more sophisticated melody, rhythm, and structure algorithms can always be added. But I did reach a good pausing point where I could generate and release some tracks to showcase the generator.

318, an album entirely generated by my music generator.

318 is an album of 23 tracks produced by the music generator. The tracks are named after the people in CS 318. I literally wrote a Python script that told the generator to produce 23 tracks, assign them titles, and shuffle them to create the track list. I then adjusted the drum levels for half of the tracks before releasing them on Bandcamp. I actually didn't listen to a single track all the way through before releasing the album because I wanted to be faithful to the process of letting the algorithms generate and sequence the album.

Overall, I'm super happy with the album. First of all, it showcases the variety in output of the generator across the 23 tracks. Second, within the tracks the music does flow and evolve in surprising and sometimes delightful ways. My personal favorite tracks are "Junyi", "Yasmeen", and "Kaeden".

It's a strange feeling to code a music generator, generate an album, and then listen to it. There are moments in the music that take my breath away. I'm proud of those moments, but at the same time I can't really take credit for them. I made them possible, but the generator itself produced those particular moments.

Next Steps

Leave a Comment

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