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/C5 - Sequence Models/Week 1/Jazz improvisation with LSTM/qa.py
Views: 4819
'''1Author: Ji-Sung Kim, Evan Chow2Project: deepjazz3Purpose: Provide pruning and cleanup functions.45Code adapted from Evan Chow's jazzml, https://github.com/evancchow/jazzml6with express permission.7'''8from itertools import zip_longest9import random1011from music21 import *1213#----------------------------HELPER FUNCTIONS----------------------------------#1415''' Helper function to down num to the nearest multiple of mult. '''16def __roundDown(num, mult):17return (float(num) - (float(num) % mult))1819''' Helper function to round up num to nearest multiple of mult. '''20def __roundUp(num, mult):21return __roundDown(num, mult) + mult2223''' Helper function that, based on if upDown < 0 or upDown >= 0, rounds number24down or up respectively to nearest multiple of mult. '''25def __roundUpDown(num, mult, upDown):26if upDown < 0:27return __roundDown(num, mult)28else:29return __roundUp(num, mult)3031''' Helper function, from recipes, to iterate over list in chunks of n32length. '''33def __grouper(iterable, n, fillvalue=None):34args = [iter(iterable)] * n35return zip_longest(*args, fillvalue=fillvalue)3637#----------------------------PUBLIC FUNCTIONS----------------------------------#3839''' Smooth the measure, ensuring that everything is in standard note lengths40(e.g., 0.125, 0.250, 0.333 ... ). '''41def prune_grammar(curr_grammar):42pruned_grammar = curr_grammar.split(' ')4344for ix, gram in enumerate(pruned_grammar):45terms = gram.split(',')46terms[1] = str(__roundUpDown(float(terms[1]), 0.250,47random.choice([-1, 1])))48pruned_grammar[ix] = ','.join(terms)49pruned_grammar = ' '.join(pruned_grammar)5051return pruned_grammar5253''' Remove repeated notes, and notes that are too close together. '''54def prune_notes(curr_notes):55for n1, n2 in __grouper(curr_notes, n=2):56if n2 == None: # corner case: odd-length list57continue58if isinstance(n1, note.Note) and isinstance(n2, note.Note):59if n1.nameWithOctave == n2.nameWithOctave:60curr_notes.remove(n2)6162return curr_notes6364''' Perform quality assurance on notes '''65def clean_up_notes(curr_notes):66removeIxs = []67for ix, m in enumerate(curr_notes):68# QA1: ensure nothing is of 0 quarter note len, if so changes its len69if (m.quarterLength == 0.0):70m.quarterLength = 0.25071# QA2: ensure no two melody notes have same offset, i.e. form a chord.72# Sorted, so same offset would be consecutive notes.73if (ix < (len(curr_notes) - 1)):74if (m.offset == curr_notes[ix + 1].offset and75isinstance(curr_notes[ix + 1], note.Note)):76removeIxs.append((ix + 1))77curr_notes = [i for ix, i in enumerate(curr_notes) if ix not in removeIxs]7879return curr_notes8081