Example #1
0
    def testTuningProgram(self):
        #import pdb; pdb.set_trace()
        program = 10
        channel = 0
        MyMIDI = MIDIFile(1)
        MyMIDI.changeTuningProgram(0, 0, 0, program)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type,
                         'ControllerEvent')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x65)  # Controller Number
        self.assertEqual(data.unpack_into_byte(3), 0x0)  # Controller Value
        self.assertEqual(data.unpack_into_byte(4), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(5), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(6), 0x64)  # Controller Number
        self.assertEqual(data.unpack_into_byte(7), 0x03)  # Controller Value
        self.assertEqual(data.unpack_into_byte(8), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(9), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(10), 0x06)  # Bank MSB
        self.assertEqual(data.unpack_into_byte(11), 0x00)  # Value
        self.assertEqual(data.unpack_into_byte(12), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(13), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(14), 0x26)  # Bank LSB
        self.assertEqual(data.unpack_into_byte(15),
                         program)  # Bank value (bank number)
Example #2
0
    def testPitchWheel(self):

        val = 1000
        MyMIDI = MIDIFile(1)
        MyMIDI.addPitchWheelEvent(0, 0, 0, val)
        MyMIDI.close()

        MSB = (val + 8192) >> 7
        LSB = (val + 8192) & 0x7F

        data = Decoder(MyMIDI.tracks[1].MIDIdata)
        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 224)  # Code
        self.assertEqual(data.unpack_into_byte(2), LSB)
        self.assertEqual(data.unpack_into_byte(3), MSB)

        val = -1000
        MyMIDI = MIDIFile(1)
        MyMIDI.addPitchWheelEvent(0, 0, 0, val)
        MyMIDI.close()

        MSB = (val + 8192) >> 7
        LSB = (val + 8192) & 0x7F

        data = Decoder(MyMIDI.tracks[1].MIDIdata)
        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 224)  # Code
        self.assertEqual(data.unpack_into_byte(2), LSB)
        self.assertEqual(data.unpack_into_byte(3), MSB)
Example #3
0
    def testTuningBank(self):
        bank = 1
        channel = 0
        MyMIDI = MIDIFile(1)
        MyMIDI.changeTuningBank(0, 0, 0, bank)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'ControllerEvent')

        self.assertEqual(data.unpack_into_byte(0), 0x00)                # time
        self.assertEqual(data.unpack_into_byte(1), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x65)                # Controller Number
        self.assertEqual(data.unpack_into_byte(3), 0x0)                 # Controller Value
        self.assertEqual(data.unpack_into_byte(4), 0x00)                # time
        self.assertEqual(data.unpack_into_byte(5), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(6), 0x64)                # Controller Number
        self.assertEqual(data.unpack_into_byte(7), 0x4)                 # Controller Value
        self.assertEqual(data.unpack_into_byte(8), 0x00)                # time
        self.assertEqual(data.unpack_into_byte(9), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(10), 0x06)               # Bank MSB
        self.assertEqual(data.unpack_into_byte(11), 0x00)               # Value
        self.assertEqual(data.unpack_into_byte(12), 0x00)               # time
        self.assertEqual(data.unpack_into_byte(13), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(14), 0x26)                # Bank LSB
        self.assertEqual(data.unpack_into_byte(15), bank)                # Bank value (bank number)
Example #4
0
    def testText(self):
        #import pdb; pdb.set_trace()
        text = "2016(C) MCW"
        MyMIDI = MIDIFile(1)
        MyMIDI.addText(0, 0, text)
        MyMIDI.close()

        payload_encoded = text.encode("ISO-8859-1")
        payloadLength = len(payload_encoded)
        payloadLengthVar = writeVarLength(payloadLength)

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'Text')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xff)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x01)  # Subcode
        index = 3
        for i in range(len(payloadLengthVar)):
            self.assertEqual(data.unpack_into_byte(index), payloadLengthVar[i])
            index = index + 1
        for i in range(len(payload_encoded)):
            if sys.version_info < (3, ):
                test_char = ord(payload_encoded[i])
            else:
                test_char = payload_encoded[i]
            self.assertEqual(data.unpack_into_byte(index), test_char)
            index = index + 1
Example #5
0
    def testTuning(self):
        MyMIDI = MIDIFile(1)
        MyMIDI.changeNoteTuning(0, [(1, 440), (2, 880)])
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type,
                         'UniversalSysEx')

        self.assertEqual(data.unpack_into_byte(0), 0x00)
        self.assertEqual(data.unpack_into_byte(1), 0xf0)
        self.assertEqual(data.unpack_into_byte(2), 15)
        self.assertEqual(data.unpack_into_byte(3), 0x7F)
        self.assertEqual(data.unpack_into_byte(4), 0x7F)
        self.assertEqual(data.unpack_into_byte(5), 0x08)
        self.assertEqual(data.unpack_into_byte(6), 0x02)
        self.assertEqual(data.unpack_into_byte(7), 0x00)
        self.assertEqual(data.unpack_into_byte(8), 0x2)
        self.assertEqual(data.unpack_into_byte(9), 0x1)
        self.assertEqual(data.unpack_into_byte(10), 69)
        self.assertEqual(data.unpack_into_byte(11), 0)
        self.assertEqual(data.unpack_into_byte(12), 0)
        self.assertEqual(data.unpack_into_byte(13), 0x2)
        self.assertEqual(data.unpack_into_byte(14), 81)
        self.assertEqual(data.unpack_into_byte(15), 0)
        self.assertEqual(data.unpack_into_byte(16), 0)
        self.assertEqual(data.unpack_into_byte(17), 0xf7)
Example #6
0
    def testTempo(self):
        #import pdb; pdb.set_trace()
        tempo = 60
        MyMIDI = MIDIFile(1, file_format=2)
        MyMIDI.addTempo(0, 0, tempo)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[0].MIDIdata)

        self.assertEqual(MyMIDI.tracks[0].MIDIEventList[0].type, 'Tempo')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xff)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x51)
        self.assertEqual(data.unpack_into_byte(3), 0x03)
        self.assertEqual(data[4:7],
                         struct.pack('>L', int(60000000 / tempo))[1:4])

        # Also check the format 1 file

        tempo = 60
        MyMIDI = MIDIFile(2, file_format=1)
        MyMIDI.addTempo(1, 0, tempo)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[0].MIDIdata)

        self.assertEqual(MyMIDI.tracks[0].MIDIEventList[0].type, 'Tempo')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xff)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x51)
        self.assertEqual(data.unpack_into_byte(3), 0x03)
        self.assertEqual(data[4:7],
                         struct.pack('>L', int(60000000 / tempo))[1:4])
Example #7
0
    def testAdujustOrigin(self):
        track = 0
        channel = 0
        pitch = 69
        time = 1
        duration = 0.1
        volume = 64
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        time = 1.1
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)

        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # first time
        self.assertEqual(data.unpack_into_byte(8), 0x00)  # seconds time

        MyMIDI = MIDIFile(1, adjust_origin=False)
        time = 0.1
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        time = 0.2
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(data.unpack_into_byte(0), TICKSPERBEAT /
                         10)  # first time, should be an integer < 127
        self.assertEqual(data.unpack_into_byte(8), 0x00)  # first time
Example #8
0
    def testCopyright(self):
        notice = "2016(C) MCW"
        MyMIDI = MIDIFile(1)
        MyMIDI.addCopyright(0, 0, notice)
        MyMIDI.close()

        payload_encoded = notice.encode("ISO-8859-1")
        payloadLength = len(payload_encoded)
        payloadLengthVar = writeVarLength(payloadLength)

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'Copyright')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xff)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x02)  # Subcode
        index = 3
        for i in range(len(payloadLengthVar)):
            self.assertEqual(data.unpack_into_byte(index), payloadLengthVar[i])
            index = index + 1
        for i in range(len(payload_encoded)):
            if sys.version_info < (3,):
                test_char = ord(payload_encoded[i])
            else:
                test_char = payload_encoded[i]
            self.assertEqual(data.unpack_into_byte(index), test_char)
            index = index + 1
Example #9
0
    def testNRPNCallWithTimeOrder(self):
        #import pdb; pdb.set_trace()
        track = 0
        time = 0
        channel = 0
        controller_msb = 1
        controller_lsb =  2
        data_msb = 3
        data_lsb = 4
        MyMIDI = MIDIFile(1)
        MyMIDI.makeNRPNCall(track, channel, time, controller_msb, controller_lsb, data_msb, data_lsb, time_order=True)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'ControllerEvent')

        self.assertEqual(data.unpack_into_byte(0), 0x00)               # time
        self.assertEqual(data.unpack_into_byte(1), 0xB << 4 | channel) # Code
        self.assertEqual(data.unpack_into_byte(2), 99)                 # Controller Number
        self.assertEqual(data.unpack_into_byte(3), controller_msb)     # Controller Value
        self.assertEqual(data.unpack_into_byte(4), 0x01)               # time
        self.assertEqual(data.unpack_into_byte(5), 0xB << 4 | channel) # Code
        self.assertEqual(data.unpack_into_byte(6), 98)                 # Controller Number
        self.assertEqual(data.unpack_into_byte(7), controller_lsb)     # Controller Value
        self.assertEqual(data.unpack_into_byte(8), 0x01)               # time
        self.assertEqual(data.unpack_into_byte(9), 0xB << 4 | channel) # Code
        self.assertEqual(data.unpack_into_byte(10), 0x06)              # Bank MSB
        self.assertEqual(data.unpack_into_byte(11), data_msb)          # Value
        self.assertEqual(data.unpack_into_byte(12), 0x01)              # time
        self.assertEqual(data.unpack_into_byte(13), 0xB << 4 | channel) # Code
        self.assertEqual(data.unpack_into_byte(14), 0x26)               # Bank LSB
        self.assertEqual(data.unpack_into_byte(15), data_lsb) # Bank value (bank number)
Example #10
0
    def testNonRealTimeUniversalSysEx(self):
        code           = 1
        subcode        = 2
        payload_number = 42

        payload = struct.pack('>B', payload_number)

        MyMIDI = MIDIFile(1, adjust_origin=False)

        # Just for fun we'll use a multi-byte time
        time = 1
        time_bytes = writeVarLength(time * MyMIDI.ticks_per_quarternote)
        MyMIDI.addUniversalSysEx(0, time, code, subcode, payload, realTime=False)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'UniversalSysEx')

        self.assertEqual(data.unpack_into_byte(0), time_bytes[0]) # Time
        self.assertEqual(data.unpack_into_byte(1), time_bytes[1]) # Time
        self.assertEqual(data.unpack_into_byte(2), 0xf0) # UniversalSysEx == 0xF0
        self.assertEqual(data.unpack_into_byte(3), 5 + len(payload))    # Payload length = 5+actual pyayload
        self.assertEqual(data.unpack_into_byte(4), 0x7E) # 0x7E == non-realtime
        self.assertEqual(data.unpack_into_byte(5), 0x7F) # Sysex channel (always 0x7F)
        self.assertEqual(data.unpack_into_byte(6), code)
        self.assertEqual(data.unpack_into_byte(7), subcode)
        self.assertEqual(data.unpack_into_byte(8), payload_number) # Data
        self.assertEqual(data.unpack_into_byte(9), 0xf7) # End of message
Example #11
0
    def testTimeSignature(self):
        time = 0
        track = 0
        numerator = 4
        denominator = 2
        clocks_per_tick = 24
        MyMIDI = MIDIFile(1, file_format=2)
        MyMIDI.addTimeSignature(track, time, numerator, denominator,
                                clocks_per_tick)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[0].MIDIdata)

        self.assertEqual(MyMIDI.tracks[0].MIDIEventList[0].type,
                         'TimeSignature')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xFF)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x58)  # subcode
        self.assertEqual(data.unpack_into_byte(3), 0x04)  # Data length
        self.assertEqual(data.unpack_into_byte(4), numerator)
        self.assertEqual(data.unpack_into_byte(5), denominator)
        self.assertEqual(data.unpack_into_byte(6),
                         clocks_per_tick)  # Data length
        self.assertEqual(data.unpack_into_byte(7),
                         0x08)  # 32nd notes per quarter note

        # We also want to check with a format 1 file, make sure it ends up in
        # the tempo track

        time = 0
        track = 1
        numerator = 4
        denominator = 2
        clocks_per_tick = 24
        MyMIDI = MIDIFile(2, file_format=1)
        MyMIDI.addTimeSignature(track, time, numerator, denominator,
                                clocks_per_tick)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[0].MIDIdata)

        self.assertEqual(MyMIDI.tracks[0].MIDIEventList[0].type,
                         'TimeSignature')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xFF)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x58)  # subcode
        self.assertEqual(data.unpack_into_byte(3), 0x04)  # Data length
        self.assertEqual(data.unpack_into_byte(4), numerator)
        self.assertEqual(data.unpack_into_byte(5), denominator)
        self.assertEqual(data.unpack_into_byte(6),
                         clocks_per_tick)  # Data length
        self.assertEqual(data.unpack_into_byte(7),
                         0x08)  # 32nd notes per quarter note
Example #12
0
 def testSysEx(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.addSysEx(0, 0, 0, struct.pack(">B", 0x01))
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "SysEx")
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[0])[0], 0x00)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[1])[0], 0xF0)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[2])[0], 3)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[3])[0], 0x00)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[4])[0], 0x01)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[5])[0], 0xF7)
Example #13
0
 def testSysEx(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.addSysEx(0,0, 0, struct.pack('>B', 0x01))
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, 'SysEx')
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[0])[0], 0x00)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[1])[0], 0xf0)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[2])[0], 3)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[3])[0], 0x00)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[4])[0], 0x01)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[5])[0], 0xf7)
Example #14
0
    def testLongTrackName(self):
        track_name = 'long track name ' * 8
        MyMIDI = MIDIFile(1)
        MyMIDI.addTrackName(0, 0, track_name)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'TrackName')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xFF)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x03)  # subcodes
Example #15
0
 def testDeinterleaveNotes(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.addNote(0, 0, 100, 0, 2, 100)
     MyMIDI.addNote(0, 0, 100, 1, 2, 100)
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "NoteOn")
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].time, 0)
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].type, "NoteOff")
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].time, 128)
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[2].type, "NoteOn")
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[2].time, 0)
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[3].type, "NoteOff")
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[3].time, 256)
Example #16
0
 def testDeinterleaveNotes(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.addNote(0, 0, 100, 0, 2, 100)
     MyMIDI.addNote(0, 0, 100, 1, 2, 100)
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, 'NoteOn')
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].time, 0)
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].type, 'NoteOff')
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].time, 960)
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[2].type, 'NoteOn')
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[2].time, 0)
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[3].type, 'NoteOff')
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[3].time, 1920)
Example #17
0
    def testTrackName(self):
        #import pdb; pdb.set_trace()
        track_name = "track"
        MyMIDI = MIDIFile(1)
        MyMIDI.addTrackName(0, 0, track_name)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'TrackName')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xFF)  # Code
        self.assertEqual(data.unpack_into_byte(2), 0x03)  # subcodes
Example #18
0
 def testUniversalSysEx(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.addUniversalSysEx(0,0, 1, 2, struct.pack('>B', 0x01))
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, 'UniversalSysEx')
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[0])[0], 0x00)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[1])[0], 0xf0)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[2])[0], 6)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[3])[0], 0x7E)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[4])[0], 0x7F)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[5])[0], 0x01)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[6])[0], 0x02)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[7])[0], 0x01)
     self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[8])[0], 0xf7)
Example #19
0
    def testTuningProgramWithTimeOrder(self):
        program = 10
        MyMIDI = MIDIFile(1)
        MyMIDI.changeTuningProgram(0, 0, 0, program, time_order=True)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'ControllerEvent')

        self.assertEqual(data.unpack_into_byte(0), 0x00)              # time
        self.assertEqual(data.unpack_into_byte(4), 0x01)              # time
        self.assertEqual(data.unpack_into_byte(8), 0x01)              # time
        self.assertEqual(data.unpack_into_byte(12), 0x01)             # time
Example #20
0
 def testUniversalSysEx(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.addUniversalSysEx(0, 0, 1, 2, struct.pack(">B", 0x01))
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "UniversalSysEx")
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[0])[0], 0x00)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[1])[0], 0xF0)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[2])[0], 6)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[3])[0], 0x7E)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[4])[0], 0x7F)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[5])[0], 0x01)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[6])[0], 0x02)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[7])[0], 0x01)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[8])[0], 0xF7)
Example #21
0
    def testSysEx(self):
        MyMIDI = MIDIFile(1)
        MyMIDI.addSysEx(0, 0, 0, struct.pack('>B', 0x01))
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'SysEx')

        self.assertEqual(data.unpack_into_byte(0), 0x00)
        self.assertEqual(data.unpack_into_byte(1), 0xf0)
        self.assertEqual(data.unpack_into_byte(2), 3)
        self.assertEqual(data.unpack_into_byte(3), 0x00)
        self.assertEqual(data.unpack_into_byte(4), 0x01)
        self.assertEqual(data.unpack_into_byte(5), 0xf7)
Example #22
0
    def testTuningBankWithTimeOrder(self):
        #import pdb; pdb.set_trace()
        bank = 1
        MyMIDI = MIDIFile(1)
        MyMIDI.changeTuningBank(0, 0, 0, bank, time_order=True)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'ControllerEvent')

        self.assertEqual(data.unpack_into_byte(0),  0x00)               # time
        self.assertEqual(data.unpack_into_byte(4),  0x01)               # time
        self.assertEqual(data.unpack_into_byte(8),  0x01)               # time
        self.assertEqual(data.unpack_into_byte(12), 0x01)               # time
Example #23
0
 def testUnknownEventType(self):
     track = 0
     channel = 0
     pitch = 69
     time = 0
     duration = 1.0
     volume = 64
     bad_type = "bad"
     MyMIDI = MIDIFile(1)
     MyMIDI.addNote(track, channel, pitch, time, duration, volume)
     MyMIDI.tracks[1].eventList[0].type = bad_type
     with self.assertRaises(Exception) as context:
         MyMIDI.close()
     self.assertTrue(('Error in MIDITrack: Unknown event type %s' %
                      bad_type) in str(context.exception))
Example #24
0
    def testProgramChange(self):
        #import pdb; pdb.set_trace()
        program = 10
        channel = 0
        MyMIDI = MIDIFile(1)
        MyMIDI.addProgramChange(0, channel, 0, program)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[0].MIDIdata)

        self.assertEqual(MyMIDI.tracks[0].MIDIEventList[0].type,
                         'ProgramChange')
        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xC << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(2), program)
Example #25
0
    def testMultiClose(self):
        track = 0
        channel = 0
        pitch = 69
        time = 0
        duration = 1.0
        volume = 64
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        MyMIDI.close()
        data_length_1 = len(MyMIDI.tracks[0].MIDIdata)
        MyMIDI.close()
        data_length_2 = len(MyMIDI.tracks[0].MIDIdata)

        self.assertEqual(data_length_1, data_length_2)
        MyMIDI.tracks[0].closeTrack()
        data_length_3 = len(MyMIDI.tracks[0].MIDIdata)
        self.assertEqual(data_length_1, data_length_3)
Example #26
0
    def testProgramChange(self):
        program = 10
        channel = 0
        tracknum = 0
        realtracknum = tracknum
        time = 0.0
        MyMIDI = MIDIFile(1)
        if MyMIDI.header.numeric_format == 1:
            realtracknum = tracknum + 1
        MyMIDI.addProgramChange(tracknum, channel, time, program)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[realtracknum].MIDIdata)

        self.assertEqual(MyMIDI.tracks[realtracknum].MIDIEventList[0].evtname, 'ProgramChange')
        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xC << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(2), program)
Example #27
0
    def testChannelPressure(self):
        pressure = 10
        channel = 0
        time = 0.0
        tracknum = 0
        realtracknum = tracknum
        MyMIDI = MIDIFile(1)
        if MyMIDI.header.numeric_format == 1:
            realtracknum = tracknum + 1
        MyMIDI.addChannelPressure(tracknum, channel, time, pressure)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[realtracknum].MIDIdata)

        self.assertEqual(MyMIDI.tracks[realtracknum].MIDIEventList[0].evtname, 'ChannelPressure')
        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xD0 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(2), pressure)
Example #28
0
    def testAddControllerEvent(self):
        track = 0
        time = 0
        channel = 3
        controller_number = 1
        parameter = 2
        MyMIDI = MIDIFile(1)
        MyMIDI.addControllerEvent(track, channel, time, controller_number, parameter)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'ControllerEvent')

        self.assertEqual(data.unpack_into_byte(0), 0x00)  # time
        self.assertEqual(data.unpack_into_byte(1), 0xB << 4 | channel)  # Code
        self.assertEqual(data.unpack_into_byte(2), controller_number)  # Controller Number
        self.assertEqual(data.unpack_into_byte(3), parameter)  # Controller Value
Example #29
0
 def testTuning(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.changeNoteTuning(0, [(1, 440), (2, 880)])
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type,
                       'UniversalSysEx')
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[0])[0], 0x00)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[1])[0], 0xf0)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[2])[0], 15)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[3])[0], 0x7E)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[4])[0], 0x7F)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[5])[0], 0x08)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[6])[0], 0x02)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[7])[0], 0x00)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[8])[0], 0x2)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[9])[0], 0x1)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[10])[0], 69)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[11])[0], 0)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[12])[0], 0)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[13])[0], 0x2)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[14])[0], 81)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[15])[0], 0)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[16])[0], 0)
     self.assertEquals(
         struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[17])[0], 0xf7)
Example #30
0
    def testKeySignature(self):
        time            = 0
        track           = 0
        accidentals     = 3
        accidental_type = MINOR
        mode            = MAJOR

        MyMIDI = MIDIFile(1)
        MyMIDI.addKeySignature(track, time, accidentals, accidental_type, mode)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'KeySignature')

        self.assertEqual(data.unpack_into_byte(0), 0x00) # time
        self.assertEqual(data.unpack_into_byte(1), 0xFF) # Code
        self.assertEqual(data.unpack_into_byte(2), 0x59) # subcode
        self.assertEqual(data.unpack_into_byte(3), 0x02) # Event subtype
        self.assertEqual(data.unpack_into_byte(4), accidentals * accidental_type)
        self.assertEqual(data.unpack_into_byte(5), mode)
Example #31
0
    def testDeinterleaveNotes(self):
        MyMIDI = MIDIFile(1, adjust_origin=False)
        track = 0
        channel = 0
        pitch = 100
        time1 = 0
        time2 = 1
        duration = 2
        volume = 100
        MyMIDI.addNote(track, channel, pitch, time1, duration, volume) # on at 0 off at 2
        MyMIDI.addNote(track, channel, pitch, time2, duration, volume+1) # on at 1 off at 3
        MyMIDI.close()

        # ticks have already been converted to delta ticks
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].tick, MyMIDI.time_to_ticks(time1))
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].tick, MyMIDI.time_to_ticks(time2))
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[2].evtname, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[2].tick, MyMIDI.time_to_ticks(time2 - time2))
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[3].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[3].tick, MyMIDI.time_to_ticks(time2 - time2 + duration))
Example #32
0
    def testTimeShift(self):

        # With one track
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(0, 0, 100, 5, 1, 100)
        MyMIDI.close()
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].time, 0)
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].type, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].time, TICKSPERBEAT)

        # With two tracks
        MyMIDI = MIDIFile(2)
        MyMIDI.addNote(0, 0, 100, 5, 1, 100)
        MyMIDI.addNote(1, 0, 100, 6, 1, 100)
        MyMIDI.close()
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].time, 0)
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].type, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].time, TICKSPERBEAT)
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].type, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].time, TICKSPERBEAT)
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].type, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].time, TICKSPERBEAT)

        # Negative Time
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(0, 0, 100, -5, 1, 100)
        MyMIDI.close()
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].time, 0)
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].type, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].time, TICKSPERBEAT)

        # Negative time, two tracks

        MyMIDI = MIDIFile(2)
        MyMIDI.addNote(0, 0, 100, -1, 1, 100)
        MyMIDI.addNote(1, 0, 100, 0, 1, 100)
        MyMIDI.close()
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].time, 0)
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].type, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].time, TICKSPERBEAT)
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].type, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].time, TICKSPERBEAT)
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].type, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].time, TICKSPERBEAT)
Example #33
0
    def testTimeShift(self):

        # With one track
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(0, 0, 100, 5, 1, 100)
        MyMIDI.close()
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "NoteOn")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].time, 0)
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].type, "NoteOff")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].time, 128)

        # With two tracks
        MyMIDI = MIDIFile(2)
        MyMIDI.addNote(0, 0, 100, 5, 1, 100)
        MyMIDI.addNote(1, 0, 100, 6, 1, 100)
        MyMIDI.close()
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "NoteOn")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].time, 0)
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].type, "NoteOff")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].time, 128)
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[0].type, "NoteOn")
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[0].time, 128)
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[1].type, "NoteOff")
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[1].time, 128)

        # Negative Time
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(0, 0, 100, -5, 1, 100)
        MyMIDI.close()
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "NoteOn")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].time, 0)
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].type, "NoteOff")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].time, 128)

        # Negative time, two tracks

        MyMIDI = MIDIFile(2)
        MyMIDI.addNote(0, 0, 100, -1, 1, 100)
        MyMIDI.addNote(1, 0, 100, 0, 1, 100)
        MyMIDI.close()
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "NoteOn")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].time, 0)
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].type, "NoteOff")
        self.assertEquals(MyMIDI.tracks[0].MIDIEventList[1].time, 128)
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[0].type, "NoteOn")
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[0].time, 128)
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[1].type, "NoteOff")
        self.assertEquals(MyMIDI.tracks[1].MIDIEventList[1].time, 128)
Example #34
0
 def testTuning(self):
     MyMIDI = MIDIFile(1)
     MyMIDI.changeNoteTuning(0, [(1, 440), (2, 880)])
     MyMIDI.close()
     self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, "UniversalSysEx")
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[0])[0], 0x00)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[1])[0], 0xF0)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[2])[0], 15)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[3])[0], 0x7E)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[4])[0], 0x7F)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[5])[0], 0x08)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[6])[0], 0x02)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[7])[0], 0x00)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[8])[0], 0x2)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[9])[0], 0x1)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[10])[0], 69)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[11])[0], 0)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[12])[0], 0)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[13])[0], 0x2)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[14])[0], 81)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[15])[0], 0)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[16])[0], 0)
     self.assertEquals(struct.unpack(">B", MyMIDI.tracks[0].MIDIdata[17])[0], 0xF7)
Example #35
0
    def testRealTimeUniversalSysEx(self):
        code           = 1
        subcode        = 2
        payload_number = 47

        payload = struct.pack('>B', payload_number)
        MyMIDI = MIDIFile(1)
        MyMIDI.addUniversalSysEx(0, 0, code, subcode, payload, realTime=True)
        MyMIDI.close()

        data = Decoder(MyMIDI.tracks[1].MIDIdata)

        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'UniversalSysEx')

        self.assertEqual(data.unpack_into_byte(0), 0x00)
        self.assertEqual(data.unpack_into_byte(1), 0xf0)
        self.assertEqual(data.unpack_into_byte(2), 5 + len(payload))
        self.assertEqual(data.unpack_into_byte(3), 0x7F) # 0x7F == real-time
        self.assertEqual(data.unpack_into_byte(4), 0x7F)
        self.assertEqual(data.unpack_into_byte(5), code)
        self.assertEqual(data.unpack_into_byte(6), subcode)
        self.assertEqual(data.unpack_into_byte(7), payload_number)
        self.assertEqual(data.unpack_into_byte(8), 0xf7)
Example #36
0
class MidiManager(object):
    MidiPortName = "MIDIphon"

    def __init__(self, midiPhonConfig):
        super(MidiManager, self).__init__()

        self.midiPhonConfig = midiPhonConfig
        self.midiChannels = {}
        self.oldPlayers = {}
        self.availableChannels = range(1, self.midiPhonConfig.NumMidiChannels + 1)
        self.mout = rtmidi.RtMidiOut()
        # self.min = rtmidi.RtMidiIn()
        # self.min.openVirtualPort(MidiManager.MidiPortName)
        # self.mout.openVirtualPort(MidiManager.MidiPortName)
        self.midiPort = -1
        for i in xrange(0, self.mout.getPortCount()):
            name = self.mout.getPortName(i)
            print ("Port {0} is named {1}".format(i, name))
            if name == ("IAC Driver " + MidiManager.MidiPortName):
                self.midiPort = i
                break

        if self.midiPort == -1:
            raise Exception("You need to have a virtual midi port named 'MIDIphon'")

        self.mout.openPort(self.midiPort)
        self.startedPlaying = False
        self.initialTime = time.clock()
        # for i in range(0, self.mout.getPortCount()):
        #     if self.mout.getPortName(i) == MidiManager.MidiPortName:
        #         self.midiPort = i
        #         break

        # if self.midiPort == -1:
        #     raise Exception('Epic failure of finding midi channel I just opened.')

        self.twilio_client = TwilioRestClient(
            account=self.midiPhonConfig.TwilioAppSid, token=self.midiPhonConfig.TwilioApiToken
        )

    def releaseMidi(self):
        self.mout.closePort()

    def uploadMidiFile(self, filename):
        print "Uploading midi file"
        ftp = ftplib.FTP("midiphon.bartnett.com", "midiphon_uploader", "grantophone")
        mf = open(filename)
        ftp.storbinary("STOR midiphon.bartnett.com/" + filename, mf)
        mf.close()
        print "Done storing midi file"

        if self.midiPhonConfig.BitlyApiToken:
            link = self.getBitlyLink("http://midiphon.bartnett.com/" + str(filename))
            print "GOT LINK: " + link
            self.sendBitlyLink(link)
            print "SMS Sent!"
        else:
            print "Not Bit.ly api token specified, not sending out the link to midi file."

    def getBitlyLink(self, url):
        print "Opening bitly connection"
        connect = Connection("midiphon", self.midiPhonConfig.BitlyApiToken)
        print "Shortening URL"
        short = connect.shorten(url)
        print "Done shortening URL"
        return short["url"]

    def sendBitlyLink(self, link):
        for p in self.oldPlayers:
            self.twilio_client.sms.messages.create(
                to=p, from_="13866434928", body=("Listen to your performance at " + link)
            )

        self.oldPlayers.clear()
        self.startedPlaying = False

    def setNumMidiChannels(numChannels):
        if not self.startedPlaying:
            if numChannels <= 16:
                self.availableChannels = range(1, numChannels + 1)
            else:
                print "Error: limit is 16 channels"
                return False
        else:
            print "Error, can't change number of midi channels in the middle of a session."

    def addPlayer(self, phone):
        if not self.startedPlaying:
            self.startedPlaying = True
            self.midiFile = MIDIFile(self.midiPhonConfig.NumMidiChannels)
            for i in range(0, self.midiPhonConfig.NumMidiChannels):
                self.midiFile.addTrackName(i, 0, str(i))
                self.midiFile.addTempo(i, 0, 60)

        if self.midiChannels.has_key(phone):
            return True

        channelCount = len(self.availableChannels)
        if channelCount > 0:
            self.midiChannels[phone] = PhoneMusician(
                phone, self.availableChannels.pop(random.randint(1, channelCount) - 1)
            )
            print "Adding player#" + phone
            return True

        return False

    def removePlayer(self, phone):
        if self.midiChannels.has_key(phone):
            player = self.midiChannels.pop(phone)
            channelNumber = player.midiChannel
            print "Removing player {0} with midi channel {1}".format(phone, channelNumber)
            self.availableChannels.append(channelNumber)
            self.oldPlayers[phone] = player
            if len(self.midiChannels) < 1:
                fn = str(uuid.uuid1()) + ".mid"
                f = open(fn, "wb")
                self.midiFile.writeFile(f)
                f.close()
                self.midiFile.close()
                self.uploadMidiFile(fn)

    def playNote(self, phone, digit):
        if self.midiChannels.has_key(phone):
            player = self.midiChannels[phone]
            msg = player.getNoteOnMessage(digit)
            if msg:
                noteLength = 1.5
                elapsedTime = (time.clock() - self.initialTime) * 60.0
                try:
                    self.midiFile.addNote(
                        player.getMidiChannel() - 1,
                        player.getMidiChannel() - 1,
                        msg.getNoteNumber(),
                        elapsedTime,
                        noteLength,
                        127,
                    )
                    print "Sending midi message: channel={0} note={1} vel={2}".format(
                        msg.getChannel(), msg.getNoteNumber(), msg.getVelocity()
                    )
                    self.mout.sendMessage(msg)
                    t = threading.Timer(noteLength, self.stopNote, [phone, digit])
                    t.start()
                except IndexError:
                    print "Error adding midi note"
                    print "PlayerInfo: MidiChannel: {0} MidiNote: {1}".format(
                        player.getMidiChannel(), msg.getNoteNumber()
                    )
                    return False

            return True

    def stopNote(self, phone, digit):
        if self.midiChannels.has_key(phone):
            player = self.midiChannels[phone]
        elif self.oldPlayers.has_key(phone):
            player = self.oldPlayers[phone]
        else:
            player = None

        if player:
            msg = player.getNoteOffMessage(digit)
            if msg:
                print "Sending midi message: channel={0} note={1}".format(msg.getChannel(), msg.getNoteNumber())
                self.mout.sendMessage(msg)