def to_midi_wav(melody): # convert to midi filename = melody['raw_filename'] k = melody['duration'] * melody['bpm'] / (np.array(melody['lengths']).sum() * 60) time = 0 track = 0 channel = 0 volume = 100 my_midi = MIDIFile(1) my_midi.addTempo(track, time, melody['bpm']) my_midi.addProgramChange(track, channel, time, 0) for i, pitch in enumerate(melody['midi']): length = k * melody['lengths'][i] if pitch != 'P' and 0 <= pitch <= 255 and length >= 1/16: my_midi.addNote(track, channel, round(pitch), time, length, volume) time = time + k * melody['lengths'][i] midi_filename = 'tmp/' + filename.split('.')[0] + '.mid' with open(midi_filename, "wb") as output_file: my_midi.writeFile(output_file) # convert back to wav filename_processed = 'tmp/'+ filename.split('.')[0] + '_processed' + '.wav' fs = FluidSynth('static/Drama Piano.sf2') fs.midi_to_audio(midi_filename, filename_processed)
def convert_to_MIDI(self, instruments=["Piano"], start_times=[4], tempos=[80], tracks=1, channel=0, volume=100): if not self.verify_track(tracks): return #Adjusts instrument, start_times, and tempos to match with number of specified tracks instr = self.set_instruments(instruments, tracks) self.set_start_times(start_times, tracks) self.set_tempos(tempos, tracks) MIDI_File = MIDIFile(tracks, adjust_origin=False) print len(self.SOLset) #for every track of the Midi File for t in range(tracks): print('T,instruments,tempos: %s, %s, %s', (t, instr, tempos)) MIDI_File.addTempo(t, 0, tempos[t]) #Adds tempo t MIDI_File.addProgramChange(t, 0, 0, instr[t]) #sets instrument for tempo t prevAccidental = -1 #if the previous sheet object was a sharp or flat currOctave = 1 time = start_times[ t] #Current time placement of a not in the given track #For every object in a single sheet object list for ob in self.SOLset[t]: #print(ob.clef,ob.duration,ob.run) #If object is an accidental, set variable and finish current iteration if ob.accidental != -1: prevAccidental = ob.accidental continue #If the object is a clef, set currOctave and finish current iteration if ob.clef != -1: currOctave = ob.clef continue #Calculate note id and pitch note_id = self.note_id(ob.run, currOctave) pitch = self.note_pitch(note_id, prevAccidental) #Reset accidental to base value prevAccidental = -1 if ob.duration > 0 and ob.rest != 1: #If the object has a note duration, add it as a note MIDI_File.addNote(t, t, pitch, time + ob.duration, ob.duration, volume) time = time + ob.duration elif ob.rest > 0: #If the object has a rest duration, add it as a rest MIDI_File.addNote(t, t, 0, time + ob.rest, ob.rest, 0) time = time + ob.rest self.MIDI = MIDI_File
def write(melodies, rhythms): global tim global MyMIDI tim -= time.process_time() degrees = [60, 62, 64, 65, 67, 69, 71, 72] # MIDI note number track = 0 channel = 0 starttime = 0 # In beats duration = 0.5 # In beats tempo = 60 # In BPM volume = 100 # 0-127, as per the MIDI standard MyMIDI = MIDIFile( 1) # One track, defaults to format 1 (tempo track is created # automatically) for i, instrument in enumerate(config.instruments): MyMIDI.addProgramChange(0, i, 0, instrument) MyMIDI.addTempo(track, starttime, tempo) # print len(melodies[0]) # print len(rhythms[0]) for i, pitch in enumerate(melodies[0]): melodies[0][i] = melodies[0][i] + config.tone0 MyMIDI.addNote(track, channel, melodies[0][i], starttime, rhythms[0][i], volume) starttime += rhythms[0][i] # print rhythms[0][i] tim += time.process_time()
def createFile(self): MyMIDI = MIDIFile(1) MyMIDI.addProgramChange(self.track, self.channel, self.time, self.program) MyMIDI.addTempo(self.track, self.time, self.tempo) return MyMIDI
def runMido(self): mid = mido.MidiFile('./scripts/Magenta/SecondOutput/SecondOutput.mid') onOff = [] notes = [] time = [] trackTime = 0 program = 0 tempo = 60 MyMIDI = MIDIFile(1) MyMIDI.addProgramChange(0, 0, 0, self.program) MyMIDI.addTempo(0, 0, self.tempo) print("start") for msg in mid.play(): onOff.append(msg.type) time.append(msg.time) test = msg.bytes() notes.append(test[1]) print("finished") for i in range(0, len(notes)): MyMIDI.addNote(0, 0, notes[i], trackTime + time[i], 1, 100) trackTime += time[i] with open("static/audio/" + self.name + ".mid", "wb") as output_file: MyMIDI.writeFile(output_file)
def writeSong(self, ascii_text): self.reset() MyMIDI = MIDIFile(16) MyMIDI.addTempo(0, 0, 120) MyMIDI.addProgramChange(4, 4, 0, 37) MyMIDI.addProgramChange(5, 5, 0, 38) ascii_text = self.getCountIn() + ascii_text trackCt = 0 for lines in ascii_text.split("\n"): trackCt = 0 print str(len(lines.split(","))) + ":" + lines + ":Track=" + str( trackCt) + ":Time=" + str(self.time) for note in lines.split(","): if note != "": if (trackCt < 4): channel = 9 else: channel = trackCt print "adding " + str(trackCt) + " " + str( channel) + " " + str(note) + " " + str( self.time) + " 1 127" MyMIDI.addNote(trackCt, channel, int(note) - 1, self.time, 0.5, 127) trackCt = trackCt + 1 if len(lines.split(",")) == 6: self.time = self.time + 0.25 with open("myfilename.mid", "wb") as output_file: MyMIDI.writeFile(output_file)
def render_midi(spec_path, o_path="", cycle_instr=False): with open(spec_path) as data: spec = json.load(data) tempo = spec['bpm'] tracks = spec['tracks'] for idx, t in enumerate(tracks): nts = [(x + 1) + t['note_floor'] for x in t['notes']] midi_track = MIDIFile(1) note_dur = 4 / t['note_length'] track_notes = list(nts) track = 0 channel = idx time = note_dur duration = note_dur volume = 127 if 'midi_volume' not in t.keys() else t['midi_volume'] instrument = 1 if 'midi_instrument' not in t.keys() else t['midi_instrument'] midi_track.addTempo(track, time, tempo) for i, pitch in enumerate(track_notes): if cycle_instr: instrument = int(abs(math.sin((1/(len(track_notes))) * i)) * 127) midi_track.addProgramChange(track, channel, time * i, instrument) midi_track.addNote(track, channel, pitch, time * i, duration, volume) with open(o_path + '_-_Track 0' + str(idx+1)+".mid", "wb") as output_file: midi_track.writeFile(output_file)
def __init__(self, program, tempo, pitch, chord, duration=1, volume=1, start_beat=1, trail_silence=1, noise_type='none', noise_volume=0): self.program = program self.tempo = tempo self.pitch = pitch self.chord = chord self.duration = duration self.volume = volume self.start_beat = start_beat self.trail_silence = trail_silence self.noise_type = noise_type self.noise_volume = noise_volume self.track = 0 self.channel = 0 my_midi = MIDIFile(1) my_midi.addTempo(self.track, 0, self.tempo) for item in self.chord: my_midi.addNote(self.track, self.channel, self.pitch + item, self.start_beat, self.duration, self.volume) my_midi.addProgramChange(self.track, self.channel, 0, self.program) self.midi_file = my_midi
def writefile(self, filepath): """ Writes the current internal musical representation to the file specified by ``filepath``. """ midi = MIDIFile( sum(1 for v in self.voices if v) + 1, True, True, True, 1) i = -1 for vindex in range(len(self.voices)): voice = self.voices[vindex] if not voice: continue i += 1 if i == 9: i += 1 time = 0.0 midi.addTempo(i, 0, self.tempo) midi.addProgramChange(i, i, 0, self.instruments[vindex]) for note in voice: if note.pitch >= 0: midi.addNote(i, i, note.pitch, time, note.duration, note.volume) time += note.duration time = 0.0 midi.addTempo(9, 0, self.tempo) for note in self.drums: if note.pitch >= 0: midi.addNote(9, 9, note.pitch, time, note.duration, note.volume) time += note.duration with open(filepath, "wb") as outputfile: midi.writeFile(outputfile)
def make_midi(self, data_list): degrees = [] volume = [] duration = [] # channel = [] track = [] time = [] for i in range(len(data_list)): data_list[i] = data_list[i].strip('\n') current = data_list[i].split(",") degrees.append(int(current[0])) volume.append(int(current[1])) duration.append(float(current[2])) track.append(int(current[3])) time.append(float(current[4])) """ print(degrees) print(volume) print(duration) print(track) print(time) """ # degrees = [38, 42, 57, 38, 57, 42, 38] # MIDI note number # track = 0 channel = 0 # time = 1 # In beats # duration = [15, 15, 12, 13, 11, 13, 3] # In beats tempo = 20 # In BPM # volume = [110, 25, 100, 80, 40, 70, 120] # 0-127, as per the MIDI standard program = 10 MyMIDI = MIDIFile( 3, deinterleave=False ) # One track, defaults to format 1 (tempo track is created # automatically) MyMIDI.addTempo(0, 1, tempo) MyMIDI.addTempo(1, 1, tempo) MyMIDI.addTempo(2, 1, tempo) MyMIDI.addProgramChange(0, channel, 1, program) MyMIDI.addProgramChange(1, channel, 1, program) MyMIDI.addProgramChange(2, channel, 1, program) for i, pitch in enumerate(degrees): MyMIDI.addNote(track[i], channel, pitch, time[i], duration[i], volume[i]) with open("simulacrum.mid", "wb") as output_file: MyMIDI.writeFile(output_file) fs = FluidSynth(usesoundfont) # usesoundfont is defined at top of code fs.midi_to_audio('simulacrum.mid', 'simulacrum.wav') AudioSegment.from_wav("simulacrum.wav").export("simulacrum.mp3", format="mp3")
def write_midifile(progression_semitones, filename): track = 0 channel_lead = 0 channel_bass = 1 channel_drums = 9 time = 0 # In beats tempo = 60 # In BPM volume = 100 # 0-127, as per the MIDI standard MyMIDI = MIDIFile(1) # One track, defaults to format 1 (tempo track automatically created) MyMIDI.addTempo(track, time, tempo) MyMIDI.addProgramChange(track, channel_lead, 0, 0) # Piano MyMIDI.addProgramChange(track, channel_bass, 0, 32) # Acoustic Bass MyMIDI.addProgramChange(track, channel_drums, 0, 0) # Drums Channel WITH_DRUMS = False pitch_bassdrum = 35 pitch_snaredrum = 38 pitch_hihat = 42 duration_drums = 1 p_C1 = 24 p_C2 = 36 p_C3 = 48 start_pitch = p_C3 duration_bass = 4 durations_lead = [1] * (len(progression_semitones) - 1) durations_lead.append(4) for i, chord_semitones in enumerate(progression_semitones): # The chord for semitone in chord_semitones: pitch_lead = start_pitch + semitone MyMIDI.addNote(track, channel_lead, pitch_lead, time, durations_lead[i], volume) # Bass note pitch_bass = start_pitch - 12 + chord_semitones[0] MyMIDI.addNote(track, channel_bass, pitch_bass, time, duration_bass, volume) if WITH_DRUMS: if time % 2 == 0: MyMIDI.addNote(track, channel_drums, pitch_bassdrum, time, duration_drums, volume) if time % 2 == 1: MyMIDI.addNote(track, channel_drums, pitch_snaredrum, time, duration_drums, volume) for i in [1,2,3,4]: MyMIDI.addNote(track, channel_drums, pitch_hihat, time + (i-1)/4.0, duration_drums, volume) time = time + 1 with open(filename, "wb") as output_file: MyMIDI.writeFile(output_file)
def makemidi(img, midi, lo=74, hi=110): if int(lo) > 0: lo = 0 if int(hi) < 127: hi = 127 filename = img if filename.endswith('.png'): a = cv2.imread(filename, cv2.IMREAD_UNCHANGED) trans = a[:, :, 3] == 0 a[trans] = [255, 255, 255, 255] a = cv2.cvtColor(a, cv2.COLOR_BGRA2BGR) else: a = cv2.imread(filename, cv2.IMREAD_UNCHANGED) h, w = a.shape[:2] scale = w / h w = int(127 * scale) dim = (w, 127) res = cv2.resize(a, dim, interpolation=cv2.INTER_AREA) gray = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY) (tresh, newimg) = cv2.threshold(gray, 127, 225, cv2.THRESH_BINARY) # cv2.imshow('jjj', newimg) # cv2.waitKey(0) # cv2.destroyAllWindows() color = 0 pixels1 = np.argwhere(newimg == 0) pixels2 = np.argwhere(newimg == 225) if pixels1.shape > pixels2.shape: pixels = pixels2 else: pixels = pixels1 MyMIDI = MIDIFile( 4) # One track, defaults to format 1 (tempo track is created # automatically) MyMIDI.addTempo(0, 0, 180 * scale) MyMIDI.addProgramChange(0, 0, 0, 0) for note, step in pixels: MyMIDI.addNote(0, 0, 127 - note + 1, step, 1, random.randint(int(lo), int(hi))) with open(midi, "wb") as output_file: MyMIDI.writeFile(output_file) exit("write {} successful".format(midi))
def play_chord(notes, sf2, program): notes = [n + 40 for n in notes] t = 0 # In beats duration = 1.5 # In beats tempo = 60 # In BPM MyMIDI = MIDIFile(1) # One track, defaults to format 1 (tempo track is created # automatically) MyMIDI.addTempo(0, t, tempo) MyMIDI.addProgramChange(0, 0, 0, program) # Number is soundfount number for i, pitch in enumerate(notes): MyMIDI.addNote(0, 0, pitch, t + 0.02*i, duration, np.random.randint(80,120)) with open("chord.mid", "wb") as output_file: MyMIDI.writeFile(output_file) time.sleep(0.1) os.system('fluidsynth --no-shell -a pulseaudio "sf2/%s" chord.mid &>/dev/null &' % (sf2)) print(sf2)
def convert(self, tune: Tune, output_file_path: str): midi_file = MIDIFile( numTracks=len(tune.tracks) ) midi_file.addTempo(0, 0, tune.bpm) length_of_quarter_seconds = 60 / tune.bpm for idx, track in enumerate(tune.tracks): midi_file.addTrackName(idx, 0.0, 'Track ' + str(idx)) midi_file.addProgramChange(idx, idx, 0.0, self._generate_program_number(track.timbre)) for note in track.notes: start_time_in_quarters = note.start_time_seconds / length_of_quarter_seconds length_in_quarters = (note.end_time_seconds - note.start_time_seconds) / length_of_quarter_seconds midi_file.addNote(idx, idx, note.note, start_time_in_quarters, length_in_quarters, round(note.velocity * 127)) with open(output_file_path, "wb") as output_file: midi_file.writeFile(output_file)
def write_midi(input_data, output_file, mode="pitch"): midi = MIDIFile(1) midi.addTrackName(track=0, time=0, trackName="Sample Track") midi.addTempo(track=0, time=0, tempo=BPM) for track in range(len(input_data)): if mode == "both" and track >= len(input_data) // 2: break midi.addProgramChange(0, track, 0, program=INSTRUMENTS[track]) track_data = input_data[track] time_per_note = SONG_LEN / len(track_data) for i, note in enumerate(track_data): z = percentile(track_data, note) if mode == "both": volume_track = input_data[track + len(input_data) // 2] index = int(i * len(volume_track) / len(track_data)) volume_z = percentile(volume_track, volume_track[index]) volume = int(volume_z * 100) + 1 assert 127 > volume >= 0 midi.addNote(track=0, channel=track, pitch=get_pitch(z * TOTAL_RANGE), time=time_per_note * i, duration=time_per_note, volume=volume) elif mode == "pitch": midi.addNote(track=0, channel=track, pitch=get_pitch(z * TOTAL_RANGE), time=time_per_note * i, duration=time_per_note, volume=100) elif mode == "volume": midi.addNote(track=0, channel=track, pitch=60 + 12 * track, time=time_per_note * i, duration=time_per_note, volume=int(z * 100)) with open(output_file, 'wb') as binfile: midi.writeFile(binfile)
class SaveMIDI: def __init__(self, tempo, instrument, background, file_path): self.track = 0 self.channel = 0 self.channel2 = 1 self.time = 0 self.back_time = 0 self.tempo = tempo self.volume = 100 self.volume2 = 65 self.instrument = instrument self.background = background self.file_path = file_path self.MyMIDI = MIDIFile(1, file_format=0) self.create_midi() def create_midi(self): self.MyMIDI.addTempo(self.track, self.time, self.tempo) self.MyMIDI.addProgramChange( self.track, self.channel, self.time, self.instrument) # ustawienia linii melodycznej self.MyMIDI.addProgramChange(self.track, self.channel2, self.time, self.background) # ustawienia podkładu def save_midi(self): with open(self.file_path + ".mid", "wb") as output_file: self.MyMIDI.writeFile(output_file) def write_midi(self, tacts): for notes in tacts: for note in notes: self.MyMIDI.addNote(self.track, self.channel, note[0], self.time, note[1], self.volume) self.time = self.time + note[1] def write_background(self, tacts): for notes in tacts: for note in notes: self.MyMIDI.addNote(self.track, self.channel2, note, self.back_time, 2, self.volume2) self.back_time = self.back_time + 2
def generate_midi(notes, instrument, tempo, file_name): """Generate midi file from notes array.""" track = 0 channel = 0 time = 0 MyMIDI = MIDIFile(1) MyMIDI.addTempo(track, time, tempo) MyMIDI.addProgramChange(track, channel, 0, instrument) duration_counter = 0 for pitch, duration, volume in notes: MyMIDI.addNote(track, channel, pitch, time + duration_counter, duration, volume) duration_counter = duration_counter + duration with open(file_name + ".mid", "wb") as output_file: MyMIDI.writeFile(output_file)
def midiGenerator(self,a): MyMIDI = MIDIFile(1) MyMIDI.addProgramChange(self.track, self.channel, self.time,1) MyMIDI.addTempo(self.track, self.time, self.tempo) time=0 for i in range(len(a[0])): for j in range(len(a)): duration = self.duration if a[j][i]!='-': if a[j][i+1]=='-': duration = self.duration+1 MyMIDI.addNote(self.track,self.channel,int(a[j][i]),time,duration,self.volume) time+=self.time with open("output.mid", "wb") as output_file: MyMIDI.writeFile(output_file)
class Transcriber: # https://soundprogramming.net/file-formats/general-midi-instrument-list/ # 1 track, each index is a channel def __init__(self, file_name): self.file_name = file_name def compile(self, song_generator): self.generator = MIDIFile(1) for i in song_generator.song: self.generator.addProgramChange(0, song_generator.song[i]["channel"], 0, song_generator.song[i]["program"]) for note in song_generator.song[i]["note_series"]: self.generator.addNote(0, song_generator.song[i]["channel"], note["pitch"], note["time"], note["duration"], note["volume"]) for i in song_generator.events: if i["type"] == "tempo": self.generator.addTempo(0, i["time"], i["value"]) self.write_to_file() def write_to_file(self): with open(self.file_name, "wb") as output_file: self.generator.writeFile(output_file)
def convert_to_midi(seq_note, file, repertory="output/"): track = 0 channel = 9 tempo = 120 # In BPM volume = 100 # 0-127, as per the MIDI standard my_midi = MIDIFile( 1 ) # One track, defaults to format 1 (tempo track is created automatically) my_midi.addTempo(track, 0, tempo) my_midi.addProgramChange(0, 10, 0, 0) my_midi.tracks[0].addChannelPressure(0, 4, 0) for note in seq_note: #print(note) my_midi.addNote(track, channel, note.pitch, note.timestamp, note.duration, volume) with open(repertory + file, "wb") as output_file: my_midi.writeFile(output_file)
class MelodyCreator: def __init__(self, path='melody.mid', tempo=200): self._path = path self._melody = MIDIFile(1, True, True, True) self._track = 0 self._tempo = tempo self._melody.addTempo(self._track, 0, tempo) self._free_channels = [x for x in range(16, -1, -1) if x != 9] self._current_channel = 0 self._beat_instrument = 0 self._beat_drum = 0 def add_instrument(self, instrument_number): self._current_channel = self._free_channels.pop() self._melody.addProgramChange(self._track, self._current_channel, 0, instrument_number) self._beat_instrument = 0 def add_instrument_pattern(self, pattern): self._beat_instrument = self._add_pattern(self._current_channel, self._beat_instrument, pattern) def add_drum_pattern(self, pattern): self._beat_drum = self._add_pattern(9, self._beat_drum, pattern) def _add_pattern(self, channel, start_beat, pattern): for bar in pattern.bars: for notes in bar.beats: for note in notes: self._add_note(channel, start_beat, note) start_beat += 1 return start_beat def _add_note(self, channel, beat, note): self._melody.addNote(self._track, channel, note.pitch, beat, note.duration, note.volume) def save_melody(self): with open(self._path, "wb") as output_file: self._melody.writeFile(output_file)
def export_midi_score(self): my_midi = MIDIFile(1, eventtime_is_ticks=True) print(f"Tempo: {self.tempo}") my_midi.addTempo(0, 0, self.tempo) my_midi.addProgramChange(0, 0, 0, 73) for current_phrase in self.phrases: for current_measure in current_phrase.measures: for current_obj in current_measure.notes: offset_in_ticks = int(current_obj.absolute_offset * 960) duration_in_ticks = int(current_obj.duration * 960) if isinstance(current_obj, Note): my_midi.addNote( 0, 0, current_obj.midi_num, offset_in_ticks, duration_in_ticks, 100 ) try: with open("theme.mid", "wb") as midi_output: my_midi.writeFile(midi_output) except PermissionError: print("You must close the previous midi file to overwrite it.")
def create_track_map(midi_instance: MIDIFile, tempo: int = 90): track_map = {} i = 0 for k, v in channel_map.items(): track = Track.create_track(midi_instance=midi_instance, track=i, channel=v, tempo=tempo, track_name=k) print('track = %d, channel = %d' % (i, v)) if v != 9: midi_instance.addProgramChange(i, i, 0, get_channel_program_int(v)) track_map[reversed_channel_map[v]] = track midi_instance.addControllerEvent( track=i, channel=v, time=0, controller_number=Track.PAN_CONTROLLER_NUMBER, parameter=channel_panning_map[k]) i += 1 return track_map
def write_midi_from_counterpoint(self, lines: list[list[RhythmicValue]], filename: str, speed_up: float = 1.0 ) -> None: if lines is None: return tempo = 672 * speed_up channel = 0 start_time = 0 CounterpointMIDI = MIDIFile(len(lines), deinterleave=False, removeDuplicates=False) for i, line in enumerate(lines): #75 is the "recorder" instrument in General MIDI instrument = 75 if i == 0 else 70 volume_level = 100 if i == 0 else 95 CounterpointMIDI.addProgramChange(i, i, 0, instrument) track = i channel = i CounterpointMIDI.addTempo(track, start_time, tempo) time_index = start_time for entity in line + [Rest(8)]: duration = entity.get_duration() pitch = entity.get_pitch_value() if isinstance(entity, Pitch) else 0 volume = volume_level if isinstance(entity, Pitch) else 0 CounterpointMIDI.addNote(track, channel, pitch, time_index, duration, volume) time_index += duration with open(filename, "wb") as output_file: CounterpointMIDI.writeFile(output_file)
def create_midi_file(self, file_name=None): track = 0 channel = 9 tempo = 120 # In BPM volume = 100 # 0-127, as per the MIDI standard my_midi = MIDIFile( 1 ) # One track, defaults to format 1 (tempo track is created automatically) my_midi.addTempo(track, 0, tempo) my_midi.addProgramChange(0, 10, 0, 0) my_midi.tracks[0].addChannelPressure(0, 4, 0) repertory = "output/" if file_name is not None: file = file_name + ".mid" else: file = str(self.ind) + ".mid" for note in self.sequence: my_midi.addNote(track, channel, note.bit.pitch, note.bit.timestamp, note.bit.duration, volume) with open(repertory + file, "wb") as output_file: my_midi.writeFile(output_file)
def run(instrument, notes): o = instrument if instrument == "Piano": instrument = 2 elif instrument == "Guitar": instrument = 26 elif instrument == "Bass": instrument = 34 midi = MIDIFile(1) midi.addProgramChange(0, 0, 0, instrument) k = len(notes) if instrument == 2: s = 51 elif instrument == 26: s = 40 else: s = 30 for i in range(k): for j in range(6): if notes[i][j] == 1: midi.addNote(0, 0, s + i, j, 1, 100) with open("Samples/%s.mid" % (o), "wb") as output_file: midi.writeFile(output_file)
def build_midi_file(self) -> MIDIFile: # Compress runs of the same note reduces_song_map: typing.List[typing.Tuple[str, int]] reduced_song_map = [(self.song_map[0], 1)] # [(note, duration), ...] for note in self.song_map[1:]: if note == "-": last = reduced_song_map[-1] reduced_song_map[-1] = (last[0], last[1] + 1) else: reduced_song_map.append((note, 1)) midi = MIDIFile() midi.addTempo(0, 0, self.bpm) midi.addProgramChange(0, 0, 0, 7) offset = 0 for note, count in reduced_song_map: if note not in (".", "—"): pitch = self.midi_notes[note] duration = count - 0.5 midi.addNote(0, 0, pitch, offset, duration, 127) offset += count return midi
Drums[(xNote, yNote)] = Percussion Percussion += 1 track = 0 # Midi allows for multiple tracks to be written. 0 is one track, 1 is an additional track, and so on. count = 0 # This declares where the note will be placed based on beats. duration = 1 # How long a note will last (in beats). tempo = 144 # Beats Per Minute (BPM) volume = 127 # 0-127, as per the MIDI standard midi = MIDIFile(1) #Calling of the midiutil module midi.addTempo(track, count, tempo) midi.addTrackName( track, count, "Langton's Launch Jams." ) #Title of the midi file (can only be viewed in notation software) midi.addProgramChange(track, 0, count, 107) def writeMidi(ant): #Function to write the chords in the midi file x, y = (ant.curpos['x'] / 64), ( ant.curpos['y'] / 64 ) #Takes the ant's current x and y position and divides both values by 64, #this is so because the ant's position increments 64 pixels at a time. chord = Notes[int(x)][int( y)] #finds the chord in Notes based on the x and y value of the ant for i in chord: midi.addNote(track, 0, i, ant.turns, 2, volume) #Function to add the note to the midi file. #midi.addnote(track, channel, pitch, time, duration, volume) if ant.turns == 5000: #Outputs the midi file after 5000 turns. This number can be changed to anything, beware that a bigger number
def create_midi(path_midi, protein, midi_keys, tempo, instrus, aa_phy_chi, logger, debug=False): ''' Creates the MIDI file from the protein data. :param str path_midi: the path to the MIDI file. :param dict protein: the dictionary descri the protein. :param dict midi_keys: the dictionary of the keys :param list initial_keys: the list of the initial keys :param int tempo: the tempo in BPM :param list instrus: the list of the MIDI instrument numbers :param dict aa_phy_chi: dictionary of the physico-chemical attributes of the amino acids :param logger logger: the logger :param boolean debug: the enable debug mode :return: the list of keys durations :rtype: list of floats ''' # octaves DO, RE, MI, FA, SOL, LA, SI. 2 octaves and 1 more SOL, # the remaining 7 keys are altérations (#) KEYS_OCTAVE_ALTERATIONS = [48, 50, 52, 53, 55, 57, 59, 60, 62, 64, 65, 67, 69, 71, 72, 54, 66, 49, 61, 56, 68, 51] KEYS_OCTAVE_ONLY = KEYS_OCTAVE_ALTERATIONS[:15] with open(path_midi, 'wb') as midiFile: track = 0 time = 0 # In beats # a channel is defined by an instrument nbr and # a volume (0-127, as per the MIDI standard, # see: http://www.pjb.com.au/muscript/gm.html) # channel 9 is for percussions # (see https://pjb.com.au/muscript/gm.html#perc) channels = {0: {'instrument': instrus[0], 'vol': 100}, 1: {'instrument': instrus[1], 'vol': 40}, 2: {'instrument': instrus[2], 'vol': 60}} if debug: logger.info('Instrument number by channel, see: http://www.pjb.com.au/muscript/gm.html for instruments number correspondance:') for channel_nb in channels: logger.info('\tchannel {}: instrument {}'.format(channel_nb, channels[channel_nb]['instrument'])) MyMIDI = MIDIFile(numTracks=1, adjust_origin=False) # One track, defaults to format 1 (tempo track automatically created) MyMIDI.addTempo(track, time, tempo) # add the channels (1 per instrument) for channel_nbr in channels: MyMIDI.addProgramChange(track, channel=channel_nbr, time=time, program=channels[channel_nbr]['instrument']) sequence_length = len(protein['seq']) durations_list = [] for i in range(0, sequence_length): AA = protein['seq'][i] pitch_list = [midi_keys[AA]] if i == 0: prev_AA = protein['seq'][sequence_length - 1] next_AA = protein['seq'][i + 1] elif i == sequence_length - 1: prev_AA = protein['seq'][i - 1] next_AA = protein['seq'][0] else: prev_AA = protein['seq'][i - 1] next_AA = protein['seq'][i + 1] # set the duration of the key (current AA) depending on the number # of shared properties with the next AA if AA == 'X' or next_AA == 'X': # non determined AA shared_properties_current_next = 0 else: shared_properties_current_next = len(set.intersection(aa_phy_chi[AA], aa_phy_chi[next_AA])) if shared_properties_current_next == 0: duration = 1 elif shared_properties_current_next == 1: duration = 1.5 elif shared_properties_current_next == 2: duration = 2 else: duration = 4 # add each duration adjusted with the tempo durations_list.append(float(duration) * (60 / tempo)) # set the chords depending on number of shared properties between # current AA and the previous AA if AA == 'X' or prev_AA == 'X': # non determined AA shared_properties_current_previous = 0 else: shared_properties_current_previous = len(set.intersection(aa_phy_chi[AA], aa_phy_chi[prev_AA])) if shared_properties_current_previous == 2: # 2 keys chord keys_in_chord = 2 idx_key = KEYS_OCTAVE_ALTERATIONS.index(midi_keys[AA]) pitch_list = create_chord(pitch_list, keys_in_chord, idx_key, KEYS_OCTAVE_ONLY) elif shared_properties_current_previous == 3: # 3 keys chord keys_in_chord = 3 idx_key = KEYS_OCTAVE_ALTERATIONS.index(midi_keys[AA]) pitch_list = create_chord(pitch_list, keys_in_chord, idx_key, KEYS_OCTAVE_ONLY) elif shared_properties_current_previous >= 4: # 4 keys chord keys_in_chord = 4 idx_key = KEYS_OCTAVE_ALTERATIONS.index(midi_keys[AA]) pitch_list = create_chord(pitch_list, keys_in_chord, idx_key, KEYS_OCTAVE_ONLY) # change the volume of each instrument depending on the structure if 'structure' in protein.keys(): if i in protein['structure'].keys(): logger.debug('{}: {}'.format(protein['structure'][i], i)) if protein['structure'][i] == 'HELIX': channels[0]['vol'] = 40 channels[1]['vol'] = 100 channels[2]['vol'] = 60 elif protein['structure'][i] == 'STRAND': channels[0]['vol'] = 60 channels[1]['vol'] = 40 channels[2]['vol'] = 100 elif protein['structure'][i] == 'TURN': channels[0]['vol'] = 100 channels[1]['vol'] = 40 channels[2]['vol'] = 60 else: channels[0]['vol'] = 100 channels[1]['vol'] = 60 channels[2]['vol'] = 40 if debug: logger.debug('position: {}'.format(i)) logger.debug('AA: {}'.format(AA)) logger.debug('pitch: {}'.format(pitch_list)) logger.debug('time: {}'.format(time)) logger.debug('duration: {}'.format(duration)) for channel_nbr in channels: for pitch in pitch_list: MyMIDI.addNote(track, channel=channel_nbr, pitch=pitch, time=time, duration=duration, volume=channels[channel_nbr]['vol']) time = time + duration MyMIDI.writeFile(midiFile) return durations_list
range(88, 95)) + list(range(112, 119)) main_track_instruments = list(range(7)) + list(range(16, 31)) + list( range(40, 79)) + list(range(104, 111)) # Choosing the instruments randomly from the list beat_track_instr = beat_track_instruments[random.randint( 0, len(beat_track_instruments) - 1)] main_track_instr = main_track_instruments[random.randint( 0, len(main_track_instruments) - 1)] # Changing Beat Track to Beat Track Instrument MyMIDI.addProgramChange(beat_track, beat_channel, beat_time, beat_track_instr) # Add Beat Track to MIDIFile Object t = 0 for i, pitch in enumerate(beat_degrees): duration = durations[i % len(durations)] MyMIDI.addNote(beat_track, beat_channel, pitch, beat_time + t, durations[i], beat_volume) t = t + durations[i] # Changing Main Track to Main Track Instrument MyMIDI.addProgramChange(music_track, music_channel, music_time, main_track_instr)