Hi there,
I can try to help you but keep in mind this was made a long time ago, so maybe some changes/revisions will be needed to work with modern versions of the libraries.
To understand how the program works, you really need to have a high-level view of how the method works. Roughly, I came up with a way to make canons sound “good by construction”. This is a different method from how you would normally write a canon in sheet music.
In sheet music, you normally write the canon measure by measure. Every time you add a measure in one voice, new measures are automatically added to the other voices (it’s a canon after all, so what the first voice does fully determines what the other voices do) and you need to check all the time if the different voices keep sounding good together (and if not, change the notes you’re trying to add).
In the algorithmic method, I work the other way around: I start from a chord progression or chorale that I already know sounds good, then rip it apart into canon melody lines that, once they play together, will form the chord progression I started from.
Suppose I want to make a canon with four voices. I then first write (or generate) a chord progression - these are the chords you will hear once all the voices play together. Then I rip apart each of the chords to end up with 4 melodies (e.g. all the chord’s upper notes forms one melody, all the upper middle notes form a second melody, all the lower middle notes form a third melody and all the lowest notes form a fourth melody). By putting these 4 melodies after each other, and playing them four times simultaneously with a suitable delay (and optionally an octave transposition), I get the resulting canon. When all voices are playing together I hear the chord progression I started with.
It’s kind of abstract to explain in just words but once you “get” it, it’s an extremely simple method really
Anyway, with that knowledge, perhaps the code will make more sense. In canon-generator/canon-gen.py at master · shimpe/canon-generator · GitHub you can see that I start from a chord progression (line 358), rip them apart to melodies which are concatenated into one long melody (lines 386-401), then I apply some transformations to these melodies to spice them up (inserting extra notes, modifying rhythms) (lines 404-408) and finally sequence multiple copies of these unraveled chords together, applying some octaviations to add more variation, into a canon (line 425).
Does this help or did I make things worse?