Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/Sequence Models/Week 1/Jazz improvisation with LSTM/data_utils.py
Views: 13378
from music_utils import *1from preprocess import *2from keras.utils import to_categorical34chords, abstract_grammars = get_musical_data('data/original_metheny.mid')5corpus, tones, tones_indices, indices_tones = get_corpus_data(abstract_grammars)6N_tones = len(set(corpus))7n_a = 648x_initializer = np.zeros((1, 1, 78))9a_initializer = np.zeros((1, n_a))10c_initializer = np.zeros((1, n_a))1112def load_music_utils():13chords, abstract_grammars = get_musical_data('data/original_metheny.mid')14corpus, tones, tones_indices, indices_tones = get_corpus_data(abstract_grammars)15N_tones = len(set(corpus))16X, Y, N_tones = data_processing(corpus, tones_indices, 60, 30)17return (X, Y, N_tones, indices_tones)181920def generate_music(inference_model, corpus = corpus, abstract_grammars = abstract_grammars, tones = tones, tones_indices = tones_indices, indices_tones = indices_tones, T_y = 10, max_tries = 1000, diversity = 0.5):21"""22Generates music using a model trained to learn musical patterns of a jazz soloist. Creates an audio stream23to save the music and play it.2425Arguments:26model -- Keras model Instance, output of djmodel()27corpus -- musical corpus, list of 193 tones as strings (ex: 'C,0.333,<P1,d-5>')28abstract_grammars -- list of grammars, on element can be: 'S,0.250,<m2,P-4> C,0.250,<P4,m-2> A,0.250,<P4,m-2>'29tones -- set of unique tones, ex: 'A,0.250,<M2,d-4>' is one element of the set.30tones_indices -- a python dictionary mapping unique tone (ex: A,0.250,< m2,P-4 >) into their corresponding indices (0-77)31indices_tones -- a python dictionary mapping indices (0-77) into their corresponding unique tone (ex: A,0.250,< m2,P-4 >)32Tx -- integer, number of time-steps used at training time33temperature -- scalar value, defines how conservative/creative the model is when generating music3435Returns:36predicted_tones -- python list containing predicted tones37"""3839# set up audio stream40out_stream = stream.Stream()4142# Initialize chord variables43curr_offset = 0.0 # variable used to write sounds to the Stream.44num_chords = int(len(chords) / 3) # number of different set of chords4546print("Predicting new values for different set of chords.")47# Loop over all 18 set of chords. At each iteration generate a sequence of tones48# and use the current chords to convert it into actual sounds49for i in range(1, num_chords):5051# Retrieve current chord from stream52curr_chords = stream.Voice()5354# Loop over the chords of the current set of chords55for j in chords[i]:56# Add chord to the current chords with the adequate offset, no need to understand this57curr_chords.insert((j.offset % 4), j)5859# Generate a sequence of tones using the model60_, indices = predict_and_sample(inference_model)61indices = list(indices.squeeze())62pred = [indices_tones[p] for p in indices]6364predicted_tones = 'C,0.25 '65for k in range(len(pred) - 1):66predicted_tones += pred[k] + ' '6768predicted_tones += pred[-1]6970#### POST PROCESSING OF THE PREDICTED TONES ####71# We will consider "A" and "X" as "C" tones. It is a common choice.72predicted_tones = predicted_tones.replace(' A',' C').replace(' X',' C')7374# Pruning #1: smoothing measure75predicted_tones = prune_grammar(predicted_tones)7677# Use predicted tones and current chords to generate sounds78sounds = unparse_grammar(predicted_tones, curr_chords)7980# Pruning #2: removing repeated and too close together sounds81sounds = prune_notes(sounds)8283# Quality assurance: clean up sounds84sounds = clean_up_notes(sounds)8586# Print number of tones/notes in sounds87print('Generated %s sounds using the predicted values for the set of chords ("%s") and after pruning' % (len([k for k in sounds if isinstance(k, note.Note)]), i))8889# Insert sounds into the output stream90for m in sounds:91out_stream.insert(curr_offset + m.offset, m)92for mc in curr_chords:93out_stream.insert(curr_offset + mc.offset, mc)9495curr_offset += 4.09697# Initialize tempo of the output stream with 130 bit per minute98out_stream.insert(0.0, tempo.MetronomeMark(number=130))99100# Save audio stream to fine101mf = midi.translate.streamToMidiFile(out_stream)102mf.open("output/my_music.midi", 'wb')103mf.write()104print("Your generated music is saved in output/my_music.midi")105mf.close()106107# Play the final stream through output (see 'play' lambda function above)108# play = lambda x: midi.realtime.StreamPlayer(x).play()109# play(out_stream)110111return out_stream112113114def predict_and_sample(inference_model, x_initializer = x_initializer, a_initializer = a_initializer,115c_initializer = c_initializer):116"""117Predicts the next value of values using the inference model.118119Arguments:120inference_model -- Keras model instance for inference time121x_initializer -- numpy array of shape (1, 1, 78), one-hot vector initializing the values generation122a_initializer -- numpy array of shape (1, n_a), initializing the hidden state of the LSTM_cell123c_initializer -- numpy array of shape (1, n_a), initializing the cell state of the LSTM_cel124Ty -- length of the sequence you'd like to generate.125126Returns:127results -- numpy-array of shape (Ty, 78), matrix of one-hot vectors representing the values generated128indices -- numpy-array of shape (Ty, 1), matrix of indices representing the values generated129"""130131### START CODE HERE ###132pred = inference_model.predict([x_initializer, a_initializer, c_initializer])133indices = np.argmax(pred, axis = -1)134results = to_categorical(indices, num_classes=78)135### END CODE HERE ###136137return results, indices138139