def roll2midi(roll, notesMap, reductionRatio=128): #roll is a (1, ts, input_dim) tensor mid = MidiFile() track = MidiTrack() mid.tracks.append(track) tones = np.zeros(roll.shape[1]) ticks = 0 for ts in roll: for i in range(ts.shape[0]-1): if ts[i] == 1 and tones[i] == 0: #record note_on event track.append(Message('note_on', velocity=127, note=notesMap[i], time=ticks*reductionRatio)) tones[i] = 1 ticks = 0 if ts[i] == 0 and tones[i] == 1: #record note_off event track.append(Message('note_off', velocity=127, note=notesMap[i], time=ticks*reductionRatio)) tones[i] = 0 ticks = 0 ticks += 1 #last pass for notes off (end of track) for i in range(roll.shape[1]): if tones[i] == 1: track.append(Message('note_off', note=notesMap[i], time=ticks*reductionRatio)) ticks = 0 return mid
def comptineN2(): """Generate the midi file of the comptine d'un autre été""" mid = MidiFile() trackl = MidiTrack() trackl.name = "Left hand" for i in range(8): trackl = comp_lh1(trackl) trackl = comp_lh1(trackl) trackl = comp_lh2(trackl) trackl = comp_lh2(trackl) trackl.append(Message('note_on', note=52)) trackl.append(Message('note_off', note=52, time=200)) mid.tracks.append(trackl) trackr = MidiTrack() trackr.name = 'Right hand' trackr.append(Message('note_on', note=67, velocity=0, time=3200)) trackr = comp_rh1(trackr) trackr = comp_rh2(trackr) trackr = comp_rh2(trackr) trackr = comp_rh3(trackr) trackr = comp_rh3(trackr, end=True) trackr = comp_rh4(trackr) trackr.append(Message('note_on', note=71)) trackr.append(Message('note_off', note=71, time=200)) mid.tracks.append(trackr) mid.ticks_per_beat = 100 vols = generate_vol() mid = volume(mid, vols) return mid
def save_to_midi(midi_info, sub_div, filename) -> None: mid = MidiFile() track = MidiTrack() mid.tracks.append(track) Rhythm = [] note_event = [] BEATS = [] for beat, event in enumerate(midi_info): note = event[1] tat_loc = event[0] for i in zip(tat_loc, note): note_event.append(i) BEATS.append(note_event) note_event = [] ## iterate over the arrays for event, decode in enumerate(BEATS): Beat_frame = np.zeros(16) for element in decode: Beat_frame[element[0]] = element[1] Rhythm.append(Beat_frame) for Ry in Rhythm: for y in Ry: y = int((y / 1000) * 127) message = 'note_{}'.format('on' if y != 0 else 'off') track.append(Message(message, note=y, time=sub_div)) mid.save(filename)
def drum_pattern_repeat_recursion(level: Dict[str, Union[str, Dict[str, Union[str, list]], int]], drum_track: MidiTrack, ticks_per_measure: int, ticks_per_beat: int) -> None: """Parses, recurisvely, a drum pattern and adds note events :param level: The current level of the nested pattern :type level: Dict[str, Union[str, Dict[str, Union[str, list]], int]] :param drum_track: The drum track to add note events to :type drum_track: mido.MidiTrack :param ticks_per_measure: how many ticks in a measure of this pattern :type ticks_per_measure: int :param ticks_per_beat: how many ticks per beat of this file :type ticks_per_beat: int """ if "repeat_count" in level: for _ in range(0, cast(int, level["repeat_count"])): for b in cast( List[Dict[str, Union[str, Dict[str, Union[str, list]], int]]], level["subpattern"]): drum_pattern_repeat_recursion(b, drum_track, ticks_per_measure, ticks_per_beat) else: drum_track.append( Message(cast(str, level['note_event']), note=drum_types[cast(str, level["drum_type"])], channel=9, time=int( round( cast(int, level["time"]) * ticks_per_beat * 4 / ticks_per_measure))))
def toMidi(Indexes, ticks): #print(Indexes) moments = [[] for i in range(len(Indexes) + 4)] current = 0 for note in Indexes: decoded = indexToNote(note) moments[current].append(decoded[0]) #print(current, decoded[1], len(Indexes)) moments[current + decoded[1]].append(-decoded[0]) current += 1 newMid = MidiFile() track = MidiTrack() newMid.tracks.append(track) tick_time = round(ticks * 0.1) * 2 for moment in moments: for ivent in moment: if (ivent < 0): track.append( Message('note_off', note=-ivent, velocity=0, time=tick_time)) else: track.append( Message('note_on', note=ivent, velocity=64, time=tick_time)) return newMid
class SaveMIDI: def __init__(self): self.isrecording = False self.start_time = time.time() def start_recording(self): self.mid = MidiFile() self.track = MidiTrack() self.mid.tracks.append(self.track) self.isrecording = True menu.render_message("Recording started", "", 1500) self.restart_time() def cancel_recording(self): self.isrecording = False menu.render_message("Recording canceled", "", 1500) def add_track(self, status, note, velocity, time): self.track.append(Message(status, note=int(note), velocity=int(velocity), time=int(time))) def add_control_change(self, status, channel, control, value, time): self.track.append(Message(status, channel=int(channel), control=int(control), value=int(value), time=int(time))) def save(self, filename): self.isrecording = False self.mid.save('Songs/'+filename+'.mid') menu.render_message("File saved", filename+".mid", 1500) def restart_time(self): self.start_time = time.time()
def handle_recording(self): self.log.info('Starting recording thread') self.log.info('Getting a handle to the sequencer...') self.midi_recording = self.get_midi_sequencer() self.log.info('Got sequencer.') mid = MidiFile() track = MidiTrack() mid.tracks.append(track) self.log.info('About to enter loop, output file: %s' % repr(self.output_file)) last_event_time = None while True: for event in self.midi_recording.iter_pending(): now_time = current_milli_time() if last_event_time is not None: event.time = now_time - last_event_time # Otherwise event.time stays at 0. last_event_time = now_time track.append(event) self.log.info('Appending event to track: %s' % event) if self.mode != RECORD: break time.sleep(0.001) self.log.info('Saving to output_file %s (filename %s)' % (repr(self.output_file), self.output_filename)) mid.save(self.output_file) self.midi_recording.close() self.log.info('Exiting recording thread')
def save_midi(path, pitches, intervals, velocities): """ Save extracted notes as a MIDI file Parameters ---------- path: the path to save the MIDI file pitches: np.ndarray of bin_indices intervals: list of (onset_index, offset_index) velocities: list of velocity values """ file = MidiFile() track = MidiTrack() file.tracks.append(track) ticks_per_second = file.ticks_per_beat * 2.0 events = [] for i in range(len(pitches)): events.append(dict(type='on', pitch=pitches[i], time=intervals[i][0], velocity=velocities[i])) events.append(dict(type='off', pitch=pitches[i], time=intervals[i][1], velocity=velocities[i])) events.sort(key=lambda row: row['time']) last_tick = 0 for event in events: current_tick = int(event['time'] * ticks_per_second) velocity = int(event['velocity'] * 127) if velocity > 127: velocity = 127 pitch = int(round(hz_to_midi(event['pitch']))) track.append(Message('note_' + event['type'], note=pitch, velocity=velocity, time=current_tick - last_tick)) last_tick = current_tick file.save(path)
def guitar_pattern_repeat_recursion(level: Dict[str, Union[str, int, Dict[str, Union[str, list]]]], track: MidiTrack, sequences: List[List[List[int]]], a: int, b: int, ticks_per_measure: int, ticks_per_beat: int) -> None: """Parses, recurisvely, a guitar pattern and adds note_events :param level: The current level of the nested pattern :type level: Dict[str, Union[str, Dict[str, Union[str, list]], int]] :param track: The guitar track to add note events to :type track: mido.MidiTrack :param sequences: The array of notes :type sequences: List[List[List[int]]] :param a: The current sequence :type a: int :param b: The current chord in the sequence :type b: int :param ticks_per_measure: how many ticks in a measure of this pattern :type ticks_per_measure: int :param ticks_per_beat: how many ticks per beat of this file :type ticks_per_beat: int """ if "repeat_count" in level: for _ in range(0, cast(int, level["repeat_count"])): for c in cast(List[Dict[str, Union[str, int, Dict[str, Union[str, list]]]]], level["subpattern"]): guitar_pattern_repeat_recursion(c, track, sequences, a, b, ticks_per_measure, ticks_per_beat) else: if "pitchIndex" in level: track.append(Message(cast(str, level['note_event']), note=sequences[a][b][cast(int, level["pitchIndex"])] + C_VAL, channel=1, time=int(round(cast(int, level["time"]) * ticks_per_beat * 4 / ticks_per_measure)))) else: track.append(Message(cast(str, level['note_event']), note=sequences[a][b][0] + cast(int, level["pitch"]), channel=1, time=int(round(cast(int, level["time"]) * ticks_per_beat * 4 / ticks_per_measure))))
def apply_mutation(mutantnotelist, midino, snote=50): mid = MidiFile(type=0) # type0 can have only one track track = MidiTrack() # note list (kind of) mid.tracks.append(track) time = 100 # Create mutant music folder if it does not exist if not os.path.exists('mutantmusic'): os.makedirs('mutantmusic') # add the octaves back mutantnotelist2 = [x+snote for x in mutantnotelist] for note in mutantnotelist2: #print(note) track.append(Message('note_on', channel=0, note=int(note), time=time)) track.append(Message('note_off', channel=0, note=int(note), time=time)) mid.save('mutantmusic/random' + str(midino) + '.mid')
def melo_to_midi(self, input_melo): """ Convert Melo to Midi. Melo need to be sorted by time within each track, or negative time will occur. Melo can have multiple tracks though. Args: input_melo (Melo) Output: midifile (MidiFile) """ midifile = MidiFile() ticks_per_beat = midifile.ticks_per_beat rel_melo = self._convert_melo_to_relative_time(input_melo) for melo_track in rel_melo.tracks: midi_track = MidiTrack() midi_track.append(Message('program_change', program=0, time=0)) for note in melo_track.notes: msg = Message(note.type, note=note.pitch, velocity=127, time=note.time * ticks_per_beat // self.args.prepare_resolution) midi_track.append(msg) midifile.tracks.append(midi_track) return midifile
def df_to_midi(dfc, ticks_per_beat, filename): """ Function to write midi dataframes returned by midi_to_df() back to a midi file :param dfc: dataframe containing the meta event information returned by midi_to_df :type dfc: pandas.DataFrame :param ticks_per_beat: integer containing the ticks_per_beat information returned by mido.MidiFile :type ticks_per_beat: integer :param filename: string containing the name of the midi file to be written :type filename: string """ outfile = MidiFile() outfile.ticks_per_beat = ticks_per_beat track = MidiTrack() outfile.tracks.append(track) for index, row in dfc.iterrows(): if row['meta'] == True: if row['msg']['type'] == 'track_name': track = MidiTrack() outfile.tracks.append(track) track.append(MetaMessage(**row['msg'])) else: track.append(Message(**row['msg'])) outfile.save(filename)
def main(): MAX_SONG_LEN = 60 genre_dir = '_data/midifiles/clean_midi/genres/rock/' all_chains = [] for song_path in glob.glob( ".\\_data\\midifiles\\clean_midi\\genres\\rock\\*.mid")[1:10]: print(song_path) mid = MidiFile(song_path) values = [] for i, track in enumerate(mid.tracks): #print('Track {}: {}'.format(i, track.name)) for message in track: if not isinstance(message, MetaMessage): values.append(message) chain = make_model(values) all_chains.extend(chain) state_map = markov_dictify(all_chains) segments = [START] while segments[ -1] != END: #taking the last part found and pulling the prob out of state map start_part = tuple(segments[-1:]) next_probabilities = state_map[start_part] weights = next_probabilities.values() winner = weighted_choice_sub(weights) next_part = list(next_probabilities.keys())[winner] segments.append(next_part) mid = MidiFile() track = MidiTrack() curr = [] last_delay = 0 mid.tracks.append(track) ticks = 0 in_use = [] is_in_use = {} for i in range(len(segments)): if isinstance( segments[i], tuple ): #START and END are objects and I can't index/key through them #getting mem error for some reason #I wanted to see what the song would look like without me attempting to detect changes segment = segments[i] note_list = segment[0] for note in note_list: #generate a message and turn on track.append(Message('turn_on', note=note, time=segment[1])) curr = note_list #if we do this all the time how can i move to the next item and call a diff on it? #use segments of -1? no thats not it i-1? ticks += segment[1] if ticks > MAX_SONG_LEN: break mid.save('some.mid')
def record(midi_file, bpm): ctx = zmq.Context() sock = ctx.socket(zmq.SUB) sock.connect(INPUT_ZMQ_URL) sock.subscribe(b'') track = MidiTrack() track.append( MetaMessage('track_name', name=f'MIDIate Recorder {str(datetime.now())}', time=0)) midi_file.tracks.append(track) print('Recording...') try: while True: data = sock.recv() current_ts, msg = data[:8], data[8:] current_ts, = struct.unpack("<Q", current_ts) msg = Message.from_bytes(msg) msg.time = int( second2tick(current_ts / NANOSECONDS_IN_SECONDS, TICKS_PER_BEAT, bpm2tempo(bpm))) track.append(msg) except KeyboardInterrupt: print('Recorder stopped.')
def merge_midi(midis, input_dir, output, default_tempo=500000): '''Merge midi files into one''' pairs = [(int(x[:-4].split('_')[-1]), x) for x in midis] pairs = sorted(pairs, key=lambda x: x[0]) midis = [join(input_dir, x[1]) for x in pairs] mid = MidiFile(midis[0]) # identify the meta messages metas = [] # tempo = default_tempo tempo = default_tempo // 2 for msg in mid: if msg.type is 'set_tempo': tempo = msg.tempo if msg.is_meta: metas.append(msg) for meta in metas: meta.time = int(mido.second2tick(meta.time, mid.ticks_per_beat, tempo)) target = MidiFile() track = MidiTrack() track.extend(metas) target.tracks.append(track) for midi in midis: mid = MidiFile(midi) for msg in mid: if msg.is_meta: continue if msg.type is not 'end_of_track': msg.time = int( mido.second2tick(msg.time, mid.ticks_per_beat, tempo)) track.append(msg) track.append(MetaMessage('end_of_track')) target.save(output)
def generate_midi(mkv_order=4): """ Generates and saves a midi file using an Nth order markov chain trained on midi files from training_music/single_track. Generated midi file is saved in the generated directory. Args: mkv_order (int): The order of the markov chain that should be used to generate the file """ corpus_files = (MidiFile(f'training_music/single_track/{file_name}', clip=True) for file_name in listdir('training_music/single_track')) messages = (message for f in corpus_files for message in ['START'] + f.tracks[0] + ['END']) mkv = MarkovModel(midi_data=messages, order=mkv_order) # Type 0 single track file gen_midi = MidiFile(type=0) track = MidiTrack() gen_midi.tracks.append(track) for message in mkv.sample(): track.append(message) gen_midi.save(f'generated/generated{mkv_order}.mid')
def write_song(self, file_name): mid = MidiFile(type=1) # 0 type means all messages are on one track track_pitch = [0, -12] track_num = 2 tracks = [] for i in range(track_num): track = MidiTrack() tracks.append(track) mid.tracks.append(track) track.append( MetaMessage("set_tempo", tempo=mido.bpm2tempo(self.bpm))) for i, note in enumerate(self.notes): tracks[i % track_num].append( Message("note_on", note=note.pitch + track_pitch[i % track_num], velocity=127, time=0)) tracks[i % track_num].append( Message("note_on", note=note.pitch + track_pitch[i % track_num], velocity=0, time=note.duration * mid.ticks_per_beat)) mid.save(file_name)
def samples_to_midi(samples, fname, ticks_per_sample, thresh=0.5): mid = MidiFile() track = MidiTrack() mid.tracks.append(track) ticks_per_beat = mid.ticks_per_beat ticks_per_measure = 4 * ticks_per_beat ticks_per_sample = ticks_per_measure / samples_per_measure abs_time = 0 last_time = 0 for sample in samples: for y in range(sample.shape[0]): abs_time += ticks_per_sample for x in range(sample.shape[1]): note = x + (128 - num_notes) / 2 if sample[y, x] >= thresh and (y == 0 or sample[y - 1, x] < thresh): delta_time = abs_time - last_time track.append( Message('note_on', note=note, velocity=127, time=delta_time)) last_time = abs_time if sample[y, x] >= thresh and (y == sample.shape[0] - 1 or sample[y + 1, x] < thresh): delta_time = abs_time - last_time track.append( Message('note_off', note=note, velocity=127, time=delta_time)) last_time = abs_time mid.save(fname)
def midi_from_indexes(indexes, max_dur_note, amount_dur, each_dur): time_now = 0 events = [] for i in range(len(indexes)): if (indexes[i] == '<EOS>'): note = -1 elif (indexes[i] == 128 * amount_dur): note = -1 else: note = indexes[i] % 128 type_dur = (indexes[i] - note) / 128 dur = max_dur_note / amount_dur * (type_dur + 1) if (note != -1): events.append([time_now, 'note_on', note]) events.append([time_now + dur, 'note_off', note]) time_now += each_dur events = sorted(events, key=itemgetter(0)) for i in range(len(events) - 1, 0, -1): events[i][0] -= events[i - 1][0] mid = MidiFile() track = MidiTrack() mid.tracks.append(track) for ev in events: track.append( Message(ev[1], note=ev[2], velocity=64, time=int(ev[0] / 0.0013354687499999999))) return mid
def combine_tracks(metadata, instrument_tracks): """ Combines array of instruments to MidiFile object :param instrument_tracks: array of instruments metadata: metadata of the conditioning file so that the output is in the same style and key :return MidFile object: """ mid = MidiFile() header = [] for data in metadata: for msg in data: if msg.type == 'smpte_offset' or msg.type == 'time_signature' or msg.type == 'key_signature'\ or msg.type == 'set_tempo': header.append(data) break for data in header: track = MidiTrack() mid.tracks.append(track) for elements in data: track.append(elements) for data in instrument_tracks: track = MidiTrack() mid.tracks.append(track) for elements in data: track.append(elements) return mid
def oneDimArrayToMidi(oneDimArr, name): #orig = MidiFile('Midi/rh.mid') mid = MidiFile() track = MidiTrack() mid.tracks.append(track) # for tr in orig.tracks: # for msg in tr: # msg_count = msg_count + 1 # if msg.type == 'note_on': # if (counter < len(oneDimArr)): # msg.note = int(oneDimArr[counter]) # else: # msg.note = 0 # track.append(msg) # counter = counter + 1 for i in range(len(oneDimArr)): if (oneDimArr[i] > 0.0 and oneDimArr[i] < 127.0): msg1 = mido.Message('note_on', note=int(oneDimArr[i]), velocity=60, time=0) msg2 = mido.Message('note_on', note=int(oneDimArr[i]), velocity=0, time=80) track.append(msg1) track.append(msg2) mid.save(name)
class MIDI_writer: def __init__(self, ticks_per_beat=480, tempo=500000, start_time=None, folder='', filename=''): self.ticks_per_beat = ticks_per_beat self.tempo = tempo self.folder = folder self.filename = filename self.midi_file = MidiFile() self.track = MidiTrack() self.midi_file.tracks.append(self.track) self.track.append(MetaMessage("set_tempo", tempo=500000)) if start_time is None: self.t0 = time.time() else: self.t0 = start_time def add_to_midi(self, msgs): start_time = msgs[0][1] for msg, msg_time in msgs: msg.time = int(mido.second2tick(msg_time-start_time, self.ticks_per_beat, self.tempo)) self.track.append(msg) start_time = msg_time def write(self): self.midi_file.save("{}{}".format(self.folder, self.filename))
def merge_tracksFIXED(tracks): """Returns a MidiTrack object with all messages from all tracks. The messages are returned in playback order with delta times as if they were all in one track. """ now = 0 # REMOVE THIS messages = MidiTrack() for track in tracks: now = 0 # ADD THIS for message in track: now += message.time if message.type not in ('track_name', 'end_of_track'): messages.append(message.copy(time=now)) if message.type == 'end_of_track': break messages.sort(key=lambda x: x.time) messages.append(MetaMessage('end_of_track', time=now)) # Convert absolute time back to delta time. last_time = 0 for message in messages: message.time -= last_time last_time += message.time return messages
def to_temporal_midi_track(notes): track = MidiTrack() notes = np.asarray(notes, dtype=np.int) for note in notes: track.append(Message('note_on', note=note[0], time=0)) track.append(Message('note_off', note=note[0], time=note[1])) return track
def transpose(track, factor): new_track = MidiTrack() for msg in track: if msg.type == "note_on" or msg.type == "note_off": msg = msg.copy(note=msg.note + factor) new_track.append(msg) return new_track
def write_note(track: MidiTrack, note: Note, rest_val: Union[Rest, None] = None, channel: int = 0) -> None: """ Writes a note to the provided midi track :param track: track to write to :param note: note to add to track :param rest_val: how long of a rest to how in ticks per quarter note :param channel: which channel it takes on MIDI file (possible values 0..15) """ if isinstance(note.value, str): note_val = const.NOTE_MIDI_MAP[note.value] else: note_val = note.value time_l = rest_val or 0 track.append( Message( "note_on", note=note_val, velocity=note.velocity, time=time_l, channel=channel, ) ) track.append( Message( "note_off", note=note_val, velocity=note.velocity, time=note.duration, channel=channel, ) )
def matrix_to_mid(matrix, outfile_name): mid = MidiFile() track = MidiTrack() mid.tracks.append(track) mid.ticks_per_beat = 24 cumulative_step = 0 for m in range(16): for s in range(96): current_step = s + (96 * m) notes_at_step = matrix[m, :, s] notes = [(i, v) for (i, v) in enumerate(notes_at_step) if v != 0] for note, velocity in notes: # note that delta_time won't change after the first note is added # which is what we're looking for. All notes are sounded at the same # time, so we want all but the first note of a step to delta_time = current_step - cumulative_step # make a new attack at specified notes track.append(Message('note_on', channel = 0, note = 116 - note, velocity = int(velocity), time = delta_time)) cumulative_step += delta_time for note, velocity in notes: #release all of the notes track.append(Message('note_on', channel = 0, note = 116 - note, velocity = 0, time = 0)) # meta_track.append(MetaMessage('end_of_track')) mid.save(outfile_name)
def change_midi_file_tempo(input_file, output_file, ratio=1.0): """ Change the tempo in a midi file """ infile = MidiFile(input_file) with MidiFile() as outfile: outfile.type = infile.type outfile.ticks_per_beat = infile.ticks_per_beat for msg_idx, track in enumerate(infile.tracks): out_track = MidiTrack() outfile.tracks.append(out_track) for message in track: if message.type == 'set_tempo': bpm = tempo2bpm(message.tempo) new_bpm = ratio * bpm message.tempo = bpm2tempo(new_bpm) out_track.append(message) outfile.save(output_file)
def reconstructFromBeats(filename, sequence, ticks_per_beat, subdivisions = 2): mid = MidiFile() track = MidiTrack() mid.tracks.append(track) mid.ticks_per_beat = ticks_per_beat divisions = int(ticks_per_beat / subdivisions) numticks = 0 curTone = 0 curVel = 0 for beat in sequence: tone, velocity = binToNote(beat) # print(tone, velocity) if tone != curTone: if curTone != 0: track.append(Message('note_off', note = curTone, velocity = 0, time = numticks)) numticks = 0 track.append(Message('note_on', note = tone, velocity = velocity, time = numticks)) numticks = 0 curTone = tone numticks += divisions mid.save('output/' + filename) return mid
def samples_to_midi(samples, fname, thresh=0.5): samples = samples.numpy() mid = MidiFile() track = MidiTrack() mid.tracks.append(track) ticks_per_sample = (mid.ticks_per_beat * 4) / N_MEASURES abs_time = 0 last_time = 0 last_tick = samples[0].shape[0] - 1 for j, sample in enumerate(samples): s = np.argwhere(sample>thresh) for i in range(len(s)): y, x = s[i] abs_time = y * ticks_per_sample + (j*N_NOTES*ticks_per_sample) note = int(x + (128 - N_NOTES)/2) if y == 0 or sample[y-1,x] < thresh: delta_time = int(abs_time - last_time) track.append(Message('note_on', note=note, velocity=127, time=delta_time)) last_time = abs_time if y == last_tick or sample[y+1, x] < thresh: delta_time = int(abs_time - last_time) track.append(Message('note_off', note=note, velocity=127, time=delta_time)) last_time = abs_time mid.save(fname) print("Midi saved to:", fname)
def writeSong(predictionList): from mido import Message, MidiFile, MidiTrack mid = MidiFile() track = MidiTrack() mid.tracks.append(track) onNotes = set() last_i = 0 for i, prediction in enumerate(predictionList): for note in prediction: if (prediction[note] > 0.9): if (note not in onNotes): track.append( Message('note_on', channel=9, note=note, velocity=int(prediction[note] * 127), time=last_i)) onNotes.add(note) last_i = 0 else: if (note in onNotes): track.append( Message('note_on', channel=9, note=note, velocity=0, time=last_i)) onNotes.remove(note) last_i = 0 last_i += 1 return mid
def gen_sample_file(n, name): print('\n\tGenerating sample file') ry = np.array([[utils.track_seed()]]) rh = np.zeros([1, INTERNALSIZE * NLAYERS]) mid = MidiFile() trk = MidiTrack() mid.tracks.append(trk) flubbs = 0 cur_notes = 0 non_zero = 0 for _ in range(n): # print(mido_utils.vec2msg(ry[0][0])) # generate a new state and output vec ryo, rh = sess.run([Yo, H], feed_dict={Xo: ry, Hin: rh, batchsize: 1, pkeep: 1}) if True in np.isnan(ryo[0]): continue # sample the output vec into an argmaxed version rc = utils.prep_vec(ryo) if rc[0] > 0: non_zero += 1 if rc[0]==0: cur_notes += 1 if cur_notes > 20: rc = utils.random_note(dt=256) cur_notes = 0 flubbs+=1 # append this to our midi file as a mido.Message trk.append(mido_utils.vec2msg(rc)) ry = np.array([[rc]]) mid.save('samples/{}_{}.mid'.format(run_timestamp, name)) print('flubbs/n {:04.4f}%, nonzero: {:04.4f}%'.format(100*flubbs/n, 100*non_zero/n))
def output_messages(filename, *messages): # Takes the name of a MIDI file to create and fill with the list of messages. # Returns nothing. with MidiFile() as outfile: for message_track in messages: track = MidiTrack() outfile.tracks.append(track) for message in message_track: track.append(message) outfile.save(filename)
def generate_random(snote=50, mlength=12, numofmidi=10, time=150, filename='random', pitchrnd=False): notes = range(snote, snote+mlength) noterange = range(mlength) # pitch range for random pitch value ; pitches = range(-8192,8191) # Create music folder if it does not exist if not os.path.exists('music'): os.makedirs('music') for j in range(numofmidi): mid = MidiFile(type=0) # type0 can have only one track track = MidiTrack() # note list (kind of) mid.tracks.append(track) # the note which the pitch will change for pitchnote = random.choice(noterange) numofpnote = random.choice(noterange) for i in noterange: note = random.choice(notes) pitch = random.choice(pitches) if pitchrnd: if i == pitchnote: # Change the pitch on the note track.append(Message('pitchwheel', pitch=pitch)) if i == (pitchnote+numofpnote): # Change the pitch back to default track.append(Message('pitchwheel')) track.append(Message('note_on', note=note, velocity = 127, time=time)) track.append(Message('note_off', note=note, velocity = 127, time=time)) note = random.choice(notes) track.append(Message('note_on', note=note, velocity = 127, time=time)) track.append(Message('note_off', note=note, velocity = 127, time=500)) mid.save('music/' + filename + str(j) + '.mid')
def time_warp(source_path, dest_path, ratio): # Read a midi file and return a dictionnary {track_name : pianoroll} mid_in = MidiFile(source_path) mid_out = MidiFile() # The two files need to have the same ticks per beat ticks_per_beat = mid_in.ticks_per_beat mid_out.ticks_per_beat = ticks_per_beat # Parse track by track for i, track_in in enumerate(mid_in.tracks): track_out = MidiTrack() mid_out.tracks.append(track_out) for message_in in track_in: time_in = message_in.time time_out = int(round(time_in * ratio)) # For absolutely every message, just mutliply the time by the ratio message_out = message_in.copy(time=time_out) track_out.append(message_out) mid_out.save(dest_path) return
def apply_mutation(mutantnotelist, midino, snote=50, time=150, filename='random'): mid = MidiFile(type=0) # type0 can have only one track track = MidiTrack() # note list (kind of) mid.tracks.append(track) # Create mutant music folder if it does not exist if not os.path.exists('mutantmusic'): os.makedirs('mutantmusic') # add the octaves back mutantnotelist2 = [x+snote for x in mutantnotelist] for note in mutantnotelist2[:len(mutantnotelist2)-2]: #print(note) track.append(Message('note_on', note=int(note), velocity = 127, time=time)) track.append(Message('note_off', note=int(note), velocity = 127, time=time)) track.append(Message('note_on', note=mutantnotelist2[len(mutantnotelist2)-1], velocity = 127, time=time)) track.append(Message('note_off', note=mutantnotelist2[len(mutantnotelist2)-1], velocity = 127, time=500)) mid.save('mutantmusic/' + filename + str(midino) + '.mid')
def SaveVelocityDatatoMIDIFile(vData, fileName): with MidiFile(ticks_per_beat = 24) as mFile: track = MidiTrack() mFile.tracks.append(track) for n in MIDINotes: if (vData[0,n]>0): event = Message("note_on", velocity=int(vData[0,n]), note = int(n), time = int(0)) track.append(event) timeOfLastEvent = 0 for t in range(1,vData.shape[0]-1): for n in MIDINotes: if vData[t,n] != vData[t-1,n]: relativeTick = t - timeOfLastEvent timeOfLastEvent = t event = Message("note_on", velocity=int(vData[t,n]), note = int(n), time = int(relativeTick)) track.append(event) mFile.save(fileName) print("MIDI file was saved. Events: {} Length in ticks: {} Data dimensions: {}".format(len(track), timeOfLastEvent, vData.shape))
def toMIDI(filename, ch, notes, rms, onset_start_times, onset_end_times, nOnsets): print 'Transcribing to MIDI in ' + filename delta = 0 with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) for i in range(nOnsets): stime = int((onset_start_times[i] - delta) * 1000) message = Message('note_on', note=int(notes[i]), velocity=int(rms[i] * 127), time=stime) message.channel = ch track.append(message) etime = int((onset_end_times[i] - delta) * 1000) off_message = Message('note_off', note=int(notes[i]), velocity=int(rms[i] * 127), time=etime) off_message.channel = ch track.append(off_message) delta = onset_end_times[i] outfile.print_tracks() outfile.save('/media/sf_VMshare/' + filename) print 'Transcription successfull!'
def toMidi(self, fname): with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) track.append(Message('program_change', program=12)) for note in self.getNotes(): for pitch in note.pitches: track.append(Message('note_on', note=pitch, velocity=100, time=0)) delta = note.duration for pitch in note.pitches: track.append(Message('note_off', note=pitch, velocity=100, time=delta)) delta = 0 outfile.save(fname)
def createMidiFromPianoRoll(piano_roll, lowest_note, directory, mel_test_file, threshold, res_factor=1): ticks_per_beat = int(96/res_factor) mid = MidiFile(type=0, ticks_per_beat=ticks_per_beat) track = MidiTrack() mid.tracks.append(track) mid_files = [] delta_times = [0] for k in range(piano_roll.shape[1]):#initial starting values if piano_roll[0, k] == 1: track.append(Message('note_on', note=k+lowest_note, velocity=100, time=0)) delta_times.append(0) for j in range(piano_roll.shape[0]-1):#all values between first and last one set_note = 0 #Check, if for the current timestep a note has already been changed (set to note_on or note_off) for k in range(piano_roll.shape[1]): if (piano_roll[j+1, k] == 1 and piano_roll[j, k] == 0) or (piano_roll[j+1, k] == 0 and piano_roll[j, k] == 1):#only do something if note_on or note_off are to be set if set_note == 0: time = j+1 - sum(delta_times) delta_times.append(time) else: time = 0 if piano_roll[j+1, k] == 1 and piano_roll[j, k] == 0: set_note += 1 track.append(Message('note_on', note=k+lowest_note, velocity=100, time=time)) if piano_roll[j+1, k] == 0 and piano_roll[j, k] == 1: set_note += 1 track.append(Message('note_off', note=k+lowest_note, velocity=64, time=time)) mid.save('%s%s_th%s.mid' %(directory, mel_test_file, threshold)) mid_files.append('%s.mid' %(mel_test_file)) return
""" Create a new MIDI file with some random notes. The file is saved to test.mid. """ from __future__ import division import random import sys from mido import Message, MidiFile, MidiTrack, MAX_PITCHWHEEL notes = [64, 64+7, 64+12] outfile = MidiFile() track = MidiTrack() outfile.tracks.append(track) track.append(Message('program_change', program=12)) delta = 300 ticks_per_expr = int(sys.argv[1]) if len(sys.argv) > 1 else 20 for i in range(4): note = random.choice(notes) track.append(Message('note_on', note=note, velocity=100, time=delta)) for j in range(delta // ticks_per_expr): pitch = MAX_PITCHWHEEL * j * ticks_per_expr // delta track.append(Message('pitchwheel', pitch=pitch, time=ticks_per_expr)) track.append(Message('note_off', note=note, velocity=100, time=0)) outfile.save('test.mid')
#!/usr/bin/env python import mido from mido import Message, MidiFile, MidiTrack import time tracks = [] with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) # track.append(Message('program_change', program=12, time=0)) track.append(Message("note_on", note=64, velocity=64, time=0)) track.append(Message("note_off", note=64, velocity=127, time=1000)) outfile.save("new_song.mid")
import ROOT tb = ROOT.TBrowser() f = ROOT.TFile("/afs/cern.ch/user/y/yijiang/SA_test_ttH_ttHemjets10.root") t = f.Get("METree") for event in t: n1= event.ME_Sig_Max_Likelihoods import mido from mido import Message, MidiFile, MidiTrack with MidiFile() as mid: track = MidiTrack() mid.tracks.append(track) track.append(mido.Message('program_change', program=12, time=0)) for val in n1 : track.append(mido.Message('note_on', note=int(val), velocity=64, time=100)) track.append(mido.Message('note_off', note=int(val), velocity=127, time=100)) mid.save('/afs/cern.ch/user/y/yijiang/new_song.mid')
from mido import Message, MetaMessage, MidiFile, MidiTrack # MIDI test objects # Track that is already quantized. track0 = MidiTrack() track0.append(MetaMessage('track_name', name='test0', time=0)) track0.append(Message('note_on', note=60, velocity=64, time=0)) track0.append(Message('note_off', note=60, velocity=64, time=50)) track0.append(MetaMessage('end_of_track', time=0)) # Simple track that is not quantized. track1 = MidiTrack() track1.append(MetaMessage('track_name', name='test1', time=0)) track1.append(Message('note_on', note=60, velocity=64, time=2)) track1.append(Message('note_off', note=60, velocity=64, time=50)) track1.append(MetaMessage('end_of_track', time=0)) # Track with notes that, when quantized to 32nd notes, would run over # the original end time of the track. track2 = MidiTrack() track2.append(MetaMessage('track_name', name='test2', time=0)) track2.append(Message('note_on', note=60, velocity=64, time=29)) track2.append(Message('note_off', note=60, velocity=64, time=31)) track2.append(MetaMessage('end_of_track', time=0)) meta_track = MidiTrack() meta_track.append(MetaMessage('track_name', name='meta-track', time=0)) midi_notes_in_track0 = MidiFile() midi_notes_in_track0.tracks.append(track0)
def quantize_track(track, ticks_per_quarter, quantization): '''Return the differential time stamps of the note_on, note_off, and end_of_track events, in order of appearance, with the note_on events quantized to the grid given by the quantization. Arguments: track -- MIDI track containing note event and other messages ticks_per_quarter -- The number of ticks per quarter note quantization -- The note duration, represented as 1/2**quantization.''' pp = pprint.PrettyPrinter() # Message timestamps are represented as differences between # consecutive events. Annotate messages with cumulative timestamps. # Assume the following structure: # [header meta messages] [note messages] [end_of_track message] first_note_msg_idx = None for i, msg in enumerate(track): if msg.type == 'note_on': first_note_msg_idx = i break cum_msgs = zip( np.cumsum([msg.time for msg in track[first_note_msg_idx:]]), [msg for msg in track[first_note_msg_idx:]]) end_of_track_cum_time = cum_msgs[-1][0] quantized_track = MidiTrack() quantized_track.extend(track[:first_note_msg_idx]) # Keep track of note_on events that have not had an off event yet. # note number -> message open_msgs = defaultdict(list) quantized_msgs = [] for cum_time, msg in cum_msgs: if DEBUG: print msg pp.pprint(open_msgs) if msg.type == 'note_on' and msg.velocity > 0: # Store until note off event. Note that there can be # several note events for the same note. Subsequent # note_off events will be associated with these note_on # events in FIFO fashion. open_msgs[msg.note].append((cum_time, msg)) elif msg.type == 'note_off' or (msg.type == 'note_on' and msg.velocity == 0): assert msg.note in open_msgs, \ 'Bad MIDI. Cannot have note off event before note on event' note_on_open_msgs = open_msgs[msg.note] note_on_cum_time, note_on_msg = note_on_open_msgs[0] open_msgs[msg.note] = note_on_open_msgs[1:] # Quantized note_on time quantized_note_on_cum_time = quantize_tick( note_on_cum_time, ticks_per_quarter, quantization) # The cumulative time of note_off is the quantized # cumulative time of note_on plus the orginal difference # of the unquantized cumulative times. quantized_note_off_cum_time = quantized_note_on_cum_time + (cum_time - note_on_cum_time) quantized_msgs.append((min(end_of_track_cum_time, quantized_note_on_cum_time), note_on_msg)) quantized_msgs.append((min(end_of_track_cum_time, quantized_note_off_cum_time), msg)) elif msg.type == 'end_of_track': quantized_msgs.append((cum_time, msg)) # Now, sort the quantized messages by (cumulative time, # note_type), making sure that note_on events come before note_off # events when two event have the same cumulative time. Compute # differential times and construct the quantized track messages. quantized_msgs.sort( key=lambda (cum_time, msg): cum_time if (msg.type=='note_on' and msg.velocity > 0) else cum_time + 0.5) diff_times = [0] + list( np.diff([ msg[0] for msg in quantized_msgs ])) for diff_time, (cum_time, msg) in zip(diff_times, quantized_msgs): quantized_track.append(msg.copy(time=diff_time)) if DEBUG: pp.pprint(quantized_msgs) pp.pprint(diff_times) return quantized_track
tolerance = 0.8 notes_o = notes("default", win_s, hop_s, samplerate) print("%8s" % "time","[ start","vel","last ]") # create a midi file mid = MidiFile() track = MidiTrack() mid.tracks.append(track) ticks_per_beat = mid.ticks_per_beat # default: 480 bpm = 120 # default midi tempo tempo = bpm2tempo(bpm) track.append(MetaMessage('set_tempo', tempo=tempo)) track.append(MetaMessage('time_signature', numerator=4, denominator=4)) def frames2tick(frames, samplerate=samplerate): sec = frames / float(samplerate) return int(second2tick(sec, ticks_per_beat, tempo)) last_time = 0 # total number of frames read total_frames = 0 while True: samples, read = s() new_note = notes_o(samples) if (new_note[0] != 0): note_str = ' '.join(["%.2f" % i for i in new_note])
from mido import MidiFile, MidiTrack, Message import random mid = MidiFile(type=0) track = MidiTrack() mid.tracks.append(track) notes = range(40, 90) for i in range(20): note = random.choice(notes) track.append(Message('note_on', note=note, velocity=100, time=i*100)) track.append(Message('note_off', note=note, velocity=100, time=(i+1)*100)) mid.save('random.mid')
for pred in prediction: for i in range(0,4): pred[i] = pred[i] * (max_val[i]-min_val[i]) + min_val[i] if pred[i] < min_val[i]: pred[i] = min_val[i] if pred[i] >= max_val[i]: pred[i] = max_val[i] ########################################### ###### SAVING TRACK FROM BYTES DATA ####### mid = MidiFile() track = MidiTrack() mid.tracks.append(track) for note in prediction: # 147 means note_on note = np.insert(note, 1, 144) bytes = np.round(note).astype(int) msg = Message.from_bytes(bytes[1:4]) msg.time = int(note[4]/0.00125) # to rescale to midi's delta ticks. arbitrary value for now. msg.channel = bytes[0] print(msg) track.append(msg) mid.save('new_song.mid')
def array_to_MIDI(array,sig_length): # get relative times between events test_times = (np.diff(np.sort(np.concatenate((array[:,1],array[:,2])))* 512./44100)).astype(float) test_duration = (np.diff(np.sort(np.concatenate((array[:,1],array[:,2])))* 512./44100*960)).astype(int) #print array #print test_duration #print test_times #* 512./44100*960) # write MIDI file with MidiFile() as outfile: # Initialize track = MidiTrack() outfile.tracks.append(track) # add MIDI events track.append(Message('program_change', program=12)) seg_skip_on = 1 # take segments and make midi note events for segment in xrange(0,array.shape[0]): if segment == 0: track.append(Message('note_on', note=array[0,0], velocity=array[0,3], time=int(array[0,1]*512./44100*960))) track.append(Message('note_off', note=array[0,0], velocity=array[0,3], time=test_duration[0])) else: track.append(Message('note_on', note=array[segment,0], velocity=array[segment,3], time=test_duration[seg_skip_on])) seg_skip_off = seg_skip_on + 1 track.append(Message('note_off', note=array[segment,0], velocity=array[segment,3], time=test_duration[seg_skip_off])) #print test_duration[seg_skip_off] seg_skip_on = seg_skip_off + 1 track_end = int((sig_length/44100. - 512./44100 * array[-1,2])*960) track.append(Message('program_change', program=12, time=track_end)) track.append(MetaMessage('end_of_track')) #outfile.save('output.mid') # output MIDI file return outfile
#!/usr/bin/env python """ Create a new MIDI file with some random notes. The file is saved to test.mid. """ import random from mido import Message, MidiFile, MidiTrack notes = [64, 64+7, 64+12] with MidiFile() as outfile: track = MidiTrack() outfile.tracks.append(track) track.append(Message('program_change', program=12)) delta = 16 for i in range(4): note = random.choice(notes) track.append(Message('note_on', note=note, velocity=100, time=delta)) track.append(Message('note_off', note=note, velocity=100, time=delta)) outfile.save('test.mid')
def array_to_midi(array, name, quantization=5, pitch_offset=0, midi_type=1, ticks_per_quarter=240): '''Convert an array into a MIDI object. When an MIDI object is converted to an array, information is lost. That information needs to be provided to create a new MIDI object from the array. For this application, we don't care about this metadata, so we'll use some default values. Arguments: array -- An array A[time_step, note_number] = 1 if note on, 0 otherwise. quantization -- The note duration, represented as 1/2**quantization. pitch_offset -- Offset the pitch number relative to the array index. midi_type -- Type of MIDI format. ticks_per_quarter -- The number of MIDI timesteps per quarter note.''' mid = MidiFile() meta_track = MidiTrack() note_track = MidiTrack() mid.tracks.append(meta_track) mid.tracks.append(note_track) meta_track.append(MetaMessage('track_name', name=name, time=0)) meta_track.append(MetaMessage('time_signature', numerator=4, denominator=4, clocks_per_click=24, notated_32nd_notes_per_beat=8, time=0)) meta_track.append(MetaMessage('set_tempo', tempo=500000, time=0)) meta_track.append(MetaMessage('end_of_track', time=0)) ticks_per_quantum = ticks_per_quarter * 4 / 2**quantization note_track.append(MetaMessage('track_name', name=name, time=0)) cumulative_events = [] for t, time_slice in enumerate(array): for i, pitch_on in enumerate(time_slice): if pitch_on > 0: cumulative_events.append(dict( type = 'note_on', pitch = i + pitch_offset, time = ticks_per_quantum * t )) cumulative_events.append(dict( type = 'note_off', pitch = i + pitch_offset, time = ticks_per_quantum * (t+1) )) cumulative_events.sort( key=lambda msg: msg['time'] if msg['type']=='note_on' else msg['time'] + 0.5) last_time = 0 for msg in cumulative_events: note_track.append(Message(type=msg['type'], channel=9, note=msg['pitch'], velocity=100, time=msg['time']-last_time)) last_time = msg['time'] note_track.append(MetaMessage('end_of_track', time=0)) return mid