def write_pitches(self, smf_track, channel, program, voice_pitch_data): track = midi.MidiTrack(smf_track) self.add_program_change(track, channel, program) last_pitch_data = tuple() deoverlapped = [] for pitch_data in sorted(voice_pitch_data, key=lambda x: x[0]): if last_pitch_data: last_clock, last_duration, last_pitch, last_velocity = last_pitch_data assert last_duration > 0, (last_pitch_data, pitch_data) clock, _, _, _ = pitch_data last_duration = min(last_duration, clock - last_clock) assert last_duration > 0, (last_duration, clock, last_clock, clock - last_clock) deoverlapped.append( (last_clock, last_duration, last_pitch, last_velocity)) last_pitch_data = pitch_data if deoverlapped: deoverlapped.append(last_pitch_data) last_clock = 0 for pitch_data in deoverlapped: clock, duration, pitch, velocity = pitch_data assert velocity last_clock = self.add_note(track, channel, pitch, velocity, last_clock, clock, duration) add_end_of_track(track, channel) return track
def main(): mt = midi.MidiTrack(1) # duration, pitch, velocity data = [] # one start note beats_per_measure = 4 measures = 16 num_beats = measures * beats_per_measure # note array is ordered [duration, pitch, velocity] for i in range(1, num_beats): # pick random pitch and velocity for 8th note duration = 512 pitch = random.randint(0, 128) velocity = random.randint(0, 128) data.append([duration, pitch, velocity]) populate_midi_track_from_data(mt, data) mf = midi.MidiFile() mf.tracks.append(mt) env = environment.Environment() temp_filename = env.getTempFile('.mid') print("Saving file to: %s" % temp_filename) mf.open(temp_filename, 'wb') mf.write() mf.close()
def save_song(song): ''' Takes in the converted sequence and creates a midi stream, saves each note/chord and rest object to the stream then saves as a midi file in the VAE_generated_sequences fdir ''' mt = midi.MidiTrack(0) dtime = midi.DeltaTime(mt) dtime.time = 0.5 new_stream = stream.Stream() midi_save_dir = 'VAE_generated_sequences\\' for element in song: if ('.' in element) or element.isdigit(): chord_component = element.split('-') duration_ = 1.0 if '/' in chord_component[1]: duration_components = chord_component[1].split('/') duration_ = (int(duration_components[0])) / (int( duration_components[1])) else: duration_ = chord_component[1] notes_in_chord = chord_component[0].split('.') notes = [] for current_note in notes_in_chord: new_note = note.Note(int(current_note)) notes.append(new_note) new_chord = chord.Chord(notes) new_chord.quarterLength = float(duration_) new_stream.append(new_chord) elif '.' not in element and (len(element) != 0): note_component = element.split('-') duration_ = None if '/' in note_component[1]: duration_components = note_component[1].split('/') duration_ = (int(duration_components[0])) / (int( duration_components[1])) else: duration_ = note_component[1] new_note = note.Note(int(note_component[0])) new_note.quarterLength = float(duration_) new_stream.append(new_note) elif element is "": new_stream.append(rest.Rest()) count = len(os.listdir(midi_save_dir)) + 1 midi_out = new_stream.write('midi', fp=midi_save_dir + str(count) + '_' + dataset_name + '_' + str(100) + '_' + str(timestamp) + ".mid") print('-----------------------------') print('Sequence has been generated') print('-----------------------------')
def events_to_track(index, channel, events): track = midi.MidiTrack(index=index) last_clock = 0 for clock, event in sorted(events, key=lambda t: t[0]): delta_clock = clock - last_clock last_clock = clock add_event(track, event, delta_clock, channel) add_end_of_track(track, channel) return track
def save_song(song, folder): mt = midi.MidiTrack(0) dtime = midi.DeltaTime(mt) dtime.time = 0.5 new_stream = stream.Stream() new_stream.duration.quarterLength save_dir = params['save_dir'] + folder + '\\' for element in song: if ('.' in element) or element.isdigit(): chord_component = element.split('-') duration_ = 1.0 if '/' in chord_component[1]: duration_components = chord_component[1].split('/') duration_ = (int(duration_components[0])) / (int( duration_components[1])) else: duration_ = chord_component[1] notes_in_chord = chord_component[0].split('.') notes = [] for current_note in notes_in_chord: new_note = note.Note(int(current_note)) notes.append(new_note) new_chord = chord.Chord(notes) new_chord.quarterLength = float(duration_) new_stream.append(new_chord) elif '.' not in element and (len(element) != 0): note_component = element.split('-') duration_ = None if '/' in note_component[1]: duration_components = note_component[1].split('/') duration_ = (int(duration_components[0])) / (int( duration_components[1])) else: duration_ = note_component[1] new_note = note.Note(int(note_component[0])) new_note.quarterLength = float(duration_) new_stream.append(new_note) elif element is "": new_stream.append(rest.Rest()) name = folder + 'file_' count = len(os.listdir(save_dir)) + 1 midi_out = new_stream.write('midi', fp=save_dir + name + str(count) + ".mid")
def requiredHeader(tempo=117): mt1 = midi.MidiTrack(1) ''' FROM EVENT: midi.getNumber('<str data>', 3)[0] TEMPO TO EVENT: int(round(60000000.0/bpm) me.data = midi.putNumber(<result>, 3) ''' tempo = tempo tempo = int(round(60000000.0 / tempo)) tempo = midi.putNumber(tempo, 3) deltaWrite(mt1, 0) eventWrite(mt1, 'SEQUENCE_TRACK_NAME', 'Piano') deltaWrite(mt1, 0) eventWrite(mt1, 'SET_TEMPO', tempo) deltaWrite(mt1, 0) eventWrite(mt1, 'TIME_SIGNATURE', '\x04\x02\x18\x08') return mt1
def process_midi(self, message, deltatime): self._wallclock += deltatime status, note, velocity = message dt = midi.DeltaTime(self.track) dt.time = deltatime * 1000 self.track.events.append(dt) event = midi.MidiEvent(self.track) event.channel = 1 event.pitch = note event.velocity = velocity if status & 0xF0 == NOTE_ON: event.type = "NOTE_ON" self.track.events.append(event) else: event.type = "NOTE_OFF" self.track.events.append(event) stream = midi.translate.midiTrackToStream( self.track).flat.notesAndRests if len(stream) >= seq_len: print("Go Predict", flush=True) self.process_stream(stream[-seq_len:]) self.track = midi.MidiTrack(1)
def np_seq2mid(np_seq): """ Converts a numpy array to a midi file. :param np_seq: numpy beat sequence :return: music21.midi.MidiFile """ mt = midi.MidiTrack(1) t = 0 tlast = 0 for step in np_seq: # onset will be true if at least one trig is > 0.0 # the remaining trigs are added at the same delta time onset = False # we encountered an onset at this step for idx, trig in enumerate(step[:15]): # find the group group = None for index, grp in enumerate(PERC_GROUPS): if idx in grp: group = index if trig > 0.0: vel = int(step[15 + group] * 127) pitch = PERC_MAP[idx] dt = midi.DeltaTime(mt) if onset is False: dt.time = t - tlast else: dt.time = 0 mt.events.append(dt) me = midi.MidiEvent(mt) me.type = "NOTE_ON" me.channel = 10 me.time = None # d me.pitch = pitch me.velocity = vel mt.events.append(me) if onset is False: tlast = t + 6 onset = True if onset is True: # reset onset for the noteoff onset = False # makes the note off now for idx, trig in enumerate(step[:15]): if trig > 0.0: pitch = PERC_MAP[idx] dt = midi.DeltaTime(mt) if onset is False: dt.time = 6 else: dt.time = 0 mt.events.append(dt) me = midi.MidiEvent(mt) me.type = "NOTE_OFF" me.channel = 10 me.time = None # d me.pitch = pitch me.velocity = 0 mt.events.append(me) if onset is False: onset = True t += TICKS_PER_Q / BEAT_DIV # add end of track dt = midi.DeltaTime(mt) dt.time = 0 mt.events.append(dt) me = midi.MidiEvent(mt) me.type = "END_OF_TRACK" me.channel = 1 me.data = '' # must set data to empty string mt.events.append(me) # make midi file mf = midi.MidiFile() mf.ticksPerQuarterNote = TICKS_PER_Q # cannot use: 10080 mf.tracks.append(mt) return mf
def idxsToMidi(idxs, verbose=False): mf = midi.MidiFile() mf.ticksPerQuarterNote = 1024 # The maestro dataset uses the first track to store tempo data, and the second # track to store the actual performance. So follow that convention. tempo_track = midi.MidiTrack(0) track = midi.MidiTrack(1) mf.tracks = [tempo_track, track] tempo = midi.MidiEvent(tempo_track, type=midi.MetaEvents.SET_TEMPO) # temp.data is the number of microseconds per beat (per quarter note) # So to set ticks per millis = 1 (easy translation from time-shift values to ticks), # tempo.data must be 1e3 * 1024, since ticksPerQuarterNote is 1024 (see above) tempo.data = int(1e3 * 1024).to_bytes(3, 'big') end_of_track = midi.MidiEvent(tempo_track, type=midi.MetaEvents.END_OF_TRACK) end_of_track.data = '' tempo_track.events = [ # there must always be a delta time before each event midi.DeltaTime(tempo_track, time=0), tempo, midi.DeltaTime(tempo_track, time=0), end_of_track ] track.events = [midi.DeltaTime(track, time=0)] current_velocity = 0 notes_on = set() errors = {'is_on': 0, 'is_not_on': 0} for idx in idxs: if 0 <= idx < 128: # note-on pitch = idx if pitch in notes_on: if verbose: print(pitch, 'is already on') errors['is_on'] += 1 continue if track.events[-1].type != 'DeltaTime': track.events.append(midi.DeltaTime(track, time=0)) track.events.append(makeNote(track, pitch, current_velocity)) notes_on.add(pitch) elif 128 <= idx < (128 + 128): # note-off pitch = idx - 128 if pitch not in notes_on: if verbose: print(pitch, 'is not on') errors['is_not_on'] += 1 continue if track.events[-1].type != 'DeltaTime': track.events.append(midi.DeltaTime(track, time=0)) track.events.append(makeNote(track, pitch, 0)) notes_on.remove(pitch) elif (128 + 128) <= idx < (128 + 128 + 100): # time-shift t = (1 + idx - (128 + 128)) * 10 if track.events[-1].type == 'DeltaTime': # combine repeated delta times track.events[-1].time += t else: track.events.append(midi.DeltaTime(track, time=t)) else: # velocity current_velocity = (idx - (128 + 128 + 100)) * 4 if verbose: print('remaining notes left on:', notes_on) if track.events[-1].type != 'DeltaTime': track.events.append(midi.DeltaTime(track, time=0)) track.events.append(end_of_track) return mf, errors
def __init__(self, port): self.port = port self._wallclock = 0 self.track = midi.MidiTrack(1)
def track_zero(): track_zero = midi.MidiTrack(0) add_end_of_track(track_zero, 0) return track_zero