# Path: bl/instrument/interfaces.py
# class IMIDIInstrument(Interface):
#     """
#     A MIDI-like instrument supported a minimal subset of MIDI commands.
#     """
# 
#     channel = Attribute("""
#         The MIDI channel or None if this is a virtual MIDI instrument with no
#         real channel assigned.
#         """)
# 
#     def noteon(note, velocity):
#         """
#         Send a "Note On" event with a MIDI note and velocity ("loudness").
# 
#         @param note: The note [0,127]
#         @param velocity: The velocity [0,127]
#         """
# 
#     def noteoff(note):
#         """
#         Send a "Note Off" event with a MIDI note.
# 
#         @param note: The note [0,127]
#         """
# 
#     def chordon(chord, velocity):
#         """
#         Call noteon(note, velocity) for each note in chord.
# 
#         @param chord: The notes (list)
#         @param velocity: The velocity for the chord.
#         """
# 
#     def chordoff(chord):
#         """
#         Call noteoff(note) for each note in chord.
# 
#         @param chord: The notes (list)
#         """
# 
#     def controlChange(vibrato=None, pan=None, expression=None, sustain=None,
#                       reverb=None, chorus=None, **other):
#         """
#         Send a "Control Change" (CC) event. The implementation may support 0 to
#         all of the predefined controls.
# 
#         @param vibrato: vibrato (Control #76) [0,127]
#         @param pan: pan (Control #10) [0,127]
#         @param expression: expression (Control #11) [0,127]
#         @param sustain: sustain/pedal (Control #64) [0,127]
#         @param reverb: reverb effect (Control #91) [0,127]
#         @param chorus: chorus effect (Control #93) [0,127]
#         @param other: Other control keyword arguments (naming may vary by
#         implementation)
#         """
# 
#     def pitchBend(value):
#         """
#         Send a "Pitch Bend" event.
# 
#         @param value: The pitch bend amount [0,127]
#         """
# 
# Path: bl/instrument/fsynth.py
# class SynthRouter:
# class SynthPool:
# class ChordPlayerMixin(object):
# class Recorder(object):
# class Instrument(ChordPlayerMixin):
# class MultiInstrument(ChordPlayerMixin):
# class Layer(ChordPlayerMixin):
#     def __init__(self, *p, **synth_factories):
#     def __getitem__(self, key):
#     def __init__(self, router, reactor=None, audiodev=None):
#     def bindSettings(self, connection, gain=0.5, samplerate=44100):
#     def startSynths(self):
#     def synthObject(self, connection='mono'):
#             def seq():
#     def loadSoundFont(self, synth, sf2path, channel=None, bank=0, preset=0):
#     def connectInstrument(self, synth, instr, sfpath=None,
#                          channel=None, bank=0, preset=0, sfid=None):
# def MonoPool():
# def StereoPool():
# def QuadPool():
# def NConnectionPool(*p, **synth_factories):
#     def strum(self, notes, velocity=80):
#     def chordon(self, notes, velocity=80):
#     def chordoff(self, notes):
#     def stopall(self):
#     def __init__(self, clock=None):
#     def __call__(self, object, commandname, **arguments):
#     def __str__(self):
#     def toDict(self):
#     def __init__(self, sfpath, synth=None, connection='mono',
#                  channel=None, bank=0, preset=0, pool=None, clock=None):
#     def __str__(self):
#     def registerSoundfont(self, sfid, channel):
#     def cap(self, maxVelocity):
#     def noteon(self, note, velocity=80):
#     def noteoff(self, note):
#     def controlChange(self, vibrato=None, pan=None, expression=None,
#                       sustain=None, reverb=None, chorus=None, **ignored):
#     def pitchBend(self, value):
#     def __init__(self, instrumentMapping, strict=True):
#     def noteon(self, note, velocity=80):
#     def noteoff(self, note):
#     def __init__(self, instruments):
#     def noteon(self, note, velocity=80):
#     def noteoff(self, note):
# def suggestDefaultPool(pool):
# CC_VIBRATO = 1
# CC_VOLUME = 7
# CC_PAN = 10
# CC_EXPRESSION = 11
# CC_SUSTAIN = 64
# CC_REVERB = 91
# CC_CHORUS = 93
#     MIDI = dict([[n, n] for n in range(128)])


from zope.interface.verify import verifyClass, verifyObject
from twisted.trial.unittest import TestCase
from bl.instrument.interfaces import IMIDIInstrument
from bl.instrument import fsynth
import synthmodule
        instr = TestInstrument()
        self.pool.connectInstrument(synth, instr, sfid=99)
        self.assertEquals(instr.sfid, 99)
        self.assertEquals(instr.channel, 0)

    def test_connectInstrumentWithChannel(self):
        synth = self.pool.synthObject()
        instr = TestInstrument()
        self.pool.connectInstrument(synth, instr, sfid=99, channel=7)
        self.assertEquals(instr.sfid, 99)
        self.assertEquals(instr.channel, 7)
        instr = TestInstrument()
        self.pool.connectInstrument(synth, instr, channel=7)
        self.assertEquals(instr.sfid, 0)
        self.assertEquals(instr.channel, 7)


class InstrumentTests(TestCase):

    def setUp(self):
        self.patch(fsynth, 'Synth', Synth)
        defaultPool = fsynth.defaultPool
        self.addCleanup(fsynth.suggestDefaultPool, defaultPool)
        fsynth.suggestDefaultPool(fsynth.StereoPool())

    def tearDown(self):
        synthmodule.nextid = synthmodule._nextid(0)

    def test_iface(self):
        verifyClass(IMIDIInstrument, Instrument)

# Path: bl/instrument/interfaces.py
# class IMIDIInstrument(Interface):
#     """
#     A MIDI-like instrument supported a minimal subset of MIDI commands.
#     """
# 
#     channel = Attribute("""
#         The MIDI channel or None if this is a virtual MIDI instrument with no
#         real channel assigned.
#         """)
# 
#     def noteon(note, velocity):
#         """
#         Send a "Note On" event with a MIDI note and velocity ("loudness").
# 
#         @param note: The note [0,127]
#         @param velocity: The velocity [0,127]
#         """
# 
#     def noteoff(note):
#         """
#         Send a "Note Off" event with a MIDI note.
# 
#         @param note: The note [0,127]
#         """
# 
#     def chordon(chord, velocity):
#         """
#         Call noteon(note, velocity) for each note in chord.
# 
#         @param chord: The notes (list)
#         @param velocity: The velocity for the chord.
#         """
# 
#     def chordoff(chord):
#         """
#         Call noteoff(note) for each note in chord.
# 
#         @param chord: The notes (list)
#         """
# 
#     def controlChange(vibrato=None, pan=None, expression=None, sustain=None,
#                       reverb=None, chorus=None, **other):
#         """
#         Send a "Control Change" (CC) event. The implementation may support 0 to
#         all of the predefined controls.
# 
#         @param vibrato: vibrato (Control #76) [0,127]
#         @param pan: pan (Control #10) [0,127]
#         @param expression: expression (Control #11) [0,127]
#         @param sustain: sustain/pedal (Control #64) [0,127]
#         @param reverb: reverb effect (Control #91) [0,127]
#         @param chorus: chorus effect (Control #93) [0,127]
#         @param other: Other control keyword arguments (naming may vary by
#         implementation)
#         """
# 
#     def pitchBend(value):
#         """
#         Send a "Pitch Bend" event.
# 
#         @param value: The pitch bend amount [0,127]
#         """
# 
# Path: bl/instrument/fsynth.py
# class SynthRouter:
# class SynthPool:
# class ChordPlayerMixin(object):
# class Recorder(object):
# class Instrument(ChordPlayerMixin):
# class MultiInstrument(ChordPlayerMixin):
# class Layer(ChordPlayerMixin):
#     def __init__(self, *p, **synth_factories):
#     def __getitem__(self, key):
#     def __init__(self, router, reactor=None, audiodev=None):
#     def bindSettings(self, connection, gain=0.5, samplerate=44100):
#     def startSynths(self):
#     def synthObject(self, connection='mono'):
#             def seq():
#     def loadSoundFont(self, synth, sf2path, channel=None, bank=0, preset=0):
#     def connectInstrument(self, synth, instr, sfpath=None,
#                          channel=None, bank=0, preset=0, sfid=None):
# def MonoPool():
# def StereoPool():
# def QuadPool():
# def NConnectionPool(*p, **synth_factories):
#     def strum(self, notes, velocity=80):
#     def chordon(self, notes, velocity=80):
#     def chordoff(self, notes):
#     def stopall(self):
#     def __init__(self, clock=None):
#     def __call__(self, object, commandname, **arguments):
#     def __str__(self):
#     def toDict(self):
#     def __init__(self, sfpath, synth=None, connection='mono',
#                  channel=None, bank=0, preset=0, pool=None, clock=None):
#     def __str__(self):
#     def registerSoundfont(self, sfid, channel):
#     def cap(self, maxVelocity):
#     def noteon(self, note, velocity=80):
#     def noteoff(self, note):
#     def controlChange(self, vibrato=None, pan=None, expression=None,
#                       sustain=None, reverb=None, chorus=None, **ignored):
#     def pitchBend(self, value):
#     def __init__(self, instrumentMapping, strict=True):
#     def noteon(self, note, velocity=80):
#     def noteoff(self, note):
#     def __init__(self, instruments):
#     def noteon(self, note, velocity=80):
#     def noteoff(self, note):
# def suggestDefaultPool(pool):
# CC_VIBRATO = 1
# CC_VOLUME = 7
# CC_PAN = 10
# CC_EXPRESSION = 11
# CC_SUSTAIN = 64
# CC_REVERB = 91
# CC_CHORUS = 93
#     MIDI = dict([[n, n] for n in range(128)])


# Path: bl/instrument/tests/test_fsynth.py
from zope.interface.verify import verifyClass, verifyObject
from twisted.trial.unittest import TestCase
from bl.instrument.interfaces import IMIDIInstrument
from bl.instrument import fsynth
import synthmodule

        instr = TestInstrument()
        self.pool.connectInstrument(synth, instr, sfid=99)
        self.assertEquals(instr.sfid, 99)
        self.assertEquals(instr.channel, 0)

    def test_connectInstrumentWithChannel(self):
        synth = self.pool.synthObject()
        instr = TestInstrument()
        self.pool.connectInstrument(synth, instr, sfid=99, channel=7)
        self.assertEquals(instr.sfid, 99)
        self.assertEquals(instr.channel, 7)
        instr = TestInstrument()
        self.pool.connectInstrument(synth, instr, channel=7)
        self.assertEquals(instr.sfid, 0)
        self.assertEquals(instr.channel, 7)


class InstrumentTests(TestCase):

    def setUp(self):
        self.patch(fsynth, 'Synth', Synth)
        defaultPool = fsynth.defaultPool
        self.addCleanup(fsynth.suggestDefaultPool, defaultPool)
        fsynth.suggestDefaultPool(fsynth.StereoPool())

    def tearDown(self):
        synthmodule.nextid = synthmodule._nextid(0)

    def test_iface(self):
        verifyClass(IMIDIInstrument, Instrument)

        verifyObject(IMIDIInstrument, Instrument('sf2/instrument.sf2'))