def __call__(self, ev): now = _engine.time() # remove old notes from the lists if hold_time has elapsed for k, t in list(self.notes_lower.items()): if t and t < now - self.hold_time: del self.notes_lower[k] for k, t in list(self.notes_upper.items()): if t and t < now - self.hold_time: del self.notes_upper[k] # the lower reference point is the highest note played in the region # below the split point, but never below the lower threshold by more # than the set margin lower = self.threshold_lower - self.margin_lower if len(self.notes_lower): m = max(self.notes_lower) lower = max(m, lower) # the upper reference point is the lowest note played in the region # above the split point, but never above the upper threshold by more # than the set margin upper = self.threshold_upper + self.margin_upper if len(self.notes_upper): m = min(self.notes_upper) upper = min(m, upper) # calculate new threshold as the center between upper and lower # reference point, but confined by the given thresholds self.threshold = min(max((lower + upper + 1) // 2, self.threshold_lower), self.threshold_upper) if ev.type == _m.NOTEON: # add notes to the appropriate list if ev.note < self.threshold: self.notes_lower[ev.note] = 0 else: self.notes_upper[ev.note] = 0 elif ev.type == _m.NOTEOFF: # mark notes for removal if ev.note in self.notes_lower: self.notes_lower[ev.note] = now if ev.note in self.notes_upper: self.notes_upper[ev.note] = now return ev
def __call__(self, ev): now = _engine.time() # remove old notes from the lists if hold_time has elapsed for k, t in list(self.notes_lower.items()): if t and t < now - self.hold_time: del self.notes_lower[k] for k, t in list(self.notes_upper.items()): if t and t < now - self.hold_time: del self.notes_upper[k] # the lower reference point is the highest note played in the region # below the split point, but never below the lower threshold by more # than the set margin lower = self.threshold_lower - self.margin_lower if len(self.notes_lower): m = max(self.notes_lower) lower = max(m, lower) # the upper reference point is the lowest note played in the region # above the split point, but never above the upper threshold by more # than the set margin upper = self.threshold_upper + self.margin_upper if len(self.notes_upper): m = min(self.notes_upper) upper = min(m, upper) # calculate new threshold as the center between upper and lower # reference point, but confined by the given thresholds self.threshold = min( max((lower + upper + 1) // 2, self.threshold_lower), self.threshold_upper) if ev.type == _m.NOTEON: # add notes to the appropriate list if ev.note < self.threshold: self.notes_lower[ev.note] = 0 else: self.notes_upper[ev.note] = 0 elif ev.type == _m.NOTEOFF: # mark notes for removal if ev.note in self.notes_lower: self.notes_lower[ev.note] = now if ev.note in self.notes_upper: self.notes_upper[ev.note] = now return ev
def __call__(self, ev): t = _engine.time() if ev.type == _m.NOTEON: # store new note, its velocity, and its time self.notes[ev.note] = (ev.velocity, t) elif ev.type == _m.NOTEOFF: # delete released note try: del self.notes[ev.note] except KeyError: # ignore unmatched note-offs (just in case...) pass sorted_notes = sorted(self.notes.keys()) if len(sorted_notes): try: n = sorted_notes[self.voice] d = False except IndexError: # use the next best note: # lowest for negative index, otherwise highest n = sorted_notes[0 if self.voice < 0 else -1] d = True else: n = None d = False dt = ((t - self.notes[self.current_note][1]) if self.current_note in self.notes else 0.0) # change current note if... if ( # note number changed and... n != self.current_note and ( # we're always retriggering notes self.retrigger or # lowest/heighest voice are a bit of a special case self.voice in (0, -1) or # current note is no longer held self.current_note not in self.notes or # our previous note is very recent (ev.type == _m.NOTEON and dt < self.time) or # the new note is "better" than previous one self.diverted and not d)): # yield note-off for previous note (if any) if self.current_note: yield _event.NoteOffEvent(ev.port, ev.channel, self.current_note, 0) self.current_note = None dt = (t - self.notes[n][1]) if n in self.notes else 0.0 # yield note-on for new note (if any) if n is not None and ( # this is the note being played right now ev.note == n or # we're retriggering whenever a key is pressed or released self.retrigger or # our previous note is very recent dt < self.time): yield _event.NoteOnEvent(ev.port, ev.channel, n, self.notes[n][0]) self.current_note = n self.diverted = d
def __call__(self, ev): t = _engine.time() if ev.type == _m.NOTEON: # store new note, its velocity, and its time self.notes[ev.note] = (ev.velocity, t) elif ev.type == _m.NOTEOFF: # delete released note del self.notes[ev.note] sorted_notes = sorted(self.notes.keys()) if len(sorted_notes): try: n = sorted_notes[self.voice] d = False except IndexError: # use the next best note: # lowest for negative index, otherwise highest n = sorted_notes[0 if self.voice < 0 else -1] d = True else: n = None d = False dt = ((t - self.notes[self.current_note][1]) if self.current_note in self.notes else 0.0) # change current note if... if ( # note number changed and... n != self.current_note and ( # we're always retriggering notes self.retrigger or # lowest/heighest voice are a bit of a special case self.voice in (0, -1) or # current note is no longer held self.current_note not in self.notes or # our previous note is very recent (ev.type == _m.NOTEON and dt < self.time) or # the new note is "better" than previous one self.diverted and not d )): # yield note-off for previous note (if any) if self.current_note: yield _event.NoteOffEvent( ev.port, ev.channel, self.current_note, 0) self.current_note = None dt = (t - self.notes[n][1]) if n in self.notes else 0.0 # yield note-on for new note (if any) if n is not None and ( # this is the note being played right now ev.note == n or # we're retriggering whenever a key is pressed or released self.retrigger or # our previous note is very recent dt < self.time ): yield _event.NoteOnEvent( ev.port, ev.channel, n, self.notes[n][0]) self.current_note = n self.diverted = d