diff --git a/project/generate.py b/project/generate.py index e9a67ea..4ea192d 100644 --- a/project/generate.py +++ b/project/generate.py @@ -48,18 +48,14 @@ output_path = sys.argv[2] # this dictionary is generated with model print('Loading... {}'.format(trained_model_path)) model = pickle.load(open(trained_model_path, 'rb')) -int_to_note = pickle.load(open('{}_dict'.format(trained_model_path), 'rb')) - -# TODO: 16 it should a variable by integrated with model seq_len -# TODO: random.randint(0,50), the range should be a variable of lenght of vocab size -seed = [random.randint(0,250) for x in range(16)] +int_to_note, n_vocab, seq_len = pickle.load(open('{}_dict'.format(trained_model_path), 'rb')) +seed = [random.randint(0,n_vocab) for x in range(seq_len)] music = [] print('Generating...') for i in trange(124): - #TODO: 16 it should a variable by integrated with model seq_len - predicted_vector = model.predict(np.array(seed).reshape(1,16,1)) + predicted_vector = model.predict(np.array(seed).reshape(1,seq_len,1)) # using best fitted note # predicted_index = np.argmax(predicted_vector) # using propability distribution for choosing note @@ -67,14 +63,14 @@ for i in trange(124): predicted_index = choose_by_prob(predicted_vector) music.append(int_to_note[predicted_index]) seed.append(predicted_index) - #TODO: 16 it should a variable by integrated with model seq_len - seed = seed[1:1+16] + seed = seed[1:1+seq_len] print('Saving...') offset = 0 output_notes = [] -for event in tqdm(music): +for _event in tqdm(music): + event, note_len = _event.split(';') if (' ' in event) or event.isdigit(): notes_in_chord = event.split(' ') notes = [] @@ -91,7 +87,7 @@ for event in tqdm(music): new_note.storedInstrument = instrument.Piano() output_notes.append(new_note) - offset += 0.5 + offset += float(note_len) midi_stream = stream.Stream(output_notes) diff --git a/project/midi.py b/project/midi.py index 096be74..8cbfea9 100644 --- a/project/midi.py +++ b/project/midi.py @@ -8,8 +8,7 @@ that is prepared for model training. output_path - the output path where will be created samples of data Usage: - >>> ./midi.py - + >>> ./midi.py ''' import settings @@ -24,9 +23,22 @@ import pickle from music21 import converter, instrument, note, chord, stream import music21 -midi_folder_path = sys.argv[1] -output_path = sys.argv[2] -seq_len = int(sys.argv[3]) +class MidiParseError(Exception): + """Error that is raised then midi file cannot be parsed""" + pass + + +def parse_argv(argv): + '''This function is parsing given arguments when running a midi script. + Returns a tuple consinting of midi_folder_path, output_path, seq_len''' + try: + midi_folder_path = argv[1] + output_path = argv[2] + seq_len = int(argv[3]) + return midi_folder_path, output_path, seq_len + except IndexError: + raise AttributeError('You propably didnt pass parameters to run midi.py script.\ + >>> ./midi.py ') def to_sequence(midi_path, seq_len): ''' This function is supposed to be used on one midi file in directory loop. @@ -40,22 +52,24 @@ def to_sequence(midi_path, seq_len): - midi_path: path to midi file - seq_len: lenght of sequance before prediction - Returns: Tuple of train_X, train_y directories''' + Returns: Tuple of train_X, train_y dictionaries consisinting of samples of song grouped by instruments + ''' seq_by_instrument = defaultdict( lambda : [] ) - midi_file = music21.converter.parse(midi_path) + + try: + midi_file = music21.converter.parse(midi_path) + except music21.midi.MidiException: + raise MidiParseError stream = music21.instrument.partitionByInstrument(midi_file) for part in stream: for event in part: if part.partName != None: - # TODO: add note lenght as parameter if isinstance(event, music21.note.Note): - # to_export_event = (str(event.pitch), event.quarterLength) - to_export_event = str(event.pitch) + to_export_event = '{};{}'.format(str(event.pitch), float(event.quarterLength)) seq_by_instrument[part.partName].append(to_export_event) elif isinstance(event, music21.chord.Chord): - to_export_event = ' '.join(str(note) for note in event.pitches) - # to_export_event = (' '.join(str(note) for note in event.pitches), event.quarterLength) + to_export_event = '{};{}'.format(' '.join(str(note) for note in event.pitches), float(event.quarterLength)) seq_by_instrument[part.partName].append(to_export_event) X_train_by_instrument = defaultdict( lambda : [] ) @@ -65,39 +79,54 @@ def to_sequence(midi_path, seq_len): for i in range(len(sequence)-(seq_len)) : X_train_by_instrument[instrument].append(np.array(sequence[i:i+seq_len])) #