# Path: bl/orchestra/midi.py
# class Player(OneSchedulePlayerMixin):
# 
#     onMethodName = 'noteon'
#     offMethodName = 'noteoff'
# 
#     def __init__(self, instr, note, velocity=None, release=None,
#                  interval=(1, 8), time=None, clock=None, cc=None):
#         """
#         @param note: A ugen for notes
#         @param velocity: A ugen for the velocity
#         @param release: A ugen for the release (amount of time before calling
#         noteoff)
#         @param time: A ugen for relative time (values returned must be greater
#         than or equal to previously returned value - monotonically increasing)
#         @param interval: An interval division (e.g. C{(1, 4)}) that may be
#         specified as an alternative to time--this creates a metronome with the
#         given interval.
#         @param cc: C{dict} of control-change ugens.
#         @param clock: A L{BeatClock} (defaults to global default clock)
#         """
#         self.instr = IMIDIInstrument(instr)
#         self.clock = getClock(clock)
#         if velocity is None:
#             velocity = cycle([127]).next
#         if release is None:
#             release = cycle([None]).next
#         self.note = note
#         self.velocity = velocity
#         self.release = release
#         self.cc = cc
#         self.time = timing(self.clock, time, interval)
#         noteMemo = CallMemo(lambda: self.note())
#         noteonSchedule = schedule(self.time, self.noteon,
#                                   {'note': noteMemo,
#                                    'velocity': (lambda: self.velocity())})
#         self.schedulePlayer = SchedulePlayer(noteonSchedule, self.clock)
#         releaseChild = childSchedule(self._scheduleNoteoff,
#                                  {'note': noteMemo.lastValue,
#                                   'when': (lambda: self.release())})
#         self.schedulePlayer.addChild(releaseChild)
#         if cc:
#             ccChild = childSchedule(self.instr.controlChange, self.cc)
#             self.schedulePlayer.addChild(ccChild)
# 
#     def noteon(self, note, velocity):
#         m = getattr(self.instr, self.onMethodName)
#         return m(note, velocity)
# 
#     def noteoff(self, note):
#         m = getattr(self.instr, self.offMethodName)
#         return m(note)
# 
#     def _scheduleNoteoff(self, note, when):
#         if when is None:
#             return
#         self.clock.callLater(when, self.noteoff, note)
# 
# Path: bl/arp.py
# class OrderedArp(IndexedArp):
# 
#     def sort(self, values):
#         return values


from zope.interface import implements, Interface, Attribute
from bl.orchestra.midi import Player
from bl.arp import OrderedArp
import itertools
    """
    q = ticksPerBeat / 24.
    name = '%s_TPB%s' % (rudimentClass.__name__, ticksPerBeat)
    if name not in _rudiment_classes:
        _rudiment_classes[name] = klass = type(name, (rudimentClass,), {})
        klass.defaultDivisionLength = int(q * klass.defaultDivisionLength)
    return _rudiment_classes[name]


class RudimentSchedulePlayer(Player):
    """
    A schedule player for a rudiment. This also gives us arps to manipulate
    or change during the runtime.

    noteArp: The note arp (OrderedArp)
    velocityArp: The velocity arp (OrderedArp)
    sustainArp: the sustain arp (OrderedArp)
    """

    def __init__(self, instrument, rudiment, r, l, release=None, **kw):
        """
        @param instrument: The backend instrument (Fsynth instrument etc)
        @param rudiment: A IRudiment provider
        @param r: The "right" note
        @param l: the "left" note
        @param sustainArp: An optional "sustain" value arp.
        """
        self.rudiment = rudiment
        time = rudiment.time(cycle=True).next
        note = OrderedArp(list(rudiment.strokes(r, l, cycle=False)))

# Path: bl/orchestra/midi.py
# class Player(OneSchedulePlayerMixin):
# 
#     onMethodName = 'noteon'
#     offMethodName = 'noteoff'
# 
#     def __init__(self, instr, note, velocity=None, release=None,
#                  interval=(1, 8), time=None, clock=None, cc=None):
#         """
#         @param note: A ugen for notes
#         @param velocity: A ugen for the velocity
#         @param release: A ugen for the release (amount of time before calling
#         noteoff)
#         @param time: A ugen for relative time (values returned must be greater
#         than or equal to previously returned value - monotonically increasing)
#         @param interval: An interval division (e.g. C{(1, 4)}) that may be
#         specified as an alternative to time--this creates a metronome with the
#         given interval.
#         @param cc: C{dict} of control-change ugens.
#         @param clock: A L{BeatClock} (defaults to global default clock)
#         """
#         self.instr = IMIDIInstrument(instr)
#         self.clock = getClock(clock)
#         if velocity is None:
#             velocity = cycle([127]).next
#         if release is None:
#             release = cycle([None]).next
#         self.note = note
#         self.velocity = velocity
#         self.release = release
#         self.cc = cc
#         self.time = timing(self.clock, time, interval)
#         noteMemo = CallMemo(lambda: self.note())
#         noteonSchedule = schedule(self.time, self.noteon,
#                                   {'note': noteMemo,
#                                    'velocity': (lambda: self.velocity())})
#         self.schedulePlayer = SchedulePlayer(noteonSchedule, self.clock)
#         releaseChild = childSchedule(self._scheduleNoteoff,
#                                  {'note': noteMemo.lastValue,
#                                   'when': (lambda: self.release())})
#         self.schedulePlayer.addChild(releaseChild)
#         if cc:
#             ccChild = childSchedule(self.instr.controlChange, self.cc)
#             self.schedulePlayer.addChild(ccChild)
# 
#     def noteon(self, note, velocity):
#         m = getattr(self.instr, self.onMethodName)
#         return m(note, velocity)
# 
#     def noteoff(self, note):
#         m = getattr(self.instr, self.offMethodName)
#         return m(note)
# 
#     def _scheduleNoteoff(self, note, when):
#         if when is None:
#             return
#         self.clock.callLater(when, self.noteoff, note)
# 
# Path: bl/arp.py
# class OrderedArp(IndexedArp):
# 
#     def sort(self, values):
#         return values


# Path: bl/rudiments.py
from zope.interface import implements, Interface, Attribute
from bl.orchestra.midi import Player
from bl.arp import OrderedArp
import itertools

    """
    q = ticksPerBeat / 24.
    name = '%s_TPB%s' % (rudimentClass.__name__, ticksPerBeat)
    if name not in _rudiment_classes:
        _rudiment_classes[name] = klass = type(name, (rudimentClass,), {})
        klass.defaultDivisionLength = int(q * klass.defaultDivisionLength)
    return _rudiment_classes[name]


class RudimentSchedulePlayer(Player):
    """
    A schedule player for a rudiment. This also gives us arps to manipulate
    or change during the runtime.

    noteArp: The note arp (OrderedArp)
    velocityArp: The velocity arp (OrderedArp)
    sustainArp: the sustain arp (OrderedArp)
    """

    def __init__(self, instrument, rudiment, r, l, release=None, **kw):
        """
        @param instrument: The backend instrument (Fsynth instrument etc)
        @param rudiment: A IRudiment provider
        @param r: The "right" note
        @param l: the "left" note
        @param sustainArp: An optional "sustain" value arp.
        """
        self.rudiment = rudiment
        time = rudiment.time(cycle=True).next
        note = OrderedArp(list(rudiment.strokes(r, l, cycle=False)))

        velocity = OrderedArp(list(rudiment.velocity(cycle=False)))