def part_midi(f, key=None): fname = f.split(os.path.sep)[-1] _midi = PrettyMIDI(f) # part for ind, instrument in enumerate(_midi.instruments): midi = PrettyMIDI(f) n = len(midi.instruments) # sound for ind2, inst in enumerate(midi.instruments): if ind2 != ind: inst.program = subSound else: inst.program = mainSound if instrument.name: name = instrument.name elif len(names) == n: name = names[ind] else: name = str(ind) if n != len(volumes): continue # volume for inst, value in zip(midi.instruments, volumes): if instrument is inst: value += volumeDiff inst.control_changes.append( ControlChange(number=7, value=value, time=0.001)) midi.write( os.path.join(outdir, fname.rsplit(".", 1)[0] + "_" + name + ".mid"))
def _render_midi( midifile: pretty_midi.PrettyMIDI, basename: str, delete_wave: bool = True, ) -> None: """ Requires system packages: fluidsynth fluid-soundfont-gm lame http://wootangent.net/2010/11/converting-midi-to-wav-or-mp3-the-easy-way/ """ filename_mid = basename + ".mid" filename_wav = basename + ".wav" filename_mp3 = basename + ".mp3" midifile.write(filename_mid) print("\n *** Rendering MIDI") os.system( "fluidsynth -F {} /usr/share/sounds/sf2/FluidR3_GM.sf2 {}".format( filename_wav, filename_mid, )) print("\n *** Converting to MP3") os.system("lame --preset standard {} {}".format( filename_wav, filename_mp3, )) if delete_wave: os.system("rm {}".format(filename_wav))
def write_midi(self, score_events, midi_program, pitch_low_passband=0, pitch_high_passband=127, time_offset=0.0): """ Given a sequence of NoteEvents, calculate the MIDI ticks for each note and write these to a MIDI file. PARAMETERS: score_events (list): list of ScoreEvents midi_program (int): MIDI program to use for the MIDI track pitch_low_passband (int): discard any pitches with midi numbers less than this bound pitch_high_passband (int): discard any pitches with midi numbers greater than this bound time_offset (float): amount of time (s) to delay MIDI note events """ midi = PrettyMIDI(resolution=MidiIO.DEFAULT_PPQ, initial_tempo=MidiIO.DEFAULT_TEMPO) instr = Instrument(program=midi_program) for n in score_events: if pitch_low_passband <= n.midi_number <= pitch_high_passband: note = MidiNote( velocity=MidiIO.DEFAULT_VELOCITY, pitch=n.midi_number, start=(n.onset_ts + time_offset), end=(n.offset_ts + time_offset) ) instr.notes.append(note) midi.instruments.append(instr) midi.remove_invalid_notes() directory = os.path.split(self._path)[0] if not os.path.exists(directory): os.makedirs(directory) midi.write(self._path)
def get_beat_time( pm: PrettyMIDI, beat_division=4 ) -> Tuple[ndarray, ndarray, ndarray, List[int], List[int]]: beats = pm.get_beats() beats = np.unique(beats, axis=0) divided_beats = [] for i in range(len(beats) - 1): for j in range(beat_division): divided_beats.append((beats[i + 1] - beats[i]) / beat_division * j + beats[i]) divided_beats.append(beats[-1]) divided_beats = np.unique(divided_beats, axis=0) beat_indices = [] for beat in beats: beat_indices.append(np.argwhere(divided_beats == beat)[0][0]) down_beats = pm.get_downbeats() if divided_beats[-1] > down_beats[-1]: down_beats = np.append( down_beats, down_beats[-1] - down_beats[-2] + down_beats[-1]) down_beats = np.unique(down_beats, axis=0) down_beat_indices = [] for down_beat in down_beats: down_beat_indices.append(np.argmin(np.abs(down_beat - divided_beats))) return np.array(divided_beats), np.array(beats), np.array( down_beats), beat_indices, down_beat_indices
def extract_pianos(msd_id: str) -> List[PrettyMIDI]: """ Extracts a list of PrettyMIDI instance of all the separate piano tracks from the given MSD id. :param msd_id: the MSD id :return: the list of PrettyMIDI instances of the separate piano tracks """ os.makedirs(args.path_output_dir, exist_ok=True) midi_md5 = get_matched_midi_md5(msd_id, MSD_SCORE_MATCHES) midi_path = get_midi_path(msd_id, midi_md5, args.path_dataset_dir) pm = PrettyMIDI(midi_path) pm.instruments = [ instrument for instrument in pm.instruments if instrument.program in PIANO_PROGRAMS and not instrument.is_drum ] pm_pianos = [] if len(pm.instruments) > 1: for piano_instrument in pm.instruments: pm_piano = copy.deepcopy(pm) pm_piano_instrument = Instrument(program=piano_instrument.program) pm_piano.instruments = [pm_piano_instrument] for note in piano_instrument.notes: pm_piano_instrument.notes.append(note) pm_pianos.append(pm_piano) else: pm_pianos.append(pm) for index, pm_piano in enumerate(pm_pianos): if len(pm_piano.instruments) != 1: raise Exception(f"Invalid number of piano {msd_id}: " f"{len(pm_piano.instruments)}") if pm_piano.get_end_time() > 1000: raise Exception(f"Piano track too long {msd_id}: " f"{pm_piano.get_end_time()}") return pm_pianos
def midi_to_list(filename: str, start_time: float, duration: float) -> List[int]: pm = PrettyMIDI(filename) pm.adjust_times(np.array([start_time, start_time + duration]), np.array([0., duration])) # ensure one midi contain only on instrument note_seq = NoteSeq(notes=pm.instruments[0].notes) event_seq = EventSeq.from_note_seq(note_seq) return event_seq.to_list()
def all_midi(f, key=None): midi = PrettyMIDI(f) fname = f.split(os.path.sep)[-1] n = len(midi.instruments) for ind, instrument in enumerate(midi.instruments): # sound instrument.program = mainSound if n == len(volumes): instrument.control_changes.append( ControlChange(number=7, value=volumes[ind], time=0.001)) midi.write(os.path.join(outdir, fname.rsplit(".", 1)[0] + "_all.mid"))
def __init__(self, midi_path='', phrase=None, meta=None, note_shift=0, **kwargs): try: self.midi_path = None self.note_shift = note_shift self.midi = PrettyMIDI(midi_path) self.melo = self.midi.instruments[0] except: self.midi_path = midi_path self.melo = self.__load_pop909_melo() self.meta = meta self.phrase = phrase
def write_midi(note_sequence, output_dir, filename): #make output directory pathlib.Path(output_dir).mkdir(parents=True, exist_ok=True) #generate midi midi = PrettyMIDI() piano_track = Instrument(program=0, is_drum=False, name=filename) piano_track.notes = note_sequence midi.instruments.append(piano_track) output_name = output_dir + f"{filename}.midi" midi.write(output_name)
def midi_to_spec_otf(midi: pm.PrettyMIDI, spec_params: dict, sound_font_path=None) -> np.ndarray: """MIDI to Spectrogram (on the fly) Synthesizes a MIDI with fluidsynth and extracts a spectrogram. The spectrogram is directly returned """ processor = spectrogram_processor(spec_params) def render_audio(midi_file_path, sound_font): """ Render midi to audio """ # split file name and extention name, extention = midi_file_path.rsplit(".", 1) # set file names audio_file = name + ".wav" # audio_file = tempfile.TemporaryFile('w+b') # synthesize midi file to audio cmd = "fluidsynth -F %s -O s16 -T wav %s %s 1> /dev/null" % ( audio_file, sound_font, midi_file_path) os.system(cmd) return audio_file mid_path = os.path.join(tempfile.gettempdir(), str(time.time()) + '.mid') with open(mid_path, 'wb') as f: midi.write(f) audio_path = render_audio(mid_path, sound_font=sound_font_path) spec = processor.process(audio_path).T if spec_params.get('norm', False): spec = librosa.util.normalize(spec, norm=2, axis=0, threshold=0.01, fill=False) # compute spectrogram spec = np.expand_dims(spec, 0) os.remove(mid_path) os.remove(audio_path) return spec
def pitch_lists_to_midi_file(pitch_lists, midi_path): midi = PrettyMIDI() ins = Instrument(0) cursor = 0 unit_length = 0.125 for pitch_list in pitch_lists: for pitch in pitch_list: if pitch != 0: ins.notes.append(Note(start=cursor, end=cursor + unit_length, pitch=pitch, velocity=60)) cursor += unit_length midi.instruments.append(ins) midi.write(midi_path)
def read_midi(filename: str, start_time: float, duration: float) -> PrettyMIDI: """ :param filename: :param start_time: in seconds :param duration: in seconds :return: """ pm = PrettyMIDI(filename) pm.adjust_times([start_time, start_time + duration], [0., duration]) return pm
def read_midi_files(path: Union[Path, str], regex: str, extra: bool = True) -> List[Tuple[PrettyMIDI, int]]: """ Reads mid files in given folder and returns a list of PrettyMIDI. For all following directories use **/*.*. """ folder = Path(path) if extra: return [(PrettyMIDI(file.as_posix()), int(file.parent.stem) if file.parent.stem != 'extra' else int(file.parent.parent.stem)) for file in folder.glob(regex)] return [(PrettyMIDI(file.as_posix()), int(file.parent.stem)) for file in folder.glob(regex) if file.parent.stem != 'extra']
def create_drum_pretty_midi( onset_matrix: np.ndarray, vel_matrix: np.ndarray, q_note_res: int = Q_NOTE_RES, bpm: float = 120.0, playback_midi_map: List[int] = CHRISTHETREE_PLAYBACK_MIDI_MAP_8 ) -> PrettyMIDI: pm = PrettyMIDI(initial_tempo=bpm) res = (60.0 / bpm) / q_note_res drum_inst = Instrument(0, is_drum=True) n_beats = vel_matrix.shape[0] for beat_idx in range(n_beats): onset_vals = onset_matrix[beat_idx, :] onsets = np.nonzero(onset_vals >= 0.5)[0] vels = vel_matrix[beat_idx, :] for onset in onsets: pitch = playback_midi_map[onset] vel = int((vels[onset] * 127) + 0.5) _add_note(drum_inst, pitch, vel, res * beat_idx, (res * beat_idx) + 0.2) pm.instruments.append(drum_inst) return pm
def listen_pitches(midi_pitch: list, time, instrument=0): midi = PrettyMIDI() ins = Instrument(instrument) for i in midi_pitch: ins.notes.append(Note(pitch=i, start=0, end=time, velocity=80)) midi.instruments.append(ins) listen(midi)
def to_midi(self, tempo=120, instrument=PIANO, tonic=None, lib=None): if not self.progression: Logging.error("Progression not assigned!") return None if not tonic: tonic = self.meta['tonic'] midi = PrettyMIDI() unit_length = 30 / tempo ins = Instrument(instrument) if not self.saved_in_source_base: current_pos = 0 for i in self.get_chord_progression(): memo = -1 length = 0 for j in i: if j == memo: length += unit_length else: if memo != -1: for pitch in memo.to_midi_pitch( tonic=self.__key_changer( self.meta['tonic'], memo.root, tonic)): note = Note(pitch=pitch, velocity=80, start=current_pos, end=current_pos + length) ins.notes.append(note) current_pos += length length = unit_length memo = j for pitch in memo.to_midi_pitch(tonic=self.__key_changer( self.meta['tonic'], memo.root, tonic)): note = Note(pitch=pitch, velocity=80, start=current_pos, end=current_pos + length) ins.notes.append(note) current_pos += length else: if lib is None: lib = pickle_read('lib') try: all_notes = lib[self.meta['source']] except: Logging.error( 'Progression with source name {n} ' 'cannot be find in library! ' 'Call set_in_lib(in_lib=False) to generate MIDI ' 'by progression list itself'.format(n=self.meta['source'])) return False for note in all_notes: ins.notes.append( Note(start=note[0] * unit_length, end=note[1] * unit_length, pitch=note[2] + str_to_root[tonic], velocity=note[3])) midi.instruments.append(ins) return midi
def convert2midi(self): midi = PrettyMIDI(resolution=STATE_RESOLUTION, initial_tempo=STATE_TEMP) inst = Instrument(1, False, 'Note_Seqce') inst.notes = copy.deepcopy(self.notes) midi.instruments.append(inst) return midi
def occupation_polyphony_rate(pm: PrettyMIDI) -> Tuple[ndarray, ndarray]: occupation_rate = [] polyphony_rate = [] total_roll = pm.get_piano_roll() for instrument in pm.instruments: piano_roll = instrument.get_piano_roll() if piano_roll.shape[1] == 0: occupation_rate.append(0) else: occupation_rate.append( np.count_nonzero(np.any(piano_roll, 0)) / total_roll.shape[1]) if np.count_nonzero(np.any(piano_roll, 0)) == 0: polyphony_rate.append(0) else: polyphony_rate.append( np.count_nonzero(np.count_nonzero(piano_roll, 0) > 1) / np.count_nonzero(np.any(piano_roll, 0))) occupation_rate = np.array(occupation_rate) zero_idx = np.where(occupation_rate < 0.01)[0] if len(zero_idx) > 0: occupation_rate[zero_idx] = 0 occupation_rate = occupation_rate[:, np.newaxis] polyphony_rate = np.array(polyphony_rate) zero_idx = np.where(polyphony_rate < 0.01)[0] if len(zero_idx) > 0: polyphony_rate[zero_idx] = 0 polyphony_rate = polyphony_rate[:, np.newaxis] return occupation_rate, polyphony_rate
def extract_drums(midi_path: str) -> Optional[PrettyMIDI]: """ Extracts a PrettyMIDI instance of all the merged drum tracks from the given MIDI path. :param midi_path: the path to the MIDI file :return: the PrettyMIDI instance of the merged drum tracks """ os.makedirs(args.path_output_dir, exist_ok=True) pm = PrettyMIDI(midi_path) pm_drums = copy.deepcopy(pm) pm_drums.instruments = [ instrument for instrument in pm_drums.instruments if instrument.is_drum ] if len(pm_drums.instruments) > 1: # Some drum tracks are split, we can merge them drums = Instrument(program=0, is_drum=True) for instrument in pm_drums.instruments: for note in instrument.notes: drums.notes.append(note) pm_drums.instruments = [drums] if len(pm_drums.instruments) != 1: raise Exception(f"Invalid number of drums {midi_path}: " f"{len(pm_drums.instruments)}") return pm_drums
def listen(midi: PrettyMIDI, path=None, out=None): if not fs_exist: return False if not path: path = string.STATIC_DIR + "audio/" midi.write(path + "__listen__.mid") fs = FluidSynth(sound_font=string.STATIC_DIR + 'default_sound_font.sf2') try: os.makedirs(path) except: pass if out is None: out = time.strftime("%H_%M_%S", time.localtime()) + ".wav" fs.midi_to_audio(path + "__listen__.mid", path + out) os.remove(path + "__listen__.mid") return True
def array_to_pm(array, fs=DEFAULT_FS, velocity=DEFAULT_VELOCITY, pitch_range=DEFAULT_PITCH_RANGE): pm = PrettyMIDI() inst = Instrument(1) pm.instruments.append(inst) last_notes = {} last_state = np.zeros(array.shape[1]) > 0.5 for i, step in enumerate(array): now = i / fs step = step > 0.5 changed = step != last_state for pitch in np.where(changed)[0]: if step[pitch]: last_notes[pitch] = Note(velocity, pitch + pitch_range.start, now, None) inst.notes.append(last_notes[pitch]) else: last_notes[pitch].end = now del last_notes[pitch] last_state = step now = (i + 1) / fs for note in last_notes.values(): note.end = now return pm
def to_midi(self, program=DEFAULT_SAVING_PROGRAM, resolution=DEFAULT_RESOLUTION, tempo=DEFAULT_TEMPO): midi = PrettyMIDI(resolution=resolution, initial_tempo=tempo) inst = Instrument(program, False, 'NoteSeq') inst.notes = copy.deepcopy(self.notes) midi.instruments.append(inst) return midi
def convert_midi_files(): """Save a multi-track piano-roll converted from a MIDI file to target dataset directory and update MIDI information to `midi_dict`""" converter_root_dir = 'E:/MIDI_converted' root_dir = 'E:/free_MIDI' midi_collection = get_midi_collection() for midi in midi_collection.find({'Converted': False}): genre = midi['Genre'] name = midi['Name'] performer = midi['Performer'] filepath = root_dir + '/' + genre + '/' + name + ' - ' + performer + '.mid' try: midi_name = os.path.splitext(os.path.basename(filepath))[0] multitrack = Multitrack(beat_resolution=24, name=midi_name) pm = PrettyMIDI(filepath) midi_info = get_midi_info(pm) multitrack = Multitrack(filepath) merged = get_merged(multitrack) os.chdir(converter_root_dir) if not os.path.exists(converter_root_dir + '/' + genre): os.mkdir(converter_root_dir + '/' + genre) converter_path = converter_root_dir + '/' + genre + '/' + midi_name + '.npz' # merged.save(converter_path) print(get_midi_info(pm)) ''' midi_collection.update_one( {'_id', midi['_id']}, {'$set' :{'Converted': True}} ) ''' # print([midi_name, midi_info]) except: print(filepath) print(traceback.format_exc())
def extract_drums(msd_id: str) -> Optional[PrettyMIDI]: """ Extracts a PrettyMIDI instance of all the merged drum tracks from the given MSD id. :param msd_id: the MSD id :return: the PrettyMIDI instance of the merged drum tracks """ os.makedirs(args.path_output_dir, exist_ok=True) midi_md5 = get_matched_midi_md5(msd_id, MSD_SCORE_MATCHES) midi_path = get_midi_path(msd_id, midi_md5, args.path_dataset_dir) pm = PrettyMIDI(midi_path) pm_drums = copy.deepcopy(pm) pm_drums.instruments = [instrument for instrument in pm_drums.instruments if instrument.is_drum] if len(pm_drums.instruments) > 1: # Some drum tracks are split, we can merge them drums = Instrument(program=0, is_drum=True) for instrument in pm_drums.instruments: for note in instrument.notes: drums.notes.append(note) pm_drums.instruments = [drums] if len(pm_drums.instruments) != 1: raise Exception(f"Invalid number of drums {msd_id}: " f"{len(pm_drums.instruments)}") return pm_drums
def __init__(self, path): pm = PrettyMIDI(path) pm.remove_invalid_notes() self.midi = pm self.tempo = pm.estimate_tempo() self.beat_times = pm.get_beats() self.bar_times = pm.get_downbeats() self.end_time = pm.get_end_time() self.instruments = pm.instruments
def get_midi_file_list(self): midi_list = [] for root, dirs, files in os.walk(self._midi_dir): for file in files: if fnmatch.fnmatch(file, "*.mid"): midi_filename = os.path.join(root, file) pretty_midi = PrettyMIDI(midi_filename) midi_list.append(pretty_midi) return midi_list
def _get_qpm(self, pm: PrettyMIDI): """ Returns the first tempo change that is not zero, raises exception if not found or multiple tempo present. """ if self._qpm: return self._qpm qpm = None for tempo_change in pm.get_tempo_changes(): if tempo_change.min() and tempo_change.max() and tempo_change.min( ) == tempo_change.max(): if qpm: raise Exception( "Multiple tempo changes are not supported " + str(pm.get_tempo_changes())) qpm = tempo_change.min() if not qpm: raise Exception("Unknown qpm in: " + str(pm.get_tempo_changes())) return qpm
def test_encode_decode(): mid_seq = MidiSequencer.from_file(PrettyMIDI("audio/rock.mid")) encoded = mid_seq.encode() decoded = MidiSequencer.decode(encoded) for mid_row, decoded_row in zip(mid_seq.pattern, decoded.pattern): for mid_note, decoded_note in zip(mid_row, decoded_row): if mid_note is None and decoded_note is None: assert mid_note is None assert decoded_note is None else: assert mid_note.pitch == decoded_note.pitch assert mid_note.start == decoded_note.start
def dump_midi(data, note_sets, path): midi_file = PrettyMIDI(resolution=220, initial_tempo=120) track = Instrument(0) time = 0 # Shift first timing to 0 #time -= note_sets['timing'][data[0][0]] * 30 for note in data: # <padding> == 0 if note[0] == 0: continue time += note_sets['timing'][note[0]] * 15 / 120 track.notes.append( Note(velocity=100, start=time, end=time + note_sets['duration'][note[1]] * 15 / 120, pitch=note_sets['pitch'][note[2]])) #print(track.notes[-1]) midi_file.instruments.append(track) midi_file.write(path)
def write_to_midi(note_sequences, output_dir, n_to_write=None): if len(note_sequences) == 0: print("No note sequences to write out...") return #number of sequences to write out as MIDI files if n_to_write is None: n_to_write = len(note_sequences) #make the output directory if it doesn't already exist pathlib.Path(output_dir).mkdir(parents=True, exist_ok=True) for i in range(n_to_write): #for note_sequence in note_sequences: midi = PrettyMIDI(initial_tempo=80) piano = Instrument(program=0, is_drum=False, name="test{}".format(i)) piano.notes = note_sequences[i] midi.instruments.append(piano) output_name = output_dir + "/test{}.midi".format(i) #with open(output_name, 'w') midi.write(output_name) print("Piano data successfully extracted from midis, navigate to {} to listen"\ .format(output_dir))
def section(pm, start, end, index=None, exclude_drum=False): section_midi = PrettyMIDI() for i, instrument in enumerate(pm.instruments): if exclude_drum and instrument.is_drum: continue if index != None and i not in index: continue section_instrument = pretty_midi.Instrument(instrument.program) section_instrument.notes = [ note for note in instrument.notes if start <= note.end < end ] section_midi.instruments.append(section_instrument) return section_midi
def identify_key(midi_filename, command_line_print = True, save_results = True, measure_value = 1): """ Runs key identification algorithm :parameters: - midi_filename : String of name of existing midi file to process. - command_line_print : Boolean to allow for printing results to command line. - save_results : Boolean to allow saving the approximated key and the names of those keys to a .npz file matching the midi files name - measure_value : int > 0 that sets how many beats the program will process per approximation. """ song = PrettyMIDI(midi.read_midifile(midi_filename)) #get beat locations for slices beats = song.get_beats() #output is an np.ndarray times = beats.flatten() sectionBeats = True #create slices of chroma data to process including summing them up #output: every "measure" of beats if measure_value< 1 or measure_value >times.size or measure_value == None: sectionBeats = False print "WARNING: measure_value selected less than 1 or greater than beat size. Will do one approximation for the whole song." key_weight, names = load_keys() #get Chroma features chroma = song.get_chroma() #normalize chroma features chroma /= (chroma.max( axis = 0 ) + (chroma.max( axis = 0 ) == 0)) # first case if sectionBeats: chroma_slice = chroma[:,0:round(times[0])*100] else: chroma_slice = chroma # Sum rows to find intensity of each note. vec = np.sum(chroma_slice, axis=1) keys_approx = get_approx_key(vec, key_weight) #for each slice, get approximated key and score into 2 column array (key, score) #possiblymay need to use indices of key names instead of actual keys #chroma time indices have a resolution of 10 ms times_used = np.array([[times[0]]]) if sectionBeats: for t in range(1, times.size-1,measure_value): #make chroma slice based on time if times.size -t < measure_value: chroma_slice = chroma[:,round(times[t]*100):round(times[t+1]*100)] # print chroma_slice # vec = make_chroma_vector(chroma_slice) vec = np.sum(chroma_slice, axis=1) # vec = vec[::-1] else: chroma_slice = chroma[:,round(times[t]*100):round(times[t+1]*100)] # print chroma_slice # vec = make_chroma_vector(chroma_slice) vec = np.sum(chroma_slice, axis=1) # vec = vec[::-1] apr = get_approx_key(vec, key_weight) #if the score isn't 0 (which happens in silence), add the approximated key to the list if not apr[0,1] == 0: keys_approx = np.vstack((keys_approx, apr)) times_used = np.vstack((times_used, np.array([[times[t]]]))) # DUMMIED OUT CODE FOR FUTURE IMPLEMENTATION # final_keys = np.array([ [ keys_approx[0,0],times[0,0] ] ]) #mark first # print final_keys # # #iterate through rows of array- if there is a change, get % difference in scores for each key and use threshold to figure # #if it is a key change. mark key change in final 2 column array of (key, time start) # threshold = .15 #experimental value # # if times.size > 1: # print "going thru removal loop" # for t in range (1, keys_approx.shape[0]): # current = keys_approx[t,0] # prev = keys_approx[t-1,0] # if not current == prev: #if not equal to previous, check % difference of scores # print "In key change check" # score1 = keys_approx[t,1] #score of key of this time slice # # print score1 # vec = make_chroma_vector(chroma, round(times[0,t])*100,round(times[0,t+1])*100 ) # # print vec # score2 = get_key_score(vec, key_weight, prev) #score it would have gotten with last input key # # print score2 # diff = abs(score1-score2)/(score1+score2) # print diff # if diff > threshold: # arr = np.array([[keys_approx[t,0], times[t,0] ]]) # # print arr # print "Key change at index: ", times[t,0] # final_keys = np.vstack((final_keys, arr)) # else: # print "difference not large enough to constitute key change " keys_approx = final_keys e = keys_approx.shape[0] if command_line_print: for i in range(0, e): key_int = int(keys_approx[i,0]) print "In key: ",names[0,key_int],"at time: ", times_used[i,0] if save_results: filename = os.path.basename(midi_filename) filename_raw = os.path.splitext(filename)[0] # if not os.path.exists(directory): dirname = "Results_of_key_approximation" if not os.path.exists(dirname): os.makedirs(dirname) np.savez(dirname+"/"+filename_raw+"_key_approx-vars", keys_approx = keys_approx, names = names) file_results = open(dirname+"/"+filename_raw+"_key_approx-text_form.txt",'w') file_results.write(filename_raw+"\n") for i in range(0, e): key_int = int(keys_approx[i,0]) file_results.write("In key: "+names[0,key_int]+" at time: "+ str(times_used[i,0])+"\n") file_results.close() return keys_approx, names