Blastov!

a generative music solar system.

A rocket moves through a system of planets, its trajectory influenced by competing gravitational pulls. Each planet represents a chord, and whichever is exerting the most force on the rocket is used as the basis for the music generation. This results in dynamic harmonic movement, and the rocket can often settle into slowly evolving chord progressions as orbits drift in and out of phase. The performer can also influence the path of the rocket by clicking and dragging. The music generation consisted of a melody generated with a Markov chain and an arpeggiated accompaniment. The choices of chords were determined by a genetic algorithm, which was my main contribution, and I will go into more detail on this here. 

Blastov was made for a group project for my masters course in Sound and Music Computing and the Music Technology Group at UPF, Barcelona. It was built in Python, and the code is available on GitHub. 

the genetic algorithm

By pressing a letter key from A-G with a combination of arrow keys, the user can prompt a genetic algorithm to assign each of the planets a chord from any major or minor key.  The algorithm takes a population of individuals (sets of chords) and uses standard processes of crossover and selection to fit them to a target key. This generation is played out in ‘real-time’, with the chords on screen gradually evolving until they fit the key. The benefit of a genetic algorithm is the diversity of solutions it can provide, meaning that if the user triggers a key change to C major, then to C# major, then to C major again, the chords chosen to represent C major the second time will likely be different. 

blastov! in use. The user can redirect the rocket by clicking and dragging, and can trigger the genetic algorithm to change key with keyboard input.

The suitability of a set of chords is defined by a fitness function which measures the proportion of notes in those chords which are diatonic in the target key. The evolution process is stopped when the average fitness of all individuals in the population passes a threshold. Setting a threshold value of less than one ensures that some non-diatonic notes are allowed in the chosen progression – in Blastov, it is set to 0.8, which allows for harmonically interesting combinations of chords. 

After a run to produce chords in a new key, the whole population resulting from that is taken as the starting population for the next run. This raises a particular challenge when dealing with genetic algorithms, as there is a ‘shifting objective’ – a population optimised towards C major has no way of combining its chords to reach a new objective of C# major. The standard counter for this is a technique called ‘random immigration’, where at each generation, a certain proportion of the population is replaced with individuals with randomised genes. When this proportion is small, diversity is introduced without disrupting emerging trends amongst the existing population. 

However, in this particular case, it isn’t unusual that our population might already contain relatively high-fitness individuals, but just doesn’t quite cross our threshold for ending the algorithm. For example, if our population had been optimised towards G major, and we wanted to modulate to C major, it would only be chords containing F# that would be incompatible. Therefore, any completely randomised individuals would likely score lower than the individuals in our existing population, and so would not be selected for crossover, and no diversity would be introduced. In this case then, a more advanced variation of random immigration, ‘self-organising’ random immigration, is used. Here we initialise small subpopulations, and perform crossover and mutation within this subset without allowing for crossover with the main population. Once this new group reaches a certain fitness level, we then combine it with the main population, initialise a new subpopulation, and start the process again. 

In order to display the results of this genetic algorithm, one gene is randomly chosen to output to the planets. Each generation, this gene is crossed over exactly once to produce exactly one child, which is then set to the output of the planets. As a result of this structure, when the user prompts a key change, they can see the lineage of one gene and its children playing out in real time until the algorithm meets the threshold. This exposes the workings of the genetic algorithm. This was chosen in opposition to the hidden workings of black-box music generation techniques such as transformers. Here, the process of generation is very visible, interpretable to non-experts, and often inefficient. No intelligence can be ascribed to the generation process, and the creative work of both the designers and users of the technology is brought to the fore.