async def make_midi(self, tempo: int, data: str) -> MIDIFile: midi_file = MIDIFile(1) midi_file.addTrackName(0, 0, 'beep boop') midi_file.addTempo(0, 0, tempo) channel_datas = data.split('|') log.debug(f'creating MIDI out of "{data}"') for channel_index, channel_data in enumerate(channel_datas): await self.add_channel(midi_file, channel_index, channel_data) log.info('successfully created MIDI') return midi_file
def create_midi_file(daw_state): num_tracks = len(daw_state['tracks']) channel = 0 time = 0 # In beats duration = 1 # In beats tempo = daw_state['tempo'] # In BPM volume = 50 # 0-127, as per the MIDI standard midi_object = MIDIFile( numTracks=num_tracks ) # One track, defaults to format 1 (tempo track is created automatically) # The daw_state representation gives note a time state array. To write a MIDI file, # we'll need to transpose the mapping so that each time step maps to a set of active note numerals. max_time_steps = len(daw_state['tracks'][0][0]['timeStates']) for current_time_step in range(0, max_time_steps): notes_active_at_this_timestep = [] for track_index in range(0, num_tracks): note_states = daw_state['tracks'][track_index] for note in note_states: if note['timeStates'][current_time_step]: this_note_numeral = note_name_to_numeral(note['id']) notes_active_at_this_timestep.append(this_note_numeral) # This timestep has been scanned and active notes gathered. We can write all notes to the file. midi_object.addTempo(track_index, time, tempo) for note in notes_active_at_this_timestep: midi_object.addNote(track_index, channel, note, current_time_step, duration, volume) with open("midi-export.mid", "wb") as output_file: midi_object.writeFile(output_file) return ("midi-export.mid", output_file)
class MidiExport: global midiExportFile midinote_l = 36 midinote_m = 38 midinote_h = 42 midinote_ho = 46 def __init__(self, generator): self.midiExportFile = MIDIFile(2) # (track, time, tempo) self.midiExportFile.addTempo(1000, 0, bpm) numerator = generator.beatPerMeasure denominator = int(math.log(generator.beatUnit, 2)) clocksPerTick = int(24 * (4 / generator.beatUnit)) self.midiExportFile.addTimeSignature(1000, 0, numerator, denominator, clocksPerTick) def export(self, sequence, filename): sixteenthNoteDuration = (60. / bpm) * .25 for event in sequence: if (len(event) > 2): for sound in event[2:]: if sound is "l": pitch = self.midinote_l amp = 110 if event[1] == 0 else 80 elif sound is "m": pitch = self.midinote_m amp = 110 if event[1] == 0 else 80 elif sound is "h": pitch = self.midinote_h amp = 80 # (track, channel, pitch, time, duration, volume) self.midiExportFile.addNote(0, 9, pitch, event[0] * .25, .25, amp) with open(filename + ".mid", "wb") as output_file: self.midiExportFile.writeFile(output_file)
def chords_wav(tempo, key, instrument): chords = progression(key) track = 0 channel = 0 time = 0 duration = 2 tempo = tempo volume = 90 midi = MIDIFile(1) midi.addTempo(track, time, tempo) delay = randint(0, 1) print(delay) for chord in chords: i = 0 for note in chord: midi.addNote(track, channel, note, time + 0.05 * i * delay, duration, volume) i += 1 time += 2 with open('midi/chords.mid', 'wb') as output_file: midi.writeFile(output_file) fs = FluidSynth(instrument) fs.midi_to_audio('midi/chords.mid', 'wav/chords.wav') lowpass('wav/chords.wav', 'wav/processed_chords.wav', 1000) return chords
def add_track(self, notes: list, id: str): track = 0 channel = 0 time = 0 duration = 1 tempo = 160 volume = 100 COUNT = 0 MyMIDI = MIDIFile(1) MyMIDI.addTempo(track, time, tempo) for note in notes: COUNT = (COUNT + 1) % 7 MyMIDI.addNote(track, channel, note[PITCH], time, duration, volume) time += note[BEATS] if COUNT % 7 == 0: time += 1 with open( os.path.join(app.root_path, app.config["UPLOAD_FOLDER"], "{}.mid".format(id)), "wb") as output_file: MyMIDI.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
def write_midi(self): """writes midi file for the piece""" time = 0 MyMIDI = MIDIFile(1) MyMIDI.addTempo(track, time, tempo) piece = self.in_notes() # adding notes for note in piece[0]: for pitch in note.pitch: MyMIDI.addNote(track, channel, pitch, time, note.duration, volume) time += note.duration # adding bass time = 0 for note in piece[1]: for pitch in note.pitch: MyMIDI.addNote(track, channel + 1, pitch - 12, time, note.duration, volume) time += note.duration with open("test.mid", "wb") as output_file: MyMIDI.writeFile(output_file) print('Done! Midi file saved as "test.mid"')
def generate(filename): # generate upper = random.randint(0, 128) lower = random.randint(0, upper) degrees = generateNotes( lower, upper, random.randint(0, 501) ) # This is where the actual notes are stored ... ex: [60, 62, 64, 65, 67, 69, 71, 72] # MIDI note number track = 0 # Literally, the track at which the notes are stored channel = 0 # 1 = mono, 2 = stereo time = 0 # When the note is played (the beat at which the note is played) duration = 1 # 1 = quarter note, 1/2 = eigth note tempo = random.randint(40, 201) # 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) MyMIDI.addTempo(track, time, tempo) # Idea: every iteration of the for loop, you randomly generate a new number for i, pitch in enumerate(degrees): timeScalar = 1.0 / random.randint( 1, 10) # This has to do with note position durationScalar = 1.0 / random.randint( 1, 10 ) # This has to do with the notes duration (i.e. quarter note, half-note, etc.) duration = random.randint(1, 10) MyMIDI.addNote( track, channel, pitch, i + timeScalar, duration * durationScalar, volume) # This is where we can configure the timing of each note # If we want to add more notes to track 0 then we can do this: # MyMIDI.addNote(track, channel, 60, time + 7, duration*0.5, volume-10) with open(filename, "wb") as output_file: MyMIDI.writeFile(output_file)
def create_midi_file(self, file_name=None): track = 0 channel = 1 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: # print(note) my_midi.addNote(track, channel, note.bit.pitch + 36, note.bit.timestamp, note.bit.duration, volume) with open(repertory + file, "wb") as output_file: my_midi.writeFile(output_file)
def generateMidi(pitches): for i in range(len(pitches)): pitches[i] = getNum(pitches[i]) track = 0 channel = 0 time = 0 duration = 1 tempo = 120 # default tempo for now volume = 100 newMidi = MIDIFile(1) newMidi.adjust_origin = True newMidi.addTempo(track, time, tempo) for i, pitch in enumerate(pitches): newMidi.addNote(track, channel, pitch, time + i, duration, volume) ts = datetime.datetime.now() ofp = "Twinkle{}.mid".format(ts.strftime("%H-%M-%S")) with open(ofp, "wb") as midi_output: newMidi.writeFile(midi_output)
def drum_wav(tempo, instrument, keys): notes = [keys["kick"], keys["snare"]] track = 0 channel = 0 time = 0 duration = 1 tempo = tempo volume = 127 midi = MIDIFile(1) midi.addTempo(track, time, tempo) for note in notes: midi.addNote(track, channel, note, time, duration, volume) time += 1 time = 0 hat_pattern = rhytm_generator() for i in range(16): # if hat_pattern[i] == 1: # midi.addNote(track,channel,keys["hi-hat"],time,0.125,90) if (i) % 4 == 0 and i % 8 != 0: midi.addNote(track, channel, keys["op-hat"], time, 0.125, 70) time += 0.125 with open('midi/drums.mid', 'wb') as output_file: midi.writeFile(output_file) fs = FluidSynth(instrument) fs.midi_to_audio('midi/drums.mid', 'wav/drums.wav')
def createMIDI(): ''' So, I guess this generates some MIDI data? Depending on what the instrument type (or whatever) is, there doesnt even need to be pitch info, it can just be an on and off, right? And that is a signal for the sample to be written Would be cool to create a DSL for specifying midi patterns, and then I can just write an engine to convert that to a MIDIFile What might that look like? {"Track1" : {}} ''' degrees = [60, 62, 64, 65, 67, 69, 71, 72] # MIDI note number track = 0 channel = 0 time = 0 # In beats duration = 1 # In beats tempo = 120 # 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) MyMIDI.addTempo(track, time, tempo) for i, pitch in enumerate(degrees): MyMIDI.addNote(track, channel, pitch, time + i, duration, volume) track = 1 degrees.reverse() MyMIDI.addTempo(track, time, tempo) for i, pitch in enumerate(degrees): MyMIDI.addNote(track, channel, pitch, time + i, duration, volume) with open("major-scale.mid", "wb") as output_file: MyMIDI.writeFile(output_file)
for xNote in range(0, 8): for yNote in range(0, 8): if Percussion == 82: Percussion = 35 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,
def main(argv): file_name = ''.join(map(str, argv)) file_path = "./uploads/" + file_name print(file_name) print(file_path) model = Model() checkpoint = torch.load('./machine_learning/model/CNN_model.pt', map_location='cpu') model.load_state_dict(checkpoint['state_dict'], strict=False) model.eval() pred = [] sr, song = wavfile.read(file_path) # Loading your audio song = song / abs(max(song.min(), song.max(), key=abs)) segs = len(song) // 4410 for j in range(segs - 1): #lazy seg = song[j * 4410:(j + 1) * 4410] x = seg.mean(1) # Converting Stereo to Mono x = torch.tensor( x, device=device, dtype=torch.float) # casting the array into a PyTorch Tensor y_pred = model(x) to_numpy = y_pred.cpu().detach().numpy()[0] pred.append(to_numpy) pred = np.round(np.array(pred)) pred = pred.T # 88 is the 🎹 🔑 (21 to 108) predT = pred.T new_notes = [] for i in predT: x = np.where(i != 0)[0] + 21 new_notes.append(x.tolist()) degrees = new_notes # MIDI note number track = 0 channel = 0 time = 0.1 # In beats duration = 1 # 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) MyMIDI.addTempo(track, time, tempo) for i, pitches in enumerate(degrees): if pitches != []: for pitch in pitches: MyMIDI.addNote(track, channel, pitch, time * i, duration, volume) with open("./transcribed/outputtest.midi", "wb") as output_file: MyMIDI.writeFile(output_file) print(argv)
pattern = random.choice(words)() text.append(pattern.name) # Tick in first measure event = [track, channel, 34, time, 1, 127] song.append(event) for note in pattern.getNotes(): event = [track, channel] event.append(note[0]) event.append(time) event.append(note[1]) event.append(volume) #print(event) song.append(event) time += note[1] # Update time printSong(text) MyMIDI = MIDIFile( 1 ) # One track, defaults to format 1 (tempo track is created automatically) MyMIDI.addTempo(track, 0, tempo) for event in song: track, channel, pitch, time, duration, volume = event MyMIDI.addNote(track, channel, pitch, time, duration, volume) with open("C:/Users/magarami/Desktop/rythmTraining.mid", "wb") as output_file: MyMIDI.writeFile(output_file)
for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.MOUSEBUTTONUP: pos = pygame.mouse.get_pos() x, y = pos #If record button is pressed, make a new midi file to record the notes in, #set the current time as start time to keep track of note timings, #change the button to recording, and toggle recording and going variables so #the program enters the recording loop if 125 > x > 75 and 145 > y > 95: mf = MIDIFile(1) starttime = time.time() mf.addTrackName(track, 0, "Track") mf.addTempo(track, 0, 60) pygame.draw.rect(screen, bright_red, (60, 80, 80, 80)) text_surface = my_font.render("RECORDING", True, WHITE) rect = text_surface.get_rect(center=(100, 120)) screen.blit(text_surface, rect) RECORDING = True going = False #If play button is pressed if 225 > x > 175 and 145 > y > 95: #If it was playing, stop playing the recorded file and change the button #to play. Set playing to False so the music would not play again. if playing: pygame.mixer.music.stop() playing = False pygame.draw.rect(screen, green, (160, 80, 80, 80)) text_surface = my_font.render("PLAY", True, WHITE)
offsetsMap[i] = stepValuesArray[3+18] rhythm.append(stepValuesArray) if rhythm[0][21] < 0: rhythm[0][21]=0 offsetsMap[0]=0 track = 0 channel = 0 duration = 1/4 # In beats volume = 127 # 0-127, as per the MIDI standard pitch = 46 MyMIDI = MIDIFile(1) # One track, defaults to format 1 (tempo track is created # automatically) MyMIDI.addTempo(track, 0, bpm) for i, offset in offsetsMap.items(): MyMIDI.addNote(track, channel, pitch, (i + offset)/4, duration, volume) with open("output.mid", "wb") as output_file: MyMIDI.writeFile(output_file) fig = plt.figure() ax0 = fig.add_subplot(211) ax0.plot(AAsignal, label='signal') ax0.set_xlabel("Original signal") fig = plt.figure() ax0 = fig.add_subplot(211) ax0.plot(AAabssignal, label='envelope')
import sys bpm = 60 vartrack = 2 toadd = [ 1, (60, 1, 2), (62, 1, 25), (64, 1, 64), (65, 1, 53), (67, 1, 32), (69, 1, 14), (71, 1, 87), (72, 1, 69), 2 ] toadd1 = [ 1, (60, 1, 5), (62, 1, 55), (64, 1, 31), (65, 1, 45), (67, 1, 115), (69, 1, 54), (71, 1, 87), (72, 1, 69), 2 ] midi = MIDIFile( vartrack ) #it takes the number of tracks as a parameter, I haven't played with it. midi.addTempo(0, 0, bpm) time = toadd[ 0] #if there's initial silence it's the first parameter, for aditional silence please pass the note 0 temp = 1 currtrack = 1 def addnotes(toadd): global temp global time global instrument global currtrack negativeError = ValueError("Start time should be positive") if toadd[0] < 0: raise negativeError
else: break if MIDIsafe == "Y": #MIDI file write degrees = sound1list # MIDI note number track = 0 channel = 9 timer = 0 # In beats tempo = BPM # 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, timer, tempo) for volume in degrees: MyMIDI.addNote(track, channel, 36, timer, 0.25, volume * 100) timer = timer + 0.25 degrees = sound2list timer = 0 for volume in degrees: MyMIDI.addNote(track, channel, 38, timer, 0.25, volume * 100) timer = timer + 0.25 degrees = sound3list timer = 0 for volume in degrees: MyMIDI.addNote(track, channel, 42, timer, 0.25, volume * 100)
cv2.imwrite("res.png", img) open_file("res.png") for note_group in note_groups: print([note.note + " " + note.sym for note in note_group]) midi = MIDIFile(1) track = 0 time = 0 channel = 0 volume = 100 midi.addTrackName(track, time, "Track") midi.addTempo(track, time, 140) for note_group in note_groups: duration = None for note in note_group: note_type = note.sym if note_type == "1": duration = 4 elif note_type == "2": duration = 2 elif note_type == "4,8": duration = 1 if len(note_group) == 1 else 0.5 pitch = note.pitch midi.addNote(track, channel, pitch, time, duration, volume) time += duration
from midiutil import MIDIFile from math import sqrt midi_file = MIDIFile(1) # Create MIDI file with one track. midi_file.addTempo(0, 0, 160) # set the tempo to 120 BPM on track 0, at time 0. def get_fibonacci_number(n): PHI = (1 + sqrt(5)) / 2 return round(pow(PHI, n) / sqrt(5)) N = 20 # generate note mapping notes = {} for i in range(10): # i semitones from D5-Sharp (75) notes[i] = 75 + i # N is some positive integer greater than one. for i in range(N): # get_fibonacci_number(n) returns the n-th fibonacci number (one-based) note = notes[get_fibonacci_number(i + 1) % 10] midi_file.addNote(0, 0, note, i, 1, 100) def save_midi(midi_handle, filename): with open(f'{filename}.mid', 'wb') as output_file: midi_handle.writeFile(output_file)
result = open('tmp').read() onsets = result.split("\n") # midi parameters pitch = 60 track = 0 channel = 0 duration = 0.25 inS = open('tempos.txt').read() # tempo detection done through essentia bpm = int(tempo_detection.detect(filename)) volume = 100 midi = MIDIFile(1) midi.addTempo(track, 0, bpm) # extract the times from the aubio output as a list, normalized by bpm times = [] for onset in onsets: if onset != "": sec = float(onset.strip()) time = (sec / 60) * bpm times.append(time) assert (len(times) > 0) # shift back so that the first onset starts from 0 shifted_times = [] for time in times:
def generate_melody(with_chords, repetitions=1): use_custom_scale = pyip.inputYesNo( prompt="Do you want to use a custom scale? (y/n) ") possible_chords = [] if use_custom_scale == "yes": scale_input = input( """Insert the notes from the scale separated by a space, do not use flats, only sharps. \t\tExample: C D E F# A\n""") chosen_scale = scale_input.upper().split() for x in range(len(chosen_scale) + 1): combinations_object = combinations(chosen_scale, x) combinations_list = list(combinations_object) possible_chords += combinations_list for _ in range(len(chosen_scale) + 1): del possible_chords[0] get_random_scale = False use_custom_scale = True else: get_random_scale = True use_custom_scale = False try: determined_scale = scales.determine(chosen_scale)[0] except: determined_scale = "" amount_of_notes = pyip.inputInt( prompt="How many notes do you want for this melody? ", min=1) if with_chords: chords_each_x = pyip.inputInt( prompt="How many notes you want between chords? ", min=1) chord_in_note = [x for x in range(0, amount_of_notes, chords_each_x)] for _ in range(repetitions): melody_name = generate_random_name() melody_path = f"Melodies/{melody_name}" os.mkdir(melody_path) track = 0 channel = 0 time = 0 duration = 1 tempo = 120 volume = 100 midi_melody = MIDIFile(1) midi_melody.addTempo(track, time, tempo) if get_random_scale: chosen_scale = choice(scales_content["scales"]) possible_chords = chosen_scale["chords"] chosen_scale = chosen_scale["scale"] ly_string = r'''\version "2.20.0" \header{title = "PLACEHOLDER_NAME" subtitle = "PLACEHOLDER_SUBTITLE" tagline = ##f} \score { { ''' ly_string = ly_string.replace("PLACEHOLDER_NAME", melody_name) ly_string = ly_string.replace( "PLACEHOLDER_SUBTITLE", f"{str(chosen_scale)} - {determined_scale}") print( f"\nGenerating melody with scale: {chosen_scale} - {determined_scale}\n" ) print(f"\t****{melody_name}****") all_parts = [] for i in range(amount_of_notes): if with_chords: if i in chord_in_note: if i != 0: time += duration chosen_chord = choice(possible_chords) chosen_chord = chosen_chord[:3] try: determined_chord = chords.determine( list(chosen_chord))[0] except: determined_chord = "" ly_string += "\n< " for note in chosen_chord: ly_string += f"{note_to_ly(note)}' " note_midi_value = int(Note(note)) + 12 midi_melody.addNote(track, channel, note_midi_value, time, duration, volume) ly_string += ">\n\n" all_parts.append( f"\n\t{chosen_chord} - {determined_chord}\n") chosen_note = choice(chosen_scale) ly_string += f"{note_to_ly(chosen_note)}4' " note_midi_value = int(Note(chosen_note)) + 12 midi_melody.addNote(track, channel, note_midi_value, time + duration, duration, volume) time += duration all_parts.append(f"\t{chosen_note}") ly_string += """} \layout { } \midi { } }""" with open(f"{melody_path}/{melody_name}.txt", "w") as f: for part in all_parts: f.write(f"{part}\n") print(part) with open(f"{melody_path}/{melody_name}_pond.ly", "w") as f: f.write(ly_string) with open(f"{melody_path}/{melody_name}.mid", "wb") as f: midi_melody.writeFile(f)
def track_preprocessing(tempo=160, channel=0, tracks=6, time=0): midi = MIDIFile(tracks, deinterleave=False) for track in range(tracks): midi.addTempo(track, time, tempo) return midi, channel, tracks
import copy bpm = 60 #to be defined by user vartrack = 2 #to be defined by user longest = 0 #### toadd = [[1,10,15,25,36],[(64,0.5,2,3),(62,0.25,25,4)],1] toadd2 = [[1,10,15,25,36],[(64,0.5,2,3),(62,0.25,25,4)]] toadd3 = [(64,0.5,2,3),(62,0.25,25,4)] toadd4 = [[0], [(56, 0.5, 1, 0), (-37, 0.5, 1, 0.5), (61, 0.5, 1, 1.0), (-37, 0.5, 1, 1.5), (68, 1.2, 1, 2.0), (68, 1.2, 1, 3.2), (68, 0.8, 1, 4.4), (64, 0.5, 1, 5.2), (-37, 0.5, 1, 5.7), (69, 0.5, 1, 6.2), (-37, 0.5, 1, 6.7), (63, 1.2, 1, 7.2), (63, 1.2, 1, 8.4), (63, 0.8, 1, 9.6)], 4] midi = MIDIFile(numTracks=1500, file_format=1) #it takes the number of tracks as a parameter midi.addTempo(0,0,bpm) #adding tempo currtrack = 999 #what track are we writting on def addnotes(notes): time = notes[0] #When the sequence will start time wise temp = 1 #default instrument global currtrack #we want the global scope of this variable duration(notes) repeat_times = (int)(notes[len(notes)-1]) for x in range(len(time)): initialTime = time[x] - duration(notes[1])
#turn off the while loop to go to the next step running = False else: ti.sleep(0.001) #___________MIDISETUP____________ BPM = askUserBPM() midiFile = MIDIFile(1) track = 0 time = 0 channel = 0 duration = 1 volume = 100 midiFile.addTrackName(track, time, "eindopdracht") midiFile.addTempo(track, time, BPM) def retrievePitch(event): return event['midiNote'] def retrieveTime(event, sixteenthStep): return (int(event['timestamp'] / sixteenthStep) / 4) def addMidiNote(pitch, time): midiFile.addNote(track, channel, pitch, time, duration, volume) #___________START_____________
# # Demo program for asking user for some note(s), then write them to # a MIDI file using midiutil # https://pypi.org/project/MIDIUtil # from midiutil import MIDIFile note = int(input("Enter a note: ")) velocity = int(input("Velocity: ")) mf = MIDIFile(1) track = 0 time = 0 mf.addTrackName(track, time, "Beat Sample Track") mf.addTempo(track, time, 120) # # Format: # mf.addNote(track, channel, pitch, time, duration, velocity) # mf.addNote(0, 0, note, 2, 1, velocity) with open("symphony.midi", 'wb') as outf: mf.writeFile(outf)
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
from midiutil import MIDIFile import struct short_list = list() with open("../../../test.lmg", "rb") as f: byte_start = f.read(8) byte_end = f.read(8) while byte_start: unpacked_start = struct.unpack("d", byte_start)[0] unpacked_end = struct.unpack("d", byte_end)[0] short_list.append([unpacked_start, unpacked_end]) byte_start = f.read(8) byte_end = f.read(8) print(short_list) file = MIDIFile(1) file.addTempo(0, 0, 120) time = 0 for time in short_list: file.addNote(0, 0, 69, time[0], time[1] - time[0], 127) with open("myfile.mid", "wb") as open_file: file.writeFile(open_file)
midis_dir = path.realpath('../midis') track = 0 channel = 0 time = 0 # In beats duration = 1 # In beats tempo = 72 # In BPM volume = 127 # 0-127, as per the MIDI standard major_scale_formula = [0, 2, 2, 1, 2, 2, 2, 1] major_scale_formula_desc = [0, -1, -2, -2, -2, -1, -2, -2] major_chord_formula = [0, 4, 3] # For C4 (degree 60) to C5 (degree 72), generate 1 midi file with 1 note each for degree in range(60, 73): my_midi = MIDIFile(1) my_midi.addTempo(track, time, tempo) my_midi.addNote(track, channel, degree, time, duration, volume) with open("%s/%s.mid" % (midis_dir, degree), "wb") as output_file: my_midi.writeFile(output_file) # Generate all notes of the D major scale degree = 62 for i, degree_change in enumerate(major_scale_formula): degree += degree_change my_midi = MIDIFile(1) my_midi.addTempo(track, time, tempo) my_midi.addNote(track, channel, degree, time, duration, volume) with open("%s/%s.mid" % (midis_dir, degree), "wb") as output_file: my_midi.writeFile(output_file) # Generate all notes of the G major scale
print(f"\nHEIGHTS: {HEIGHTS}") STEPS = [] for i, pitch in enumerate(TONES_MAP): nearest = (np.abs(pitch - HEIGHTS)).argmin() STEPS.append(nearest) print(f"\nSTEPS: {STEPS}") # Verifying if there is the same amount of tempos and tones assert len(TONES_MAP) == len(TEMPO_MAP), "Different amount of tempos and notes" # Creating MIDI file from mapped data midi = MIDIFile(numTracks=1) midi.addTempo(track=0, time=0, tempo=80) # Hash for tempos and tones hsh_tempo = {2: 0.5, 3: 1.5, 4: 1., 5: 2.} c4_to_b4 = np.array([60, 62, 64, 65, 67, 69, 71]) c5_to_b5 = c4_to_b4 + 12 c4_to_b4_map = {i: c4_to_b4[i] for i in range(np.size(c4_to_b4))} c5_to_b5_map = {i + 7: c5_to_b5[i] for i in range(np.size(c5_to_b5))} c4_to_b5_map = {**c4_to_b4_map, **c5_to_b5_map} # Inserting midi data into midi file time = 0 for i, tone in enumerate(TONES_MAP): midi.addNote(track=0,