def create_midi_file(pads, notes, midi_tempo, path, pattern, sampleformat): midi_file = MIDIFile(numTracks=1) midi_file.addTrackName(track=0, time=0, trackName="Roland SP404SX Pattern " + pattern.upper() + " " + date) midi_file.addTempo(track=0, time=0, tempo=midi_tempo) note_path_to_pitch = {} # for C1. see "midi note numbers" in http://www.sengpielaudio.com/calculator-notenames.htm next_available_pitch = 36 wave_table_list = [] path_list = [] time_in_beats_for_next_note = 0 for note in notes: if note.pad != 128: note_filename = notetuple_to_note_filename(note, sampleformat) note_path = path + SAMPLE_DIRECTORY + note_filename wave_table_list.append(note_filename) path_list.append(note_path) if note_path not in note_path_to_pitch: note_path_to_pitch[note_path] = next_available_pitch next_available_pitch += 1 if os.path.isfile(note_path): pad = pads[notetuple_to_sample_number(note)] user_start_sample, user_end_sample = padtuple_to_trim_samplenums(pad) outfile_path = "/tmp/" + os.path.basename(note_path) trim_wav_by_frame_numbers(note_path, outfile_path, user_start_sample, user_end_sample) stereo_to_mono(outfile_path, outfile_path + "_mono.wav") length = note.length / (PPQ * 1.0) midi_file.addNote(track=0, channel=0, pitch=note_path_to_pitch[note_path], time=time_in_beats_for_next_note, duration=length, volume=100) else: print("skipping missing sample") else: print("skipping empty note") delay = note.delay / (PPQ * 1.0) print("incrementing time by", delay) time_in_beats_for_next_note += delay # j = 36 # while True: for i in note_path_to_pitch: template_wav_path = "template" + ('%02d' % (note_path_to_pitch[i] - 35)) + ".wav" trimmed_mono_path = "/tmp/" + os.path.basename(i) + "_mono.wav" if os.path.isfile(i): shutil.copyfile(trimmed_mono_path, template_wav_path) else: print("skipping missing sample wav") binfile = open("PTN_" + pattern.upper() + ".mid", 'wb') midi_file.writeFile(binfile) binfile.close() return wave_table_list, path_list
def saveScale(scaleNoteArrays, key): mf = MIDIFile(1) mf.addTrackName(track, time, key) mf.addTempo(track, time, 120) for i in range(0, 8): #7 notes in a scale as supertonic will be repeated for r in range(0, 9): #8 octave repeats mf.addNote(track, channel, 9 + (r * 12) + scaleNoteArrays[i], time, duration, volume) #9 is first A filename = "Scales/" + key + ".mid" os.makedirs(os.path.dirname(filename), exist_ok=True) with open(filename, 'wb') as outf: mf.writeFile(outf)
def testTrackName(self): #import pdb; pdb.set_trace() track_name = "track" MyMIDI = MIDIFile(1) MyMIDI.addTrackName(0, 0, track_name) MyMIDI.close() data = Decoder(MyMIDI.tracks[1].MIDIdata) self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'TrackName') self.assertEqual(data.unpack_into_byte(0), 0x00) # time self.assertEqual(data.unpack_into_byte(1), 0xFF) # Code self.assertEqual(data.unpack_into_byte(2), 0x03) # subcodes
def matrix_to_midi(input_mat, first_note=0, tempo=120, duration=1, output_file=None): """ Converts a numpy matrix into midi format and writes it to a file. Parameters ========== input_mat : numpy matrix where y is notes and x is time first_note : first note of y-axis in midi note number tempo : tempo of track to be written duration : Duration of each beat output_file : String of path and filename of midi file to write to. Should end in .mid """ # shit is upside down for no reason input_mat = np.flipud(input_mat) num_times = np.shape(input_mat)[1] track = 0 channel = 0 time = 0 # Time it starts MyMIDI = MIDIFile(1) # One track MyMIDI.addTempo(track, time, tempo) print 'writing midi file' for times in range(num_times): freq = np.nonzero(input_mat[:, times])[0] + first_note volume = np.squeeze( np.matrix( (input_mat[np.nonzero(input_mat[:, times]), times]))) * 100 if len(freq) > 0: for jj in range(len(freq)): MyMIDI.addNote(track, channel, freq[jj], times, duration, volume[0, jj].astype(np.int64)) if not output_file: binfile = open("output.mid", 'wb') else: binfile = open(output_file, 'wb') MyMIDI.writeFile(binfile) binfile.close() return True
def create_midi(frequency): my_midi = MIDIFile(1) track = 0 channel = 0 pitch = 69 + 12 * log(max(frequency) / 440, 2) time = 0 duration = 1 volume = 100 my_midi.addTempo(track, time, 120) my_midi.addNote(track, channel, pitch, time, duration, volume) return my_midi
def testDeinterleaveNotes(self): MyMIDI = MIDIFile(1) MyMIDI.addNote(0, 0, 100, 0, 2, 100) MyMIDI.addNote(0, 0, 100, 1, 2, 100) MyMIDI.close() self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].type, 'NoteOn') self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].time, 0) self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].type, 'NoteOff') self.assertEqual(MyMIDI.tracks[1].MIDIEventList[1].time, TICKSPERBEAT) self.assertEqual(MyMIDI.tracks[1].MIDIEventList[2].type, 'NoteOn') self.assertEqual(MyMIDI.tracks[1].MIDIEventList[2].time, 0) self.assertEqual(MyMIDI.tracks[1].MIDIEventList[3].type, 'NoteOff') self.assertEqual(MyMIDI.tracks[1].MIDIEventList[3].time, TICKSPERBEAT * 2)
def testTuningProgramWithTimeOrder(self): program = 10 MyMIDI = MIDIFile(1) MyMIDI.changeTuningProgram(0, 0, 0, program, time_order=True) MyMIDI.close() data = Decoder(MyMIDI.tracks[1].MIDIdata) self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'ControllerEvent') self.assertEqual(data.unpack_into_byte(0), 0x00) # time self.assertEqual(data.unpack_into_byte(4), 0x01) # time self.assertEqual(data.unpack_into_byte(8), 0x01) # time self.assertEqual(data.unpack_into_byte(12), 0x01) # time
def testAddNote(self): MyMIDI = MIDIFile(1) # a format 1 file, so we increment the track number below track = 0 channel = 0 pitch = 100 time = 0 duration = 1 volume = 100 MyMIDI.addNote(track, channel, pitch, time, duration, volume) self.assertEqual(MyMIDI.tracks[1].eventList[0].evtname, "NoteOn") self.assertEqual(MyMIDI.tracks[1].eventList[0].pitch, pitch) self.assertEqual(MyMIDI.tracks[1].eventList[0].tick, MyMIDI.time_to_ticks(time)) self.assertEqual(MyMIDI.tracks[1].eventList[0].duration, MyMIDI.time_to_ticks(duration)) self.assertEqual(MyMIDI.tracks[1].eventList[0].volume, volume)
def testUniversalSysEx(self): MyMIDI = MIDIFile(1) MyMIDI.addUniversalSysEx(0,0, 1, 2, struct.pack('>B', 0x01)) MyMIDI.close() self.assertEquals(MyMIDI.tracks[0].MIDIEventList[0].type, 'UniversalSysEx') self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[0])[0], 0x00) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[1])[0], 0xf0) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[2])[0], 6) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[3])[0], 0x7E) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[4])[0], 0x7F) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[5])[0], 0x01) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[6])[0], 0x02) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[7])[0], 0x01) self.assertEquals(struct.unpack('>B', MyMIDI.tracks[0].MIDIdata[8])[0], 0xf7)
def write_to_midifile(data, track_type='single', file='temp.mid'): """ data: list of tuples of x, y coordinates for pitch and timing Optional: add a string to the start of the data list to specify instrument! type: the type of data passed to create tracks. Either 'single' or 'multiple' """ if track_type not in ['single', 'multiple']: raise ValueError('Track type must be single or multiple') if track_type == 'single': data = [data] #memfile = io.BytesIO() realfile = open(file, 'wb') midifile = MIDIFile(numTracks=len(data), adjust_origin=False) track = 0 time = 0 program = 0 channel = 0 duration = 1 volume = 90 for data_list in data: midifile.addTrackName(track, time, 'Track {}'.format(track)) midifile.addTempo(track, time, 60) instrument_type = 'melodic' if type(data_list[0]) != tuple: program, instrument_type = get_instrument(data_list.pop(0)) if instrument_type == 'percussion': volume = 100 channel = 9 # Write the notes we want to appear in the file for point in data_list: time = point[0] pitch = int(point[1]) if instrument_type == 'melodic' else program midifile.addNote(track, channel, pitch, time, duration, volume) midifile.addProgramChange(track, channel, time, program) track += 1 channel = 0 midifile.writeFile(realfile) realfile.close() return file
def __init__(self, length=4, tempo=90): self.length = length self.tempo = tempo rules_file = open("rules.json", "r") rules = json.load(rules_file) rules_file.close() self.rhythm = rules["rhythm"] self.seq_chord = rules["seq_chord"] self.seq_perc = rules["seq_perc"] self.velocity = rules["velocity"] self.rn = RandomNote(rules["notes"], rules["interval_upper"], rules["interval_lower"]) self.MyMIDI = MIDIFile(3) self.current_track_number = 0
def testProgramChange(self): #import pdb; pdb.set_trace() program = 10 channel = 0 MyMIDI = MIDIFile(1) MyMIDI.addProgramChange(0, channel, 0, program) MyMIDI.close() data = Decoder(MyMIDI.tracks[0].MIDIdata) self.assertEqual(MyMIDI.tracks[0].MIDIEventList[0].type, 'ProgramChange') self.assertEqual(data.unpack_into_byte(0), 0x00) # time self.assertEqual(data.unpack_into_byte(1), 0xC << 4 | channel) # Code self.assertEqual(data.unpack_into_byte(2), program)
def testTuningBankWithTimeOrder(self): #import pdb; pdb.set_trace() bank = 1 MyMIDI = MIDIFile(1) MyMIDI.changeTuningBank(0, 0, 0, bank, time_order=True) MyMIDI.close() data = Decoder(MyMIDI.tracks[1].MIDIdata) self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'ControllerEvent') self.assertEqual(data.unpack_into_byte(0), 0x00) # time self.assertEqual(data.unpack_into_byte(4), 0x01) # time self.assertEqual(data.unpack_into_byte(8), 0x01) # time self.assertEqual(data.unpack_into_byte(12), 0x01) # time
def store_session(self, session: Session, file_path: str): midi_file = MIDIFile(1) track, channel = 0, 9 self.add_session_meta_data_to_midi_file(midi_file, session) notes = self.distribute_midi_notes(session.samples) for e in session.events: midi_file.addNote( track, channel, notes[e.sample.name], e.time_stamp / session.time_signature.ticks_per_quarter_note, e.duration, e.velocity) with open(file_path, 'wb') as f: midi_file.writeFile(f)
def createSong(notes): # Create MIDI file with prediction MIDI = MIDIFile(1) track = 0 time=0 MIDI.addTrackName(track, time, "sample") MIDI.addTempo(track,time,120) channel = 0 addNote(MIDI, track, time, channel, notes) with open("output.mid", 'wb') as outf: # Save MIDI MIDI.writeFile(outf) print('Midi output created in directory folder')
def testUnknownEventType(self): track = 0 channel = 0 pitch = 69 time = 0 duration = 1.0 volume = 64 bad_type = "bad" MyMIDI = MIDIFile(1) MyMIDI.addNote(track, channel, pitch, time, duration, volume) MyMIDI.tracks[1].eventList[0].type = bad_type with self.assertRaises(Exception) as context: MyMIDI.close() self.assertTrue(('Error in MIDITrack: Unknown event type %s' % bad_type) in str(context.exception))
def testSysEx(self): MyMIDI = MIDIFile(1) MyMIDI.addSysEx(0, 0, 0, struct.pack('>B', 0x01)) MyMIDI.close() data = Decoder(MyMIDI.tracks[1].MIDIdata) self.assertEqual(MyMIDI.tracks[1].MIDIEventList[0].evtname, 'SysEx') self.assertEqual(data.unpack_into_byte(0), 0x00) self.assertEqual(data.unpack_into_byte(1), 0xf0) self.assertEqual(data.unpack_into_byte(2), 3) self.assertEqual(data.unpack_into_byte(3), 0x00) self.assertEqual(data.unpack_into_byte(4), 0x01) self.assertEqual(data.unpack_into_byte(5), 0xf7)
def make_midi(name, tempo, key, m, maxD, root, smallestNote, biggestNote, length, startOct): melody = make_melody(key, m, maxD, root, smallestNote, biggestNote, length, startOct + 2) MyMIDI = MIDIFile(1) track = 0 time = 0 MyMIDI.addTrackName(track, time, name) MyMIDI.addTempo(track, time, tempo) for i in melody: MyMIDI.addNote(track, 0, i[0], time, 4 * i[1], 100) time += 4 * i[1] return MyMIDI
def handle_score(score): parts = score.findall('part-list/score-part') midiparts = [] for part in parts: actualpart = score.find('part[@id="%s"]' % part.get('id')) tuning = handle_tuning(actualpart) trackname = gettext(part.find('part-name')) midipart = MIDIFile(1) midipart.addTrackName(0, 0, trackname) midipart.name = trackname for channel, _ in enumerate(tuning): midipart.addProgramChange(0, channel, 0, getint(part.find('.//midi-program'))) midipart.addTempo(0, 0, 120) handle_measures(midipart, actualpart, tuning) midiparts.append(midipart) return midiparts
def saveTriad(chordName, root, _type, key): name = chordName + " " + triadNames[_type] + " Triad" mf = MIDIFile(1) mf.addTrackName(track, time, name) mf.addTempo(track, time, 120) mf.addNote(track, channel, root, time, duration, volume) mf.addNote(track, channel, root + triadDisplacement[_type][0], time, duration, volume) mf.addNote(track, channel, root + triadDisplacement[_type][1], time, duration, volume) filename = key + "/" + name + ".mid" os.makedirs(os.path.dirname(filename), exist_ok=True) with open(filename, 'wb') as outf: mf.writeFile(outf)
def testShiftTrack(self): track = 0 channel = 0 pitch = 100 time = 1 duration = 1 volume = 100 MyMIDI = MIDIFile(1) MyMIDI.addNote(track, channel, pitch, time, duration, volume) self.assertEqual(MyMIDI.tracks[1].eventList[0].evtname, "NoteOn") self.assertEqual(MyMIDI.tracks[1].eventList[0].pitch, pitch) self.assertEqual(MyMIDI.tracks[1].eventList[0].tick, MyMIDI.time_to_ticks(time)) self.assertEqual(MyMIDI.tracks[1].eventList[0].duration, MyMIDI.time_to_ticks(duration)) self.assertEqual(MyMIDI.tracks[1].eventList[0].volume, volume) MyMIDI.shiftTracks() self.assertEqual(MyMIDI.tracks[1].eventList[0].tick, 0)
def createSong(notes, lastNote): # Create MIDI file MIDI = MIDIFile(1) # Load MIDI data track = 0 time=0 MIDI.addTrackName(track, time, "sample") MIDI.addTempo(track,time,120) channel = 0 # Add notes to MIDI addNote(MIDI, track, time, channel, notes, lastNote) with open("output.mid", 'wb') as outf: # Save MIDI file MIDI.writeFile(outf) print('Midi output created in directory folder')
def write_midi(filename, sequence): filename = "music/" + filename midi = MIDIFile(1) track = 0 start_time = 0 midi.addTrackName(track, start_time, filename[:-4]) tempo = random.randrange(120, 480) midi.addTempo(track, start_time, tempo) for seq in range(len(sequence)): for note in sequence[seq]: midi.addNote(track, 9, note.pitch, note.time, note.duration, note.volume) # midi.addProgramChange(0, seq, 0, instrList[seq]) f = open(filename, 'w') midi.writeFile(f) f.close()
def __init__(self, track_name, filepath, bpm=120): """ Wraper around MIDIFile :param track_name: Track name :param bpm: Beat per minute, default=120 """ self.__midi_file = MIDIFile(1, adjust_origin=0) # Single track self.__track = 0 time = 0 self.__track_name = track_name self.__midi_file.addTrackName(self.__track, time, self.__track_name) self.__midi_file.addTempo(self.__track, time, bpm) self.__channel = 0 self.__filepath = filepath
def __init__(self, name='sample', notes=[], bpm=120, instrument=Instrument("Piano", 1), volume=100, octave=4, actual_time=0): self.actual_time = actual_time self.instrument = instrument self.octave = octave self.name = name self.notes = notes self.bpm = bpm self.volume = volume self.midi_file = MIDIFile(1)
def generateMIDI(notes): # Tworzymy nasz obiekt MIDI z jedną ścieżką midifile = MIDIFile(1) track = 0 time = 0 midifile.addTrackName(track, time, "Track 0") midifile.addTempo(track, time, 120) # Dodajemy dźwięki for n in notes: midifile.addNote(track, 0, int(n), time, 1, 100) time += 1 # Zapisujemy plik MIDI with open('output.mid', 'wb') as outf: midifile.writeFile(outf)
def savemidi(): global length quarterNoteDuration = 60 / bpm sixteenthNoteDuration = quarterNoteDuration / 4.0 measureDuration = beatsPerMeasure * quarterNoteDuration print('How many bars would you like to save?') hist = custom_input('int', 1, 16) # create a list that is as long as the user wanted while hist + 2 > len(history): # Create new parts if they requested more bars than we had ready compose() print('\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n') # select the right part of our history and flip it histlist = history[int(hist * -1):][::-1] # I get errors if I deinterleave, but this works mf = MIDIFile(len(parts), deinterleave=False) time = 0 # prepare for 5 instruments for i in range(len(parts)): # make tracks for each instrument mf.addTrackName(i, 0, tracknames[i]) mf.addTempo(i, 0, bpm) channel = 0 # cycle though our history, turn everything into midi for y in range(len(histlist)): for x in range(len(histlist[y][i])): if isinstance(histlist[y][i][x][1], int): histlist[y][i][x][1] = [histlist[y][i][x][1]] for pitch in histlist[y][i][x][1]: if pitch != 0 and isinstance(pitch, int): volume = histlist[y][i][x][2] time = (histlist[y][i][x][0] + (y * length) ) / 4 #convert from beats to sixteenths duration = abs( (((histlist[y][i][x][3] / 4) - 0.25) * (i != 2)) + 0.25) # This doesn't seem to work somehow??? # add the note!! mf.addNote(int(i), int(channel), pitch, float(time), float(duration), int(volume)) filename = (input('Save As:') + ".mid") try: with open(filename, 'wb') as outf: # MIDIUtil is still pretty glitchy on python3 # The fact that we give users the choice to export massive amounts of MIDI makes it a lot more likely for these errors to show up mf.writeFile(outf) except: print('error printing midi file')
def write_midi(filename, sequence): filename = "markov/" + filename midi = MIDIFile(1) track = 0 start_time = 0 midi.addTrackName(track, start_time, filename[:-4]) tempo = random.randrange(360, 480) midi.addTempo(track, start_time, tempo) midi.addProgramChange(0, 0, 0, 1) for i in range(len(sequence)): note = sequence[i] midi.addNote(track, 0, note.pitch, note.time, note.duration, note.volume) f = open(filename, 'w') midi.writeFile(f) f.close()
def write_midi(self, x, y, count): """ Creates a midi file based on the fibonacci sequence, using x and y as the starting integers. Parameters: x: an integer used as the first item in the sequence - 0 for Fibonacci numbers, 2 for Lucas numbers y: an integer used as the second item in the sequence - 1 for both Fibonacci and Lucas numbers count: how many notes to be returned """ self.resulttype = MIDI MyMIDI = MIDIFile(1) MyMIDI.addTempo(track, time, self.tempo) for i, pitch in enumerate(self.do_fib(x, y, count)): MyMIDI.addNote(track, channel, pitch, time + i, duration, volume) with open(self.midifilename + ".mid", "wb") as output_file: MyMIDI.writeFile(output_file) print("Created " + self.midifilename + ".mid in the current folder")
def _createRawMIDI(filename, clips): channel = 0 track = 0 tempo = 60 volume = 100 time = 0 outfile = MIDIFile(1) outfile.addTempo(track, time, tempo) for clip in clips: channel = (channel + 1) % 16 for note in clip.notes: time = note.time + clip.startTime duration = note.duration pitch = note.pitch outfile.addNote(track, channel, pitch, time, duration, volume) with open(filename, "wb") as written_file: outfile.writeFile(written_file)