# Path: bl/ugen.py
# R = Random
# 
# N = _Nothing()
# 
# 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/scheduler.py
# class Tempo(object):
# class Beat(_BeatBase):
# class Meter(object):
# class SynthControllerMixin(object):
# class BeatClock(SelectReactor, SynthControllerMixin):
# class ScheduledEvent(object):
#     def __init__(self, bpm=120, tpb=24):
#     def reset(self, bpm=None, tpb=None, tpm=None):
#     def __str__(self):
#     def __repr__(self):
#     def __init__(self, length=4, division=4, number=1, tempo=TEMPO_120_24):
#     def resetTempo(self, tempo):
#     def beat(self, ticks):
#     def ticks(self, ticks):
#     def divisionToTicks(self, n, d):
#     def nextDivision(self, ticks, n, d):
#     def nextMeasure(self, ticks, measures=1):
#     def untilNextMeasure(self, ticks, measures=1):
#     def measure(self, ticks):
#     def __repr__(self):
#     def __hash__(self):
#     def __init__(self, tempo=TEMPO_120_24, meter=None, meters=(), reactor=None,
#                  syncClockClass=None, default=False):
#     def setTempo(self, tempo):
#     def run(self):
#     def _initBackends(self):
#     def startTicking(self):
#     def tick(self):
#     def _syncToTick(self, tick, ts):
#     def seconds(self):
#     def schedule(self, _f, *args, **kwargs):
#     def callWhenRunning(self, *a, **kw):
#     def untilNextMeasure(self, measures=0):
#     def callAfterMeasures(self, measures, f, *a, **kw):
#     def nudge(self, pause=0.1):
#     def __init__(self, clock, _f, *args, **kwargs):
#     def startAfterTicks(self, ticks, interval):
#         def _start():
#     def startAfter(self, divisions=(1, 1), interval=(1, 4)):
#     def _divisions(self, divisions):
#     def start(self, ticks=None, now=True):
#         def _start():
#     def stopAfterTicks(self, ticks):
#         def _schedule_stop():
#             def _stop():
#     def stopAfter(self, divisions=(1, 1)):
#     def stop(self):
# TEMPO_120_24 = Tempo()
# STANDARD_TICKS_PER_MEASURE = 96
# 
# Path: tutor/complib.py
# _HERE = os.path.dirname(__file__)
# def sf2(sf2name):
# def kitFactory(kit_name):
#     def f(connection='mono'):


import random
from itertools import cycle
from bl.ugen import R, N
from bl.orchestra.midi import Player
from bl.scheduler import clock
from tutor.complib import piano_f
# Sprechenreit explains to you that Players can take a generator of
# numbers for both notes and velocities and then you don't have to
# work with the lower-level BeatClock interface. "Es ist zher super abstraction
# layer!!"
#
# First let's start by making a generator for our notes. Sprechereit also
# points out the R or Random function which creates a callable that returns
# some random value for the arguments we provide; yes, just a partial of
# random.choice(), if you care. Also N is special function to represent and
# return None (this translates to a pause in playing).

notes = cycle([R(60, 64, 67, 69), R(36, 48, 60, N), R(48, 52, 55),
               R(36, 40, 43, 45)]).next


# Next we'll create a callable for our velocity.

velocity = cycle([120, 80, 89, 83]).next


# Finally let's create a Player whick takes as its arguments (amongst, some
# other things), the notes generator and veocity functions from above. The
# argument stop is function which returns a "release" time (for stop notes
# played). The interval is the interval between note plays.

player = Player(piano, notes, velocity,
                release=(random.randint(12, 48) for i in cycle([1])).next,
                interval=dtt(1,8))



# Path: bl/ugen.py
# R = Random
# 
# N = _Nothing()
# 
# 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/scheduler.py
# class Tempo(object):
# class Beat(_BeatBase):
# class Meter(object):
# class SynthControllerMixin(object):
# class BeatClock(SelectReactor, SynthControllerMixin):
# class ScheduledEvent(object):
#     def __init__(self, bpm=120, tpb=24):
#     def reset(self, bpm=None, tpb=None, tpm=None):
#     def __str__(self):
#     def __repr__(self):
#     def __init__(self, length=4, division=4, number=1, tempo=TEMPO_120_24):
#     def resetTempo(self, tempo):
#     def beat(self, ticks):
#     def ticks(self, ticks):
#     def divisionToTicks(self, n, d):
#     def nextDivision(self, ticks, n, d):
#     def nextMeasure(self, ticks, measures=1):
#     def untilNextMeasure(self, ticks, measures=1):
#     def measure(self, ticks):
#     def __repr__(self):
#     def __hash__(self):
#     def __init__(self, tempo=TEMPO_120_24, meter=None, meters=(), reactor=None,
#                  syncClockClass=None, default=False):
#     def setTempo(self, tempo):
#     def run(self):
#     def _initBackends(self):
#     def startTicking(self):
#     def tick(self):
#     def _syncToTick(self, tick, ts):
#     def seconds(self):
#     def schedule(self, _f, *args, **kwargs):
#     def callWhenRunning(self, *a, **kw):
#     def untilNextMeasure(self, measures=0):
#     def callAfterMeasures(self, measures, f, *a, **kw):
#     def nudge(self, pause=0.1):
#     def __init__(self, clock, _f, *args, **kwargs):
#     def startAfterTicks(self, ticks, interval):
#         def _start():
#     def startAfter(self, divisions=(1, 1), interval=(1, 4)):
#     def _divisions(self, divisions):
#     def start(self, ticks=None, now=True):
#         def _start():
#     def stopAfterTicks(self, ticks):
#         def _schedule_stop():
#             def _stop():
#     def stopAfter(self, divisions=(1, 1)):
#     def stop(self):
# TEMPO_120_24 = Tempo()
# STANDARD_TICKS_PER_MEASURE = 96
# 
# Path: tutor/complib.py
# _HERE = os.path.dirname(__file__)
# def sf2(sf2name):
# def kitFactory(kit_name):
#     def f(connection='mono'):


# Path: tutor/song2.py
import random
from itertools import cycle
from bl.ugen import R, N
from bl.orchestra.midi import Player
from bl.scheduler import clock
from tutor.complib import piano_f

# Sprechenreit explains to you that Players can take a generator of
# numbers for both notes and velocities and then you don't have to
# work with the lower-level BeatClock interface. "Es ist zher super abstraction
# layer!!"
#
# First let's start by making a generator for our notes. Sprechereit also
# points out the R or Random function which creates a callable that returns
# some random value for the arguments we provide; yes, just a partial of
# random.choice(), if you care. Also N is special function to represent and
# return None (this translates to a pause in playing).

notes = cycle([R(60, 64, 67, 69), R(36, 48, 60, N), R(48, 52, 55),
               R(36, 40, 43, 45)]).next


# Next we'll create a callable for our velocity.

velocity = cycle([120, 80, 89, 83]).next


# Finally let's create a Player whick takes as its arguments (amongst, some
# other things), the notes generator and veocity functions from above. The
# argument stop is function which returns a "release" time (for stop notes
# played). The interval is the interval between note plays.

player = Player(piano, notes, velocity,
                release=(random.randint(12, 48) for i in cycle([1])).next,
                interval=dtt(1,8))



player.resumePlaying()