# Path: mididings/extra/per_channel.py
# class PerChannel(object):
#     """
#     Utility class, usable with Process() and Call(), that delegates events
#     to different instances of the same class, using one instance per
#     channel/port combination.
#     New instances are created as needed, using the given factory function,
#     when the first event with a new channel/port arrives.
#     """
#     def __init__(self, factory):
#         self.channel_proc = {}
#         self.factory = factory
# 
#     def __call__(self, ev):
#         k = (ev.port, ev.channel)
#         if k not in self.channel_proc:
#             self.channel_proc[k] = self.factory()
#         return self.channel_proc[k](ev)


import mididings as _m
import mididings.event as _event
import mididings.util as _util
from mididings.extra.per_channel import PerChannel as _PerChannel
                # monophonic: turn off previous note, play new note
                if len(self.notes):
                    r = [_event.NoteOffEvent(
                                    ev.port, ev.channel, self.notes[0], 0)]
                else:
                    r = []
                self.notes = [ev.note]
                return r + [ev]

        elif ev.type == _m.NOTEOFF:
            # ignore all note-off events
            return None


def LatchNotes(polyphonic=False, reset=None):
    """
    Makes notes latching, so they will keep playing when the key is
    released.

    :param polyphonic:
        If true, each note can be stopped individually by pressing the
        corresponding key again.
        Otherwise pressing a key will automatically turn off any previous
        notes.

    :param reset:
        a note (name/number) that acts as a reset key, stopping all
        currently playing notes.
    """
    return (_m.Filter(_m.NOTE) %

# Path: mididings/extra/per_channel.py
# class PerChannel(object):
#     """
#     Utility class, usable with Process() and Call(), that delegates events
#     to different instances of the same class, using one instance per
#     channel/port combination.
#     New instances are created as needed, using the given factory function,
#     when the first event with a new channel/port arrives.
#     """
#     def __init__(self, factory):
#         self.channel_proc = {}
#         self.factory = factory
# 
#     def __call__(self, ev):
#         k = (ev.port, ev.channel)
#         if k not in self.channel_proc:
#             self.channel_proc[k] = self.factory()
#         return self.channel_proc[k](ev)


# Path: mididings/extra/latch.py
import mididings as _m
import mididings.event as _event
import mididings.util as _util
from mididings.extra.per_channel import PerChannel as _PerChannel

                # monophonic: turn off previous note, play new note
                if len(self.notes):
                    r = [_event.NoteOffEvent(
                                    ev.port, ev.channel, self.notes[0], 0)]
                else:
                    r = []
                self.notes = [ev.note]
                return r + [ev]

        elif ev.type == _m.NOTEOFF:
            # ignore all note-off events
            return None


def LatchNotes(polyphonic=False, reset=None):
    """
    Makes notes latching, so they will keep playing when the key is
    released.

    :param polyphonic:
        If true, each note can be stopped individually by pressing the
        corresponding key again.
        Otherwise pressing a key will automatically turn off any previous
        notes.

    :param reset:
        a note (name/number) that acts as a reset key, stopping all
        currently playing notes.
    """
    return (_m.Filter(_m.NOTE) %

                _m.Process(_PerChannel(