Cantussy
Cantussy is a web app that procedurally generates musical material in three stages:
- First, it generates a cantus firmus. This is a simple vocal melody, free of rhythmic differentiation, which meets various criteria to do with ease of singing, and freedom from monotony.
- A second melody is generated in note-against-note (“first species”) counterpoint against the cantus. This melody broadly meets the same criteria as the cantus.
- The generated two-voice texture is then unfolded to create a more “instrumental” single-voice melody.
This project is something of a proof of concept. It uses randomised tree descent with backtracking to generate the cantus, and a similar process to generate the counterpoint: using a lookup table to retrieve a list of “valid contrapuntal moves” for a given cantus motion and current vertical interval, and then randomly exhausting each option recursively.
It also uses both the C and TypeScript versions of Meantonal for pitch representation and manipulation, which is another project featured on this site, with the low level generative algorithms written in C and compiled to WebAssembly via emscripten. The web frontend then calls these functions via JavaScript, using Verovio to generate notation as SVG code, which is then rendered to the screen.
The playback stage uses Meantonal’s TuningMap class to render frequencies from the arrays of generated Pitch instances, using the Web Audio API. As a free bonus feature, this makes it trivially easy to add user-facing controls to change the tuning system, so I added a selector to change between 12, 19, 31, 50, 53 and 55 tone equal temperament. 53edo is not treated as a meantone temperament, and instead uses a rather primitive algorithm to silently “respell” notes before rendering their frequencies. When playing E and C together, for instance, the E (which is very sharp in 53edo) is silently respelled as Fb, which is within a cent of a pure 5/4 major third. The algorithm isn’t very sophisticated, and introduces other subtle problems, but was another nice proof of concept for me.
This project enabled me to learn a lot about Emscripten and incorporating code written in languages like C into web apps.
Roadmap
While it’s not a high priority right now, I’d like to do the following when time permits:
- Tighten up the constraints on the cantus and counterpoint generation steps.
- Develop the unfolding step more, and add controls. Currently it simply alternates between the two voices in triplets, but there are many more sophisticated possibilities.
- Extend counterpoint generation to encompass second, third and fourth species counterpoint. I suspect fifth species may require a fundamentally different approach, but have no way of verifying this currently.
← Back to projects