예제 #1
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))
예제 #2
0
    def testAdjustOrigin(self):
        track = 0
        channel = 0
        pitch = 69
        time = 1
        duration = 0.1
        volume = 64
        MyMIDI = MIDIFile(1, adjust_origin=True)
        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),
                         MyMIDI.ticks_per_quarternote /
                         10)  # first time, should be an integer < 127
        self.assertEqual(data.unpack_into_byte(8), 0x00)  # first time
예제 #3
0
 def testAddNote(self):
     MyMIDI = MIDIFile(
         1)  # a format 1 file, so we increment the track number below
     track = 0
     channel = 0
     pitch = 100
     time = 0
     duration = 1
     volume = 100
     MyMIDI.addNote(track, channel, pitch, time, duration, volume)
     self.assertEqual(MyMIDI.tracks[1].eventList[0].evtname, "NoteOn")
     self.assertEqual(MyMIDI.tracks[1].eventList[0].pitch, pitch)
     self.assertEqual(MyMIDI.tracks[1].eventList[0].tick,
                      MyMIDI.time_to_ticks(time))
     self.assertEqual(MyMIDI.tracks[1].eventList[0].duration,
                      MyMIDI.time_to_ticks(duration))
     self.assertEqual(MyMIDI.tracks[1].eventList[0].volume, volume)
예제 #4
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)
예제 #5
0
 def testShiftTrack(self):
     track = 0
     channel = 0
     pitch = 100
     time = 1
     duration = 1
     volume = 100
     MyMIDI = MIDIFile(1)
     MyMIDI.addNote(track, channel, pitch, time, duration, volume)
     self.assertEqual(MyMIDI.tracks[1].eventList[0].evtname, "NoteOn")
     self.assertEqual(MyMIDI.tracks[1].eventList[0].pitch, pitch)
     self.assertEqual(MyMIDI.tracks[1].eventList[0].tick,
                      MyMIDI.time_to_ticks(time))
     self.assertEqual(MyMIDI.tracks[1].eventList[0].duration,
                      MyMIDI.time_to_ticks(duration))
     self.assertEqual(MyMIDI.tracks[1].eventList[0].volume, volume)
     MyMIDI.shiftTracks()
     self.assertEqual(MyMIDI.tracks[1].eventList[0].tick, 0)
예제 #6
0
    def testRemoveDuplicates(self):
        # First notes
        track = 0
        channel = 0
        pitch = 69
        time = 0
        duration = 1
        volume = 64
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(track, channel, pitch, time, duration,
                       volume)  # also adds a corresponding NoteOff
        MyMIDI.addNote(track, channel, pitch, time, duration,
                       volume)  # also adds a corresponding NoteOff
        MyMIDI.close()
        self.assertEqual(2, len(
            MyMIDI.tracks[1].eventList))  # One NoteOn event, one NoteOff event
        MyMIDI = MIDIFile(1)
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        pitch = 70
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        MyMIDI.close()
        self.assertEqual(4, len(MyMIDI.tracks[1].eventList)
                         )  # Two NoteOn events, two NoteOff events

        # Next tempo
        tempo = 60
        track = 0
        time = 0
        MyMIDI = MIDIFile(1)
        MyMIDI.addTempo(track, time, tempo)
        MyMIDI.addTempo(track, time, tempo)
        MyMIDI.close()
        self.assertEqual(1, len(MyMIDI.tracks[0].eventList))
        MyMIDI = MIDIFile(1)
        MyMIDI.addTempo(track, time, tempo)
        tempo = 80
        MyMIDI.addTempo(track, time, tempo)
        MyMIDI.close()
        self.assertEqual(2, len(MyMIDI.tracks[0].eventList))

        # Program Number
        time = 0
        track = 0
        program = 10
        channel = 0
        MyMIDI = MIDIFile(1)
        MyMIDI.addProgramChange(track, channel, time, program)
        MyMIDI.addProgramChange(track, channel, time, program)
        MyMIDI.close()
        self.assertEqual(1, len(MyMIDI.tracks[track + 1].eventList))
        MyMIDI = MIDIFile(1)
        MyMIDI.addProgramChange(track, channel, time, program)
        program = 11
        MyMIDI.addProgramChange(track, channel, time, program)
        MyMIDI.close()
        self.assertEqual(2, len(MyMIDI.tracks[track + 1].eventList))

        # Track Name
        track = 0
        time = 0
        track_name = "track"
        MyMIDI = MIDIFile(1)
        MyMIDI.addTrackName(track, time, track_name)
        MyMIDI.addTrackName(track, time, track_name)
        MyMIDI.close()
        self.assertEqual(1, len(MyMIDI.tracks[1].eventList))
        MyMIDI = MIDIFile(1)
        MyMIDI.addTrackName(track, time, track_name)
        track_name = "track 2"
        MyMIDI.addTrackName(track, time, track_name)
        MyMIDI.close()
        self.assertEqual(2, len(MyMIDI.tracks[1].eventList))

        # SysEx. These are never removed
        track = 0
        time = 0
        manufacturer = 10
        MyMIDI = MIDIFile(1)
        MyMIDI.addSysEx(track, time, manufacturer, struct.pack('>B', 0x01))
        MyMIDI.addSysEx(track, time, manufacturer, struct.pack('>B', 0x01))
        MyMIDI.close()
        self.assertEqual(2, len(MyMIDI.tracks[1].eventList))

        # UniversalSysEx. Same thing -- never remove

        track = 0
        time = 0
        code = 1
        subcode = 2
        payload_number = 47

        payload = struct.pack('>B', payload_number)
        MyMIDI = MIDIFile(1)
        MyMIDI.addUniversalSysEx(track,
                                 time,
                                 code,
                                 subcode,
                                 payload,
                                 realTime=True)
        MyMIDI.addUniversalSysEx(track,
                                 time,
                                 code,
                                 subcode,
                                 payload,
                                 realTime=True)
        MyMIDI.close()
        self.assertEqual(2, len(MyMIDI.tracks[1].eventList))
예제 #7
0
 def testWriteFile(self):
     # Just to make sure the stream can be written without throwing an error.
     MyMIDI = MIDIFile(1)
     MyMIDI.addNote(0, 0, 100, 0, 1, 100)
     with open("/tmp/test.mid", "wb") as output_file:
         MyMIDI.writeFile(output_file)
예제 #8
0
    def testTimeShift(self):

        # With one track
        MyMIDI = MIDIFile(1, adjust_origin=True)
        track = 0
        channel = 0
        pitch = 100
        time1 = 5
        duration = 1
        volume = 100
        MyMIDI.addNote(track, channel, pitch, time1, duration, volume)
        MyMIDI.close()
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].tick,
                         MyMIDI.time_to_ticks(0))
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].tick,
                         MyMIDI.time_to_ticks(duration))

        # With two tracks
        track2 = 1
        MyMIDI = MIDIFile(2, adjust_origin=True)
        MyMIDI.addNote(track, channel, pitch, time1, duration, volume)
        time2 = 6
        MyMIDI.addNote(track2, channel, pitch, time2, duration, volume)
        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(0))
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].tick,
                         MyMIDI.time_to_ticks(duration))
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].evtname, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].tick,
                         MyMIDI.time_to_ticks(0 + duration))
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].tick,
                         MyMIDI.time_to_ticks(0 + duration))

        # Negative Time
        MyMIDI = MIDIFile(1, adjust_origin=True)
        track = 0
        channel = 0
        pitch = 100
        time = -5
        duration = 1
        volume = 100
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        MyMIDI.close()
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].tick,
                         MyMIDI.time_to_ticks(0))
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].tick,
                         MyMIDI.time_to_ticks(0 + duration))

        # Negative time, two tracks

        MyMIDI = MIDIFile(2, adjust_origin=True)
        track = 0
        channel = 0
        pitch = 100
        time = -1
        duration = 1
        volume = 100
        MyMIDI.addNote(track, channel, pitch, time, duration, volume)
        track2 = 1
        time2 = 0
        MyMIDI.addNote(track2, channel, pitch, time2, duration, volume)
        MyMIDI.close()
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].tick,
                         MyMIDI.time_to_ticks(0))
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].tick,
                         MyMIDI.time_to_ticks(1))
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].evtname, 'NoteOn')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[0].tick,
                         MyMIDI.time_to_ticks(1))
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].evtname, 'NoteOff')
        self.assertEqual(MyMIDI.tracks[2].MIDIEventList[1].tick,
                         MyMIDI.time_to_ticks(1))
예제 #9
0
    def testEndOfTrack(self):

        MyMIDI = MIDIFile(1, ticks_per_quarternote=480)
        MyMIDI.addTimeSignature(0, 0, 4, 2, 8)
        MyMIDI.addNote(0, 0, 60, 0, 0.75, 55)
        MyMIDI.addNote(0, 0, 64, 1, 0.75, 55)
        MyMIDI.addNote(0, 0, 67, 2, 0.75, 55)
        MyMIDI.addNote(0, 0, 60, 4, 0.75, 55)
        MyMIDI.addNote(0, 0, 64, 5, 0.75, 55)
        MyMIDI.addNote(0, 0, 67, 6, 0.75, 55)

        with open(os.path.join(gettempdir(), "TestEndOfTrack_1.mid"),
                  "wb") as f_midi:
            MyMIDI.writeFile(f_midi)

        MyMIDI = MIDIFile(1, ticks_per_quarternote=480)
        MyMIDI.addTimeSignature(0, 0, 4, 2, 8)
        MyMIDI.addNote(0, 0, 60, 0, 0.75, 55)
        MyMIDI.addNote(0, 0, 64, 1, 0.75, 55)
        MyMIDI.addNote(0, 0, 67, 2, 0.75, 55)
        MyMIDI.addNote(0, 0, 60, 4, 0.75, 55)
        MyMIDI.addNote(0, 0, 64, 5, 0.75, 55)
        MyMIDI.addNote(0, 0, 67, 6, 0.75, 55)
        MyMIDI.addEndOfTrack(0, 6.65)

        with open(os.path.join(gettempdir(), "TestEndOfTrack_2.mid"),
                  "wb") as f_midi:
            MyMIDI.writeFile(f_midi)

        # No "End-Of-Track" and "End-Of-Track" placed before the final note event
        # should give the same result
        #  --- Actually, not correct. The system track end comes at a different
        #      time. This test is commented for now.
        #self.assertTrue(filecmp.cmp(os.path.join(gettempdir(), "TestEndOfTrack_1.mid"), os.path.join(gettempdir(), "TestEndOfTrack_2.mid")))

        MyMIDI = MIDIFile(1, ticks_per_quarternote=480)
        MyMIDI.addTimeSignature(0, 0, 4, 2, 8)
        MyMIDI.addNote(0, 0, 60, 0, 0.75, 55)
        MyMIDI.addNote(0, 0, 64, 1, 0.75, 55)
        MyMIDI.addNote(0, 0, 67, 2, 0.75, 55)
        MyMIDI.addNote(0, 0, 60, 4, 0.75, 55)
        MyMIDI.addNote(0, 0, 64, 5, 0.75, 55)
        MyMIDI.addNote(0, 0, 67, 6, 0.75, 55)
        MyMIDI.addEndOfTrack(0, 8)

        with open(os.path.join(gettempdir(), "TestEndOfTrack_3.mid"),
                  "wb") as f_midi:
            MyMIDI.writeFile(f_midi)

        # No "End-Of-Track" and "End-Of-Track" placed after the final note event
        # should give a different result

        self.assertFalse(
            filecmp.cmp(os.path.join(gettempdir(), "TestEndOfTrack_1.mid"),
                        os.path.join(gettempdir(), "TestEndOfTrack_3.mid")))

        os.remove(os.path.join(gettempdir(), "TestEndOfTrack_1.mid"))
        os.remove(os.path.join(gettempdir(), "TestEndOfTrack_2.mid"))
        os.remove(os.path.join(gettempdir(), "TestEndOfTrack_3.mid"))