Beispiel #1
0
 def build_evt(self, evt_data):
     if len(evt_data) < 3:
         return None
     evt = None
     evt_type = evt_data[0]
     try:
         tick = int(evt_data[1])
         data1 = int(evt_data[2])
         data2=None
         if len(evt_data) > 3:
             data2 = int(evt_data[3])
     except ValueError:
         return None
     if evt_type == "n":
         if data2 is not None:
             evt = midi.NoteOnEvent(tick=tick, channel=0, data=[data1, data2])
         else:
             evt = midi.NoteOnEvent(tick=tick, channel=0, data=[data1])
     if evt_type == "p":
         if data2 is not None:
             evt = midi.ProgramChangeEvent(tick=tick, channel=0, data=[data1 + 50, data2])
         else:
             evt = midi.ProgramChangeEvent(tick=tick, channel=0, data=[data1])
     if evt_type == "c":
         if data2 is not None:
             evt = midi.ControlChangeEvent(tick=tick, channel=0, data=[data1, data2])
         else:
             evt = midi.ControlChangeEvent(tick=tick, channel=0, data=[data1])
     print(evt)
     return evt
Beispiel #2
0
def handlePerf(type, value, duration, maxValue, track, tick):
  event2 = None
  if type == 0:
    # volume
    event1 = midi.ControlChangeEvent(tick=tick)
    event1.control = 7 # Main Volume
    #if maxValue > 0x7F:
    #  event1.value = (value>>8)&0xFF
    #  event2 = midi.ControlChangeEvent(tick=0)
    #  event2.control = 39 # Volume LSB
    #  event2.value = value&0xFF
    #else:
    #  event1.value = value
    event1.value = (value*0x7F)/maxValue
  elif type == 1:
    # pitch
    event1 = midi.PitchWheelEvent(tick=tick)
    event1.pitch = (value*0x7FFF)/maxValue
  elif type == 3:
    # pan
    event1 = midi.ControlChangeEvent(tick=tick)
    event1.control = 10 # Pan
    #if maxValue > 0x7F:
    #  event1.value = (value>>8)&0xFF
    #  event2 = midi.ControlChangeEvent(tick=0)
    #  event2.control = 42 # Pan LSB
    #  event2.value = value&0xFF
    #else:
    #  event1.value = value
    event1.value = (value*0x7F)/maxValue
  else:
    warn("Unknown perf type %d"%type)
    event1 = midi.TextMetaEvent(tick=tick, data=map(ord, "Perf %d (%d)"%(type, value)))
  track.append(event1)
  if event2 is not None: track.append(event2)
  if duration:
    if type == 0:
      # volume
      event = midi.ControlChangeEvent(tick=duration)
      event.control = 7 # Main Volume
      event.value = 0x7F
    elif type == 1:
      # pitch
      event = midi.PitchWheelEvent(tick=duration)
      event.pitch = 0x2000
    elif type == 3:
      # pan
      event = midi.ControlChangeEvent(tick=duration)
      event.control = 10 # Pan
      event.value = 0x40
    else:
      event = midi.TextMetaEvent(tick=duration, data=map(ord, "Perf %d (%d)"%(type, value)))
    return event
def list_to_midi(chunk_str_list, generated_dir, filename):
    pattern = midi.Pattern(resolution=480)

    track = midi.Track()
    pattern.append(track)

    for chunk in chunk_str_list:
        chunk_info = chunk.split("_")
        event_type = chunk_info[1]

        if event_type == "no":
            tick = int(chunk_info[0])
            pitch = int(chunk_info[2])
            velocity = int(chunk_info[3])

            e = midi.NoteOnEvent(tick=tick, channel=0, velocity=velocity, pitch=pitch)
            track.append(e)

        elif event_type == "st":
            tick = int(chunk_info[0])
            bpm = int(chunk_info[2])
            mpqn = int(chunk_info[3])
            ev = midi.SetTempoEvent(tick=tick, bpm=bpm, mpqn=mpqn)
            track.append(ev)

        elif event_type == "cc":
            control = int(chunk_info[3])
            value = int(chunk_info[4])
            e = midi.ControlChangeEvent(channel=0, control=control, value=value)
            track.append(e)

    end_event = midi.EndOfTrackEvent(tick=1)
    track.append(end_event)

    midi.write_midifile(generated_dir + filename + '.mid', pattern)
Beispiel #4
0
 def setPos(self, pos):
     """ takes between 0 and 1 """
     if self.slider_index is not None:
         event = midi.ControlChangeEvent(tick=0,
                                         control=self.slider_index + 1,
                                         value=int(pos * 127))
         xtouch.writer.event_write(event, False, False, True)
Beispiel #5
0
 def event_read(self):
     ev = S.event_input(self.client)
     if ev and (ev < 0): self._error(ev)
     if ev and ev.type in (S.SND_SEQ_EVENT_NOTEON, S.SND_SEQ_EVENT_NOTEOFF,
                           S.SND_SEQ_EVENT_CONTROLLER):
         if ev.type == S.SND_SEQ_EVENT_NOTEON:
             mev = midi.NoteOnEvent()
             mev.channel = ev.data.note.channel
             mev.pitch = ev.data.note.note
             mev.velocity = ev.data.note.velocity
         elif ev.type == S.SND_SEQ_EVENT_NOTEOFF:
             mev = midi.NoteOffEvent()
             mev.channel = ev.data.note.channel
             mev.pitch = ev.data.note.note
             mev.velocity = ev.data.note.velocity
         elif ev.type == S.SND_SEQ_EVENT_CONTROLLER:
             mev = midi.ControlChangeEvent()
             mev.channel = ev.data.control.channel
             mev.control = ev.data.control.param
             mev.value = ev.data.control.value
         if ev.time.time.tv_nsec:
             # convert to ms
             mev.msdeay = \
                 (ev.time.time.tv_nsec / 1e6) + (ev.time.time.tv_sec * 1e3)
         else:
             mev.tick = ev.time.tick
         return mev
     else:
         return None
Beispiel #6
0
def write_music(song, speed=100):
    pattern = midi.Pattern()
    track = midi.Track()
    pattern.append(track)
    for i in range(len(song[0]) // 128):
        for note in range(128):
            if song[0][i * 128 + note] > .5:
                track.append(midi.NoteOnEvent(tick=0, velocity=100,
                                              pitch=note))
        track.append(midi.ControlChangeEvent(tick=speed))
        for note in range(128):
            track.append(midi.NoteOnEvent(tick=0, velocity=0, pitch=note))
    midi.write_midifile("test.mid", pattern)
Beispiel #7
0
def handleBankProgram(which, selection, track, tick):
  if which == 7:
    # pitch
    print "Pitch", selection
    event = midi.ControlChangeEvent(tick=tick)
    event.control = 101 # RPN MSB
    event.value = 0
    track.append(event)
    event = midi.ControlChangeEvent(tick=0)
    event.control = 100 # RPN LSB
    event.value = 0
    track.append(event)
    event = midi.ControlChangeEvent(tick=0)
    event.control = 6 # Data entry MSB
    event.value = selection
    track.append(event)
    event = midi.ControlChangeEvent(tick=0)
    event.control = 38 # Data entry LSB
    event.value = 0
    track.append(event)
  elif which == 0x20:
    # bank
    print "Bank", selection
    event = midi.ControlChangeEvent(tick=tick)
    event.control = 32 # Bank Select
    event.value = selection
    track.append(event)
  elif which == 0x21:
    # program
    print "Program", selection
    event = midi.ProgramChangeEvent(tick=tick, value=selection%128)
    track.append(event)
  else:
    warn("Unknown bank/program %x (%d)"%(which, selection))
    event = midi.TextMetaEvent(tick=tick, data=map(ord, "Bank/Program %d (%d)"%(which, selection)))
    track.append(event)
Beispiel #8
0
 def event_read(self):
     ev = S.event_input(self.client)
     if not ev: return None
     if ev < 0: self._error(ev)
     if ev.type == S.SND_SEQ_EVENT_NOTEON:
         mev = midi.NoteOnEvent()
         mev.channel = ev.data.note.channel
         mev.pitch = ev.data.note.note
         mev.velocity = ev.data.note.velocity
     elif ev.type == S.SND_SEQ_EVENT_NOTEOFF:
         mev = midi.NoteOffEvent()
         mev.channel = ev.data.note.channel
         mev.pitch = ev.data.note.note
         mev.velocity = ev.data.note.velocity
     ## add cc, prog, pb, aftertouch events
     elif ev.type == S.SND_SEQ_EVENT_CONTROLLER:
         mev = midi.ControlChangeEvent()
         mev.channel = ev.data.control.channel
         mev.control = ev.data.control.param
         mev.value = ev.data.control.value
     elif ev.type == S.SND_SEQ_EVENT_PGMCHANGE:
         mev = midi.ProgramChangeEvent()
         mev.channel = ev.data.control.channel
         mev.value = ev.data.control.value
     elif ev.type == S.SND_SEQ_EVENT_PITCHBEND:
         mev = midi.PitchWheelEvent()
         mev.channel = ev.data.control.channel
         mev.pitch = ev.data.control.value
     elif ev.type == S.SND_SEQ_EVENT_KEYPRESS:
         mev = midi.AfterTouchEvent()
         mev.channel = ev.data.control.channel
         mev.value = ev.data.control.value
         mev.pitch = ev.data.control.note
     elif ev.type == S.SND_SEQ_EVENT_CHANPRESS:
         mev = midi.ChannelAfterTouchEvent()
         mev.channel = ev.data.control.channel
         mev.value = ev.data.control.value
     else:
         return None
     if ev.time.time.tv_nsec:
         # convert to ms
         mev.msdeay = \
             (ev.time.time.tv_nsec / 1e6) + (ev.time.time.tv_sec * 1e3)
     else:
         mev.tick = ev.time.tick
     return mev
    event_type = chunk_info[1]

    if event_type == "no":
        tick = int(chunk_info[0])
        pitch = int(chunk_info[2])
        velocity = int(chunk_info[3])

        e = midi.NoteOnEvent(tick=tick,
                             channel=0,
                             velocity=velocity,
                             pitch=pitch)
        track.append(e)

    elif event_type == "st":
        tick = int(chunk_info[0])
        bpm = int(chunk_info[2])
        mpqn = int(chunk_info[3])
        ev = midi.SetTempoEvent(tick=tick, bpm=bpm, mpqn=mpqn)
        track.append(ev)

    elif event_type == "cc":
        control = int(chunk_info[3])
        value = int(chunk_info[4])
        e = midi.ControlChangeEvent(channel=0, control=control, value=value)
        track.append(e)

end_event = midi.EndOfTrackEvent(tick=1)
track.append(end_event)

midi.write_midifile(file, pattern)
Beispiel #10
0
def change_music_to_pattern(music):
    music.parse_track_msg()
    # music._init_main_trank()

    pattern = midi.Pattern()
    pattern.resolution = music.get_resolution()
    pattern.format = music.get_play_format()
    for track in reversed(music.track):
        t = midi.Track()
        for event in track:
            event_tick = int(event[0])
            event_event = event[1]
            state_code = event_event["state_code"]
            if state_code == 255:
                if event_event["name"] == 'Set Tempo':
                    eve = midi.SetTempoEvent(tick=event_tick,
                                             bpm=event_event["bpm"])
                elif event_event["name"] == 'Trank Name':
                    eve = midi.TrackNameEvent(tick=event_tick,
                                              text=event_event["text"])
                elif event_event["name"] == 'Copyright Notice':
                    eve = midi.CopyrightMetaEvent(tick=event_tick,
                                                  text=event_event["text"])
                elif event_event["name"] == 'SMPTE Offset':
                    eve = midi.SmpteOffsetEvent(tick=event_tick,
                                                text=event_event["text"])
                elif event_event["name"] == 'Time Signature':
                    eve = midi.TimeSignatureEvent(
                        tick=event_tick,
                        numerator=event_event["numerator"],
                        denominator=event_event["denominator"],
                        metronome=event_event["metronome"],
                        thirtyseconds=event_event["thirtyseconds"])
                elif event_event["name"] == "End of Track":
                    eve = midi.EndOfTrackEvent(tick=event_tick)
                else:
                    continue
            elif 240 <= state_code <= 254:
                # 系统码
                eve = midi.SysexEvent()
            elif 224 <= state_code <= 239:
                # 滑音
                eve = midi.PitchWheelEvent(tick=event_tick,
                                           channel=event_event["channel"],
                                           pitch=event_event["pitch"])
            elif 208 <= state_code <= 223:
                # After Touch
                eve = midi.AfterTouchEvent()
            elif 192 <= state_code <= 207:
                # 乐器转换
                eve = midi.ProgramChangeEvent(tick=event_tick,
                                              channel=event_event["channel"],
                                              data=[event_event["program"]])
            elif 176 <= state_code <= 191:
                # midi控制器
                eve = midi.ControlChangeEvent(
                    tick=event_tick,
                    channel=event_event["channel"],
                    data=[event_event["control"], event_event["value"]])
            elif 160 <= state_code <= 175:
                continue
            elif 144 <= state_code <= 159:
                # note on
                eve = midi.NoteOnEvent(tick=event_tick,
                                       channel=event_event["channel"],
                                       velocity=event_event["velocity"],
                                       pitch=event_event["pitch"])
            elif 128 <= state_code <= 143:
                # note off
                eve = midi.NoteOffEvent(tick=event_tick,
                                        channel=event_event["channel"],
                                        velocity=event_event["velocity"],
                                        pitch=event_event["pitch"])
            elif state_code <= 127:
                continue

            t.append(eve)
        pattern.append(t)
    return pattern
Beispiel #11
0
def track_to_midi(track, resolution=120):
	midi_track = midi.Track()

	# deactivation_queue is an array with a value for each midi note pitch
	# negative numbers indicate the pitch is not active
	# positive numbers are the remaining ticks until cutoff
	deactivation_queue = np.zeros(128, dtype=np.int) - 1
	ticks_to_measure = 0

	for measure in track.measures:
		# TODO:  Handle key and time signature to create midi events
		# TODO:  The pad_rests method probably isn't going to let this handle overlapping beats/rests correctly.

		# Make sure the measure is filled so the next measure starts at the right time.
		measure.pad_rests()
		# Add an empty final beat to run the loop one last time to deactivate notes.
		measure.append_beat()

		for beat in measure.beats:
			ticks_to_beat = midi_length(beat.offset, resolution=resolution)
			if beat is measure.beats[0]:
				ticks_to_beat = ticks_to_beat + ticks_to_measure

			mask = (deactivation_queue >= 0)
			if mask.any():
				ticks_to_off_event = deactivation_queue[mask].min()
			else:
				ticks_to_off_event = 999999999

			# add note off events until time for the next beat
			while ticks_to_off_event <= ticks_to_beat:
				pitches_to_deactivate = np.where(deactivation_queue == ticks_to_off_event)[0]
				deactivation_queue[mask] -= ticks_to_off_event
				deactivation_queue[pitches_to_deactivate] -= 1
				ticks_to_beat -= ticks_to_off_event
				for pitch in pitches_to_deactivate:
					off_event = midi.NoteOffEvent(tick=int(ticks_to_off_event), pitch=int(pitch))
					midi_track.append(off_event)
					ticks_to_off_event = 0
				mask = (deactivation_queue >= 0)
				if mask.any():
					ticks_to_off_event = deactivation_queue[mask].min()
				else:
					ticks_to_off_event = 999999999

			for note in beat.notes:
				if isinstance(note, music.Rest):
					ticks_to_measure = ticks_to_measure + midi_length(note.duration, resolution=resolution)
					continue
				midi_velocity = round(note.intensity * 127)
				midi_pitch = note.value
				note_on_event = midi.NoteOnEvent(tick=int(ticks_to_beat), velocity=midi_velocity, pitch=midi_pitch)
				midi_track.append(note_on_event)
				deactivation_queue[midi_pitch] = midi_length(note.duration, resolution=resolution) # note: doesn't handle ties yet
				ticks_to_beat = 0
				ticks_to_measure = 0

			for event in beat.events:
				if event.name == 'end_track':
					midi_event = midi.EndOfTrackEvent(tick=ticks_to_beat)
				else:
					midi_event = midi.ControlChangeEvent(tick=ticks_to_beat)
				# TODO:  look into event specification
				midi_track.append(midi_event)
				ticks_to_beat = 0
				ticks_to_measure = 0

	# End the track
	if not isinstance(midi_track[-1], midi.EndOfTrackEvent):
		eot = midi.EndOfTrackEvent(tick=1)
		midi_track.append(eot)
	return midi_track
Beispiel #12
0
    def writemidi( self, filedir="" ):
        # sort the events by absoluteticks
        # put all tempo, time signature data in track 0, as well as any instrument or track names

        # first grab the track name
        if self.texts[0][0].text != "":
            trackname = MIDI.TrackNameEvent(text=self.texts[0][0].text, tick=0)
            trackname.absoluteticks = 0
            # for some reason, the data doesn't get through via the text above.
            trackname.data = [ ]
            i = 0
            while i < len(self.texts[0][0].text):
                trackname.data.append( ord( self.texts[0][0].text[i] ) ) 
                i+= 1
            tracks = [[ trackname]] 
            del trackname # so that when we reuse this variable later it doesn't change the above
        else:
            tracks = [[]]
        # put all tempo, time signature data in track 0
        tracks[0] += self.texts[0][1:] + self.tempos+self.timesignatures+self.notes[0]
        # sort everything
        tracks[0].sort(key=operator.attrgetter('absoluteticks'))

        # then grab the instrument
        if self.channels[0] != 9 and self.instruments[0]:
            tracks[0].insert(0, MIDI.ProgramChangeEvent( value=self.instruments[0],
                            channel=self.channels[0]  ) )

        for i in range(1,len(self.notes)):
            # sort each track separately
            # first grab the track name
            if self.texts[i][0].text != "":
                trackname = MIDI.TrackNameEvent(text=self.texts[i][0].text, tick=0)
                # for some reason, the data doesn't get through via the text above.
                trackname.data = [ ]
                trackname.absoluteticks = 0
                j = 0
                while j < len(self.texts[i][0].text):
                    trackname.data.append( ord( self.texts[i][0].text[j] ) ) 
                    j += 1
                tracks.append( [ trackname ] )
                del trackname # so that when we reuse this variable later it doesn't change the above
            else:
                tracks.append( [] )
            # then grab the instrument
            tracks[i] += self.texts[i][1:] + self.notes[i] 
            tracks[i].sort(key=operator.attrgetter('absoluteticks'))
            if self.channels[i] != 9 and self.instruments[i]:
                tracks[i].insert(0, MIDI.ProgramChangeEvent( value=self.instruments[i],
                            channel=self.channels[i] ))

        # now that everything is sorted globally,
        # make sure that the local ticks are correct.
        tickdivisor = config.EDITresolution
        for i in range(len(tracks)):
            tracks[i].insert(0, MIDI.ControlChangeEvent( tick=0, channel=self.channels[i],
                                                        data=[7,127]) )
        for track in tracks:
            previouseventabsoluteticks = 0
            for event in track:
                try:
                    thiseventabsoluteticks = int(event.absoluteticks)
                except AttributeError:
                    thiseventabsoluteticks = 0
                # number of ticks between previous event and the current event
                tickmeoff = thiseventabsoluteticks - previouseventabsoluteticks
                event.tick = tickmeoff
                # check to see how small we can get the resolution
                tickdivisor = gcd( tickdivisor, tickmeoff )
                # set up the ticks for next event
                previouseventabsoluteticks = thiseventabsoluteticks
         
        if config.EDITresolution % tickdivisor:
            Error(" min RESOLUTION does not divide our EDITresolution.  something is funky ")

        # prep the new pattern for creating
        newpattern = MIDI.Pattern( resolution=config.EDITresolution/tickdivisor )
        for track in tracks:
            if tickdivisor > 1:
                for event in track:
                    # divide up the relative ticks
                    event.tick /= tickdivisor
                    # keep absolute ticks in the EDITresolution
            if track[-1].name != "End of Track":
                # add an end of track if it isn't there
                track.append( MIDI.EndOfTrackEvent( tick=config.EDITresolution/tickdivisor ) )
            newpattern.append( MIDI.Track(track) )
        
        if filedir == "":
            MIDI.write_midifile(self.midifile, newpattern)
        else:
            MIDI.write_midifile(filedir, newpattern)
    def revert(self, cut_silence=True):
        invertible_controllers = 64, 65, 66, 67, 68, 69
        new_pattern = midi.Pattern(resolution=self.pattern.resolution,
                                   format=self.pattern.format)
        new_track_group = []

        # Get the time value of the last event.
        times = [
            j[0] for track in self.tracks for i in track.keys()
            for j in track[i] if len(j) != 0
        ]
        if times:
            max_time = max(times)
        else:
            max_time = 0

        for track_num, track in enumerate(self.tracks):
            notes_on = []
            controllers = []
            new_track = []

            # Change order of various events. E.g:
            # delayevt1 -> noninvertevt1 -> delayevt2 -> noninvertevt2. will be
            # changed to: noninvertevt1 -> delayevt1 -> noninvertevt2 -> delayevt2
            # so is easier to revert.

            self.delay_event(track, new_track, "track_name", max_time)
            self.delay_event(track, new_track, "tempo", max_time)
            self.delay_event(track, new_track, "time_signature", max_time)
            self.delay_event(track, new_track, "key_signature", max_time)
            self.delay_event(track, new_track, "marker", max_time)
            self.delay_event(track, new_track, "program_change", max_time)
            self.delay_event(track, new_track, "text_meta", max_time)

            # Doc: The Controller Event signals the change in a MIDI channels state.
            # Controller events might be in pairs or just alone. Check both cases.
            # This inverts appeareance order. E.g:
            # noninvertevt1start -> evt1 -> noninvertevt1end -> noninvertevt2start -> evt2 -> noninvertevt2end
            # changes to: noninvertevt1end -> evt1 -> noninvertevt1start -> noninvertevt2end -> evt2 -> noninvertevt2start.
            for i, evt in enumerate(track['control_change']):
                # First check if the controller is invertible (like pedals).
                if evt[1].data[0] in invertible_controllers:
                    controller_found = False
                    # A value in the range 0 - 63 is off, and 64 - 127 is on.
                    if evt[1].data[1] >= 64 and evt[1].data[1] <= 127:
                        controllers.append(evt)
                        tmp = midi.ControlChangeEvent(tick=evt[1].tick,
                                                      channel=evt[1].channel,
                                                      data=[evt[1].data[0], 0])
                        new_track.append((evt[0], tmp))
                    else:
                        for j, controller in enumerate(controllers):
                            # Look for controller match.
                            if controller[1].data[0] == evt[1].data[0]:
                                new_track.append((evt[0], controller[1]))
                                controllers.pop(j)
                                controller_found = True
                                break

                            if not controller_found:
                                print(
                                    "Warning: No matching controller found on invertible controller."
                                )
                                tmp = midi.ControlChangeEvent(
                                    tick=evt[1].tick,
                                    channel=evt[1].channel,
                                    data=[evt[1].data[0], 127])
                                new_track.append((evt[0], tmp))

                # If it's not invertible just append it changing the order.
                else:
                    if i == len(track['control_change']) - 1:
                        new_track.append((max_time, evt[1]))
                    else:
                        new_track.append(
                            (track['control_change'][i + 1][0], evt[1]))

            if len(controllers) != 0:
                # The unmatched ones are probably at the end of the track.
                print("Warning: Track " + str(track_num) + ", " +
                      str(len(controllers)) + " controller event/s unmatched.")
                for c in controllers:
                    new_track.append((max_time, c))

            # Revert notes (invert appearance order).
            for evt in track['note_on']:
                # Notes on.
                if evt[1].data[1] != 0:
                    notes_on.append(evt)
                    tmp = midi.NoteOnEvent(tick=evt[1].tick,
                                           channel=evt[1].channel,
                                           data=[evt[1].data[0], 0])
                    new_track.append((evt[0], tmp))

                # Notes off.
                else:
                    note_found = False
                    for i, note in enumerate(notes_on):
                        # Look for note match.
                        if note[1].data[0] == evt[1].data[0]:
                            new_track.append((evt[0], note[1]))
                            notes_on.pop(i)
                            note_found = True
                            break

                    if not note_found:
                        print("Warning: No matching note found.")
                        tmp = midi.NoteOnEvent(tick=evt[1].tick,
                                               channel=evt[1].channel,
                                               data=[evt[1].data[0], 100])
                        new_track.append((evt[0], tmp))

            # The same as before.
            for evt in track['note_off']:
                note_found = False
                for i, note in enumerate(notes_on):
                    # Look for note match.
                    if note[1].data[0] == evt[1].data[0]:
                        new_track.append((evt[0], note[1]))
                        notes_on.pop(i)
                        note_found = True
                        break

                if not note_found:
                    print("Warning: No matching note found.")
                    tmp = midi.NoteOnEvent(tick=evt[1].tick,
                                           channel=evt[1].channel,
                                           data=[evt[1].data[0], 100])
                    new_track.append((evt[0], tmp))

            if len(notes_on) != 0:
                print("Warning: Track " + str(track_num) + ", " +
                      str(len(notes_on)) + " note/s unmatched.")

            # Lyrics won't be changed.
            for evt in track['lyric']:
                new_track.append(evt)

            # Sort and eliminate the empty time after the reversal.
            new_track.sort(key=lambda x: x[0], reverse=True)
            for i, evt in enumerate(new_track):
                t = max_time - evt[0]
                new_track[i] = (t, evt[1])
            new_track_group.append(list(new_track))

        # Find the time when the first note occurs and cut the silence between.
        if cut_silence:
            noteon_times = [
                evt[0] for track in new_track_group for evt in track
                if isinstance(evt[1], midi.NoteOnEvent)
            ]
            if len(noteon_times) > 0:
                min_noteon = min(noteon_times)
                if min_noteon != 0:
                    for i, track in enumerate(new_track_group):
                        for j, evt in enumerate(track):
                            t = evt[0] - min_noteon
                            if t >= 0:
                                new_track_group[i][j] = (t, evt[1])

        self.open(read=new_track_group, open_file=False)
Beispiel #14
0
    for j in range(len(r[i])):
        r[i][j] = int(r[i][j])
# print(r)

# In[37]:

pattern = midi.Pattern(format=1,
                       resolution=480,
                       tracks=[
                           midi.Track([
                               midi.TimeSignatureEvent(tick=0,
                                                       data=[4, 2, 24, 8]),
                               midi.KeySignatureEvent(tick=0, data=[0, 0]),
                               midi.SetTempoEvent(tick=0, data=[7, 161, 32]),
                               midi.ControlChangeEvent(tick=0,
                                                       channel=0,
                                                       data=[121, 0]),
                               midi.ProgramChangeEvent(tick=0,
                                                       channel=0,
                                                       data=[0]),
                               midi.ControlChangeEvent(tick=0,
                                                       channel=0,
                                                       data=[7, 100]),
                               midi.ControlChangeEvent(tick=0,
                                                       channel=0,
                                                       data=[10, 64]),
                               midi.ControlChangeEvent(tick=0,
                                                       channel=0,
                                                       data=[91, 0]),
                               midi.ControlChangeEvent(tick=0,
                                                       channel=0,
Beispiel #15
0
def drum_matrix_to_midi(drum_matrix,tatums_per_beat,output_filename,midi_ref_file,notes=None):
    '''
    write a drum pattern matrix to a midi file

    input:
    drum_matrix - drum onsets to be converted to midi 
                [one drum per row, one tatum per column]
    tatums_per_beat - number of subdivisions per beat
    output_filename - file to write midi output to
    midi_ref_file - midi file to steal header info (tempo, etc.) from
    notes - (optional) the midi notes to write each drum column to
    '''

    if notes is None:
        notes = [36, 38, 42, 46, 51]

    parsed_midi = midi.read_midifile(midi_ref_file) #gets a list of events
    parsed_midi.make_ticks_abs() #turns the ticks into absolute ms times
    events = parsed_midi[0]
    resolution = parsed_midi.resolution
    print 'resolution:', resolution
    tempo = 0
    for e in events:
        if e.name == 'Set Tempo':
            tempo = e.get_bpm()
            print 'detected tempo:',tempo
            break
    if tempo is 0:
        print 'did not detect tempo'

    tatum = resolution/tatums_per_beat

    # ignore small amplitude onsets
    thresh = 0.05 * drum_matrix.max()
    onset_locs = np.where(drum_matrix > thresh)

    # convert tatums to ticks
    num_tatums = drum_matrix.shape[1]
    ticks = np.arange(num_tatums) * tatum

    
    # create note on/off events
    events = []
    for i in xrange(len(onset_locs[0])):

        note = notes[onset_locs[0][i]]
        tick = ticks[onset_locs[1][i]]
        vel = int(max(0,min(127, 127 * drum_matrix[onset_locs[0][i],onset_locs[1][i]])))

        on = midi.NoteOnEvent()
        on.channel = 9
        on.set_pitch(note)
        on.set_velocity(vel)
        on.tick = tick
        events += [on]

        off = midi.NoteOffEvent()
        off.channel = 9
        off.set_pitch(note)
        off.set_velocity(64)
        off.tick = tick + 60
        events += [off]
    # create hihat footcontrol events
    # (for now just set all to max [closed hihat])

    for t in ticks:

        val = 127 # all the way down

        control = midi.ControlChangeEvent()
        control.channel = 9
        control.set_control(4)
        control.set_value(val)
        control.tick = t
        events += [control]


    # sort events in tick order
    inds = np.argsort([e.tick for e in events])
    # reuse midi headers
    new_track = midi.Track(parsed_midi[0])

    for e in parsed_midi[0]:
        if e.name == 'Note Off' or e.name == 'Note On' or e.name == 'Control Change':
            new_track.remove(e)
        if e.name == 'End of Track':
            end_of_track = e
            new_track.remove(e)

    # set end of track to time of last event + one beat
    end_of_track.tick = ticks[-1] + resolution

    for i in inds:
        new_track += [events[i]]
    new_track += [end_of_track]
    parsed_midi[0] = new_track
    parsed_midi[0].make_ticks_rel()

    midi.write_midifile(output_filename,parsed_midi)

    return parsed_midi
Beispiel #16
0
 def csv_to_midi(self, fpath):
     track = midi.Track()
     track.append(midi.SequencerSpecificEvent(tick=0, data=[5, 15, 9, 70, 200]))
     track.append(midi.SequencerSpecificEvent(tick=0, data=[5, 15, 6, 71, 101, 110, 101, 114, 97, 108, 32, 77, 73, 68, 73]))
     track.append(midi.TrackNameEvent(tick=0, text='Acoustic Grand Piano High', data=[65, 99, 111, 117, 115, 116, 105, 99, 32, 71, 114, 97, 110, 100, 32, 80, 105, 97, 110, 111, 32, 72, 105, 103, 104]))
     track.append(midi.ProgramChangeEvent(tick=0, channel=0, data=[0]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[10, 64]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[10, 64]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[10, 64]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[7, 127]))
     track.append(midi.ControlChangeEvent(tick=3, channel=0, data=[100, 64]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[101, 64]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[100, 64]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[101, 64]))
     track.append(midi.ControlChangeEvent(tick=1, channel=0, data=[6, 12]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[6, 12]))
     track.append(midi.ControlChangeEvent(tick=1, channel=0, data=[38, 0]))
     track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[38, 0]))
     track.append(midi.NoteOnEvent(tick=5, channel=0, data=[67, 69]))
     df = pd.read_csv(fpath, index_col=0, names=["Tick", "Data1", "Data2","Evt_Type"], header=0)
     nrows = len(df.iloc[:, 0])
     for i in range(nrows):
         if df.Evt_Type[i] == "p":
             evt = midi.events.ProgramChangeEvent(tick=int(df.Tick[i]), data=[int(df.Data1[i]) + 50, int(df.Data2[i])])
             track.append(evt)
         if df.Evt_Type[i] == "c":
             evt = midi.events.ControlChangeEvent(tick=int(df.Tick[i]), data=[int(df.Data1[i]), int(df.Data2[i])])
             track.append(evt)
         if df.Evt_Type[i] == "n":
             evt = midi.events.NoteOnEvent(tick=int(df.Tick[i]), data=[int(df.Data1[i]), int(df.Data2[i])])
             track.append(evt)
     track.append(midi.events.EndOfTrackEvent())
     for t in track:
         print(t)
     self.tracks_to_mid([track], "output_test.mid")
Beispiel #17
0
import midi

MARY_MIDI = midi.Pattern(
    tracks=[[
        midi.TimeSignatureEvent(tick=0, data=[4, 2, 24, 8]),
        midi.KeySignatureEvent(tick=0, data=[0, 0]),
        midi.EndOfTrackEvent(tick=1, data=[])
    ],
            [
                midi.ControlChangeEvent(tick=0, channel=0, data=[91, 58]),
                midi.ControlChangeEvent(tick=0, channel=0, data=[10, 69]),
                midi.ControlChangeEvent(tick=0, channel=0, data=[0, 0]),
                midi.ControlChangeEvent(tick=0, channel=0, data=[32, 0]),
                midi.ProgramChangeEvent(tick=0, channel=0, data=[24]),
                midi.NoteOnEvent(tick=0, channel=0, data=[64, 72]),
                midi.NoteOnEvent(tick=0, channel=0, data=[55, 70]),
                midi.NoteOnEvent(tick=231, channel=0, data=[64, 0]),
                midi.NoteOnEvent(tick=25, channel=0, data=[62, 72]),
                midi.NoteOnEvent(tick=231, channel=0, data=[62, 0]),
                midi.NoteOnEvent(tick=25, channel=0, data=[60, 71]),
                midi.NoteOnEvent(tick=231, channel=0, data=[60, 0]),
                midi.NoteOnEvent(tick=25, channel=0, data=[62, 79]),
                midi.NoteOnEvent(tick=206, channel=0, data=[55, 0]),
                midi.NoteOnEvent(tick=25, channel=0, data=[62, 0]),
                midi.NoteOnEvent(tick=25, channel=0, data=[64, 85]),
                midi.NoteOnEvent(tick=0, channel=0, data=[55, 79]),
                midi.NoteOnEvent(tick=231, channel=0, data=[64, 0]),
                midi.NoteOnEvent(tick=25, channel=0, data=[64, 78]),
                midi.NoteOnEvent(tick=231, channel=0, data=[64, 0]),
                midi.NoteOnEvent(tick=25, channel=0, data=[64, 74]),
                midi.NoteOnEvent(tick=462, channel=0, data=[55, 0]),
def instrument_num(instrument):
    """Given a GUS patch name, get the MIDI instrument number.

       For percussion instruments, the instrument number is offset
       by 128.
    """
    for key, name in GUS_INSTR_PATCHES.items():
        if name == instrument:
            return key
    raise Exception("Unknown instrument %s" % instrument)


pattern = midi.Pattern(resolution=48)
track = midi.Track()
track.append(midi.ControlChangeEvent(tick=0, channel=9, data=[7, 92]))

time = 500
for group in SIMILAR_GROUPS:
    # Don't bother with special effects.
    # if group[0] == 'blank':
    #   continue

    print("Group: ")
    empty = True
    for instrument in group:
        inum = instrument_num(instrument)

        # For normal instruments, play a couple of different notes.
        # For percussion instruments, play a couple of note on
        # the percussion channel.
Beispiel #19
0
 def finish(self, filename):
     # "All Notes End" event
     self.track.append(midi.ControlChangeEvent(tick=0, control=123))
     self.track.append(midi.EndOfTrackEvent(tick=1))
     midi.write_midifile(filename, self.pattern)
Beispiel #20
0
    def writemidi(self, filedir=""):
        # sorteer de events van abs ticks
        # gooit alle tracks en time signatures in track [0]

        # pak de track naam
        if self.texts[0][0].text != "":
            trackname = MIDI.TrackNameEvent(text=self.texts[0][0].text, tick=0)
            trackname.absoluteticks = 0
            # dunno werkt niet voor een of andere reden
            trackname.data = []
            i = 0
            while i < len(self.texts[0][0].text):
                trackname.data.append(ord(self.texts[0][0].text[i]))
                i += 1
            tracks = [[trackname]]
            del trackname  # verwijderd de naam als de hierboven genoteerde naam opnieuw wordt gebruikt
        else:
            tracks = [[]]
        # gooi alles in track [0]
        tracks[0] += self.texts[0][
            1:] + self.tempos + self.timesignatures + self.notes[0]
        # sorteer alles
        tracks[0].sort(key=operator.attrgetter('absoluteticks'))

        # pakt de instrument
        if self.channels[0] != 9 and self.instruments[0]:
            tracks[0].insert(
                0,
                MIDI.ProgramChangeEvent(value=self.instruments[0],
                                        channel=self.channels[0]))

        for i in range(1, len(self.notes)):
            # sorteer de tracks
            # pak de track naam
            if self.texts[i][0].text != "":
                trackname = MIDI.TrackNameEvent(text=self.texts[i][0].text,
                                                tick=0)
                # dunno dit werkt niet voor een of andere reden
                trackname.data = []
                trackname.absoluteticks = 0
                j = 0
                while j < len(self.texts[i][0].text):
                    trackname.data.append(ord(self.texts[i][0].text[j]))
                    j += 1
                tracks.append([trackname])
                del trackname  # verwijderd de naam als de hierboven genoteerde naam opnieuw wordt gebruikt
            else:
                tracks.append([])
            # pak de instrument
            tracks[i] += self.texts[i][1:] + self.notes[i]
            tracks[i].sort(key=operator.attrgetter('absoluteticks'))
            if self.channels[i] != 9 and self.instruments[i]:
                tracks[i].insert(
                    0,
                    MIDI.ProgramChangeEvent(value=self.instruments[i],
                                            channel=self.channels[i]))

        # kijk of de lokale ticks goed zijn
        tickdivisor = config.EDITresolution
        for i in range(len(tracks)):
            tracks[i].insert(
                0,
                MIDI.ControlChangeEvent(tick=0,
                                        channel=self.channels[i],
                                        data=[7, 127]))
        for track in tracks:
            previouseventabsoluteticks = 0
            for event in track:
                try:
                    thiseventabsoluteticks = int(event.absoluteticks)
                except AttributeError:
                    thiseventabsoluteticks = 0
                # aantal ticks in vergelijking tot voorgaande ticks en current ticks
                tickmeoff = thiseventabsoluteticks - previouseventabsoluteticks
                event.tick = tickmeoff
                # om te kijken hoe klein de resolutie is
                tickdivisor = gcd(tickdivisor, tickmeoff)
                # set de ticks voor de volgende event(midi)
                previouseventabsoluteticks = thiseventabsoluteticks

        if config.EDITresolution % tickdivisor:
            Error(
                " min RESOLUTON kan niet gedeeld worden door EDITresolution.  er is iets gaande "
            )

        newpattern = MIDI.Pattern(resolution=config.EDITresolution /
                                  tickdivisor)
        for track in tracks:
            if tickdivisor > 1:
                for event in track:
                    # deel de relatieve ticks
                    event.tick /= tickdivisor
                    # laat abs ticks in de edit resolution
            if track[-1].name != "End of Track":
                # voeg het einde van een track hier als het er niet is
                track.append(
                    MIDI.EndOfTrackEvent(tick=config.EDITresolution /
                                         tickdivisor))
            newpattern.append(MIDI.Track(track))

        if filedir == "":
            MIDI.write_midifile(self.midifile, newpattern)
        else:
            MIDI.write_midifile(filedir, newpattern)
Beispiel #21
0
    def notes_only_csv_to_mid(self, fpath):
        track = midi.Track()
        track.append(midi.SequencerSpecificEvent(tick=0, data=[5, 15, 9, 70, 200]))
        track.append(midi.SequencerSpecificEvent(tick=0, data=[5, 15, 6, 71, 101, 110, 101, 114, 97, 108, 32, 77, 73, 68, 73]))
        track.append(midi.TrackNameEvent(tick=0, text='Acoustic Grand Piano High', data=[65, 99, 111, 117, 115, 116, 105, 99, 32, 71, 114, 97, 110, 100, 32, 80, 105, 97, 110, 111, 32, 72, 105, 103, 104]))
        track.append(midi.ProgramChangeEvent(tick=0, channel=0, data=[0]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[10, 64]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[10, 64]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[10, 64]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[7, 127]))
        track.append(midi.ControlChangeEvent(tick=3, channel=0, data=[100, 64]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[101, 64]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[100, 64]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[101, 64]))
        track.append(midi.ControlChangeEvent(tick=1, channel=0, data=[6, 12]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[6, 12]))
        track.append(midi.ControlChangeEvent(tick=1, channel=0, data=[38, 0]))
        track.append(midi.ControlChangeEvent(tick=0, channel=0, data=[38, 0]))
        track.append(midi.NoteOnEvent(tick=5, channel=0, data=[67, 69]))
        df = pd.read_csv(fpath, index_col=0, names=["Tick", "Data1", "Data2","Evt_Type"], header=0)
        nrows = len(df.iloc[:, 0])
        oor = False
        for i in range(nrows):
            tick = int(abs(df.iloc[i, 0]))
            d1 = int(abs(df.iloc[i, 1]))
            d2 = int(abs(df.iloc[i, 2]))
            if tick > 256 or tick < 0 or d1 > 256 or d1 < 0 or d2 > 256 or d2 < 0:
                print("Note in position {} out of range".format(str(i)))
                break
            evt = midi.events.NoteOnEvent(tick=tick, data=[d1, d2])
            track.append(evt)

        track.append(midi.events.EndOfTrackEvent())
        for t in track:
            print(t)
        self.tracks_to_mid([track], "output_test.mid")