Skip to content

Instantly share code, notes, and snippets.

@kshaffer
Created January 23, 2013 20:16
Show Gist options
  • Save kshaffer/4612552 to your computer and use it in GitHub Desktop.
Save kshaffer/4612552 to your computer and use it in GitHub Desktop.
A Python module that will spit out a random 4–8 bar compound-meter rhythmic exercise in Lilypond code. Once I add more rhythmic options and make it generate the whole Lilypond score, I'll make a proper repo.
# rhythmgen
# Python module for generating practice rhyhm exercises in Lilypond code
# usage:
# >>> from rhythmgen import *
# >>> randomLine(compoundBeats,randomCompoundTop(),randomBottom(),randomLength())
# then copy and paste the code into a Lilypond file with a percussion staff
# Copyright (C) 2013 Kris P. Shaffer
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import random
def meter(top):
if top == 6 or top == 9 or top == 12:
meter = 1
elif top == 2 or top == 3 or top == 4:
meter = 0
else:
meter = ''
return meter
class Note(object):
def __init__(self,duration,top,bottom):
self.duration = duration
self.top = top
self.bottom = bottom
self.meter = meter(self.top)
def lp(self):
output = 'c'
if self.meter == 0:
if self.duration == 'beat':
output += str(self.bottom) + ' '
if self.duration == 'div':
output += str(self.bottom * 2) + ' '
if self.duration == 'sub':
output += str(self.bottom * 4) + ' '
if self.duration == 'twobeat':
output += str(self.bottom / 2) + ' '
if self.duration == 'beat~':
output += str(self.bottom) + '~ '
if self.duration == 'div~':
output += str(self.bottom * 2) + '~ '
if self.duration == 'sub~':
output += str(self.bottom * 4) + '~ '
if self.duration == 'twobeat~':
output += str(self.bottom / 2) + '~ '
if self.duration == 'beat.':
output += str(self.bottom) + '. '
if self.duration == 'div.':
output += str(self.bottom * 2) + '. '
if self.duration == 'sub.':
output += str(self.bottom * 4) + '. '
if self.duration == 'twobeat.':
output += str(self.bottom / 2) + '. '
if self.meter == 1:
if self.duration == 'beat':
output += str(self.bottom / 2) + '. '
if self.duration == 'div':
output += str(self.bottom) + ' '
if self.duration == 'twodiv':
output += str(self.bottom /2) + ' '
if self.duration == 'sub':
output += str(self.bottom * 2) + ' '
if self.duration == 'twobeat':
output += str(self.bottom / 4) + '. '
if self.duration == 'beat~':
output += str(self.bottom / 2) + '.~ '
if self.duration == 'div~':
output += str(self.bottom) + '~ '
if self.duration == 'sub~':
output += str(self.bottom * 2) + '~ '
if self.duration == 'twobeat~':
output += str(self.bottom / 4) + '.~ '
if self.duration == 'div.':
output += str(self.bottom) + '. '
if self.duration == 'sub.':
output += str(self.bottom * 2) + '. '
return output
def bottom():
return int(random.sample([ 4, 8, 16 ],1)[0])
def lpCode(line,top,bottom):
result = '\time ' + str(top) + '/' + str(bottom) + ' '
for n in line:
result += Note(n,top,bottom).lp()
return result
compoundBeats = [ \
['beat'], \
['beat'], \
['beat'], \
['beat'], \
['beat'], \
['twodiv', 'div'], ['div', 'twodiv'], ['div.', 'div.'], \
['twodiv', 'div'], ['div', 'twodiv'], \
['twodiv', 'div'], ['div', 'twodiv'], \
['div', 'div', 'div'], ['twodiv', 'sub', 'sub'], ['div.', 'sub', 'div'], ['div', 'sub', 'div.'], ['sub', 'sub', 'twodiv'], ['div', 'div.', 'sub'], \
['div', 'div', 'sub', 'sub'], ['div', 'sub', 'sub', 'div'], ['sub', 'sub', 'div', 'div'], ['div.', 'sub', 'sub', 'sub'], ['sub', 'div', 'div', 'sub'], \
['div', 'sub', 'sub', 'sub', 'sub'], ['sub', 'sub', 'div', 'sub', 'sub'], ['sub', 'sub', 'sub', 'sub', 'div'], \
['sub', 'sub', 'sub', 'sub', 'sub', 'sub'], \
['sub', 'sub', 'sub', 'sub', 'sub', 'sub']
]
def randomLine(beats,top,bottom,bars):
line = []
if top == 2 or top == 3 or top == 4:
card = top
elif top == 6 or top == 9 or top == 12:
card = int(top / 3)
length = card * bars
i = 0
while i != length:
beat = random.sample(beats,1)[0]
for n in beat:
line.append(n)
i += 1
return lpCode(line,top,bottom)
def randomCompoundTop():
return int(random.sample([6,9,12],1)[0])
def randomBottom():
return int(random.sample([4,4,8,8,8,16],1)[0])
def randomLength():
return int(random.sample([4,5,6,7,8],1)[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment