This program generates a cantus firmus roughly in line with the restrictions given in Salzer and Schachter's Counterpoint in Composition.
The melody is generated non-deterministically via randomised recursive exploration of a tree, where each node represents a new note concatenated onto the current melody. Any time a note is tried, various checks are performed, and if no valid cantus can result from continuing down a given branch, backtracking occurs.
This method tries to achieve three objectives:
- Generation time for a cantus with length between 9 and 16 should be as low as possible.
- Any valid cantus by the ruleset given should be within the range of the function and possible to generate.
- The chances of any two canti in the range of the function being generated should be as close to even as possible.
To the extent that these objectives are achieved, it should hopefully be useful for stress-testing other species counterpoint related programs.
The error checks are also parameterised in a way that should make them easy to selectively disable and add inverse checks for to generate canti that are deliberately flawed in a specified way, which might be useful pedagogically.
- Contained within the range of a tenth.
- Only melodic consonances occur.
- One tone should not be over-emphasised.
- Climax sould not be repeated.
- Stepwise motion should predominate.
- Between 2 to 4 leaps.
- Must change direction several times.
- No more than 2 leaps larger than a 4th.
- Leaps larger than a 3rd should change direction, preferably stepwise.
- No more than 2 leaps in a row.
- Direction change should preferably be by step.
- Avoid excessive motion in a single direction.
- Avoid outlining dissonances between changes in direction.
- Avoid climaxing on the leading tone.
- No immediate repetition of tones.
- Caution in repetition of tones preceded by large leaps.
- Avoid repetition of groups of tones.
- Avoid sequences.
- Leaps should be equally likely to occur at any point in a generated cantus.
- Any acceptable range should be equally likely to be spanned. Shouldn't be biased towards narrow or wide canti.