def __init__ (self, tower, row_generator, do_up_down_in = True): self._rhythm = Rhythm (self) self.do_up_down_in = do_up_down_in self.row_generator = row_generator self._tower = tower self._tower.on_thats_all = self._on_thats_all self._tower.on_go = self._on_go self._tower.on_stand_next = self._on_stand_next self._tower.on_look_to = self._on_look_to self._tower.on_bell_ring = self._on_bell_ring self._is_ringing = False self._is_ringing_rounds = True self._should_start_method = False self._should_start_ringing_rounds = False self._should_stand = False self._row_number = 0 self._place = 0 self._row = None
def getNamedRhythm(self, title): q = Rhythm.all().filter('title =', title) r = q.fetch(1) if r: out = r[0].xml self.response.headers['Content-Type'] = "text/xml" return self.response.out.write(out) else: return self.write('not found')
def get(self): song = self.request.get('song') back = self.request.get('back') if song: context = { 'song' : song , 'back' : back } self.response.write(self.render_template_arg('animation.html', context)) else: context = {'titles' : [rhythm.title for rhythm in Rhythm.all() ] } self.response.write(self.render_template_arg('select_a_song.html', context))
def __init__(self, SCALE): NOTES, FREQ_DICT = SCALE self.note = Note(NOTES, FREQ_DICT) self.rhythm = Rhythm() self.dynamics = Dynamics() self.equalizerFactor = {} self.equalizerFactor[-0.1] = 1.0 self.equalizerFactor[220] = 1.0 self.equalizerFactor[440] = 0.7 self.equalizerFactor[880] = 0.35 self.equalizerFactor[1760] = 0.15 self.equalizerFactor[3520] = 0.15 self.equalizerFactor[7040] = 0.15 self.equalizerFactor[14080] = 0.15 self.equalizerFactor[28160] = 0.15 self.equalizerFactor[56320] = 0.15 self.equalizerBreakPoints = [ -0.1, 220, 440, 880, 1760, 3520, 7040, 14080, 28160, 56320 ]
def post(self): title, type_str, xml_str = self.request.body.split('|') xml = md.parseString(xml_str) type = int(type_str) if valid_rhythm(xml) and self.validType(type): if self.request.get('arg') == 'edit': rhy = Rhythm.all().filter('title = ', title).get() if rhy.owner == self.getUser().username: rhy.xml = xml.toxml() rhy.rhythm_type = type else: return self.write('Invalid rhythm or owner') elif valid_title(title): rhy = Rhythm(title=str(title), xml=xml.toxml(), owner=self.getUser().username, rhythm_type=type ) elif not valid_title(title): return self.write("The title is already in use or invalid") rhy.put() else: return self.write('invalid rhythm')
def get(self): self.arg = self.request.get('arg') title = self.request.get('title') if title and self.arg == 'get': self.getNamedRhythm(title) elif title and self.arg == 'delete': rhythm = Rhythm.all().filter('title =', title).get() if rhythm.owner == self.getUser().username: rhythm.delete() elif self.arg == 'delete_all': self.deleteAll()
def get(self): self.arg = self.request.get('arg') if self.arg == 'all_templates': self.rhythms = Rhythm.all().filter('rhythm_type = ', 1).fetch(limit=None) user = self.getUser() privateRhythms = Rhythm.all() privateRhythmsName = RhythmAutorisation.all().filter('username = '******'rhythm_type = ', 2, 'title = ', name).get()) privateRhythms = Rhythm.all() for rhythm in Rhythm.all().filter('owner = ', self.getUser().username).fetch(limit=None): if rhythm.rhythm_type == 2: self.rhythms.append(rhythm) for rhythm in Rhythm.all().filter('rhythm_type = ', 3).fetch(limit=None): self.rhythms.append(rhythm) return self.write(self.getEncodedRhythms()) elif self.arg == 'all_official': self.rhythms = Rhythm.all().filter('rhythm_type = ', 1).fetch(limit=None) return self.write(self.getEncodedRhythms()) elif self.arg == 'all_publicly_shared': self.rhythms = Rhythm.all().filter('rhythm_type = ', 3).fetch(limit=None) return self.write(self.getEncodedRhythms()) elif self.arg == 'all_personal': if self.isLoggedIn(): self.rhythms = Rhythm.all().filter('owner = ', self.getUser().username).fetch(limit=None) else: self.rhythms = [] return self.write(self.getEncodedRhythms()) elif self.arg == 'all_personally_shared': if isLoggedIn: self.rhythm = [] privateRhythms = Rhythm.all() privateRhythmsName = RhythmAutorisation.all().filter('username = '******'rhythm_type = ', 2, 'title = ', name).get()) privateRhythms = Rhythm.all() else: self.rhythms = [] return self.write(self.getEncodedRhythms())
def __init__(self, SCALE): NOTES, FREQ_DICT = SCALE self.note = Note(NOTES, FREQ_DICT) self.rhythm = Rhythm() self.dynamics = Dynamics() self.equalizerFactor = { } self.equalizerFactor[-0.1] = 1.0 self.equalizerFactor[220] = 1.0 self.equalizerFactor[440] = 0.7 self.equalizerFactor[880] = 0.35 self.equalizerFactor[1760] = 0.15 self.equalizerFactor[3520] = 0.15 self.equalizerFactor[7040] = 0.15 self.equalizerFactor[14080] = 0.15 self.equalizerFactor[28160] = 0.15 self.equalizerFactor[56320] = 0.15 self.equalizerBreakPoints = [-0.1, 220, 440, 880, 1760, 3520, 7040, 14080, 28160, 56320]
class SFM(object): # pitch registers transpositionSemitones = 0 octaveNumber = 3 # tempo registers tempo = 60 currentBeatValue = 60.0/tempo currentBeat = 0 totalDuration = 0.0 # dynamics registers crescendoSpeed = 1.1 currentCrescendoSpeed = crescendoSpeed crescendoBeatsRemaining = 0.0 maximumAmplitude = 0.0 # tuple registers duration = 60.0/tempo amplitude = 1.0 decay = 1.0 # I/O input = "" ######################################################### # initialize Note, Rhythm, and Dynamics objects def __init__(self, SCALE): NOTES, FREQ_DICT = SCALE self.note = Note(NOTES, FREQ_DICT) self.rhythm = Rhythm() self.dynamics = Dynamics() self.equalizerFactor = { } self.equalizerFactor[-0.1] = 1.0 self.equalizerFactor[220] = 1.0 self.equalizerFactor[440] = 0.7 self.equalizerFactor[880] = 0.35 self.equalizerFactor[1760] = 0.15 self.equalizerFactor[3520] = 0.15 self.equalizerFactor[7040] = 0.15 self.equalizerFactor[14080] = 0.15 self.equalizerFactor[28160] = 0.15 self.equalizerFactor[56320] = 0.15 self.equalizerBreakPoints = [-0.1, 220, 440, 880, 1760, 3520, 7040, 14080, 28160, 56320] # self.tempo = 60 # self.currentBeatValue = 60.0/self.tempo # self.octaveNumber = 3 def equalize(self, freq): a, b = interval(freq, self.equalizerBreakPoints) f = mapInterval(freq, a,b, self.equalizerFactor[a], self.equalizerFactor[b]) # print freq, a, b, f return f # return tuple as string given frequency, # duration, decay, and amplitude def _tuple(self, freq, duration): output = `freq` output += " "+`duration` a = self.amplitude a = a*self.equalize(freq) output += " "+`a` output += " "+`self.decay` return output # return tuple as string from frequency of token # and root and suffix of token def tuple(self, freq, root, suffix): if suffix.find(",") > -1: thisDuration = self.duration*(1 - self.rhythm.breath) output = self._tuple(freq, thisDuration) output += "\n" output += self._tuple(0, self.duration - thisDuration) else: output = self._tuple(freq, self.duration) return output def updateRhythm(self, cmd): self.currentBeatValue, self.duration = self.rhythm.value(cmd, self) def emitNote(self, token): if self.crescendoBeatsRemaining > 0: self.amplitude = self.amplitude*self.currentCrescendoSpeed self.crescendoBeatsRemaining -= self.currentBeatValue freq, root, suffix = self.note.freq(token, self.transpositionSemitones, self.octaveNumber) self.output += self.tuple(freq, root, suffix) + "\n" # summary data self.totalDuration += self.duration self.currentBeat += self.currentBeatValue if self.amplitude > self.maximumAmplitude: self.maximumAmplitude = self.amplitude def executeCommand(self, ops): cmd = ops[0] # if cmd is a rhythm symbol, change value of duration register if self.rhythm.isRhythmOp(cmd): self.updateRhythm(cmd) # if cmd is a tempo command, change value of the tempo register if self.rhythm.isTempoOp(cmd): self.tempo = self.rhythm.tempo[cmd] self.updateRhythm(cmd) if cmd == "tempo": self.tempo = float(ops[1]) self.updateRhythm(cmd) # if cmd is an articulation command, change value of the decay register if self.rhythm.isArticulationOp(cmd): self.decay = self.rhythm.decay[cmd] # if cmd is a dynamics command, change value of the amplitude register if self.dynamics.isDynamicsConstant(cmd): self.amplitude = self.dynamics.value[cmd] # crescendo and decrescendo if cmd == "crescendo" or cmd == "cresc": self.crescendoBeatsRemaining = float(ops[1]) self.currentCrescendoSpeed = self.crescendoSpeed if cmd == "decrescendo" or cmd == "decresc": self.crescendoBeatsRemaining = float(ops[1]) self.currentCrescendoSpeed = 1.0/self.crescendoSpeed # pitch transposition if cmd == "octave": self.octaveNumber = int(ops[1]) if cmd == "transpose": self.transpositionSemitones = int(ops[1]) # pass special commands through if cmd[0] == '@': CMD = catList2(ops) CMD = CMD[:len(CMD)]+"\n" self.output += CMD # tuples: returns a string of tuples from input = solfa text def tuples(self): # split intput into list of tokens self.input = self.input.replace("\n", " ") tokens = self.input.split(" ") # make sure there are not empty list elements tokens = filter( lambda x: len(x), tokens) # initialize output self.output = "" for token in tokens: if self.note.isNote(token): self.emitNote(token) else: ops = token.split(":") ops = filter(lambda x: len(x) > 0, ops) if DEBUG == ON: self.output += "cmd: "+ `ops`+"\n" self.executeCommand(ops) return self.output
class Bot: def __init__ (self, tower, row_generator, do_up_down_in = True): self._rhythm = Rhythm (self) self.do_up_down_in = do_up_down_in self.row_generator = row_generator self._tower = tower self._tower.on_thats_all = self._on_thats_all self._tower.on_go = self._on_go self._tower.on_stand_next = self._on_stand_next self._tower.on_look_to = self._on_look_to self._tower.on_bell_ring = self._on_bell_ring self._is_ringing = False self._is_ringing_rounds = True self._should_start_method = False self._should_start_ringing_rounds = False self._should_stand = False self._row_number = 0 self._place = 0 self._row = None # Convenient properties that are frequently used @property def is_handstroke (self): return self._row_number % 2 == 0 @property def stage (self): return self._tower.number_of_bells # Callbacks def _on_look_to (self): self._rhythm.initialise_line (time.time () + 3) self._should_stand = False self._should_start_method = False self._should_start_ringing_rounds = False self._is_ringing = True self._is_ringing_rounds = True self._row_number = 0 self._place = 0 # Expect the bells in rounds for b in range (self.stage): self.expect_bell (b, b) def _on_go (self): if self._is_ringing_rounds: self._should_start_method = True def _on_thats_all (self): self._should_start_ringing_rounds = True def _on_stand_next (self): self._should_stand = True def _on_bell_ring (self, bell, stroke): if self._tower.user_controlled (bell): # This will give us the stroke _after_ the bell rings, we have to invert it, because # otherwise this will always expect the bells on the wrong stroke self._rhythm.on_bell_ring (bell, not stroke, time.time ()) # Mainloop and helper methods def expect_bell (self, index, bell): if self._tower.user_controlled (bell): self._rhythm.expect_bell ( bell, self._rhythm.index_to_blow_time (self._row_number, index), self.is_handstroke ) def start_next_row (self): self._row = [x - 1 for x in self.row_generator.next_row (self.is_handstroke)] for (index, bell) in enumerate (self._row): self.expect_bell (index, bell) def start_method (self): self.row_generator.reset () self.row_generator.set_go () self.start_next_row () def main_loop (self): while True: if self._is_ringing: if time.time () > self._rhythm.index_to_real_time (self._row_number, self._place): bell = self._place if self._is_ringing_rounds else self._row [self._place] if not self._tower.user_controlled (bell): self._tower.ring_bell (bell, self.is_handstroke) self._place += 1 if self._place == self.stage: self._row_number += 1 self._place = 0 if not self._is_ringing_rounds: self.start_next_row () else: for b in range (self.stage): self.expect_bell (b, b) if self._is_ringing_rounds: if self._row_number == 2 and self.do_up_down_in: self._should_start_method = True if self._row_number % 2 == 0: # We're just starting a handstroke if self._should_stand: self._should_stand = False self._is_ringing = False if self._should_start_method and self._is_ringing_rounds: self._should_start_method = False self._is_ringing_rounds = False self.start_method () if self._should_start_ringing_rounds and not self._is_ringing_rounds: self._should_start_ringing_rounds = False self._is_ringing_rounds = True time.sleep (0.01)
class SFM(object): # pitch registers transpositionSemitones = 0 octaveNumber = 3 # tempo registers tempo = 60 currentBeatValue = 60.0 / tempo currentBeat = 0 totalDuration = 0.0 # dynamics registers crescendoSpeed = 1.1 currentCrescendoSpeed = crescendoSpeed crescendoBeatsRemaining = 0.0 maximumAmplitude = 0.0 # tuple registers duration = 60.0 / tempo amplitude = 1.0 decay = 1.0 # I/O input = "" ######################################################### # initialize Note, Rhythm, and Dynamics objects def __init__(self, SCALE): NOTES, FREQ_DICT = SCALE self.note = Note(NOTES, FREQ_DICT) self.rhythm = Rhythm() self.dynamics = Dynamics() self.equalizerFactor = {} self.equalizerFactor[-0.1] = 1.0 self.equalizerFactor[220] = 1.0 self.equalizerFactor[440] = 0.7 self.equalizerFactor[880] = 0.35 self.equalizerFactor[1760] = 0.15 self.equalizerFactor[3520] = 0.15 self.equalizerFactor[7040] = 0.15 self.equalizerFactor[14080] = 0.15 self.equalizerFactor[28160] = 0.15 self.equalizerFactor[56320] = 0.15 self.equalizerBreakPoints = [ -0.1, 220, 440, 880, 1760, 3520, 7040, 14080, 28160, 56320 ] # self.tempo = 60 # self.currentBeatValue = 60.0/self.tempo # self.octaveNumber = 3 def equalize(self, freq): a, b = interval(freq, self.equalizerBreakPoints) f = mapInterval(freq, a, b, self.equalizerFactor[a], self.equalizerFactor[b]) # print freq, a, b, f return f # return tuple as string given frequency, # duration, decay, and amplitude def _tuple(self, freq, duration): output = ` freq ` output += " " + ` duration ` a = self.amplitude a = a * self.equalize(freq) output += " " + ` a ` output += " " + ` self.decay ` return output # return tuple as string from frequency of token # and root and suffix of token def tuple(self, freq, root, suffix): if suffix.find(",") > -1: thisDuration = self.duration * (1 - self.rhythm.breath) output = self._tuple(freq, thisDuration) output += "\n" output += self._tuple(0, self.duration - thisDuration) else: output = self._tuple(freq, self.duration) return output def updateRhythm(self, cmd): self.currentBeatValue, self.duration = self.rhythm.value(cmd, self) def emitNote(self, token): if self.crescendoBeatsRemaining > 0: self.amplitude = self.amplitude * self.currentCrescendoSpeed self.crescendoBeatsRemaining -= self.currentBeatValue freq, root, suffix = self.note.freq(token, self.transpositionSemitones, self.octaveNumber) self.output += self.tuple(freq, root, suffix) + "\n" # summary data self.totalDuration += self.duration self.currentBeat += self.currentBeatValue if self.amplitude > self.maximumAmplitude: self.maximumAmplitude = self.amplitude def executeCommand(self, ops): cmd = ops[0] # if cmd is a rhythm symbol, change value of duration register if self.rhythm.isRhythmOp(cmd): self.updateRhythm(cmd) # if cmd is a tempo command, change value of the tempo register if self.rhythm.isTempoOp(cmd): self.tempo = self.rhythm.tempo[cmd] self.updateRhythm(cmd) if cmd == "tempo": self.tempo = float(ops[1]) self.updateRhythm(cmd) # if cmd is an articulation command, change value of the decay register if self.rhythm.isArticulationOp(cmd): self.decay = self.rhythm.decay[cmd] # if cmd is a dynamics command, change value of the amplitude register if self.dynamics.isDynamicsConstant(cmd): self.amplitude = self.dynamics.value[cmd] # crescendo and decrescendo if cmd == "crescendo" or cmd == "cresc": self.crescendoBeatsRemaining = float(ops[1]) self.currentCrescendoSpeed = self.crescendoSpeed if cmd == "decrescendo" or cmd == "decresc": self.crescendoBeatsRemaining = float(ops[1]) self.currentCrescendoSpeed = 1.0 / self.crescendoSpeed # pitch transposition if cmd == "octave": self.octaveNumber = int(ops[1]) if cmd == "transpose": self.transpositionSemitones = int(ops[1]) # pass special commands through if cmd[0] == '@': CMD = catList2(ops) CMD = CMD[:len(CMD)] + "\n" self.output += CMD # tuples: returns a string of tuples from input = solfa text def tuples(self): # split intput into list of tokens self.input = self.input.replace("\n", " ") tokens = self.input.split(" ") # make sure there are not empty list elements tokens = filter(lambda x: len(x), tokens) # initialize output self.output = "" for token in tokens: if self.note.isNote(token): self.emitNote(token) else: ops = token.split(":") ops = filter(lambda x: len(x) > 0, ops) if DEBUG == ON: self.output += "cmd: " + ` ops ` + "\n" self.executeCommand(ops) return self.output
def valid_title(title): if not Rhythm.all().filter('title =', title).get() and title: return True
import time if __name__ == '__main__': # Create a test song dia = Diatonic(key='C', transpose=Parameter([0, 1], length=8, interp='nearest'), rotate=Parameter([0, 5], length=16, interp='nearest')) notes = Chord(root=Parameter([1, 4, 5], length=4, interp='nearest'), num_notes=1, skip=1) rh1 = Rhythm(steps=[8], pulses=[4, 6, 8], shift=0, bar_length=1, num_notes=3) rh2 = Rhythm(steps=8, pulses=Parameter([5], interp='linear'), shift=0, num_notes=1) vel = Parameter([80, 80, 100], length=2, shift=0, bounds=(80, 100)) dur = Parameter([.2, .2, .3, .4], quantize=.1, length=1, shift=1, bounds=None) clock = Clock(timer=time.time,