Usage

The file to save to must be specified as an argument. It can then be
opened with any MusicXML software such as Musescore:

$ python prrs.py output.xml
$ musescore output.xml

A one-liner showing progress:

$ python prrs.py output.xml --show-symbols && musescore output.xml &

Warning: The output file will be clobbered if it already exists.

For full commandline options use --help.

Algorithms

(This may change as improvements are made)

To generate the chord progression, PRRS puts a V7 and Imaj7 at the end
and then works backwards, making a weighted random choice between
chords that tend to resolve to the "current" chord. For example:

I V I
I ii V I
I vi ii V I

Then the actual notes are generated working forwards. First a duration
is chosen for the current chord, then for each instrument a function
is called to generate the part for that instrument until the next
chord change. Chords that are more cadentially significant are more
likely to have a longer duration.

The bass part is just a basic walking bassline up and down the chord
notes. The piano plays the current chord using a random inversion
(weighted in favour of the root inversion) and random note length and
rests (weighted to rest more on the beat to syncopate off the
bassline). There is also a special function for each instrument to do
a random closing riff at the end of the song; this is just a random
rhythm that is increasingly likely to hold the note for longer.

TODO

Choose piano chord inversions to fit smoothly with ones before/after

Swing Beat set automatically without having to add it in musescore
(not sure how we can do this with music21)

Make duration more likely to be odd if we are already off-beat to
even it up