Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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