From a4bdd466405ee76638ffa3591f52e6920961e779 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Wed, 8 May 2019 16:45:31 +0200 Subject: [PATCH 01/21] Update repository to python3 and pure keras --- .gitignore | 4 + cpu.theanorc | 3 - gpu.theanorc | 11 - live_edit.py | 657 ++++++++++++++++++++++++----------------------- load_songs.py | 76 +++--- midi.py | 93 ------- midi_utils.py | 97 +++++++ misc.py | 112 ++++++++ results/.gitkeep | 0 train.py | 613 +++++++++++++++++++++---------------------- util.py | 104 -------- 11 files changed, 899 insertions(+), 871 deletions(-) create mode 100644 .gitignore delete mode 100644 cpu.theanorc delete mode 100644 gpu.theanorc delete mode 100644 midi.py create mode 100644 midi_utils.py create mode 100644 misc.py create mode 100644 results/.gitkeep delete mode 100644 util.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..02036bd3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +data/* +config.txt +history +results/* \ No newline at end of file diff --git a/cpu.theanorc b/cpu.theanorc deleted file mode 100644 index 57841b4c..00000000 --- a/cpu.theanorc +++ /dev/null @@ -1,3 +0,0 @@ -[global] -floatX=float32 -device=cpu diff --git a/gpu.theanorc b/gpu.theanorc deleted file mode 100644 index 53921a38..00000000 --- a/gpu.theanorc +++ /dev/null @@ -1,11 +0,0 @@ -[global] -floatX=float32 -device=cuda - -[nvcc] -compiler_bindir=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin - -[dnn] -enabled=True -include_path=C:\CUDA\v8.0\include -library_path=C:\CUDA\v8.0\lib\x64 diff --git a/live_edit.py b/live_edit.py index 05055fef..9773beaa 100644 --- a/live_edit.py +++ b/live_edit.py @@ -1,18 +1,19 @@ -import pygame -import random, math +import math +import wave + import numpy as np -import cv2 import pyaudio -import midi -import wave +import pygame -#User constants +import midi_utils + +# User constants device = "cpu" -dir_name = 'History/' -sub_dir_name = 'e2000/' +dir_name = 'history/' +sub_dir_name = 'e1/' #'e2000/' sample_rate = 48000 -note_dt = 2000 #Num Samples -note_duration = 20000 #Num Samples +note_dt = 2000 # Num Samples +note_duration = 20000 # Num Samples note_decay = 5.0 / sample_rate num_params = 120 num_measures = 16 @@ -29,7 +30,7 @@ note_h = 96 note_pad = 2 -notes_rows = num_measures / 8 +notes_rows = int(num_measures / 8) notes_cols = 8 slider_num = min(40, num_params) @@ -41,27 +42,27 @@ control_h = 30 control_pad = 5 control_num = 3 -control_colors = [(255,0,0), (0,255,0), (0,0,255)] +control_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] control_inits = [0.75, 0.5, 0.5] -#Derived constants -notes_w = notes_cols * (note_w + note_pad*2) -notes_h = notes_rows * (note_h + note_pad*2) +# Derived constants +notes_w = notes_cols * (note_w + note_pad * 2) +notes_h = notes_rows * (note_h + note_pad * 2) sliders_w = notes_w -sliders_h = slider_h + slider_pad*2 +sliders_h = slider_h + slider_pad * 2 controls_w = control_w * control_num controls_h = control_h window_w = notes_w window_h = notes_h + sliders_h + controls_h -slider_w = (window_w - slider_pad*2) / slider_num +slider_w = int((window_w - slider_pad * 2) / slider_num) notes_x = 0 notes_y = sliders_h sliders_x = slider_pad sliders_y = slider_pad -controls_x = (window_w - controls_w) / 2 +controls_x = int((window_w - controls_w) / 2) controls_y = notes_h + sliders_h -#Global variables +# Global variables prev_mouse_pos = None mouse_pressed = 0 cur_slider_ix = 0 @@ -73,7 +74,7 @@ cur_notes = np.zeros((num_measures, note_h, note_w), dtype=np.uint8) cur_controls = np.array(control_inits, dtype=np.float32) -#Setup audio stream +# Setup audio stream audio = pyaudio.PyAudio() audio_notes = [] audio_time = 0 @@ -81,347 +82,359 @@ note_time_dt = 0 audio_reset = False audio_pause = False + + def audio_callback(in_data, frame_count, time_info, status): - global audio_time - global audio_notes - global audio_reset - global note_time - global note_time_dt - - #Check if needs restart - if audio_reset: - audio_notes = [] - audio_time = 0 - note_time = 0 - note_time_dt = 0 - audio_reset = False - - #Check if paused - if audio_pause and status is not None: - data = np.zeros((frame_count,), dtype=np.float32) - return (data.tobytes(), pyaudio.paContinue) - - #Find and add any notes in this time window - cur_dt = note_dt - while note_time_dt < audio_time + frame_count: - measure_ix = note_time / note_h - if measure_ix >= num_measures: - break - note_ix = note_time % note_h - notes = np.where(cur_notes[measure_ix, note_ix] >= note_thresh)[0] - for note in notes: - freq = 2 * 38.89 * pow(2.0, note / 12.0) / sample_rate - audio_notes.append((note_time_dt, freq)) - note_time += 1 - note_time_dt += cur_dt - - #Generate the tones - data = np.zeros((frame_count,), dtype=np.float32) - for t,f in audio_notes: - x = np.arange(audio_time - t, audio_time + frame_count - t) - x = np.maximum(x, 0) - - if instrument == 0: - w = np.sign(1 - np.mod(x * f, 2)) #Square - elif instrument == 1: - w = np.mod(x * f - 1, 2) - 1 #Sawtooth - elif instrument == 2: - w = 2*np.abs(np.mod(x * f - 0.5, 2) - 1) - 1 #Triangle - elif instrument == 3: - w = np.sin(x * f * math.pi) #Sine - - #w = np.floor(w*8)/8 - w[x == 0] = 0 - w *= volume * np.exp(-x*note_decay) - data += w - data = np.clip(data, -32000, 32000).astype(np.int16) - - #Remove notes that are too old - audio_time += frame_count - audio_notes = [(t,f) for t,f in audio_notes if audio_time < t + note_duration] - - #Reset if loop occurs - if note_time / note_h >= num_measures: - audio_time = 0 - note_time = 0 - note_time_dt = 0 - audio_notes = [] - - #Return the sound clip - return (data.tobytes(), pyaudio.paContinue) - -#Keras -print "Loading Keras..." -import os -os.environ['THEANORC'] = "./" + device + ".theanorc" -os.environ['KERAS_BACKEND'] = "theano" -import theano -print "Theano Version: " + theano.__version__ + global audio_time + global audio_notes + global audio_reset + global note_time + global note_time_dt + + # Check if needs restart + if audio_reset: + audio_notes = [] + audio_time = 0 + note_time = 0 + note_time_dt = 0 + audio_reset = False + + # Check if paused + if audio_pause and status is not None: + data = np.zeros((frame_count,), dtype=np.float32) + return (data.tobytes(), pyaudio.paContinue) + + # Find and add any notes in this time window + cur_dt = note_dt + while note_time_dt < audio_time + frame_count: + measure_ix = note_time / note_h + if measure_ix >= num_measures: + break + note_ix = note_time % note_h + notes = np.where(cur_notes[int(measure_ix), note_ix] >= note_thresh)[0] + for note in notes: + freq = 2 * 38.89 * pow(2.0, note / 12.0) / sample_rate + audio_notes.append((note_time_dt, freq)) + note_time += 1 + note_time_dt += cur_dt + + # Generate the tones + data = np.zeros((frame_count,), dtype=np.float32) + for t, f in audio_notes: + x = np.arange(audio_time - t, audio_time + frame_count - t) + x = np.maximum(x, 0) + + if instrument == 0: + w = np.sign(1 - np.mod(x * f, 2)) # Square + elif instrument == 1: + w = np.mod(x * f - 1, 2) - 1 # Sawtooth + elif instrument == 2: + w = 2 * np.abs(np.mod(x * f - 0.5, 2) - 1) - 1 # Triangle + elif instrument == 3: + w = np.sin(x * f * math.pi) # Sine + + # w = np.floor(w*8)/8 + w[x == 0] = 0 + w *= volume * np.exp(-x * note_decay) + data += w + data = np.clip(data, -32000, 32000).astype(np.int16) + + # Remove notes that are too old + audio_time += frame_count + audio_notes = [(t, f) for t, f in audio_notes if audio_time < t + note_duration] + + # Reset if loop occurs + if note_time / note_h >= num_measures: + audio_time = 0 + note_time = 0 + note_time_dt = 0 + audio_notes = [] + + # Return the sound clip + return data.tobytes(), pyaudio.paContinue + + +# Keras +print("Loading Keras...") + import keras -print "Keras Version: " + keras.__version__ -from keras.models import Model, Sequential, load_model -from keras.layers import Dense, Activation, Dropout, Flatten, Reshape -from keras.layers.convolutional import Conv2D, Conv2DTranspose, ZeroPadding2D -from keras.layers.pooling import MaxPooling2D -from keras.layers.noise import GaussianNoise -from keras.layers.local import LocallyConnected2D -from keras.optimizers import Adam, RMSprop, SGD -from keras.regularizers import l2 -from keras.losses import binary_crossentropy -from keras.layers.advanced_activations import ELU -from keras.preprocessing.image import ImageDataGenerator -from keras.utils import plot_model + +print("Keras Version: " + keras.__version__) +from keras.models import Model, load_model from keras import backend as K + K.set_image_data_format('channels_first') -print "Loading Encoder..." +print("Loading Encoder...") model = load_model(dir_name + 'model.h5') enc = K.function([model.get_layer('encoder').input, K.learning_phase()], - [model.layers[-1].output]) + [model.layers[-1].output]) enc_model = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output) -print "Loading Statistics..." +print("Loading Statistics...") means = np.load(dir_name + sub_dir_name + 'means.npy') evals = np.load(dir_name + sub_dir_name + 'evals.npy') evecs = np.load(dir_name + sub_dir_name + 'evecs.npy') stds = np.load(dir_name + sub_dir_name + 'stds.npy') -print "Loading Songs..." -y_samples = np.load('samples.npy') -y_lengths = np.load('lengths.npy') +print("Loading Songs...") +y_samples = np.load('data/interim/samples.npy') +y_lengths = np.load('data/interim/lengths.npy') -#Open a window +# Open a window pygame.init() pygame.font.init() -screen = pygame.display.set_mode((window_w, window_h)) +screen = pygame.display.set_mode((int(window_w), int(window_h))) notes_surface = screen.subsurface((notes_x, notes_y, notes_w, notes_h)) pygame.display.set_caption('MusicEdit') font = pygame.font.SysFont("monospace", 15) -#Start the audio stream +# Start the audio stream audio_stream = audio.open( - format=audio.get_format_from_width(2), - channels=1, - rate=sample_rate, - output=True, - stream_callback=audio_callback) + format=audio.get_format_from_width(2), + channels=1, + rate=sample_rate, + output=True, + stream_callback=audio_callback) audio_stream.start_stream() + def update_mouse_click(mouse_pos): - global cur_slider_ix - global cur_control_ix - global mouse_pressed - x = (mouse_pos[0] - sliders_x) - y = (mouse_pos[1] - sliders_y) - - if x >= 0 and y >= 0 and x < sliders_w and y < sliders_h: - cur_slider_ix = x / slider_w - mouse_pressed = 1 - - x = (mouse_pos[0] - controls_x) - y = (mouse_pos[1] - controls_y) - if x >= 0 and y >= 0 and x < controls_w and y < controls_h: - cur_control_ix = x / control_w - mouse_pressed = 2 + global cur_slider_ix + global cur_control_ix + global mouse_pressed + x = (mouse_pos[0] - sliders_x) + y = (mouse_pos[1] - sliders_y) + + if 0 <= x < sliders_w and 0 <= y < sliders_h: + cur_slider_ix = int(x / slider_w) + mouse_pressed = 1 + + x = (mouse_pos[0] - controls_x) + y = (mouse_pos[1] - controls_y) + if 0 <= x < controls_w and 0 <= y < controls_h: + cur_control_ix = int(x / control_w) + mouse_pressed = 2 + def apply_controls(): - global note_thresh - global note_dt - global volume - - note_thresh = (1.0 - cur_controls[0]) * 200 + 10 - note_dt = (1.0 - cur_controls[1]) * 1800 + 200 - volume = cur_controls[2] * 6000 - + global note_thresh + global note_dt + global volume + + note_thresh = (1.0 - cur_controls[0]) * 200 + 10 + note_dt = (1.0 - cur_controls[1]) * 1800 + 200 + volume = cur_controls[2] * 6000 + + def update_mouse_move(mouse_pos): - global needs_update - - if mouse_pressed == 1: - y = (mouse_pos[1] - sliders_y) - if y >= 0 and y <= slider_h: - val = (float(y) / slider_h - 0.5) * (num_sigmas * 2) - cur_params[cur_slider_ix] = val - needs_update = True - elif mouse_pressed == 2: - x = (mouse_pos[0] - (controls_x + cur_control_ix*control_w)) - if x >= control_pad and x <= control_w - control_pad: - val = float(x - control_pad) / (control_w - control_pad*2) - cur_controls[cur_control_ix] = val - apply_controls() + global needs_update + + if mouse_pressed == 1: + y = (mouse_pos[1] - sliders_y) + if 0 <= y <= slider_h: + val = (float(y) / slider_h - 0.5) * (num_sigmas * 2) + cur_params[int(cur_slider_ix)] = val + needs_update = True + elif mouse_pressed == 2: + x = (mouse_pos[0] - (controls_x + cur_control_ix * control_w)) + if control_pad <= x <= control_w - control_pad: + val = float(x - control_pad) / (control_w - control_pad * 2) + cur_controls[int(cur_control_ix)] = val + apply_controls() + def draw_controls(): - for i in xrange(control_num): - x = controls_x + i * control_w + control_pad - y = controls_y + control_pad - w = control_w - control_pad*2 - h = control_h - control_pad*2 - col = control_colors[i] - - pygame.draw.rect(screen, col, (x, y, int(w*cur_controls[i]), h)) - pygame.draw.rect(screen, (0,0,0), (x, y, w, h), 1) - + for i in range(control_num): + x = controls_x + i * control_w + control_pad + y = controls_y + control_pad + w = control_w - control_pad * 2 + h = control_h - control_pad * 2 + col = control_colors[i] + + pygame.draw.rect(screen, col, (x, y, int(w * cur_controls[i]), h)) + pygame.draw.rect(screen, (0, 0, 0), (x, y, w, h), 1) + + def draw_sliders(): - for i in xrange(slider_num): - slider_color = slider_colors[i % len(slider_colors)] - x = sliders_x + i * slider_w - y = sliders_y - - cx = x + slider_w / 2 - cy_1 = y - cy_2 = y + slider_h - pygame.draw.line(screen, slider_color, (cx, cy_1), (cx, cy_2)) - - cx_1 = x + tick_pad - cx_2 = x + slider_w - tick_pad - for j in xrange(int(num_sigmas * 2 + 1)): - ly = y + slider_h/2.0 + (j-num_sigmas)*slider_h/(num_sigmas*2.0) - ly = int(ly) - col = (0,0,0) if j - num_sigmas == 0 else slider_color - pygame.draw.line(screen, col, (cx_1, ly), (cx_2, ly)) - - py = y + int((cur_params[i] / (num_sigmas * 2) + 0.5) * slider_h) - pygame.draw.circle(screen, slider_color, (cx, py), (slider_w - tick_pad)/2) + for i in range(slider_num): + slider_color = slider_colors[i % len(slider_colors)] + x = sliders_x + i * slider_w + y = sliders_y + + cx = x + slider_w / 2 + cy_1 = y + cy_2 = y + slider_h + pygame.draw.line(screen, slider_color, (cx, cy_1), (cx, cy_2)) + + cx_1 = x + tick_pad + cx_2 = x + slider_w - tick_pad + for j in range(int(num_sigmas * 2 + 1)): + ly = y + slider_h / 2.0 + (j - num_sigmas) * slider_h / (num_sigmas * 2.0) + ly = int(ly) + col = (0, 0, 0) if j - num_sigmas == 0 else slider_color + pygame.draw.line(screen, col, (cx_1, ly), (cx_2, ly)) + + py = y + int((cur_params[i] / (num_sigmas * 2) + 0.5) * slider_h) + pygame.draw.circle(screen, slider_color, (int(cx), int(py)), int((slider_w - tick_pad) / 2)) + def notes_to_img(notes): - output = np.full((3, notes_h, notes_w), 64, dtype=np.uint8) - - for i in xrange(notes_rows): - for j in xrange(notes_cols): - x = note_pad + j*(note_w + note_pad*2) - y = note_pad + i*(note_h + note_pad*2) - ix = i*notes_cols + j - - measure = np.rot90(notes[ix]) - played_only = np.where(measure >= note_thresh, 255, 0) - output[0,y:y+note_h,x:x+note_w] = np.minimum(measure * (255.0 / note_thresh), 255.0) - output[1,y:y+note_h,x:x+note_w] = played_only - output[2,y:y+note_h,x:x+note_w] = played_only - - return np.transpose(output, (2, 1, 0)) - + output = np.full((3, int(notes_h), int(notes_w)), 64, dtype=np.uint8) + + for i in range(notes_rows): + for j in range(notes_cols): + x = note_pad + j * (note_w + note_pad * 2) + y = note_pad + i * (note_h + note_pad * 2) + ix = i * notes_cols + j + + measure = np.rot90(notes[ix]) + played_only = np.where(measure >= note_thresh, 255, 0) + output[0, y:y + note_h, x:x + note_w] = np.minimum(measure * (255.0 / note_thresh), 255.0) + output[1, y:y + note_h, x:x + note_w] = played_only + output[2, y:y + note_h, x:x + note_w] = played_only + + return np.transpose(output, (2, 1, 0)) + + def draw_notes(): - pygame.surfarray.blit_array(notes_surface, notes_to_img(cur_notes)) - - measure_ix = note_time / note_h - note_ix = note_time % note_h - x = notes_x + note_pad + (measure_ix % notes_cols) * (note_w + note_pad*2) + note_ix - y = notes_y +note_pad + (measure_ix / notes_cols) * (note_h + note_pad*2) - pygame.draw.rect(screen, (255,255,0), (x, y, 4, note_h), 0) - -#Main loop + pygame.surfarray.blit_array(notes_surface, notes_to_img(cur_notes)) + + measure_ix = int(note_time / note_h) + note_ix = note_time % note_h + x = notes_x + note_pad + (measure_ix % notes_cols) * (note_w + note_pad * 2) + note_ix + y = notes_y + note_pad + int(measure_ix / notes_cols) * (note_h + note_pad * 2) + + pygame.draw.rect(screen, (255, 255, 0), (x, y, 4, note_h), 0) + + +# Main loop running = True rand_ix = 0 cur_len = 0 apply_controls() while running: - #Process events - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - break - elif event.type == pygame.MOUSEBUTTONDOWN: - if pygame.mouse.get_pressed()[0]: - prev_mouse_pos = pygame.mouse.get_pos() - update_mouse_click(prev_mouse_pos) - update_mouse_move(prev_mouse_pos) - elif pygame.mouse.get_pressed()[2]: - cur_params = np.zeros((num_params,), dtype=np.float32) - needs_update = True - elif event.type == pygame.MOUSEBUTTONUP: - mouse_pressed = 0 - prev_mouse_pos = None - elif event.type == pygame.MOUSEMOTION and mouse_pressed > 0: - update_mouse_move(pygame.mouse.get_pos()) - elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_r: - cur_params = np.clip(np.random.normal(0.0, 1.0, (num_params,)), -num_sigmas, num_sigmas) - needs_update = True - audio_reset = True - if event.key == pygame.K_e: - cur_params = np.clip(np.random.normal(0.0, 2.0, (num_params,)), -num_sigmas, num_sigmas) - needs_update = True - audio_reset = True - if event.key == pygame.K_o: - print "RandIx: " + str(rand_ix) - if is_ae: - example_song = y_samples[cur_len:cur_len + num_measures] - cur_notes = example_song * 255 - x = enc_model.predict(np.expand_dims(example_song, 0), batch_size=1)[0] - cur_len += y_lengths[rand_ix] - rand_ix += 1 - else: - rand_ix = np.array([rand_ix], dtype=np.int64) - x = enc_model.predict(rand_ix, batch_size=1)[0] - rand_ix = (rand_ix + 1) % model.layers[0].input_dim - - if use_pca: - cur_params = np.dot(x - means, evecs.T) / evals - else: - cur_params = (x - means) / stds - - needs_update = True - audio_reset = True - if event.key == pygame.K_g: - audio_pause = True - audio_reset = True - midi.samples_to_midi(cur_notes, 'live.mid', 16, note_thresh) - save_audio = '' - while True: - save_audio += audio_callback(None, 1024, None, None)[0] - if audio_time == 0: - break - wave_output = wave.open('live.wav', 'w') - wave_output.setparams((1, 2, sample_rate, 0, 'NONE', 'not compressed')) - wave_output.writeframes(save_audio) - wave_output.close() - audio_pause = False - if event.key == pygame.K_ESCAPE: - running = False - break - if event.key == pygame.K_SPACE: - audio_pause = not audio_pause - if event.key == pygame.K_TAB: - audio_reset = True - if event.key == pygame.K_1: - instrument = 0 - if event.key == pygame.K_2: - instrument = 1 - if event.key == pygame.K_3: - instrument = 2 - if event.key == pygame.K_4: - instrument = 3 - if event.key == pygame.K_c: - y = np.expand_dims(np.where(cur_notes > note_thresh, 1, 0), 0) - x = enc_model.predict(y)[0] - if use_pca: - cur_params = np.dot(x - means, evecs.T) / evals - else: - cur_params = (x - means) / stds - needs_update = True - - #Check if we need an update - if needs_update: - if use_pca: - x = means + np.dot(cur_params * evals, evecs) - else: - x = means + stds * cur_params - x = np.expand_dims(x, axis=0) - y = enc([x, 0])[0][0] - cur_notes = (y * 255.0).astype(np.uint8) - needs_update = False - - #Draw to the screen - screen.fill(background_color) - draw_notes() - draw_sliders() - draw_controls() - - #Flip the screen buffer - pygame.display.flip() - pygame.time.wait(10) - -#Close the audio stream + # Process events + for event in pygame.event.get(): + if event.type == pygame.QUIT: # QUIT BUTTON HIT + running = False + break + + elif event.type == pygame.MOUSEBUTTONDOWN: # MOUSE BUTTON DOWN + if pygame.mouse.get_pressed()[0]: + prev_mouse_pos = pygame.mouse.get_pos() + update_mouse_click(prev_mouse_pos) + update_mouse_move(prev_mouse_pos) + elif pygame.mouse.get_pressed()[2]: + cur_params = np.zeros((num_params,), dtype=np.float32) + needs_update = True + + elif event.type == pygame.MOUSEBUTTONUP: # MOUSE BUTTON UP + mouse_pressed = 0 + prev_mouse_pos = None + + elif event.type == pygame.MOUSEMOTION and mouse_pressed > 0: # MOUSE MOTION WHILE PRESSED + update_mouse_move(pygame.mouse.get_pos()) + + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_r: # KEYDOWN R + cur_params = np.clip(np.random.normal(0.0, 1.0, (num_params,)), -num_sigmas, num_sigmas) + needs_update = True + audio_reset = True + + if event.key == pygame.K_e: # KEYDOWN E + cur_params = np.clip(np.random.normal(0.0, 2.0, (num_params,)), -num_sigmas, num_sigmas) + needs_update = True + audio_reset = True + + if event.key == pygame.K_o: # KEYDOWN O + print("RandIx: " + str(rand_ix)) + if is_ae: + example_song = y_samples[cur_len:cur_len + num_measures] + cur_notes = example_song * 255 + x = enc_model.predict(np.expand_dims(example_song, 0), batch_size=1)[0] + cur_len += y_lengths[rand_ix] + rand_ix += 1 + else: + rand_ix = np.array([rand_ix], dtype=np.int64) + x = enc_model.predict(rand_ix, batch_size=1)[0] + rand_ix = (rand_ix + 1) % model.layers[0].input_dim + + if use_pca: + cur_params = np.dot(x - means, evecs.T) / evals + else: + cur_params = (x - means) / stds + + needs_update = True + audio_reset = True + + if event.key == pygame.K_g: # KEYDOWN G + audio_pause = True + audio_reset = True + midi_utils.samples_to_midi(cur_notes, 'results/live.mid', 16, note_thresh) + save_audio = b'' + while True: + save_audio += audio_callback(None, 1024, None, None)[0] + if audio_time == 0: + break + wave_output = wave.open('results/live.wav', 'w') + wave_output.setparams((1, 2, sample_rate, 0, 'NONE', 'not compressed')) + wave_output.writeframes(save_audio) + wave_output.close() + audio_pause = False + if event.key == pygame.K_ESCAPE: # KEYDOWN ESCAPE + running = False + break + + if event.key == pygame.K_SPACE: # KEYDOWN SPACE + audio_pause = not audio_pause + + if event.key == pygame.K_TAB: # KEYDOWN TAB + audio_reset = True + + if event.key == pygame.K_1: # KEYDOWN 1 + instrument = 0 + + if event.key == pygame.K_2: # KEYDOWN 2 + instrument = 1 + + if event.key == pygame.K_3: # KEYDOWN 3 + instrument = 2 + + if event.key == pygame.K_4: # KEYDOWN 4 + instrument = 3 + + if event.key == pygame.K_c: # KEYDOWN C + y = np.expand_dims(np.where(cur_notes > note_thresh, 1, 0), 0) + x = enc_model.predict(y)[0] + if use_pca: + cur_params = np.dot(x - means, evecs.T) / evals + else: + cur_params = (x - means) / stds + needs_update = True + + # Check if we need an update + if needs_update: + if use_pca: + x = means + np.dot(cur_params * evals, evecs) + else: + x = means + stds * cur_params + x = np.expand_dims(x, axis=0) + y = enc([x, 0])[0][0] + cur_notes = (y * 255.0).astype(np.uint8) + needs_update = False + + # Draw to the screen + screen.fill(background_color) + draw_notes() + draw_sliders() + draw_controls() + + # Flip the screen buffer + pygame.display.flip() + pygame.time.wait(10) + +# Close the audio stream audio_stream.stop_stream() audio_stream.close() audio.terminate() - diff --git a/load_songs.py b/load_songs.py index 48bde9f1..eb473ad6 100644 --- a/load_songs.py +++ b/load_songs.py @@ -1,35 +1,47 @@ -import midi +import midi_utils import os -import util +import misc import numpy as np +import argparse -patterns = {} -dirs = ["Music", "download", "rag", "pop", "misc"] -all_samples = [] -all_lens = [] -print "Loading Songs..." -for dir in dirs: - for root, subdirs, files in os.walk(dir): - for file in files: - path = root + "\\" + file - if not (path.endswith('.mid') or path.endswith('.midi')): - continue - try: - samples = midi.midi_to_samples(path) - except: - print "ERROR ", path - continue - if len(samples) < 8: - continue - - samples, lens = util.generate_add_centered_transpose(samples) - all_samples += samples - all_lens += lens - -assert(sum(all_lens) == len(all_samples)) -print "Saving " + str(len(all_samples)) + " samples..." -all_samples = np.array(all_samples, dtype=np.uint8) -all_lens = np.array(all_lens, dtype=np.uint32) -np.save('samples.npy', all_samples) -np.save('lengths.npy', all_lens) -print "Done" + +def load_songs(data_folders): + + all_samples = [] + all_lengths = [] + print("Loading Songs...") + for folder in data_folders: + for root, _, files in os.walk(folder): + for file in files: + path = root + "\\" + file + if not (path.endswith('.mid') or path.endswith('.midi')): + continue + try: + samples = midi_utils.midi_to_samples(path) + except Exception as e: + print("ERROR ", path) + print(e) + continue + if len(samples) < 8: + continue + + samples, lens = misc.generate_add_centered_transpose(samples) + all_samples += samples + all_lengths += lens + + assert (sum(all_lengths) == len(all_samples)) + print("Saving " + str(len(all_samples)) + " samples...") + all_samples = np.array(all_samples, dtype=np.uint8) + all_lengths = np.array(all_lengths, dtype=np.uint32) + np.save('data/interim/samples.npy', all_samples) + np.save('data/interim/lengths.npy', all_lengths) + print("Done") + + +if __name__ == "__main__": + # configure parser and parse arguments + parser = argparse.ArgumentParser(description='Load songs and put them into a dataset.') + parser.add_argument('--data_folder', default=["data/raw"], type=str, help='The path to the midi data', action='append') + + args = parser.parse_args() + load_songs(args.data_folder) diff --git a/midi.py b/midi.py deleted file mode 100644 index 404e6731..00000000 --- a/midi.py +++ /dev/null @@ -1,93 +0,0 @@ -from mido import MidiFile, MidiTrack, Message -import numpy as np - -num_notes = 96 -samples_per_measure = 96 - -def midi_to_samples(fname): - has_time_sig = False - flag_warning = False - mid = MidiFile(fname) - ticks_per_beat = mid.ticks_per_beat - ticks_per_measure = 4 * ticks_per_beat - - for i, track in enumerate(mid.tracks): - for msg in track: - if msg.type == 'time_signature': - new_tpm = msg.numerator * ticks_per_beat * 4 / msg.denominator - if has_time_sig and new_tpm != ticks_per_measure: - flag_warning = True - ticks_per_measure = new_tpm - has_time_sig = True - if flag_warning: - print " ^^^^^^ WARNING ^^^^^^" - print " " + fname - print " Detected multiple distinct time signatures." - print " ^^^^^^ WARNING ^^^^^^" - return [] - - all_notes = {} - for i, track in enumerate(mid.tracks): - abs_time = 0 - for msg in track: - abs_time += msg.time - if msg.type == 'note_on': - if msg.velocity == 0: - continue - note = msg.note - (128 - num_notes)/2 - assert(note >= 0 and note < num_notes) - if note not in all_notes: - all_notes[note] = [] - else: - single_note = all_notes[note][-1] - if len(single_note) == 1: - single_note.append(single_note[0] + 1) - all_notes[note].append([abs_time * samples_per_measure / ticks_per_measure]) - elif msg.type == 'note_off': - if len(all_notes[note][-1]) != 1: - continue - all_notes[note][-1].append(abs_time * samples_per_measure / ticks_per_measure) - for note in all_notes: - for start_end in all_notes[note]: - if len(start_end) == 1: - start_end.append(start_end[0] + 1) - samples = [] - for note in all_notes: - for start, end in all_notes[note]: - sample_ix = start / samples_per_measure - while len(samples) <= sample_ix: - samples.append(np.zeros((samples_per_measure, num_notes), dtype=np.uint8)) - sample = samples[sample_ix] - start_ix = start - sample_ix * samples_per_measure - if False: - end_ix = min(end - sample_ix * samples_per_measure, samples_per_measure) - while start_ix < end_ix: - sample[start_ix, note] = 1 - start_ix += 1 - else: - sample[start_ix, note] = 1 - return samples - -def samples_to_midi(samples, fname, ticks_per_sample, thresh=0.5): - mid = MidiFile() - track = MidiTrack() - mid.tracks.append(track) - ticks_per_beat = mid.ticks_per_beat - ticks_per_measure = 4 * ticks_per_beat - ticks_per_sample = ticks_per_measure / samples_per_measure - abs_time = 0 - last_time = 0 - for sample in samples: - for y in xrange(sample.shape[0]): - abs_time += ticks_per_sample - for x in xrange(sample.shape[1]): - note = x + (128 - num_notes)/2 - if sample[y,x] >= thresh and (y == 0 or sample[y-1,x] < thresh): - delta_time = abs_time - last_time - track.append(Message('note_on', note=note, velocity=127, time=delta_time)) - last_time = abs_time - if sample[y,x] >= thresh and (y == sample.shape[0]-1 or sample[y+1,x] < thresh): - delta_time = abs_time - last_time - track.append(Message('note_off', note=note, velocity=127, time=delta_time)) - last_time = abs_time - mid.save(fname) diff --git a/midi_utils.py b/midi_utils.py new file mode 100644 index 00000000..144c0c78 --- /dev/null +++ b/midi_utils.py @@ -0,0 +1,97 @@ +from mido import MidiFile, MidiTrack, Message +import numpy as np + +num_notes = 96 +samples_per_measure = 96 + + +def midi_to_samples(file_name): + has_time_sig = False + flag_warning = False + mid = MidiFile(file_name) + ticks_per_beat = mid.ticks_per_beat + ticks_per_measure = 4 * ticks_per_beat + + for i, track in enumerate(mid.tracks): + for msg in track: + if msg.type == 'time_signature': + new_tpm = msg.numerator * ticks_per_beat * 4 / msg.denominator + if has_time_sig and new_tpm != ticks_per_measure: + flag_warning = True + ticks_per_measure = new_tpm + has_time_sig = True + if flag_warning: + print(" ^^^^^^ WARNING ^^^^^^") + print(" " + file_name) + print(" Detected multiple distinct time signatures.") + print(" ^^^^^^ WARNING ^^^^^^") + return [] + + all_notes = {} + for i, track in enumerate(mid.tracks): + abs_time = 0 + for msg in track: + abs_time += msg.time + if msg.type == 'note_on': + if msg.velocity == 0: + continue + note = msg.note - (128 - num_notes) / 2 + assert (0 <= note < num_notes) + if note not in all_notes: + all_notes[note] = [] + else: + single_note = all_notes[note][-1] + if len(single_note) == 1: + single_note.append(single_note[0] + 1) + all_notes[note].append([abs_time * samples_per_measure / ticks_per_measure]) + elif msg.type == 'note_off': + if len(all_notes[note][-1]) != 1: + continue + all_notes[note][-1].append(abs_time * samples_per_measure / ticks_per_measure) + + for note in all_notes: + for start_end in all_notes[note]: + if len(start_end) == 1: + start_end.append(start_end[0] + 1) + samples = [] + + for note in all_notes: + for start, end in all_notes[note]: + sample_ix = start / samples_per_measure # find the sample/measure this belongs into + while len(samples) <= sample_ix: + samples.append(np.zeros((samples_per_measure, num_notes), dtype=np.uint8)) + sample = samples[int(sample_ix)] + start_ix = start - sample_ix * samples_per_measure + if False: + end_ix = min(end - sample_ix * samples_per_measure, samples_per_measure) + while start_ix < end_ix: + sample[int(start_ix), int(note)] = 1 + start_ix += 1 + else: + sample[int(start_ix), int(note)] = 1 + return samples + + +def samples_to_midi(samples, file_name, ticks_per_sample, threshold=0.5): + mid = MidiFile() + track = MidiTrack() + mid.tracks.append(track) + ticks_per_beat = mid.ticks_per_beat + ticks_per_measure = 4 * ticks_per_beat + ticks_per_sample = ticks_per_measure / samples_per_measure + abs_time = 0 + last_time = 0 + for sample in samples: + for y in range(sample.shape[0]): + abs_time += ticks_per_sample + for x in range(sample.shape[1]): + note = x + (128 - num_notes) / 2 + if sample[y, x] >= threshold and (y == 0 or sample[y - 1, x] < threshold): + delta_time = abs_time - last_time + track.append(Message('note_on', note=int(note), velocity=127, time=int(delta_time))) + last_time = abs_time + if sample[y, x] >= threshold and (y == sample.shape[0] - 1 or sample[y + 1, x] < threshold): + delta_time = abs_time - last_time + track.append(Message('note_off', note=int(note), velocity=127, time=int(delta_time))) + last_time = abs_time + mid.save(file_name) diff --git a/misc.py b/misc.py new file mode 100644 index 00000000..512dd3e3 --- /dev/null +++ b/misc.py @@ -0,0 +1,112 @@ +import numpy as np +import cv2 +import os + + +def transpose_range(samples): + merged_sample = np.zeros_like(samples[0]) + for sample in samples: + merged_sample = np.maximum(merged_sample, sample) + merged_sample = np.amax(merged_sample, axis=0) + min_note = np.argmax(merged_sample) + max_note = merged_sample.shape[0] - np.argmax(merged_sample[::-1]) + return min_note, max_note + + +def generate_add_centered_transpose(samples): + num_notes = samples[0].shape[1] + min_note, max_note = transpose_range(samples) + s = num_notes / 2 - (max_note + min_note) / 2 + out_samples = samples + out_lengths = [len(samples), len(samples)] + for i in range(len(samples)): + out_sample = np.zeros_like(samples[i]) + out_sample[:, min_note + int(s):max_note + int(s)] = samples[i][:, min_note:max_note] + out_samples.append(out_sample) + return out_samples, out_lengths + + +def generate_all_transpose(samples, radius=6): + num_notes = samples[0].shape[1] + min_note, max_note = transpose_range(samples) + min_shift = -min(radius, min_note) + max_shift = min(radius, num_notes - max_note) + out_samples = [] + out_lengths = [] + for s in range(min_shift, max_shift): + for i in range(len(samples)): + out_sample = np.zeros_like(samples[i]) + out_sample[:, min_note + s:max_note + s] = samples[i][:, min_note:max_note] + out_samples.append(out_sample) + out_lengths.append(len(samples)) + return out_samples, out_lengths + + +def sample_to_pic(fname, sample, thresh=None): + if thresh is not None: + inverted = np.where(sample > thresh, 0, 1) + else: + inverted = 1.0 - sample + cv2.imwrite(fname, inverted * 255) + + +def samples_to_pics(dir, samples, thresh=None): + if not os.path.exists(dir): os.makedirs(dir) + for i in range(samples.shape[0]): + sample_to_pic(dir + '/s' + str(i) + '.png', samples[i], thresh) + + +def pad_songs(y, y_lens, max_len): + y_shape = (y_lens.shape[0], max_len) + y.shape[1:] + y_train = np.zeros(y_shape, dtype=np.float32) + cur_ix = 0 + for i in range(y_lens.shape[0]): + end_ix = cur_ix + y_lens[i] + for j in range(max_len): + k = j % (end_ix - cur_ix) + y_train[i, j] = y[cur_ix + k] + cur_ix = end_ix + assert (end_ix == y.shape[0]) + return y_train + + +def sample_to_pattern(sample, ix, size): + num_pats = 0 + pat_types = {} + pat_list = [] + num_samples = len(sample) if type(sample) is list else sample.shape[0] + for i in range(size): + j = (ix + i) % num_samples + measure = sample[j].tobytes() + if measure not in pat_types: + pat_types[measure] = num_pats + num_pats += 1 + pat_list.append(pat_types[measure]) + return str(pat_list), pat_types + + +def embed_samples(samples): + note_dict = {} + n, m, p = samples.shape + samples.flags.writeable = False + e_samples = np.empty(samples.shape[:2], dtype=np.int32) + for i in range(n): + for j in range(m): + note = samples[i, j].data + if note not in note_dict: + note_dict[note] = len(note_dict) + e_samples[i, j] = note_dict[note] + samples.flags.writeable = True + lookup = np.empty((len(note_dict), p), dtype=np.float32) + for k in note_dict: + lookup[note_dict[k]] = k + return e_samples, note_dict, lookup + + +def e_to_samples(e_samples, lookup): + samples = np.empty(e_samples.shape + lookup.shape[-1:], dtype=np.float32) + n, m = e_samples.shape + for i in range(n): + for j in range(m): + samples[i, j] = lookup[e_samples[i, j]] + return samples diff --git a/results/.gitkeep b/results/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/train.py b/train.py index 232d63ed..4fbc9582 100644 --- a/train.py +++ b/train.py @@ -1,10 +1,10 @@ -import sys, random, os +import random + import numpy as np from matplotlib import pyplot as plt -import pydot -import cv2 -import util -import midi + +import midi_utils +import misc NUM_EPOCHS = 2000 LR = 0.001 @@ -24,323 +24,324 @@ PARAM_SIZE = 120 NUM_OFFSETS = 16 if USE_EMBEDDING else 1 -def plotScores(scores, fname, on_top=True): - plt.clf() - ax = plt.gca() - ax.yaxis.tick_right() - ax.yaxis.set_ticks_position('both') - ax.yaxis.grid(True) - plt.plot(scores) - plt.ylim([0.0, 0.009]) - plt.xlabel('Epoch') - loc = ('upper right' if on_top else 'lower right') - plt.draw() - plt.savefig(fname) - -def save_config(): - with open('config.txt', 'w') as fout: - fout.write('LR: ' + str(LR) + '\n') - fout.write('BN_M: ' + str(BN_M) + '\n') - fout.write('BATCH_SIZE: ' + str(BATCH_SIZE) + '\n') - fout.write('NUM_OFFSETS: ' + str(NUM_OFFSETS) + '\n') - fout.write('DO_RATE: ' + str(DO_RATE) + '\n') - fout.write('num_songs: ' + str(num_songs) + '\n') - fout.write('optimizer: ' + type(model.optimizer).__name__ + '\n') - ################################### # Load Keras ################################### -print "Loading Keras..." -import os, math -os.environ['THEANORC'] = "./gpu.theanorc" -os.environ['KERAS_BACKEND'] = "theano" -import theano -print "Theano Version: " + theano.__version__ - +print("Loading Keras...") +import os import keras -print "Keras Version: " + keras.__version__ -from keras.layers import Input, Dense, Activation, Dropout, Flatten, Reshape, Permute, RepeatVector, ActivityRegularization, TimeDistributed, Lambda, SpatialDropout1D -from keras.layers.convolutional import Conv1D, Conv2D, Conv2DTranspose, UpSampling2D, ZeroPadding2D + +print("Keras Version: " + keras.__version__) +from keras.layers import Input, Dense, Activation, Dropout, Flatten, Reshape, TimeDistributed, Lambda from keras.layers.embeddings import Embedding -from keras.layers.local import LocallyConnected2D -from keras.layers.pooling import MaxPooling2D, AveragePooling2D -from keras.layers.noise import GaussianNoise from keras.layers.normalization import BatchNormalization -from keras.layers.recurrent import LSTM, SimpleRNN -from keras.initializers import RandomNormal from keras.losses import binary_crossentropy -from keras.models import Model, Sequential, load_model -from keras.optimizers import Adam, RMSprop, SGD -from keras.preprocessing.image import ImageDataGenerator -from keras.regularizers import l2 +from keras.models import Model, load_model +from keras.optimizers import Adam, RMSprop from keras.utils import plot_model from keras import backend as K -from keras import regularizers -from keras.engine.topology import Layer + K.set_image_data_format('channels_first') -#Fix the random seed so that training comparisons are easier to make +# Fix the random seed so that training comparisons are easier to make np.random.seed(0) random.seed(0) -if WRITE_HISTORY: - #Create folder to save models into - if not os.path.exists('History'): - os.makedirs('History') -################################### -# Load Dataset -################################### -print "Loading Data..." -y_samples = np.load('samples.npy') -y_lengths = np.load('lengths.npy') -num_samples = y_samples.shape[0] -num_songs = y_lengths.shape[0] -print "Loaded " + str(num_samples) + " samples from " + str(num_songs) + " songs." -print np.sum(y_lengths) -assert(np.sum(y_lengths) == num_samples) - -print "Padding Songs..." -x_shape = (num_songs * NUM_OFFSETS, 1) -y_shape = (num_songs * NUM_OFFSETS, MAX_LENGTH) + y_samples.shape[1:] -x_orig = np.expand_dims(np.arange(x_shape[0]), axis=-1) -y_orig = np.zeros(y_shape, dtype=y_samples.dtype) -cur_ix = 0 -for i in xrange(num_songs): - for ofs in xrange(NUM_OFFSETS): - ix = i*NUM_OFFSETS + ofs - end_ix = cur_ix + y_lengths[i] - for j in xrange(MAX_LENGTH): - k = (j + ofs) % (end_ix - cur_ix) - y_orig[ix,j] = y_samples[cur_ix + k] - cur_ix = end_ix -assert(end_ix == num_samples) -x_train = np.copy(x_orig) -y_train = np.copy(y_orig) - -def to_song(encoded_output): - return np.squeeze(decoder([np.round(encoded_output), 0])[0]) +def plot_scores(scores, f_name, on_top=True): + plt.clf() + ax = plt.gca() + ax.yaxis.tick_right() + ax.yaxis.set_ticks_position('both') + ax.yaxis.grid(True) + plt.plot(scores) + plt.ylim([0.0, 0.009]) + plt.xlabel('Epoch') + loc = ('upper right' if on_top else 'lower right') + plt.draw() + plt.savefig(f_name) -def reg_mean_std(x): - s = K.log(K.sum(x * x)) - return s*s -def vae_sampling(args): - z_mean, z_log_sigma_sq = args - epsilon = K.random_normal(shape=K.shape(z_mean), mean=0.0, stddev=VAE_B1) - return z_mean + K.exp(z_log_sigma_sq * 0.5) * epsilon - -def vae_loss(x, x_decoded_mean): - xent_loss = binary_crossentropy(x, x_decoded_mean) - kl_loss = VAE_B2 * K.mean(1 + z_log_sigma_sq - K.square(z_mean) - K.exp(z_log_sigma_sq), axis=None) - return xent_loss - kl_loss - -test_ix = 0 -y_test_song = np.copy(y_train[test_ix:test_ix+1]) -x_test_song = np.copy(x_train[test_ix:test_ix+1]) -midi.samples_to_midi(y_test_song[0], 'gt.mid', 16) +def save_config(num_songs, model): + with open('config.txt', 'w') as fout: + fout.write('LR: ' + str(LR) + '\n') + fout.write('BN_M: ' + str(BN_M) + '\n') + fout.write('BATCH_SIZE: ' + str(BATCH_SIZE) + '\n') + fout.write('NUM_OFFSETS: ' + str(NUM_OFFSETS) + '\n') + fout.write('DO_RATE: ' + str(DO_RATE) + '\n') + fout.write('num_songs: ' + str(num_songs) + '\n') + fout.write('optimizer: ' + type(model.optimizer).__name__ + '\n') -################################### -# Create Model -################################### -if CONTINUE_TRAIN or PLAY_ONLY: - print "Loading Model..." - model = load_model('model.h5', custom_objects=custom_objects) -else: - print "Building Model..." - - if USE_EMBEDDING: - x_in = Input(shape=x_shape[1:]) - print (None,) + x_shape[1:] - x = Embedding(x_train.shape[0], PARAM_SIZE, input_length=1)(x_in) - x = Flatten(name='pre_encoder')(x) - else: - x_in = Input(shape=y_shape[1:]) - print (None,) + y_shape[1:] - x = Reshape((y_shape[1], -1))(x_in) - print K.int_shape(x) - - x = TimeDistributed(Dense(2000, activation='relu'))(x) - print K.int_shape(x) - - x = TimeDistributed(Dense(200, activation='relu'))(x) - print K.int_shape(x) - - x = Flatten()(x) - print K.int_shape(x) - - x = Dense(1600, activation='relu')(x) - print K.int_shape(x) - - if USE_VAE: - z_mean = Dense(PARAM_SIZE)(x) - z_log_sigma_sq = Dense(PARAM_SIZE)(x) - x = Lambda(vae_sampling, output_shape=(PARAM_SIZE,), name='pre_encoder')([z_mean, z_log_sigma_sq]) - else: - x = Dense(PARAM_SIZE)(x) - x = BatchNormalization(momentum=BN_M, name='pre_encoder')(x) - print K.int_shape(x) - - x = Dense(1600, name='encoder')(x) - x = BatchNormalization(momentum=BN_M)(x) - x = Activation('relu')(x) - if DO_RATE > 0: - x = Dropout(DO_RATE)(x) - print K.int_shape(x) - - x = Dense(MAX_LENGTH * 200)(x) - print K.int_shape(x) - x = Reshape((MAX_LENGTH, 200))(x) - x = TimeDistributed(BatchNormalization(momentum=BN_M))(x) - x = Activation('relu')(x) - if DO_RATE > 0: - x = Dropout(DO_RATE)(x) - print K.int_shape(x) - - x = TimeDistributed(Dense(2000))(x) - x = TimeDistributed(BatchNormalization(momentum=BN_M))(x) - x = Activation('relu')(x) - if DO_RATE > 0: - x = Dropout(DO_RATE)(x) - print K.int_shape(x) - - x = TimeDistributed(Dense(y_shape[2] * y_shape[3], activation='sigmoid'))(x) - print K.int_shape(x) - x = Reshape((y_shape[1], y_shape[2], y_shape[3]))(x) - print K.int_shape(x) - - if USE_VAE: - model = Model(x_in, x) - model.compile(optimizer=Adam(lr=LR), loss=vae_loss) - else: - model = Model(x_in, x) - model.compile(optimizer=RMSprop(lr=LR), loss='binary_crossentropy') - - plot_model(model, to_file='model.png', show_shapes=True) -################################### -# Train -################################### -print "Compiling SubModels..." -func = K.function([model.get_layer('encoder').input, K.learning_phase()], - [model.layers[-1].output]) -enc = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output) - -rand_vecs = np.random.normal(0.0, 1.0, (NUM_RAND_SONGS, PARAM_SIZE)) -np.save('rand.npy', rand_vecs) - -def make_rand_songs(write_dir, rand_vecs): - for i in xrange(rand_vecs.shape[0]): - x_rand = rand_vecs[i:i+1] - y_song = func([x_rand, 0])[0] - midi.samples_to_midi(y_song[0], write_dir + 'rand' + str(i) + '.mid', 16, 0.25) - -def make_rand_songs_normalized(write_dir, rand_vecs): - if USE_EMBEDDING: - x_enc = np.squeeze(enc.predict(x_orig)) - else: - x_enc = np.squeeze(enc.predict(y_orig)) - - x_mean = np.mean(x_enc, axis=0) - x_stds = np.std(x_enc, axis=0) - x_cov = np.cov((x_enc - x_mean).T) - u, s, v = np.linalg.svd(x_cov) - e = np.sqrt(s) - - print "Means: ", x_mean[:6] - print "Evals: ", e[:6] - - np.save(write_dir + 'means.npy', x_mean) - np.save(write_dir + 'stds.npy', x_stds) - np.save(write_dir + 'evals.npy', e) - np.save(write_dir + 'evecs.npy', v) - - x_vecs = x_mean + np.dot(rand_vecs * e, v) - make_rand_songs(write_dir, x_vecs) - - title = '' - if '/' in write_dir: - title = 'Epoch: ' + write_dir.split('/')[-2][1:] - - plt.clf() - e[::-1].sort() - plt.title(title) - plt.bar(np.arange(e.shape[0]), e, align='center') - plt.draw() - plt.savefig(write_dir + 'evals.png') - - plt.clf() - plt.title(title) - plt.bar(np.arange(e.shape[0]), x_mean, align='center') - plt.draw() - plt.savefig(write_dir + 'means.png') - - plt.clf() - plt.title(title) - plt.bar(np.arange(e.shape[0]), x_stds, align='center') - plt.draw() - plt.savefig(write_dir + 'stds.png') - -if PLAY_ONLY: - print "Generating Songs..." - make_rand_songs_normalized('', rand_vecs) - for i in xrange(20): - x_test_song = x_train[i:i+1] - y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] - midi.samples_to_midi(y_song, 'gt' + str(i) + '.mid', 16) - exit(0) - -print "Training..." -save_config() -train_loss = [] -ofs = 0 - -for iter in xrange(NUM_EPOCHS): - if USE_EMBEDDING: - history = model.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=1) - else: - cur_ix = 0 - for i in xrange(num_songs): - end_ix = cur_ix + y_lengths[i] - for j in xrange(MAX_LENGTH): - k = (j + ofs) % (end_ix - cur_ix) - y_train[i,j] = y_samples[cur_ix + k] - cur_ix = end_ix - assert(end_ix == num_samples) - ofs += 1 - - history = model.fit(y_train, y_train, batch_size=BATCH_SIZE, epochs=1) - - loss = history.history["loss"][-1] - train_loss.append(loss) - print "Train Loss: " + str(train_loss[-1]) - - if WRITE_HISTORY: - plotScores(train_loss, 'History/Scores.png', True) - else: - plotScores(train_loss, 'Scores.png', True) - - i = iter + 1 - if i in [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450] or (i % 100 == 0): - write_dir = '' - if WRITE_HISTORY: - #Create folder to save models into - write_dir = 'History/e' + str(i) - if not os.path.exists(write_dir): - os.makedirs(write_dir) - write_dir += '/' - model.save('History/model.h5') - else: - model.save('model.h5') - print "Saved" - - if USE_EMBEDDING: - y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] - else: - y_song = model.predict(y_test_song, batch_size=BATCH_SIZE)[0] - util.samples_to_pics(write_dir + 'test', y_song) - midi.samples_to_midi(y_song, write_dir + 'test.mid', 16) - - make_rand_songs_normalized(write_dir, rand_vecs) - -print "Done" +def reg_mean_std(x): + s = K.log(K.sum(x * x)) + return s * s + + +def vae_sampling(args): + z_mean, z_log_sigma_sq = args + epsilon = K.random_normal(shape=K.shape(z_mean), mean=0.0, stddev=VAE_B1) + return z_mean + K.exp(z_log_sigma_sq * 0.5) * epsilon + + +def vae_loss(x, x_decoded_mean, z_log_sigma_sq, z_mean): + xent_loss = binary_crossentropy(x, x_decoded_mean) + kl_loss = VAE_B2 * K.mean(1 + z_log_sigma_sq - K.square(z_mean) - K.exp(z_log_sigma_sq), axis=None) + return xent_loss - kl_loss + + +def make_rand_songs(func, write_dir, rand_vecs): + for i in range(rand_vecs.shape[0]): + x_rand = rand_vecs[i:i + 1] + y_song = func([x_rand, 0])[0] + midi_utils.samples_to_midi(y_song[0], write_dir + 'rand' + str(i) + '.mid', 16, 0.25) + + +def make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs): + if USE_EMBEDDING: + x_enc = np.squeeze(enc.predict(x_orig)) + else: + x_enc = np.squeeze(enc.predict(y_orig)) + + x_mean = np.mean(x_enc, axis=0) + x_stds = np.std(x_enc, axis=0) + x_cov = np.cov((x_enc - x_mean).T) + u, s, v = np.linalg.svd(x_cov) + e = np.sqrt(s) + + print("Means: ", x_mean[:6]) + print("Evals: ", e[:6]) + + np.save(write_dir + 'means.npy', x_mean) + np.save(write_dir + 'stds.npy', x_stds) + np.save(write_dir + 'evals.npy', e) + np.save(write_dir + 'evecs.npy', v) + + x_vecs = x_mean + np.dot(rand_vecs * e, v) + make_rand_songs(func, write_dir, x_vecs) + + title = '' + if '/' in write_dir: + title = 'Epoch: ' + write_dir.split('/')[-2][1:] + + plt.clf() + e[::-1].sort() + plt.title(title) + plt.bar(np.arange(e.shape[0]), e, align='center') + plt.draw() + plt.savefig(write_dir + 'evals.png') + + plt.clf() + plt.title(title) + plt.bar(np.arange(e.shape[0]), x_mean, align='center') + plt.draw() + plt.savefig(write_dir + 'means.png') + + plt.clf() + plt.title(title) + plt.bar(np.arange(e.shape[0]), x_stds, align='center') + plt.draw() + plt.savefig(write_dir + 'stds.png') + + +def train(): + if WRITE_HISTORY: + # Create folder to save models into + if not os.path.exists('history'): + os.makedirs('history') + + ################################### + # Load Dataset + ################################### + print("Loading Data...") + y_samples = np.load('data/interim/samples.npy') + y_lengths = np.load('data/interim/lengths.npy') + num_samples = y_samples.shape[0] + num_songs = y_lengths.shape[0] + print("Loaded " + str(num_samples) + " samples from " + str(num_songs) + " songs.") + print(np.sum(y_lengths)) + assert (np.sum(y_lengths) == num_samples) + + print("Padding songs...") + x_shape = (num_songs * NUM_OFFSETS, 1) + y_shape = (num_songs * NUM_OFFSETS, MAX_LENGTH) + y_samples.shape[1:] + x_orig = np.expand_dims(np.arange(x_shape[0]), axis=-1) + y_orig = np.zeros(y_shape, dtype=y_samples.dtype) + cur_ix = 0 + for i in range(num_songs): + for ofs in range(NUM_OFFSETS): + ix = i * NUM_OFFSETS + ofs + end_ix = cur_ix + y_lengths[i] + for j in range(MAX_LENGTH): + k = (j + ofs) % (end_ix - cur_ix) + y_orig[ix, j] = y_samples[cur_ix + k] + cur_ix = end_ix + assert (end_ix == num_samples) + x_train = np.copy(x_orig) + y_train = np.copy(y_orig) + + test_ix = 0 + y_test_song = np.copy(y_train[test_ix:test_ix + 1]) + x_test_song = np.copy(x_train[test_ix:test_ix + 1]) + midi_utils.samples_to_midi(y_test_song[0], 'data/interim/gt.mid', 16) + + ################################### + # Create Model + ################################### + if CONTINUE_TRAIN or PLAY_ONLY: + print("Loading model...") + model = load_model('model.h5') # , custom_objects=custom_objects) + else: + print("Building model...") + + if USE_EMBEDDING: + x_in = Input(shape=x_shape[1:]) + print((None,) + x_shape[1:]) + x = Embedding(x_train.shape[0], PARAM_SIZE, input_length=1)(x_in) + x = Flatten(name='pre_encoder')(x) + else: + x_in = Input(shape=y_shape[1:]) + print((None,) + y_shape[1:]) + + x = Reshape((y_shape[1], -1))(x_in) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(2000, activation='relu'))(x) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(200, activation='relu'))(x) + print(K.int_shape(x)) + + x = Flatten()(x) + print(K.int_shape(x)) + + x = Dense(1600, activation='relu')(x) + print(K.int_shape(x)) + + if USE_VAE: + z_mean = Dense(PARAM_SIZE)(x) + z_log_sigma_sq = Dense(PARAM_SIZE)(x) + x = Lambda(vae_sampling, output_shape=(PARAM_SIZE,), name='pre_encoder')([z_mean, z_log_sigma_sq]) + else: + x = Dense(PARAM_SIZE)(x) + x = BatchNormalization(momentum=BN_M, name='pre_encoder')(x) + print(K.int_shape(x)) + + x = Dense(1600, name='encoder')(x) + x = BatchNormalization(momentum=BN_M)(x) + x = Activation('relu')(x) + if DO_RATE > 0: + x = Dropout(DO_RATE)(x) + print(K.int_shape(x)) + + x = Dense(MAX_LENGTH * 200)(x) + print(K.int_shape(x)) + x = Reshape((MAX_LENGTH, 200))(x) + x = TimeDistributed(BatchNormalization(momentum=BN_M))(x) + x = Activation('relu')(x) + if DO_RATE > 0: + x = Dropout(DO_RATE)(x) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(2000))(x) + x = TimeDistributed(BatchNormalization(momentum=BN_M))(x) + x = Activation('relu')(x) + if DO_RATE > 0: + x = Dropout(DO_RATE)(x) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(y_shape[2] * y_shape[3], activation='sigmoid'))(x) + print(K.int_shape(x)) + x = Reshape((y_shape[1], y_shape[2], y_shape[3]))(x) + print(K.int_shape(x)) + + if USE_VAE: + model = Model(x_in, x) + model.compile(optimizer=Adam(lr=LR), loss=vae_loss) + else: + model = Model(x_in, x) + model.compile(optimizer=RMSprop(lr=LR), loss='binary_crossentropy') + + try: + plot_model(model, to_file='results/model.png', show_shapes=True) + except OSError as e: + print(e) + + ################################### + # Train + ################################### + print("Compiling submodels...") + func = K.function([model.get_layer('encoder').input, K.learning_phase()], + [model.layers[-1].output]) + enc = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output) + + rand_vecs = np.random.normal(0.0, 1.0, (NUM_RAND_SONGS, PARAM_SIZE)) + np.save('data/interim/rand.npy', rand_vecs) + + if PLAY_ONLY: + print("Generating songs...") + make_rand_songs_normalized(enc, x_orig, y_orig, func, 'results/', rand_vecs) + for i in range(20): + x_test_song = x_train[i:i + 1] + y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] + midi_utils.samples_to_midi(y_song, 'gt' + str(i) + '.mid', 16) + exit(0) + + print("Training...") + save_config(num_songs, model) + train_loss = [] + ofs = 0 + + for iter in range(NUM_EPOCHS): + if USE_EMBEDDING: + history = model.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=1) + else: + cur_ix = 0 + for i in range(num_songs): + end_ix = cur_ix + y_lengths[i] + for j in range(MAX_LENGTH): + k = (j + ofs) % (end_ix - cur_ix) + y_train[i, j] = y_samples[cur_ix + k] + cur_ix = end_ix + assert (end_ix == num_samples) + ofs += 1 + + history = model.fit(y_train, y_train, batch_size=BATCH_SIZE, epochs=1) + + loss = history.history["loss"][-1] + train_loss.append(loss) + print("Train loss: " + str(train_loss[-1])) + + if WRITE_HISTORY: + plot_scores(train_loss, 'history/scores.png', True) + else: + plot_scores(train_loss, 'scores.png', True) + + i = iter + 1 + if i in [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450] or (i % 100 == 0): + write_dir = '' + if WRITE_HISTORY: + # Create folder to save models into + write_dir += 'history/e' + str(i) + if not os.path.exists(write_dir): + os.makedirs(write_dir) + write_dir += '/' + model.save('history/model.h5') + else: + model.save('model.h5') + print("Saved") + + if USE_EMBEDDING: + y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] + else: + y_song = model.predict(y_test_song, batch_size=BATCH_SIZE)[0] + misc.samples_to_pics(write_dir + 'test', y_song) + midi_utils.samples_to_midi(y_song, write_dir + 'test.mid', 16) + + make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs) + + print("Done") + + +if __name__ == "__main__": + train() diff --git a/util.py b/util.py deleted file mode 100644 index 39d65bb4..00000000 --- a/util.py +++ /dev/null @@ -1,104 +0,0 @@ -import numpy as np -import cv2 -import os - -def transpose_range(samples): - merged_sample = np.zeros_like(samples[0]) - for sample in samples: - merged_sample = np.maximum(merged_sample, sample) - merged_sample = np.amax(merged_sample, axis=0) - min_note = np.argmax(merged_sample) - max_note = merged_sample.shape[0] - np.argmax(merged_sample[::-1]) - return min_note, max_note - -def generate_add_centered_transpose(samples): - num_notes = samples[0].shape[1] - min_note, max_note = transpose_range(samples) - s = num_notes/2 - (max_note + min_note)/2 - out_samples = samples - out_lens = [len(samples), len(samples)] - for i in xrange(len(samples)): - out_sample = np.zeros_like(samples[i]) - out_sample[:,min_note+s:max_note+s] = samples[i][:,min_note:max_note] - out_samples.append(out_sample) - return out_samples, out_lens - -def generate_all_transpose(samples, radius=6): - num_notes = samples[0].shape[1] - min_note, max_note = transpose_range(samples) - min_shift = -min(radius, min_note) - max_shift = min(radius, num_notes - max_note) - out_samples = [] - out_lens = [] - for s in xrange(min_shift, max_shift): - for i in xrange(len(samples)): - out_sample = np.zeros_like(samples[i]) - out_sample[:,min_note+s:max_note+s] = samples[i][:,min_note:max_note] - out_samples.append(out_sample) - out_lens.append(len(samples)) - return out_samples, out_lens - -def sample_to_pic(fname, sample, thresh=None): - if thresh is not None: - inverted = np.where(sample > thresh, 0, 1) - else: - inverted = 1.0 - sample - cv2.imwrite(fname, inverted * 255) - -def samples_to_pics(dir, samples, thresh=None): - if not os.path.exists(dir): os.makedirs(dir) - for i in xrange(samples.shape[0]): - sample_to_pic(dir + '/s' + str(i) + '.png', samples[i], thresh) - -def pad_songs(y, y_lens, max_len): - y_shape = (y_lens.shape[0], max_len) + y.shape[1:] - y_train = np.zeros(y_shape, dtype=np.float32) - cur_ix = 0 - for i in xrange(y_lens.shape[0]): - end_ix = cur_ix + y_lens[i] - for j in xrange(max_len): - k = j % (end_ix - cur_ix) - y_train[i,j] = y[cur_ix + k] - cur_ix = end_ix - assert(end_ix == y.shape[0]) - return y_train - -def sample_to_pattern(sample, ix, size): - num_pats = 0 - pat_types = {} - pat_list = [] - num_samples = len(sample) if type(sample) is list else sample.shape[0] - for i in xrange(size): - j = (ix + i) % num_samples - measure = sample[j].tobytes() - if measure not in pat_types: - pat_types[measure] = num_pats - num_pats += 1 - pat_list.append(pat_types[measure]) - return str(pat_list), pat_types - -def embed_samples(samples): - note_dict = {} - n, m, p = samples.shape - samples.flags.writeable = False - e_samples = np.empty(samples.shape[:2], dtype=np.int32) - for i in xrange(n): - for j in xrange(m): - note = samples[i,j].data - if note not in note_dict: - note_dict[note] = len(note_dict) - e_samples[i,j] = note_dict[note] - samples.flags.writeable = True - lookup = np.empty((len(note_dict), p), dtype=np.float32) - for k in note_dict: - lookup[note_dict[k]] = k - return e_samples, note_dict, lookup - -def e_to_samples(e_samples, lookup): - samples = np.empty(e_samples.shape + lookup.shape[-1:], dtype=np.float32) - n, m = e_samples.shape - for i in xrange(n): - for j in xrange(m): - samples[i,j] = lookup[e_samples[i,j]] - return samples - \ No newline at end of file From a7df6ffb525e6f7791380aa1f35263c331786a0e Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Wed, 8 May 2019 16:45:59 +0200 Subject: [PATCH 02/21] Add requirements.txt with pinned dependencies --- requirements.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..05899679 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +pygame==1.9.6 +pyaudio==0.2.11 + +pydot==1.4.1 +keras==2.2.4 +pyaudio==0.2.11 +numpy==1.14.3 + +mido==1.2.9 + +argparse==1.4.0 \ No newline at end of file From 3c9877e494c904846ce66f9c3eed8088916e9980 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Wed, 8 May 2019 17:23:42 +0200 Subject: [PATCH 03/21] Beautify live edit and write READMEs to run the code --- README.md | 11 ++ data/raw/README.md | 11 ++ live_edit.py | 374 +++++++++++++++++++++++---------------------- train.py | 3 +- 4 files changed, 219 insertions(+), 180 deletions(-) create mode 100644 data/raw/README.md diff --git a/README.md b/README.md index 338023d1..79964465 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ # Composer Generates video game music using neural networks. + https://youtu.be/UWxfnNXlVy8 + +## How to run: +* Find some dataset to train on. More info on where to find datasets are in data/raw/README.md. +* Run load_songs.py. This will load all midi files from your midi files folder into data/interim/samples.npy & lengths.npy. + You can point the script to a location using the --data_folder flag one or multiple times. +* Run train.py. This will train your network and store the progress from time to time (EPOCHS_TO_SAVE to change storing frequency). + Only stops if you interrupt it or after 2000 epochs. +* Run live_edit.py --model "e1/" where "e1/" indicates the folder the stored model is in. + +Have fun! diff --git a/data/raw/README.md b/data/raw/README.md new file mode 100644 index 00000000..15d5f7f1 --- /dev/null +++ b/data/raw/README.md @@ -0,0 +1,11 @@ +How to get some midi data +------------------------- + +Get some midi files of music you are interested in to work with. + +Examples are: +* https://github.com/FlorianColombo/BachProp/tree/master/data (Bach midi files) +* https://mega.nz/#!Elg1TA7T!MXEZPzq9s9YObiUcMCoNQJmCbawZqzAkHzY4Ym6Gs_Q (Large pack of all genres of midi files) +* https://www.vgmusic.com/ (Scrape midi files from here) + +Place the midi files in this folder or any subfolder to use them as the training set. \ No newline at end of file diff --git a/live_edit.py b/live_edit.py index 9773beaa..0ba5ad7e 100644 --- a/live_edit.py +++ b/live_edit.py @@ -1,3 +1,4 @@ +import argparse import math import wave @@ -7,13 +8,17 @@ import midi_utils +import keras +from keras.models import Model, load_model +from keras import backend as K + # User constants device = "cpu" dir_name = 'history/' -sub_dir_name = 'e1/' #'e2000/' +sub_dir_name = 'e1/' sample_rate = 48000 -note_dt = 2000 # Num Samples -note_duration = 20000 # Num Samples +note_dt = 2000 # num samples +note_duration = 20000 # num samples note_decay = 5.0 / sample_rate num_params = 120 num_measures = 16 @@ -102,7 +107,7 @@ def audio_callback(in_data, frame_count, time_info, status): # Check if paused if audio_pause and status is not None: data = np.zeros((frame_count,), dtype=np.float32) - return (data.tobytes(), pyaudio.paContinue) + return data.tobytes(), pyaudio.paContinue # Find and add any notes in this time window cur_dt = note_dt @@ -154,51 +159,6 @@ def audio_callback(in_data, frame_count, time_info, status): return data.tobytes(), pyaudio.paContinue -# Keras -print("Loading Keras...") - -import keras - -print("Keras Version: " + keras.__version__) -from keras.models import Model, load_model -from keras import backend as K - -K.set_image_data_format('channels_first') - -print("Loading Encoder...") -model = load_model(dir_name + 'model.h5') -enc = K.function([model.get_layer('encoder').input, K.learning_phase()], - [model.layers[-1].output]) -enc_model = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output) - -print("Loading Statistics...") -means = np.load(dir_name + sub_dir_name + 'means.npy') -evals = np.load(dir_name + sub_dir_name + 'evals.npy') -evecs = np.load(dir_name + sub_dir_name + 'evecs.npy') -stds = np.load(dir_name + sub_dir_name + 'stds.npy') - -print("Loading Songs...") -y_samples = np.load('data/interim/samples.npy') -y_lengths = np.load('data/interim/lengths.npy') - -# Open a window -pygame.init() -pygame.font.init() -screen = pygame.display.set_mode((int(window_w), int(window_h))) -notes_surface = screen.subsurface((notes_x, notes_y, notes_w, notes_h)) -pygame.display.set_caption('MusicEdit') -font = pygame.font.SysFont("monospace", 15) - -# Start the audio stream -audio_stream = audio.open( - format=audio.get_format_from_width(2), - channels=1, - rate=sample_rate, - output=True, - stream_callback=audio_callback) -audio_stream.start_stream() - - def update_mouse_click(mouse_pos): global cur_slider_ix global cur_control_ix @@ -244,7 +204,7 @@ def update_mouse_move(mouse_pos): apply_controls() -def draw_controls(): +def draw_controls(screen): for i in range(control_num): x = controls_x + i * control_w + control_pad y = controls_y + control_pad @@ -256,7 +216,7 @@ def draw_controls(): pygame.draw.rect(screen, (0, 0, 0), (x, y, w, h), 1) -def draw_sliders(): +def draw_sliders(screen): for i in range(slider_num): slider_color = slider_colors[i % len(slider_colors)] x = sliders_x + i * slider_w @@ -297,7 +257,7 @@ def notes_to_img(notes): return np.transpose(output, (2, 1, 0)) -def draw_notes(): +def draw_notes(screen, notes_surface): pygame.surfarray.blit_array(notes_surface, notes_to_img(cur_notes)) measure_ix = int(note_time / note_h) @@ -308,133 +268,189 @@ def draw_notes(): pygame.draw.rect(screen, (255, 255, 0), (x, y, 4, note_h), 0) -# Main loop -running = True -rand_ix = 0 -cur_len = 0 -apply_controls() -while running: - # Process events - for event in pygame.event.get(): - if event.type == pygame.QUIT: # QUIT BUTTON HIT - running = False - break - - elif event.type == pygame.MOUSEBUTTONDOWN: # MOUSE BUTTON DOWN - if pygame.mouse.get_pressed()[0]: - prev_mouse_pos = pygame.mouse.get_pos() - update_mouse_click(prev_mouse_pos) - update_mouse_move(prev_mouse_pos) - elif pygame.mouse.get_pressed()[2]: - cur_params = np.zeros((num_params,), dtype=np.float32) - needs_update = True - - elif event.type == pygame.MOUSEBUTTONUP: # MOUSE BUTTON UP - mouse_pressed = 0 - prev_mouse_pos = None - - elif event.type == pygame.MOUSEMOTION and mouse_pressed > 0: # MOUSE MOTION WHILE PRESSED - update_mouse_move(pygame.mouse.get_pos()) - - elif event.type == pygame.KEYDOWN: - if event.key == pygame.K_r: # KEYDOWN R - cur_params = np.clip(np.random.normal(0.0, 1.0, (num_params,)), -num_sigmas, num_sigmas) - needs_update = True - audio_reset = True - - if event.key == pygame.K_e: # KEYDOWN E - cur_params = np.clip(np.random.normal(0.0, 2.0, (num_params,)), -num_sigmas, num_sigmas) - needs_update = True - audio_reset = True - - if event.key == pygame.K_o: # KEYDOWN O - print("RandIx: " + str(rand_ix)) - if is_ae: - example_song = y_samples[cur_len:cur_len + num_measures] - cur_notes = example_song * 255 - x = enc_model.predict(np.expand_dims(example_song, 0), batch_size=1)[0] - cur_len += y_lengths[rand_ix] - rand_ix += 1 - else: - rand_ix = np.array([rand_ix], dtype=np.int64) - x = enc_model.predict(rand_ix, batch_size=1)[0] - rand_ix = (rand_ix + 1) % model.layers[0].input_dim - - if use_pca: - cur_params = np.dot(x - means, evecs.T) / evals - else: - cur_params = (x - means) / stds - - needs_update = True - audio_reset = True - - if event.key == pygame.K_g: # KEYDOWN G - audio_pause = True - audio_reset = True - midi_utils.samples_to_midi(cur_notes, 'results/live.mid', 16, note_thresh) - save_audio = b'' - while True: - save_audio += audio_callback(None, 1024, None, None)[0] - if audio_time == 0: - break - wave_output = wave.open('results/live.wav', 'w') - wave_output.setparams((1, 2, sample_rate, 0, 'NONE', 'not compressed')) - wave_output.writeframes(save_audio) - wave_output.close() - audio_pause = False - if event.key == pygame.K_ESCAPE: # KEYDOWN ESCAPE +def play(): + global mouse_pressed + global cur_notes + global audio_pause + global needs_update + global cur_params + global prev_mouse_pos + global audio_reset + global instrument + + print("Keras version: " + keras.__version__) + + K.set_image_data_format('channels_first') + + print("Loading encoder...") + model = load_model(dir_name + 'model.h5') + enc = K.function([model.get_layer('encoder').input, K.learning_phase()], + [model.layers[-1].output]) + enc_model = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output) + + print("Loading statistics...") + means = np.load(dir_name + sub_dir_name + 'means.npy') + evals = np.load(dir_name + sub_dir_name + 'evals.npy') + evecs = np.load(dir_name + sub_dir_name + 'evecs.npy') + stds = np.load(dir_name + sub_dir_name + 'stds.npy') + + print("Loading songs...") + y_samples = np.load('data/interim/samples.npy') + y_lengths = np.load('data/interim/lengths.npy') + + # Open a window + pygame.init() + pygame.font.init() + screen = pygame.display.set_mode((int(window_w), int(window_h))) + notes_surface = screen.subsurface((notes_x, notes_y, notes_w, notes_h)) + pygame.display.set_caption('MusicEdit') + + # Start the audio stream + audio_stream = audio.open( + format=audio.get_format_from_width(2), + channels=1, + rate=sample_rate, + output=True, + stream_callback=audio_callback) + audio_stream.start_stream() + + # Main loop + running = True + rand_ix = 0 + cur_len = 0 + apply_controls() + while running: + # Process events + for event in pygame.event.get(): + if event.type == pygame.QUIT: # QUIT BUTTON HIT running = False break - if event.key == pygame.K_SPACE: # KEYDOWN SPACE - audio_pause = not audio_pause - - if event.key == pygame.K_TAB: # KEYDOWN TAB - audio_reset = True - - if event.key == pygame.K_1: # KEYDOWN 1 - instrument = 0 - - if event.key == pygame.K_2: # KEYDOWN 2 - instrument = 1 - - if event.key == pygame.K_3: # KEYDOWN 3 - instrument = 2 - - if event.key == pygame.K_4: # KEYDOWN 4 - instrument = 3 - - if event.key == pygame.K_c: # KEYDOWN C - y = np.expand_dims(np.where(cur_notes > note_thresh, 1, 0), 0) - x = enc_model.predict(y)[0] - if use_pca: - cur_params = np.dot(x - means, evecs.T) / evals - else: - cur_params = (x - means) / stds - needs_update = True - - # Check if we need an update - if needs_update: - if use_pca: - x = means + np.dot(cur_params * evals, evecs) - else: - x = means + stds * cur_params - x = np.expand_dims(x, axis=0) - y = enc([x, 0])[0][0] - cur_notes = (y * 255.0).astype(np.uint8) - needs_update = False - - # Draw to the screen - screen.fill(background_color) - draw_notes() - draw_sliders() - draw_controls() - - # Flip the screen buffer - pygame.display.flip() - pygame.time.wait(10) - -# Close the audio stream -audio_stream.stop_stream() -audio_stream.close() -audio.terminate() + elif event.type == pygame.MOUSEBUTTONDOWN: # MOUSE BUTTON DOWN + if pygame.mouse.get_pressed()[0]: + prev_mouse_pos = pygame.mouse.get_pos() + update_mouse_click(prev_mouse_pos) + update_mouse_move(prev_mouse_pos) + elif pygame.mouse.get_pressed()[2]: + cur_params = np.zeros((num_params,), dtype=np.float32) + needs_update = True + + elif event.type == pygame.MOUSEBUTTONUP: # MOUSE BUTTON UP + mouse_pressed = 0 + prev_mouse_pos = None + + elif event.type == pygame.MOUSEMOTION and mouse_pressed > 0: # MOUSE MOTION WHILE PRESSED + update_mouse_move(pygame.mouse.get_pos()) + + elif event.type == pygame.KEYDOWN: + if event.key == pygame.K_r: # KEYDOWN R + cur_params = np.clip(np.random.normal(0.0, 1.0, (num_params,)), -num_sigmas, num_sigmas) + needs_update = True + audio_reset = True + + if event.key == pygame.K_e: # KEYDOWN E + cur_params = np.clip(np.random.normal(0.0, 2.0, (num_params,)), -num_sigmas, num_sigmas) + needs_update = True + audio_reset = True + + if event.key == pygame.K_o: # KEYDOWN O + print("RandIx: " + str(rand_ix)) + if is_ae: + example_song = y_samples[cur_len:cur_len + num_measures] + cur_notes = example_song * 255 + x = enc_model.predict(np.expand_dims(example_song, 0), batch_size=1)[0] + cur_len += y_lengths[rand_ix] + rand_ix += 1 + else: + rand_ix = np.array([rand_ix], dtype=np.int64) + x = enc_model.predict(rand_ix, batch_size=1)[0] + rand_ix = (rand_ix + 1) % model.layers[0].input_dim + + if use_pca: + cur_params = np.dot(x - means, evecs.T) / evals + else: + cur_params = (x - means) / stds + + needs_update = True + audio_reset = True + + if event.key == pygame.K_g: # KEYDOWN G + audio_pause = True + audio_reset = True + midi_utils.samples_to_midi(cur_notes, 'results/live.mid', 16, note_thresh) + save_audio = b'' + while True: + save_audio += audio_callback(None, 1024, None, None)[0] + if audio_time == 0: + break + wave_output = wave.open('results/live.wav', 'w') + wave_output.setparams((1, 2, sample_rate, 0, 'NONE', 'not compressed')) + wave_output.writeframes(save_audio) + wave_output.close() + audio_pause = False + if event.key == pygame.K_ESCAPE: # KEYDOWN ESCAPE + running = False + break + + if event.key == pygame.K_SPACE: # KEYDOWN SPACE + audio_pause = not audio_pause + + if event.key == pygame.K_TAB: # KEYDOWN TAB + audio_reset = True + + if event.key == pygame.K_1: # KEYDOWN 1 + instrument = 0 + + if event.key == pygame.K_2: # KEYDOWN 2 + instrument = 1 + + if event.key == pygame.K_3: # KEYDOWN 3 + instrument = 2 + + if event.key == pygame.K_4: # KEYDOWN 4 + instrument = 3 + + if event.key == pygame.K_c: # KEYDOWN C + y = np.expand_dims(np.where(cur_notes > note_thresh, 1, 0), 0) + x = enc_model.predict(y)[0] + if use_pca: + cur_params = np.dot(x - means, evecs.T) / evals + else: + cur_params = (x - means) / stds + needs_update = True + + # Check if we need an update + if needs_update: + if use_pca: + x = means + np.dot(cur_params * evals, evecs) + else: + x = means + stds * cur_params + x = np.expand_dims(x, axis=0) + y = enc([x, 0])[0][0] + cur_notes = (y * 255.0).astype(np.uint8) + needs_update = False + + # Draw to the screen + screen.fill(background_color) + draw_notes(screen, notes_surface) + draw_sliders(screen) + draw_controls(screen) + + # Flip the screen buffer + pygame.display.flip() + pygame.time.wait(10) + + # Close the audio stream + audio_stream.stop_stream() + audio_stream.close() + audio.terminate() + + +if __name__ == "__main__": + # configure parser and parse arguments + parser = argparse.ArgumentParser(description='Play and edit music of a trained model.') + parser.add_argument('--model', default="e1/", type=str, help='The folder the model is stored in.') + + args = parser.parse_args() + sub_dir_name = args.model + play() diff --git a/train.py b/train.py index 4fbc9582..d2b5dba2 100644 --- a/train.py +++ b/train.py @@ -6,6 +6,7 @@ import midi_utils import misc +EPOCHS_TO_SAVE = [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450] NUM_EPOCHS = 2000 LR = 0.001 CONTINUE_TRAIN = False @@ -318,7 +319,7 @@ def train(): plot_scores(train_loss, 'scores.png', True) i = iter + 1 - if i in [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450] or (i % 100 == 0): + if i in EPOCHS_TO_SAVE or (i % 100 == 0): write_dir = '' if WRITE_HISTORY: # Create folder to save models into From 171018c98a2cb90b0991360502aceaa494076aa9 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Wed, 8 May 2019 17:52:48 +0200 Subject: [PATCH 04/21] Add a section on how to use the live edit mode --- README.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 79964465..226da4c8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ Generates video game music using neural networks. https://youtu.be/UWxfnNXlVy8 -## How to run: +## How to run + * Find some dataset to train on. More info on where to find datasets are in data/raw/README.md. * Run load_songs.py. This will load all midi files from your midi files folder into data/interim/samples.npy & lengths.npy. You can point the script to a location using the --data_folder flag one or multiple times. @@ -11,4 +12,29 @@ https://youtu.be/UWxfnNXlVy8 Only stops if you interrupt it or after 2000 epochs. * Run live_edit.py --model "e1/" where "e1/" indicates the folder the stored model is in. -Have fun! +## Live edit + +The live edit mode will load your trained model with is +music generator trained on the midi files you provided. +Internally, it tries to compress a song into only 120 numbers. +The sliders adjust those numbers and are ordered from most +important (left) to least important (right). Just the +top 40 are shown on screen. For more details about how +this works and other fun projects, please check out my +YouTube channel 'CodeParade'. Have fun making music! + +========================================================= + +Controls: + Right Click - Reset all sliders + 'R' - Random Song + 'T' - Randomize off-screen sliders + 'M' - Save song as .mid file + 'W' - Save song as .wav file + 'S' - Save slider values to text file + 'Space' - Play/Pause + 'Tab' - Seek to start of song + '1' - Square wave instrument + '2' - Sawtooth wave instrument + '3' - Triangle wave instrument + '4' - Sine wave instrument From 1c889ca8f34efbe4416ea20f13ec11d76fc24568 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Wed, 8 May 2019 18:01:29 +0200 Subject: [PATCH 05/21] Format controls section properly --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 226da4c8..f7ac3522 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ this works and other fun projects, please check out my YouTube channel 'CodeParade'. Have fun making music! ========================================================= - +``` Controls: Right Click - Reset all sliders 'R' - Random Song @@ -38,3 +38,4 @@ Controls: '2' - Sawtooth wave instrument '3' - Triangle wave instrument '4' - Sine wave instrument +``` From 8218a22a11a1c88e98a8327ae91cf789d4d8a8c5 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Fri, 10 May 2019 15:50:08 +0200 Subject: [PATCH 06/21] Add improvements in structure and avoid learning from percussion tracks --- live_edit.py | 7 ++++--- load_songs.py | 12 ++++++++++-- midi_utils.py | 36 ++++++++++++++++++++---------------- train.py | 51 +++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 71 insertions(+), 35 deletions(-) diff --git a/live_edit.py b/live_edit.py index 0ba5ad7e..b84ebf9e 100644 --- a/live_edit.py +++ b/live_edit.py @@ -14,7 +14,7 @@ # User constants device = "cpu" -dir_name = 'history/' +dir_name = 'results/history/' sub_dir_name = 'e1/' sample_rate = 48000 note_dt = 2000 # num samples @@ -112,11 +112,11 @@ def audio_callback(in_data, frame_count, time_info, status): # Find and add any notes in this time window cur_dt = note_dt while note_time_dt < audio_time + frame_count: - measure_ix = note_time / note_h + measure_ix = int(note_time / note_h) if measure_ix >= num_measures: break note_ix = note_time % note_h - notes = np.where(cur_notes[int(measure_ix), note_ix] >= note_thresh)[0] + notes = np.where(cur_notes[measure_ix, note_ix] >= note_thresh)[0] for note in notes: freq = 2 * 38.89 * pow(2.0, note / 12.0) / sample_rate audio_notes.append((note_time_dt, freq)) @@ -388,6 +388,7 @@ def play(): wave_output.writeframes(save_audio) wave_output.close() audio_pause = False + if event.key == pygame.K_ESCAPE: # KEYDOWN ESCAPE running = False break diff --git a/load_songs.py b/load_songs.py index eb473ad6..e0f7b1d6 100644 --- a/load_songs.py +++ b/load_songs.py @@ -9,6 +9,9 @@ def load_songs(data_folders): all_samples = [] all_lengths = [] + succ = 0 + failed = 0 + ignored = 0 print("Loading Songs...") for folder in data_folders: for root, _, files in os.walk(folder): @@ -21,13 +24,18 @@ def load_songs(data_folders): except Exception as e: print("ERROR ", path) print(e) + failed += 1 continue - if len(samples) < 8: + if len(samples) < 16: + print('WARN', path, 'Sample too short, unused') + ignored += 1 continue samples, lens = misc.generate_add_centered_transpose(samples) all_samples += samples all_lengths += lens + print('SUCCESS', path, len(samples), 'samples') + succ += 1 assert (sum(all_lengths) == len(all_samples)) print("Saving " + str(len(all_samples)) + " samples...") @@ -35,7 +43,7 @@ def load_songs(data_folders): all_lengths = np.array(all_lengths, dtype=np.uint32) np.save('data/interim/samples.npy', all_samples) np.save('data/interim/lengths.npy', all_lengths) - print("Done") + print('Done', succ, 'succeded', ignored, 'ignored', failed, 'failed of', succ + ignored + failed, 'in total') if __name__ == "__main__": diff --git a/midi_utils.py b/midi_utils.py index 144c0c78..a29c6f8b 100644 --- a/midi_utils.py +++ b/midi_utils.py @@ -7,36 +7,39 @@ def midi_to_samples(file_name): has_time_sig = False - flag_warning = False mid = MidiFile(file_name) + ticks_per_beat = mid.ticks_per_beat ticks_per_measure = 4 * ticks_per_beat - for i, track in enumerate(mid.tracks): + for track in mid.tracks: for msg in track: if msg.type == 'time_signature': new_tpm = msg.numerator * ticks_per_beat * 4 / msg.denominator if has_time_sig and new_tpm != ticks_per_measure: - flag_warning = True + raise NotImplementedError('Multiple time signatures not supported') ticks_per_measure = new_tpm has_time_sig = True - if flag_warning: - print(" ^^^^^^ WARNING ^^^^^^") - print(" " + file_name) - print(" Detected multiple distinct time signatures.") - print(" ^^^^^^ WARNING ^^^^^^") - return [] all_notes = {} - for i, track in enumerate(mid.tracks): + for track in mid.tracks: abs_time = 0 for msg in track: abs_time += msg.time + + # programs 0x70-0x7F are percussion and sound effects + # we ignore them + if msg.type == 'program_change' and msg.program >= 0x70: + break + if msg.type == 'note_on': if msg.velocity == 0: continue note = msg.note - (128 - num_notes) / 2 - assert (0 <= note < num_notes) + if note < 0 or note >= num_notes: + print('Ignoring', file_name, 'note is outside 0-%d range' % (num_notes - 1)) + return [] + if note not in all_notes: all_notes[note] = [] else: @@ -57,18 +60,19 @@ def midi_to_samples(file_name): for note in all_notes: for start, end in all_notes[note]: - sample_ix = start / samples_per_measure # find the sample/measure this belongs into + sample_ix = int(start / samples_per_measure) # find the sample/measure this belongs into + assert (sample_ix < 1024 * 1024) while len(samples) <= sample_ix: samples.append(np.zeros((samples_per_measure, num_notes), dtype=np.uint8)) - sample = samples[int(sample_ix)] - start_ix = start - sample_ix * samples_per_measure + sample = samples[sample_ix] + start_ix = int(start - sample_ix * samples_per_measure) if False: end_ix = min(end - sample_ix * samples_per_measure, samples_per_measure) while start_ix < end_ix: - sample[int(start_ix), int(note)] = 1 + sample[start_ix, note] = 1 start_ix += 1 else: - sample[int(start_ix), int(note)] = 1 + sample[start_ix, int(note)] = 1 return samples diff --git a/train.py b/train.py index d2b5dba2..ec920943 100644 --- a/train.py +++ b/train.py @@ -64,7 +64,7 @@ def plot_scores(scores, f_name, on_top=True): def save_config(num_songs, model): - with open('config.txt', 'w') as fout: + with open('results/config.txt', 'w') as fout: fout.write('LR: ' + str(LR) + '\n') fout.write('BN_M: ' + str(BN_M) + '\n') fout.write('BATCH_SIZE: ' + str(BATCH_SIZE) + '\n') @@ -98,7 +98,15 @@ def make_rand_songs(func, write_dir, rand_vecs): midi_utils.samples_to_midi(y_song[0], write_dir + 'rand' + str(i) + '.mid', 16, 0.25) -def make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs): +def make_msee(enc, x_orig, y_orig, write_dir): + """ + means, stddevs, evals, evecs + :param enc: + :param x_orig: + :param y_orig: + :param write_dir: + :return: + """ if USE_EMBEDDING: x_enc = np.squeeze(enc.predict(x_orig)) else: @@ -117,6 +125,11 @@ def make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs): np.save(write_dir + 'stds.npy', x_stds) np.save(write_dir + 'evals.npy', e) np.save(write_dir + 'evecs.npy', v) + return x_mean, x_stds, e, v + + +def make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs): + x_mean, x_stds, e, v = make_msee(enc, x_orig, y_orig, write_dir) x_vecs = x_mean + np.dot(rand_vecs * e, v) make_rand_songs(func, write_dir, x_vecs) @@ -146,15 +159,19 @@ def make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs): def train(): - if WRITE_HISTORY: + if not os.path.exists('results'): + os.makedirs('results') + if WRITE_HISTORY and not os.path.exists('results/history'): # Create folder to save models into - if not os.path.exists('history'): - os.makedirs('history') + os.makedirs('history') ################################### # Load Dataset ################################### print("Loading Data...") + if not os.path.exists('data/interim/samples.npy') or not os.path.exists('data/interim/lengths.npy'): + print('No input data found, run load_songs.py first') + exit(1) y_samples = np.load('data/interim/samples.npy') y_lengths = np.load('data/interim/lengths.npy') num_samples = y_samples.shape[0] @@ -191,7 +208,7 @@ def train(): ################################### if CONTINUE_TRAIN or PLAY_ONLY: print("Loading model...") - model = load_model('model.h5') # , custom_objects=custom_objects) + model = load_model('results/model.h5') else: print("Building model...") @@ -285,7 +302,7 @@ def train(): for i in range(20): x_test_song = x_train[i:i + 1] y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] - midi_utils.samples_to_midi(y_song, 'gt' + str(i) + '.mid', 16) + midi_utils.samples_to_midi(y_song, 'results/gt' + str(i) + '.mid', 16) exit(0) print("Training...") @@ -314,22 +331,28 @@ def train(): print("Train loss: " + str(train_loss[-1])) if WRITE_HISTORY: - plot_scores(train_loss, 'history/scores.png', True) + plot_scores(train_loss, 'results/history/scores.png', True) else: - plot_scores(train_loss, 'scores.png', True) + plot_scores(train_loss, 'results/scores.png', True) i = iter + 1 - if i in EPOCHS_TO_SAVE or (i % 100 == 0): - write_dir = '' + if i in EPOCHS_TO_SAVE or (i % 100 == 0) or i == NUM_EPOCHS: + write_dir = 'results/' if WRITE_HISTORY: # Create folder to save models into - write_dir += 'history/e' + str(i) + write_dir += 'results/history/e' + str(i) if not os.path.exists(write_dir): os.makedirs(write_dir) write_dir += '/' - model.save('history/model.h5') + model.save('results/history/model.h5') else: - model.save('model.h5') + model.save('results/model.h5') + + # Save output on last epoch + if i == NUM_EPOCHS: + model.save('results/model.h5') + make_msee(enc, x_orig, y_orig, 'results/') + print("Saved") if USE_EMBEDDING: From f226a59d104c3e010b01d92fbd94b504f85ca292 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Fri, 10 May 2019 16:21:44 +0200 Subject: [PATCH 07/21] Fix path to write the history to --- train.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/train.py b/train.py index ec920943..9fc87469 100644 --- a/train.py +++ b/train.py @@ -337,7 +337,7 @@ def train(): i = iter + 1 if i in EPOCHS_TO_SAVE or (i % 100 == 0) or i == NUM_EPOCHS: - write_dir = 'results/' + write_dir = '' if WRITE_HISTORY: # Create folder to save models into write_dir += 'results/history/e' + str(i) From 58c73248e84334ad2666bc0952e714067c001886 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Fri, 10 May 2019 16:22:03 +0200 Subject: [PATCH 08/21] Write simple notebook to run the code in colab --- run_pipeline.ipynb | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 run_pipeline.ipynb diff --git a/run_pipeline.ipynb b/run_pipeline.ipynb new file mode 100644 index 00000000..33dbc8bf --- /dev/null +++ b/run_pipeline.ipynb @@ -0,0 +1,79 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Run the full pipeline to train a composer model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Uncomment the line below and run this cell to get your data from github into colab (only runnable in colab, not ordinary jupyter notebook):\n", + "! git clone https://github.com/benelot/Composer.git && mv Composer/* . && rm Composer -r" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from load_songs import load_songs\n", + "\n", + "data_folder = 'data/raw'\n", + "load_songs(data_folder)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from train import train\n", + "\n", + "train()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from live_edit import play\n", + "\n", + "sub_dir_name = 'e1/'\n", + "play()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} From 0b574f7efc63361db9200d24d4c6743cf8db0ff2 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Mon, 13 May 2019 12:50:50 +0200 Subject: [PATCH 09/21] Comment code and extract autoencoder model --- README.md | 12 +- live_edit.py => composer.py | 184 +++++++++++++------ load_songs.py | 42 ++++- midi_utils.py | 80 +++++++-- misc.py | 66 ++----- models.py | 89 ++++++++++ music_utils.py | 51 ++++++ requirements.txt | 1 + train.py | 345 ++++++++++++++++-------------------- 9 files changed, 545 insertions(+), 325 deletions(-) rename live_edit.py => composer.py (72%) create mode 100644 models.py create mode 100644 music_utils.py diff --git a/README.md b/README.md index f7ac3522..d2af7ae3 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ Generates video game music using neural networks. https://youtu.be/UWxfnNXlVy8 +## How to install + +* Install dependencies in python3 by running `pip install -r requirements.txt`. + ## How to run * Find some dataset to train on. More info on where to find datasets are in data/raw/README.md. @@ -10,13 +14,13 @@ https://youtu.be/UWxfnNXlVy8 You can point the script to a location using the --data_folder flag one or multiple times. * Run train.py. This will train your network and store the progress from time to time (EPOCHS_TO_SAVE to change storing frequency). Only stops if you interrupt it or after 2000 epochs. -* Run live_edit.py --model "e1/" where "e1/" indicates the folder the stored model is in. +* Run composer.py --model "e1/" where "e1/" indicates the folder the stored model is in. -## Live edit +## Composer -The live edit mode will load your trained model with is +The Composer script will load your trained model with is music generator trained on the midi files you provided. -Internally, it tries to compress a song into only 120 numbers. +Internally, the model tries to compress a song into only 120 numbers. The sliders adjust those numbers and are ordered from most important (left) to least important (right). Just the top 40 are shown on screen. For more details about how diff --git a/live_edit.py b/composer.py similarity index 72% rename from live_edit.py rename to composer.py index b84ebf9e..6f855753 100644 --- a/live_edit.py +++ b/composer.py @@ -1,3 +1,10 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Neural composer: Play and edit music generated by the trained model. +""" + import argparse import math import wave @@ -13,7 +20,6 @@ from keras import backend as K # User constants -device = "cpu" dir_name = 'results/history/' sub_dir_name = 'e1/' sample_rate = 48000 @@ -23,7 +29,7 @@ num_params = 120 num_measures = 16 num_sigmas = 5.0 -note_thresh = 32 +note_threshold = 32 use_pca = True is_ae = True @@ -50,7 +56,7 @@ control_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] control_inits = [0.75, 0.5, 0.5] -# Derived constants +# derived constants notes_w = notes_cols * (note_w + note_pad * 2) notes_h = notes_rows * (note_h + note_pad * 2) sliders_w = notes_w @@ -67,7 +73,7 @@ controls_x = int((window_w - controls_w) / 2) controls_y = notes_h + sliders_h -# Global variables +# global variables prev_mouse_pos = None mouse_pressed = 0 cur_slider_ix = 0 @@ -75,11 +81,11 @@ volume = 3000 instrument = 0 needs_update = True -cur_params = np.zeros((num_params,), dtype=np.float32) -cur_notes = np.zeros((num_measures, note_h, note_w), dtype=np.uint8) +current_params = np.zeros((num_params,), dtype=np.float32) +current_notes = np.zeros((num_measures, note_h, note_w), dtype=np.uint8) cur_controls = np.array(control_inits, dtype=np.float32) -# Setup audio stream +# setup audio stream audio = pyaudio.PyAudio() audio_notes = [] audio_time = 0 @@ -90,13 +96,21 @@ def audio_callback(in_data, frame_count, time_info, status): + """ + Audio call-back to influence playback of music with input. + :param in_data: + :param frame_count: + :param time_info: + :param status: + :return: + """ global audio_time global audio_notes global audio_reset global note_time global note_time_dt - # Check if needs restart + # check if needs restart if audio_reset: audio_notes = [] audio_time = 0 @@ -104,26 +118,26 @@ def audio_callback(in_data, frame_count, time_info, status): note_time_dt = 0 audio_reset = False - # Check if paused + # check if paused if audio_pause and status is not None: data = np.zeros((frame_count,), dtype=np.float32) return data.tobytes(), pyaudio.paContinue - # Find and add any notes in this time window + # find and add any notes in this time window cur_dt = note_dt while note_time_dt < audio_time + frame_count: measure_ix = int(note_time / note_h) if measure_ix >= num_measures: break note_ix = note_time % note_h - notes = np.where(cur_notes[measure_ix, note_ix] >= note_thresh)[0] + notes = np.where(current_notes[measure_ix, note_ix] >= note_threshold)[0] for note in notes: freq = 2 * 38.89 * pow(2.0, note / 12.0) / sample_rate audio_notes.append((note_time_dt, freq)) note_time += 1 note_time_dt += cur_dt - # Generate the tones + # generate the tones data = np.zeros((frame_count,), dtype=np.float32) for t, f in audio_notes: x = np.arange(audio_time - t, audio_time + frame_count - t) @@ -144,22 +158,27 @@ def audio_callback(in_data, frame_count, time_info, status): data += w data = np.clip(data, -32000, 32000).astype(np.int16) - # Remove notes that are too old + # remove notes that are too old audio_time += frame_count audio_notes = [(t, f) for t, f in audio_notes if audio_time < t + note_duration] - # Reset if loop occurs + # reset if loop occurs if note_time / note_h >= num_measures: audio_time = 0 note_time = 0 note_time_dt = 0 audio_notes = [] - # Return the sound clip + # return the sound clip return data.tobytes(), pyaudio.paContinue def update_mouse_click(mouse_pos): + """ + Update control stated based on where the mouse clicked. + :param mouse_pos: + :return: + """ global cur_slider_ix global cur_control_ix global mouse_pressed @@ -178,25 +197,36 @@ def update_mouse_click(mouse_pos): def apply_controls(): - global note_thresh + """ + Change parameters based on controls. + :return: + """ + global note_threshold global note_dt global volume - note_thresh = (1.0 - cur_controls[0]) * 200 + 10 + note_threshold = (1.0 - cur_controls[0]) * 200 + 10 note_dt = (1.0 - cur_controls[1]) * 1800 + 200 volume = cur_controls[2] * 6000 def update_mouse_move(mouse_pos): + """ + Update sliders/controls based on mouse input. + :param mouse_pos: + :return: + """ global needs_update if mouse_pressed == 1: + # change sliders y = (mouse_pos[1] - sliders_y) if 0 <= y <= slider_h: val = (float(y) / slider_h - 0.5) * (num_sigmas * 2) - cur_params[int(cur_slider_ix)] = val + current_params[int(cur_slider_ix)] = val needs_update = True elif mouse_pressed == 2: + # change controls x = (mouse_pos[0] - (controls_x + cur_control_ix * control_w)) if control_pad <= x <= control_w - control_pad: val = float(x - control_pad) / (control_w - control_pad * 2) @@ -205,6 +235,11 @@ def update_mouse_move(mouse_pos): def draw_controls(screen): + """ + Draw volume and threshold controls to screen. + :param screen: + :return: + """ for i in range(control_num): x = controls_x + i * control_w + control_pad y = controls_y + control_pad @@ -217,6 +252,11 @@ def draw_controls(screen): def draw_sliders(screen): + """ + Draw sliders to screen. + :param screen: + :return: + """ for i in range(slider_num): slider_color = slider_colors[i % len(slider_colors)] x = sliders_x + i * slider_w @@ -235,11 +275,17 @@ def draw_sliders(screen): col = (0, 0, 0) if j - num_sigmas == 0 else slider_color pygame.draw.line(screen, col, (cx_1, ly), (cx_2, ly)) - py = y + int((cur_params[i] / (num_sigmas * 2) + 0.5) * slider_h) + py = y + int((current_params[i] / (num_sigmas * 2) + 0.5) * slider_h) pygame.draw.circle(screen, slider_color, (int(cx), int(py)), int((slider_w - tick_pad) / 2)) -def notes_to_img(notes): +def get_pianoroll_from_notes(notes): + """ + Draw piano roll of notes. + :param notes: + :return: + """ + output = np.full((3, int(notes_h), int(notes_w)), 64, dtype=np.uint8) for i in range(notes_rows): @@ -249,8 +295,8 @@ def notes_to_img(notes): ix = i * notes_cols + j measure = np.rot90(notes[ix]) - played_only = np.where(measure >= note_thresh, 255, 0) - output[0, y:y + note_h, x:x + note_w] = np.minimum(measure * (255.0 / note_thresh), 255.0) + played_only = np.where(measure >= note_threshold, 255, 0) + output[0, y:y + note_h, x:x + note_w] = np.minimum(measure * (255.0 / note_threshold), 255.0) output[1, y:y + note_h, x:x + note_w] = played_only output[2, y:y + note_h, x:x + note_w] = played_only @@ -258,7 +304,14 @@ def notes_to_img(notes): def draw_notes(screen, notes_surface): - pygame.surfarray.blit_array(notes_surface, notes_to_img(cur_notes)) + """ + Draw pianoroll notes to screen. + :param screen: + :param notes_surface: + :return: + """ + + pygame.surfarray.blit_array(notes_surface, get_pianoroll_from_notes(current_notes)) measure_ix = int(note_time / note_h) note_ix = note_time % note_h @@ -270,10 +323,10 @@ def draw_notes(screen, notes_surface): def play(): global mouse_pressed - global cur_notes + global current_notes global audio_pause global needs_update - global cur_params + global current_params global prev_mouse_pos global audio_reset global instrument @@ -284,9 +337,9 @@ def play(): print("Loading encoder...") model = load_model(dir_name + 'model.h5') - enc = K.function([model.get_layer('encoder').input, K.learning_phase()], - [model.layers[-1].output]) - enc_model = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output) + encoder = Model(inputs=model.input, outputs=model.get_layer('encoder').output) + decoder = K.function([model.get_layer('decoder').input, K.learning_phase()], + [model.layers[-1].output]) print("Loading statistics...") means = np.load(dir_name + sub_dir_name + 'means.npy') @@ -298,14 +351,14 @@ def play(): y_samples = np.load('data/interim/samples.npy') y_lengths = np.load('data/interim/lengths.npy') - # Open a window + # open a window pygame.init() pygame.font.init() screen = pygame.display.set_mode((int(window_w), int(window_h))) notes_surface = screen.subsurface((notes_x, notes_y, notes_w, notes_h)) - pygame.display.set_caption('MusicEdit') + pygame.display.set_caption('Neural Composer') - # Start the audio stream + # start the audio stream audio_stream = audio.open( format=audio.get_format_from_width(2), channels=1, @@ -314,13 +367,13 @@ def play(): stream_callback=audio_callback) audio_stream.start_stream() - # Main loop + # main loop running = True rand_ix = 0 cur_len = 0 apply_controls() while running: - # Process events + # process events for event in pygame.event.get(): if event.type == pygame.QUIT: # QUIT BUTTON HIT running = False @@ -332,7 +385,7 @@ def play(): update_mouse_click(prev_mouse_pos) update_mouse_move(prev_mouse_pos) elif pygame.mouse.get_pressed()[2]: - cur_params = np.zeros((num_params,), dtype=np.float32) + current_params = np.zeros((num_params,), dtype=np.float32) needs_update = True elif event.type == pygame.MOUSEBUTTONUP: # MOUSE BUTTON UP @@ -344,40 +397,49 @@ def play(): elif event.type == pygame.KEYDOWN: if event.key == pygame.K_r: # KEYDOWN R - cur_params = np.clip(np.random.normal(0.0, 1.0, (num_params,)), -num_sigmas, num_sigmas) + # generate random song + current_params = np.clip(np.random.normal(0.0, 1.0, (num_params,)), -num_sigmas, num_sigmas) needs_update = True audio_reset = True if event.key == pygame.K_e: # KEYDOWN E - cur_params = np.clip(np.random.normal(0.0, 2.0, (num_params,)), -num_sigmas, num_sigmas) + # generate random song with larger variance + current_params = np.clip(np.random.normal(0.0, 2.0, (num_params,)), -num_sigmas, num_sigmas) needs_update = True audio_reset = True if event.key == pygame.K_o: # KEYDOWN O - print("RandIx: " + str(rand_ix)) + print("Random Index: " + str(rand_ix)) if is_ae: example_song = y_samples[cur_len:cur_len + num_measures] - cur_notes = example_song * 255 - x = enc_model.predict(np.expand_dims(example_song, 0), batch_size=1)[0] + current_notes = example_song * 255 + x = encoder.predict(np.expand_dims(example_song, 0), batch_size=1)[0] cur_len += y_lengths[rand_ix] rand_ix += 1 else: rand_ix = np.array([rand_ix], dtype=np.int64) - x = enc_model.predict(rand_ix, batch_size=1)[0] + x = encoder.predict(rand_ix, batch_size=1)[0] rand_ix = (rand_ix + 1) % model.layers[0].input_dim if use_pca: - cur_params = np.dot(x - means, evecs.T) / evals + current_params = np.dot(x - means, evecs.T) / evals else: - cur_params = (x - means) / stds + current_params = (x - means) / stds needs_update = True audio_reset = True - if event.key == pygame.K_g: # KEYDOWN G + if event.key == pygame.K_m: # KEYDOWN M + # save song as midi + audio_pause = True + audio_reset = True + midi_utils.samples_to_midi(current_notes, 'results/live.mid', note_threshold) + audio_pause = False + + if event.key == pygame.K_w: # KEYDOWN W + # save song as wave audio_pause = True audio_reset = True - midi_utils.samples_to_midi(cur_notes, 'results/live.mid', 16, note_thresh) save_audio = b'' while True: save_audio += audio_callback(None, 1024, None, None)[0] @@ -390,58 +452,66 @@ def play(): audio_pause = False if event.key == pygame.K_ESCAPE: # KEYDOWN ESCAPE + # exit application running = False break if event.key == pygame.K_SPACE: # KEYDOWN SPACE + # toggle pause/play audio audio_pause = not audio_pause if event.key == pygame.K_TAB: # KEYDOWN TAB + # reset audio playing audio_reset = True if event.key == pygame.K_1: # KEYDOWN 1 + # play instrument 0 instrument = 0 if event.key == pygame.K_2: # KEYDOWN 2 + # play instrument 1 instrument = 1 if event.key == pygame.K_3: # KEYDOWN 3 + # play instrument 2 instrument = 2 if event.key == pygame.K_4: # KEYDOWN 4 + # play instrument 3 instrument = 3 if event.key == pygame.K_c: # KEYDOWN C - y = np.expand_dims(np.where(cur_notes > note_thresh, 1, 0), 0) - x = enc_model.predict(y)[0] + # + y = np.expand_dims(np.where(current_notes > note_threshold, 1, 0), 0) + x = encoder.predict(y)[0] if use_pca: - cur_params = np.dot(x - means, evecs.T) / evals + current_params = np.dot(x - means, evecs.T) / evals else: - cur_params = (x - means) / stds + current_params = (x - means) / stds needs_update = True - # Check if we need an update + # check if params were changed so that a new song should be generated if needs_update: if use_pca: - x = means + np.dot(cur_params * evals, evecs) + x = means + np.dot(current_params * evals, evecs) else: - x = means + stds * cur_params + x = means + stds * current_params x = np.expand_dims(x, axis=0) - y = enc([x, 0])[0][0] - cur_notes = (y * 255.0).astype(np.uint8) + y = decoder([x, 0])[0][0] + current_notes = (y * 255.0).astype(np.uint8) needs_update = False - # Draw to the screen + # draw GUI to the screen screen.fill(background_color) draw_notes(screen, notes_surface) draw_sliders(screen) draw_controls(screen) - # Flip the screen buffer + # flip the screen buffer pygame.display.flip() pygame.time.wait(10) - # Close the audio stream + # if app is exited, close the audio stream audio_stream.stop_stream() audio_stream.close() audio.terminate() @@ -449,7 +519,7 @@ def play(): if __name__ == "__main__": # configure parser and parse arguments - parser = argparse.ArgumentParser(description='Play and edit music of a trained model.') + parser = argparse.ArgumentParser(description='Neural Composer: Play and edit music of a trained model.') parser.add_argument('--model', default="e1/", type=str, help='The folder the model is stored in.') args = parser.parse_args() diff --git a/load_songs.py b/load_songs.py index e0f7b1d6..60c23e03 100644 --- a/load_songs.py +++ b/load_songs.py @@ -1,24 +1,43 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Load songs from midi and save them in numpy format. +""" + import midi_utils import os -import misc +import music_utils import numpy as np import argparse def load_songs(data_folders): + """ + Load the songs from the data folders and turn them into a dataset of samples/pitches and lengths of the tones. + :param data_folders: + :return: + """ all_samples = [] all_lengths = [] - succ = 0 + + # keep some statistics + succeeded = 0 failed = 0 ignored = 0 - print("Loading Songs...") + + # load songs + print("Loading songs...") + # walk folders and look for midi files for folder in data_folders: for root, _, files in os.walk(folder): for file in files: path = root + "\\" + file if not (path.endswith('.mid') or path.endswith('.midi')): continue + + # turn midi into samples try: samples = midi_utils.midi_to_samples(path) except Exception as e: @@ -26,24 +45,29 @@ def load_songs(data_folders): print(e) failed += 1 continue + + # if the midi does not produce the minimal number of sample/measures, we skip it if len(samples) < 16: print('WARN', path, 'Sample too short, unused') ignored += 1 continue - samples, lens = misc.generate_add_centered_transpose(samples) + # transpose samples (center them in full range) + samples, lengths = music_utils.generate_centered_transpose(samples) all_samples += samples - all_lengths += lens + all_lengths += lengths print('SUCCESS', path, len(samples), 'samples') - succ += 1 + succeeded += 1 + + assert (sum(all_lengths) == len(all_samples)) # assert equal number of samples and lengths - assert (sum(all_lengths) == len(all_samples)) + # save all to disk print("Saving " + str(len(all_samples)) + " samples...") - all_samples = np.array(all_samples, dtype=np.uint8) + all_samples = np.array(all_samples, dtype=np.uint8) # reduce size when saving all_lengths = np.array(all_lengths, dtype=np.uint32) np.save('data/interim/samples.npy', all_samples) np.save('data/interim/lengths.npy', all_lengths) - print('Done', succ, 'succeded', ignored, 'ignored', failed, 'failed of', succ + ignored + failed, 'in total') + print('Done: ', succeeded, 'succeded,', ignored, 'ignored,', failed, 'failed of', succeeded + ignored + failed, 'in total') if __name__ == "__main__": diff --git a/midi_utils.py b/midi_utils.py index a29c6f8b..18e061cb 100644 --- a/midi_utils.py +++ b/midi_utils.py @@ -1,3 +1,10 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Utils to read and write midi. +""" + from mido import MidiFile, MidiTrack, Message import numpy as np @@ -5,84 +12,127 @@ samples_per_measure = 96 -def midi_to_samples(file_name): +def midi_to_samples(file_name, encode_length=False): + """ + Turn a midi file into a sample. + :param file_name: + :param encode_length: + :return: + """ has_time_sig = False mid = MidiFile(file_name) - ticks_per_beat = mid.ticks_per_beat - ticks_per_measure = 4 * ticks_per_beat + ticks_per_beat = mid.ticks_per_beat # get ticks per beat + ticks_per_measure = 4 * ticks_per_beat # get ticks per measure + # detect the time signature of the midi for track in mid.tracks: for msg in track: if msg.type == 'time_signature': - new_tpm = msg.numerator * ticks_per_beat * 4 / msg.denominator + new_tpm = ticks_per_measure * msg.numerator / msg.denominator # adapt ticks per measure of this specific song + + # skip if we find multiple time signatures in the song if has_time_sig and new_tpm != ticks_per_measure: raise NotImplementedError('Multiple time signatures not supported') + ticks_per_measure = new_tpm has_time_sig = True + # turn tracks into pianoroll representation all_notes = {} for track in mid.tracks: + abs_time = 0 for msg in track: - abs_time += msg.time + abs_time += msg.time # step time forward - # programs 0x70-0x7F are percussion and sound effects - # we ignore them + # we skip programs 0x70-0x7F which are percussion and sound effects if msg.type == 'program_change' and msg.program >= 0x70: break + # if a note starts if msg.type == 'note_on': + + # we skip notes without a velocity (basically how strong a note is played to make it sound human) if msg.velocity == 0: continue + + # transform the notes into the 96 heights note = msg.note - (128 - num_notes) / 2 - if note < 0 or note >= num_notes: + if note < 0 or note >= num_notes: # ignore a note that is outside of that range print('Ignoring', file_name, 'note is outside 0-%d range' % (num_notes - 1)) return [] + # count the number of played notes per pitch if note not in all_notes: all_notes[note] = [] else: single_note = all_notes[note][-1] if len(single_note) == 1: single_note.append(single_note[0] + 1) + + # store the time a note has been played all_notes[note].append([abs_time * samples_per_measure / ticks_per_measure]) + + # if a note ends elif msg.type == 'note_off': + + # if the note has already ended before (note_on, note_off, note_off), we skip the event if len(all_notes[note][-1]) != 1: continue + # store the time a note stops playing all_notes[note][-1].append(abs_time * samples_per_measure / ticks_per_measure) + # any note did not end playing, we end it one time tick later for note in all_notes: for start_end in all_notes[note]: if len(start_end) == 1: start_end.append(start_end[0] + 1) - samples = [] + # put the notes into their respective sample/measure panel (96 x 96) + samples = [] for note in all_notes: for start, end in all_notes[note]: sample_ix = int(start / samples_per_measure) # find the sample/measure this belongs into assert (sample_ix < 1024 * 1024) + + # fill in silence until the appropriate sample/measure is reached while len(samples) <= sample_ix: samples.append(np.zeros((samples_per_measure, num_notes), dtype=np.uint8)) + + # get sample and find its start to encode the start of the note sample = samples[sample_ix] start_ix = int(start - sample_ix * samples_per_measure) - if False: + sample[start_ix, int(note)] = 1 + + # play note until it ends if we encode length + if encode_length: end_ix = min(end - sample_ix * samples_per_measure, samples_per_measure) while start_ix < end_ix: - sample[start_ix, note] = 1 + sample[start_ix, int(note)] = 1 start_ix += 1 - else: - sample[start_ix, int(note)] = 1 + return samples -def samples_to_midi(samples, file_name, ticks_per_sample, threshold=0.5): +def samples_to_midi(samples, file_name, threshold=0.5): + """ + Turn the samples/measures back into midi. + :param samples: + :param file_name: + :param threshold: + :return: + """ + # TODO: Encode the certainties of the notes into the volume of the midi for the notes that are above threshold + mid = MidiFile() track = MidiTrack() mid.tracks.append(track) + ticks_per_beat = mid.ticks_per_beat ticks_per_measure = 4 * ticks_per_beat ticks_per_sample = ticks_per_measure / samples_per_measure + abs_time = 0 last_time = 0 for sample in samples: @@ -90,10 +140,12 @@ def samples_to_midi(samples, file_name, ticks_per_sample, threshold=0.5): abs_time += ticks_per_sample for x in range(sample.shape[1]): note = x + (128 - num_notes) / 2 + if sample[y, x] >= threshold and (y == 0 or sample[y - 1, x] < threshold): delta_time = abs_time - last_time track.append(Message('note_on', note=int(note), velocity=127, time=int(delta_time))) last_time = abs_time + if sample[y, x] >= threshold and (y == sample.shape[0] - 1 or sample[y + 1, x] < threshold): delta_time = abs_time - last_time track.append(Message('note_off', note=int(note), velocity=127, time=int(delta_time))) diff --git a/misc.py b/misc.py index 512dd3e3..d7bc910c 100644 --- a/misc.py +++ b/misc.py @@ -1,59 +1,29 @@ -import numpy as np -import cv2 -import os - - -def transpose_range(samples): - merged_sample = np.zeros_like(samples[0]) - for sample in samples: - merged_sample = np.maximum(merged_sample, sample) - merged_sample = np.amax(merged_sample, axis=0) - min_note = np.argmax(merged_sample) - max_note = merged_sample.shape[0] - np.argmax(merged_sample[::-1]) - return min_note, max_note - +#!/usr/bin/env python +# -*- coding: utf-8 -*- -def generate_add_centered_transpose(samples): - num_notes = samples[0].shape[1] - min_note, max_note = transpose_range(samples) - s = num_notes / 2 - (max_note + min_note) / 2 - out_samples = samples - out_lengths = [len(samples), len(samples)] - for i in range(len(samples)): - out_sample = np.zeros_like(samples[i]) - out_sample[:, min_note + int(s):max_note + int(s)] = samples[i][:, min_note:max_note] - out_samples.append(out_sample) - return out_samples, out_lengths +""" +Miscelaneous utility functions. +""" - -def generate_all_transpose(samples, radius=6): - num_notes = samples[0].shape[1] - min_note, max_note = transpose_range(samples) - min_shift = -min(radius, min_note) - max_shift = min(radius, num_notes - max_note) - out_samples = [] - out_lengths = [] - for s in range(min_shift, max_shift): - for i in range(len(samples)): - out_sample = np.zeros_like(samples[i]) - out_sample[:, min_note + s:max_note + s] = samples[i][:, min_note:max_note] - out_samples.append(out_sample) - out_lengths.append(len(samples)) - return out_samples, out_lengths +import os +import cv2 +import numpy as np -def sample_to_pic(fname, sample, thresh=None): - if thresh is not None: - inverted = np.where(sample > thresh, 0, 1) +def plot_sample(file_name, sample, threshold=None): + if threshold is not None: + inverted = np.where(sample > threshold, 0, 1) else: inverted = 1.0 - sample - cv2.imwrite(fname, inverted * 255) + cv2.imwrite(file_name, inverted * 255) + +def plot_samples(folder, samples, threshold=None): + if not os.path.exists(folder): + os.makedirs(folder) -def samples_to_pics(dir, samples, thresh=None): - if not os.path.exists(dir): os.makedirs(dir) for i in range(samples.shape[0]): - sample_to_pic(dir + '/s' + str(i) + '.png', samples[i], thresh) + plot_sample(folder + '/s' + str(i) + '.png', samples[i], threshold) def pad_songs(y, y_lens, max_len): @@ -109,4 +79,4 @@ def e_to_samples(e_samples, lookup): for i in range(n): for j in range(m): samples[i, j] = lookup[e_samples[i, j]] - return samples + return samples \ No newline at end of file diff --git a/models.py b/models.py new file mode 100644 index 00000000..0af80f36 --- /dev/null +++ b/models.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +The models used for music generation. +""" + +from keras import backend as K +from keras.layers import Input, Dense, Activation, Dropout, Flatten, Reshape, TimeDistributed, Lambda +from keras.layers.embeddings import Embedding +from keras.layers.normalization import BatchNormalization +from keras.models import Model + + +def vae_sampling(args): + z_mean, z_log_sigma_sq, vae_b1 = args + epsilon = K.random_normal(shape=K.shape(z_mean), mean=0.0, stddev=vae_b1) + return z_mean + K.exp(z_log_sigma_sq * 0.5) * epsilon + + +def create_model(input_shape, latent_space_size, dropout_rate, max_windows, batchnorm_momentum, use_vae=False, vae_b1=0.02, use_embedding=False, embedding_input_shape=None, embedding_shape=None): + + if use_embedding: + x_in = Input(shape=embedding_input_shape) + print((None,) + embedding_input_shape) + + x = Embedding(embedding_shape, latent_space_size, input_length=1)(x_in) + x = Flatten(name='encoder')(x) + else: + x_in = Input(shape=input_shape) + print((None,) + input_shape) + + x = Reshape((input_shape[0], -1))(x_in) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(2000, activation='relu'))(x) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(200, activation='relu'))(x) + print(K.int_shape(x)) + + x = Flatten()(x) + print(K.int_shape(x)) + + x = Dense(1600, activation='relu')(x) + print(K.int_shape(x)) + + if use_vae: + z_mean = Dense(latent_space_size)(x) + z_log_sigma_sq = Dense(latent_space_size)(x) + x = Lambda(vae_sampling, output_shape=(latent_space_size,), name='encoder')([z_mean, z_log_sigma_sq, vae_b1]) + else: + x = Dense(latent_space_size)(x) + x = BatchNormalization(momentum=batchnorm_momentum, name='encoder')(x) + print(K.int_shape(x)) + + # LATENT SPACE + + x = Dense(1600, name='decoder')(x) + x = BatchNormalization(momentum=batchnorm_momentum)(x) + x = Activation('relu')(x) + if dropout_rate > 0: + x = Dropout(dropout_rate)(x) + print(K.int_shape(x)) + + x = Dense(max_windows * 200)(x) + print(K.int_shape(x)) + x = Reshape((max_windows, 200))(x) + x = TimeDistributed(BatchNormalization(momentum=batchnorm_momentum))(x) + x = Activation('relu')(x) + if dropout_rate > 0: + x = Dropout(dropout_rate)(x) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(2000))(x) + x = TimeDistributed(BatchNormalization(momentum=batchnorm_momentum))(x) + x = Activation('relu')(x) + if dropout_rate > 0: + x = Dropout(dropout_rate)(x) + print(K.int_shape(x)) + + x = TimeDistributed(Dense(input_shape[1] * input_shape[2], activation='sigmoid'))(x) + print(K.int_shape(x)) + x = Reshape((input_shape[0], input_shape[1], input_shape[2]))(x) + print(K.int_shape(x)) + + model = Model(x_in, x) + + return model diff --git a/music_utils.py b/music_utils.py new file mode 100644 index 00000000..ab6ced68 --- /dev/null +++ b/music_utils.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Utils to edit music. +""" + +import numpy as np + + +def find_sample_range(samples): + """ + Find sample range. + :param samples: + :return: + """ + + # merge all samples + merged_sample = np.zeros_like(samples[0]) + for sample in samples: + merged_sample = np.maximum(merged_sample, sample) + + # get all pitches being played + merged_sample = np.amax(merged_sample, axis=0) + + # get min and max note + min_note = np.argmax(merged_sample) + max_note = merged_sample.shape[0] - np.argmax(merged_sample[::-1]) + return min_note, max_note + + +def generate_centered_transpose(samples): + """ + Center samples towards the middle of the pitch range. + :param samples: + :return: + """ + num_notes = samples[0].shape[1] + min_note, max_note = find_sample_range(samples) + + # find deviation from pitch center + center_deviation = num_notes / 2 - (max_note + min_note) / 2 + out_samples = samples + out_lengths = [len(samples), len(samples)] + + # center every sample by moving it by center_deviation + for i in range(len(samples)): + out_sample = np.zeros_like(samples[i]) + out_sample[:, min_note + int(center_deviation):max_note + int(center_deviation)] = samples[i][:, min_note:max_note] + out_samples.append(out_sample) + return out_samples, out_lengths diff --git a/requirements.txt b/requirements.txt index 05899679..0db5d285 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +matplotlib==3.0.2 pygame==1.9.6 pyaudio==0.2.11 diff --git a/train.py b/train.py index 9fc87469..a2cf71fb 100644 --- a/train.py +++ b/train.py @@ -1,3 +1,10 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Train a autoencoder model to learn to encode songs. +""" + import random import numpy as np @@ -5,49 +12,54 @@ import midi_utils import misc +import models + +# Load Keras +print("Loading keras...") +import os +import keras + +print("Keras version: " + keras.__version__) + +from keras.models import Model, load_model +from keras.utils import plot_model +from keras import backend as K +from keras.losses import binary_crossentropy +from keras.optimizers import Adam, RMSprop EPOCHS_TO_SAVE = [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450] NUM_EPOCHS = 2000 -LR = 0.001 +LEARNING_RATE = 0.001 # learning rate CONTINUE_TRAIN = False -PLAY_ONLY = False -USE_EMBEDDING = False -USE_VAE = False +GENERATE_ONLY = False + WRITE_HISTORY = True NUM_RAND_SONGS = 10 -DO_RATE = 0.1 -BN_M = 0.9 + +# network params +DROPOUT_RATE = 0.1 +BATCHNORM_MOMENTUM = 0.9 +USE_EMBEDDING = False +USE_VAE = False VAE_B1 = 0.02 VAE_B2 = 0.1 BATCH_SIZE = 350 -MAX_LENGTH = 16 -PARAM_SIZE = 120 +MAX_WINDOWS = 16 # the maximal number of measures a song can have +LATENT_SPACE_SIZE = 120 NUM_OFFSETS = 16 if USE_EMBEDDING else 1 -################################### -# Load Keras -################################### -print("Loading Keras...") -import os -import keras - -print("Keras Version: " + keras.__version__) -from keras.layers import Input, Dense, Activation, Dropout, Flatten, Reshape, TimeDistributed, Lambda -from keras.layers.embeddings import Embedding -from keras.layers.normalization import BatchNormalization -from keras.losses import binary_crossentropy -from keras.models import Model, load_model -from keras.optimizers import Adam, RMSprop -from keras.utils import plot_model -from keras import backend as K - K.set_image_data_format('channels_first') # Fix the random seed so that training comparisons are easier to make np.random.seed(0) random.seed(0) +def vae_loss(x, x_decoded_mean, z_log_sigma_sq, z_mean): + xent_loss = binary_crossentropy(x, x_decoded_mean) + kl_loss = VAE_B2 * K.mean(1 + z_log_sigma_sq - K.square(z_mean) - K.exp(z_log_sigma_sq), axis=None) + return xent_loss - kl_loss + def plot_scores(scores, f_name, on_top=True): plt.clf() @@ -64,38 +76,28 @@ def plot_scores(scores, f_name, on_top=True): def save_config(num_songs, model): - with open('results/config.txt', 'w') as fout: - fout.write('LR: ' + str(LR) + '\n') - fout.write('BN_M: ' + str(BN_M) + '\n') - fout.write('BATCH_SIZE: ' + str(BATCH_SIZE) + '\n') - fout.write('NUM_OFFSETS: ' + str(NUM_OFFSETS) + '\n') - fout.write('DO_RATE: ' + str(DO_RATE) + '\n') - fout.write('num_songs: ' + str(num_songs) + '\n') - fout.write('optimizer: ' + type(model.optimizer).__name__ + '\n') + with open('results/config.txt', 'w') as file_out: + file_out.write('LEARNING_RATE: ' + str(LEARNING_RATE) + '\n') + file_out.write('BATCHNORM_MOMENTUM: ' + str(BATCHNORM_MOMENTUM) + '\n') + file_out.write('BATCH_SIZE: ' + str(BATCH_SIZE) + '\n') + file_out.write('NUM_OFFSETS: ' + str(NUM_OFFSETS) + '\n') + file_out.write('DROPOUT_RATE: ' + str(DROPOUT_RATE) + '\n') + file_out.write('num_songs: ' + str(num_songs) + '\n') + file_out.write('optimizer: ' + type(model.optimizer).__name__ + '\n') -def reg_mean_std(x): - s = K.log(K.sum(x * x)) - return s * s - - -def vae_sampling(args): - z_mean, z_log_sigma_sq = args - epsilon = K.random_normal(shape=K.shape(z_mean), mean=0.0, stddev=VAE_B1) - return z_mean + K.exp(z_log_sigma_sq * 0.5) * epsilon - - -def vae_loss(x, x_decoded_mean, z_log_sigma_sq, z_mean): - xent_loss = binary_crossentropy(x, x_decoded_mean) - kl_loss = VAE_B2 * K.mean(1 + z_log_sigma_sq - K.square(z_mean) - K.exp(z_log_sigma_sq), axis=None) - return xent_loss - kl_loss - - -def make_rand_songs(func, write_dir, rand_vecs): - for i in range(rand_vecs.shape[0]): - x_rand = rand_vecs[i:i + 1] +def generate_random_songs(func, write_dir, rand_vectors): + """ + Generate random songs using random latent vectors. + :param func: + :param write_dir: + :param rand_vectors: + :return: + """ + for i in range(rand_vectors.shape[0]): + x_rand = rand_vectors[i:i + 1] y_song = func([x_rand, 0])[0] - midi_utils.samples_to_midi(y_song[0], write_dir + 'rand' + str(i) + '.mid', 16, 0.25) + midi_utils.samples_to_midi(y_song[0], write_dir + 'rand' + str(i) + '.mid', 0.25) def make_msee(enc, x_orig, y_orig, write_dir): @@ -128,11 +130,11 @@ def make_msee(enc, x_orig, y_orig, write_dir): return x_mean, x_stds, e, v -def make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs): - x_mean, x_stds, e, v = make_msee(enc, x_orig, y_orig, write_dir) +def generate_random_songs_normalized(encoder, x_orig, y_orig, decoder, write_dir, random_vectors): + x_mean, x_stds, e, v = make_msee(encoder, x_orig, y_orig, write_dir) - x_vecs = x_mean + np.dot(rand_vecs * e, v) - make_rand_songs(func, write_dir, x_vecs) + x_vectors = x_mean + np.dot(random_vectors * e, v) + generate_random_songs(decoder, write_dir, x_vectors) title = '' if '/' in write_dir: @@ -159,173 +161,129 @@ def make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs): def train(): + """ + Train model. + :return: + """ + + # Create folders to save models into if not os.path.exists('results'): os.makedirs('results') if WRITE_HISTORY and not os.path.exists('results/history'): - # Create folder to save models into os.makedirs('history') - ################################### - # Load Dataset - ################################### + # Load dataset into memory print("Loading Data...") if not os.path.exists('data/interim/samples.npy') or not os.path.exists('data/interim/lengths.npy'): - print('No input data found, run load_songs.py first') + print('No input data found, run load_songs.py first.') exit(1) + y_samples = np.load('data/interim/samples.npy') y_lengths = np.load('data/interim/lengths.npy') - num_samples = y_samples.shape[0] - num_songs = y_lengths.shape[0] - print("Loaded " + str(num_samples) + " samples from " + str(num_songs) + " songs.") + + samples_qty = y_samples.shape[0] + songs_qty = y_lengths.shape[0] + print("Loaded " + str(samples_qty) + " samples from " + str(songs_qty) + " songs.") print(np.sum(y_lengths)) - assert (np.sum(y_lengths) == num_samples) + assert (np.sum(y_lengths) == samples_qty) - print("Padding songs...") - x_shape = (num_songs * NUM_OFFSETS, 1) - y_shape = (num_songs * NUM_OFFSETS, MAX_LENGTH) + y_samples.shape[1:] + print("Preparing song samples, padding songs...") + x_shape = (songs_qty * NUM_OFFSETS, 1) # for embedding x_orig = np.expand_dims(np.arange(x_shape[0]), axis=-1) - y_orig = np.zeros(y_shape, dtype=y_samples.dtype) - cur_ix = 0 - for i in range(num_songs): - for ofs in range(NUM_OFFSETS): - ix = i * NUM_OFFSETS + ofs - end_ix = cur_ix + y_lengths[i] - for j in range(MAX_LENGTH): - k = (j + ofs) % (end_ix - cur_ix) - y_orig[ix, j] = y_samples[cur_ix + k] - cur_ix = end_ix - assert (end_ix == num_samples) + + y_shape = (songs_qty * NUM_OFFSETS, MAX_WINDOWS) + y_samples.shape[1:] # (songs_qty, max number of windows, window pitch qty, window beats per measure) + y_orig = np.zeros(y_shape, dtype=y_samples.dtype) # prepare dataset array + + # fill in measure of songs into input windows for network + song_start_ix = 0 + song_end_ix = y_lengths[0] + for song_ix in range(songs_qty): + for offset in range(NUM_OFFSETS): + ix = song_ix * NUM_OFFSETS + offset # calculate the index of the song with its offset + song_end_ix = song_start_ix + y_lengths[song_ix] # get song end ix + for window_ix in range(MAX_WINDOWS): # get a maximum number of measures from a song + song_measure_ix = (window_ix + offset) % y_lengths[song_ix] # chosen measure of song to be placed in window (modulo song length) + y_orig[ix, window_ix] = y_samples[song_start_ix + song_measure_ix] # move measure into window + song_start_ix = song_end_ix # new song start index is previous song end index + assert (song_end_ix == samples_qty) x_train = np.copy(x_orig) y_train = np.copy(y_orig) + # copy some song from the samples and write it to midi again test_ix = 0 - y_test_song = np.copy(y_train[test_ix:test_ix + 1]) - x_test_song = np.copy(x_train[test_ix:test_ix + 1]) - midi_utils.samples_to_midi(y_test_song[0], 'data/interim/gt.mid', 16) - - ################################### - # Create Model - ################################### - if CONTINUE_TRAIN or PLAY_ONLY: + y_test_song = np.copy(y_train[test_ix: test_ix + 1]) + x_test_song = np.copy(x_train[test_ix: test_ix + 1]) + midi_utils.samples_to_midi(y_test_song[0], 'data/interim/gt.mid') + + # create model + if CONTINUE_TRAIN or GENERATE_ONLY: print("Loading model...") model = load_model('results/model.h5') else: print("Building model...") - if USE_EMBEDDING: - x_in = Input(shape=x_shape[1:]) - print((None,) + x_shape[1:]) - x = Embedding(x_train.shape[0], PARAM_SIZE, input_length=1)(x_in) - x = Flatten(name='pre_encoder')(x) - else: - x_in = Input(shape=y_shape[1:]) - print((None,) + y_shape[1:]) - - x = Reshape((y_shape[1], -1))(x_in) - print(K.int_shape(x)) - - x = TimeDistributed(Dense(2000, activation='relu'))(x) - print(K.int_shape(x)) - - x = TimeDistributed(Dense(200, activation='relu'))(x) - print(K.int_shape(x)) - - x = Flatten()(x) - print(K.int_shape(x)) - - x = Dense(1600, activation='relu')(x) - print(K.int_shape(x)) - - if USE_VAE: - z_mean = Dense(PARAM_SIZE)(x) - z_log_sigma_sq = Dense(PARAM_SIZE)(x) - x = Lambda(vae_sampling, output_shape=(PARAM_SIZE,), name='pre_encoder')([z_mean, z_log_sigma_sq]) - else: - x = Dense(PARAM_SIZE)(x) - x = BatchNormalization(momentum=BN_M, name='pre_encoder')(x) - print(K.int_shape(x)) - - x = Dense(1600, name='encoder')(x) - x = BatchNormalization(momentum=BN_M)(x) - x = Activation('relu')(x) - if DO_RATE > 0: - x = Dropout(DO_RATE)(x) - print(K.int_shape(x)) - - x = Dense(MAX_LENGTH * 200)(x) - print(K.int_shape(x)) - x = Reshape((MAX_LENGTH, 200))(x) - x = TimeDistributed(BatchNormalization(momentum=BN_M))(x) - x = Activation('relu')(x) - if DO_RATE > 0: - x = Dropout(DO_RATE)(x) - print(K.int_shape(x)) - - x = TimeDistributed(Dense(2000))(x) - x = TimeDistributed(BatchNormalization(momentum=BN_M))(x) - x = Activation('relu')(x) - if DO_RATE > 0: - x = Dropout(DO_RATE)(x) - print(K.int_shape(x)) - - x = TimeDistributed(Dense(y_shape[2] * y_shape[3], activation='sigmoid'))(x) - print(K.int_shape(x)) - x = Reshape((y_shape[1], y_shape[2], y_shape[3]))(x) - print(K.int_shape(x)) + model = models.create_model(input_shape=y_shape[1:], + latent_space_size=LATENT_SPACE_SIZE, + dropout_rate=DROPOUT_RATE, + max_windows=MAX_WINDOWS, + batchnorm_momentum=BATCHNORM_MOMENTUM, + use_vae=USE_VAE, + vae_b1=VAE_B1, + use_embedding=USE_EMBEDDING, + embedding_input_shape=x_shape[1:], + embedding_shape=x_train.shape[0]) if USE_VAE: - model = Model(x_in, x) - model.compile(optimizer=Adam(lr=LR), loss=vae_loss) + model.compile(optimizer=Adam(lr=LEARNING_RATE), loss=vae_loss) else: - model = Model(x_in, x) - model.compile(optimizer=RMSprop(lr=LR), loss='binary_crossentropy') + model.compile(optimizer=RMSprop(lr=LEARNING_RATE), loss='binary_crossentropy') + # plot model with graphvis if installed try: plot_model(model, to_file='results/model.png', show_shapes=True) except OSError as e: print(e) - ################################### - # Train - ################################### - print("Compiling submodels...") - func = K.function([model.get_layer('encoder').input, K.learning_phase()], - [model.layers[-1].output]) - enc = Model(inputs=model.input, outputs=model.get_layer('pre_encoder').output) + # train + print("Referencing sub-models...") + decoder = K.function([model.get_layer('decoder').input, K.learning_phase()], + [model.layers[-1].output]) + encoder = Model(inputs=model.input, outputs=model.get_layer('encoder').output) - rand_vecs = np.random.normal(0.0, 1.0, (NUM_RAND_SONGS, PARAM_SIZE)) - np.save('data/interim/rand.npy', rand_vecs) + random_vectors = np.random.normal(0.0, 1.0, (NUM_RAND_SONGS, LATENT_SPACE_SIZE)) + np.save('data/interim/rand.npy', random_vectors) - if PLAY_ONLY: + if GENERATE_ONLY: print("Generating songs...") - make_rand_songs_normalized(enc, x_orig, y_orig, func, 'results/', rand_vecs) - for i in range(20): - x_test_song = x_train[i:i + 1] + generate_random_songs_normalized(encoder, x_orig, y_orig, decoder, 'results/', random_vectors) + for save_epoch in range(20): + x_test_song = x_train[save_epoch:save_epoch + 1] y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] - midi_utils.samples_to_midi(y_song, 'results/gt' + str(i) + '.mid', 16) + midi_utils.samples_to_midi(y_song, 'results/gt' + str(save_epoch) + '.mid') exit(0) - print("Training...") - save_config(num_songs, model) + print("Training model...") + save_config(songs_qty, model) train_loss = [] - ofs = 0 + offset = 0 - for iter in range(NUM_EPOCHS): + for epoch in range(NUM_EPOCHS): if USE_EMBEDDING: history = model.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=1) else: - cur_ix = 0 - for i in range(num_songs): - end_ix = cur_ix + y_lengths[i] - for j in range(MAX_LENGTH): - k = (j + ofs) % (end_ix - cur_ix) - y_train[i, j] = y_samples[cur_ix + k] - cur_ix = end_ix - assert (end_ix == num_samples) - ofs += 1 - - history = model.fit(y_train, y_train, batch_size=BATCH_SIZE, epochs=1) - + song_start_ix = 0 + for song_ix in range(songs_qty): + song_end_ix = song_start_ix + y_lengths[song_ix] + for window_ix in range(MAX_WINDOWS): + song_measure_ix = (window_ix + offset) % (song_end_ix - song_start_ix) + y_train[song_ix, window_ix] = y_samples[song_start_ix + song_measure_ix] + song_start_ix = song_end_ix + assert (song_end_ix == samples_qty) + offset += 1 + + history = model.fit(y_train, y_train, batch_size=BATCH_SIZE, epochs=1) # train model on reconstruction loss + + # store last loss loss = history.history["loss"][-1] train_loss.append(loss) print("Train loss: " + str(train_loss[-1])) @@ -335,12 +293,12 @@ def train(): else: plot_scores(train_loss, 'results/scores.png', True) - i = iter + 1 - if i in EPOCHS_TO_SAVE or (i % 100 == 0) or i == NUM_EPOCHS: + save_epoch = epoch + 1 + if save_epoch in EPOCHS_TO_SAVE or (save_epoch % 100 == 0) or save_epoch == NUM_EPOCHS: write_dir = '' if WRITE_HISTORY: # Create folder to save models into - write_dir += 'results/history/e' + str(i) + write_dir += 'results/history/e' + str(save_epoch) if not os.path.exists(write_dir): os.makedirs(write_dir) write_dir += '/' @@ -349,22 +307,23 @@ def train(): model.save('results/model.h5') # Save output on last epoch - if i == NUM_EPOCHS: + if save_epoch == NUM_EPOCHS: model.save('results/model.h5') - make_msee(enc, x_orig, y_orig, 'results/') + make_msee(encoder, x_orig, y_orig, 'results/') - print("Saved") + print("...Saved.") if USE_EMBEDDING: y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] else: y_song = model.predict(y_test_song, batch_size=BATCH_SIZE)[0] - misc.samples_to_pics(write_dir + 'test', y_song) - midi_utils.samples_to_midi(y_song, write_dir + 'test.mid', 16) - make_rand_songs_normalized(enc, x_orig, y_orig, func, write_dir, rand_vecs) + misc.plot_samples(write_dir + 'test', y_song) + midi_utils.samples_to_midi(y_song, write_dir + 'test.mid') + + generate_random_songs_normalized(encoder, x_orig, y_orig, decoder, write_dir, random_vectors) - print("Done") + print("...Done.") if __name__ == "__main__": From 60c4301f5e3713afe94e18517b555d362201b7ca Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Mon, 13 May 2019 13:09:59 +0200 Subject: [PATCH 10/21] Represent paths in a more generic way --- load_songs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/load_songs.py b/load_songs.py index 60c23e03..a929385b 100644 --- a/load_songs.py +++ b/load_songs.py @@ -33,7 +33,7 @@ def load_songs(data_folders): for folder in data_folders: for root, _, files in os.walk(folder): for file in files: - path = root + "\\" + file + path = os.path.join(root, file) if not (path.endswith('.mid') or path.endswith('.midi')): continue From 6a96b56881b23460f3fd7ec49f8f185963612a24 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Mon, 13 May 2019 13:56:00 +0200 Subject: [PATCH 11/21] Keep data interim folder in repository --- data/interim/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/interim/.gitkeep diff --git a/data/interim/.gitkeep b/data/interim/.gitkeep new file mode 100644 index 00000000..e69de29b From bd8082e3feaa0194e231572acd1fa3a729dde404 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Mon, 13 May 2019 14:02:44 +0200 Subject: [PATCH 12/21] Fix folder making --- misc.py | 2 +- train.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/misc.py b/misc.py index d7bc910c..5dd1aeb0 100644 --- a/misc.py +++ b/misc.py @@ -79,4 +79,4 @@ def e_to_samples(e_samples, lookup): for i in range(n): for j in range(m): samples[i, j] = lookup[e_samples[i, j]] - return samples \ No newline at end of file + return samples diff --git a/train.py b/train.py index a2cf71fb..16680190 100644 --- a/train.py +++ b/train.py @@ -170,7 +170,7 @@ def train(): if not os.path.exists('results'): os.makedirs('results') if WRITE_HISTORY and not os.path.exists('results/history'): - os.makedirs('history') + os.makedirs('results/history') # Load dataset into memory print("Loading Data...") From e06c742c9a783342649f87e29a1349788a3a2b10 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Mon, 13 May 2019 14:11:47 +0200 Subject: [PATCH 13/21] Print current epoch and total epoch while training --- train.py | 1 + 1 file changed, 1 insertion(+) diff --git a/train.py b/train.py index 16680190..ae0a606d 100644 --- a/train.py +++ b/train.py @@ -268,6 +268,7 @@ def train(): offset = 0 for epoch in range(NUM_EPOCHS): + print("Training epoch: ", epoch, "of", NUM_EPOCHS) if USE_EMBEDDING: history = model.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=1) else: From cbe4ab96ed623af9b78318bbd6c657082e59121c Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Mon, 13 May 2019 15:39:09 +0200 Subject: [PATCH 14/21] Set instrument of the midi output --- midi_utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/midi_utils.py b/midi_utils.py index 18e061cb..ace0ccc3 100644 --- a/midi_utils.py +++ b/midi_utils.py @@ -133,6 +133,14 @@ def samples_to_midi(samples, file_name, threshold=0.5): ticks_per_measure = 4 * ticks_per_beat ticks_per_sample = ticks_per_measure / samples_per_measure + # add instrument for track + # https://en.wikipedia.org/wiki/General_MIDI#Program_change_events + piano = 1 + honky_tonk_piano = 4 + xylophone = 14 + program_message = Message('program_change', program=piano, time=0, channel=0) + track.append(program_message) + abs_time = 0 last_time = 0 for sample in samples: From 1ebd6cf2fadab99826c43e1760e4c09c2bc2351c Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Wed, 15 May 2019 11:16:31 +0200 Subject: [PATCH 15/21] Refactor code --- README.md | 4 +- composer.py | 48 +++---- midi_utils.py | 11 +- misc.py | 82 ----------- models.py | 17 ++- plot_utils.py | 26 ++++ load_songs.py => preprocess_songs.py | 12 +- train.py | 199 ++++++++++++++++----------- 8 files changed, 201 insertions(+), 198 deletions(-) delete mode 100644 misc.py create mode 100644 plot_utils.py rename load_songs.py => preprocess_songs.py (82%) diff --git a/README.md b/README.md index d2af7ae3..bc0d7091 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ https://youtu.be/UWxfnNXlVy8 ## How to run * Find some dataset to train on. More info on where to find datasets are in data/raw/README.md. -* Run load_songs.py. This will load all midi files from your midi files folder into data/interim/samples.npy & lengths.npy. - You can point the script to a location using the --data_folder flag one or multiple times. +* Run preprocess_songs.py. This will load all midi files from your midi files folder data/raw/ into data/interim/samples.npy & lengths.npy. + You can point the script to a location using the --data_folder flag one or multiple times to append more folders. * Run train.py. This will train your network and store the progress from time to time (EPOCHS_TO_SAVE to change storing frequency). Only stops if you interrupt it or after 2000 epochs. * Run composer.py --model "e1/" where "e1/" indicates the folder the stored model is in. diff --git a/composer.py b/composer.py index 6f855753..77b03445 100644 --- a/composer.py +++ b/composer.py @@ -33,6 +33,7 @@ use_pca = True is_ae = True +# colors background_color = (210, 210, 210) edge_color = (60, 60, 60) slider_colors = [(90, 20, 20), (90, 90, 20), (20, 90, 20), (20, 90, 90), (20, 20, 90), (90, 20, 90)] @@ -341,11 +342,11 @@ def play(): decoder = K.function([model.get_layer('decoder').input, K.learning_phase()], [model.layers[-1].output]) - print("Loading statistics...") - means = np.load(dir_name + sub_dir_name + 'means.npy') - evals = np.load(dir_name + sub_dir_name + 'evals.npy') - evecs = np.load(dir_name + sub_dir_name + 'evecs.npy') - stds = np.load(dir_name + sub_dir_name + 'stds.npy') + print("Loading gaussian/pca statistics...") + latent_means = np.load(dir_name + sub_dir_name + 'latent_means.npy') + latent_stds = np.load(dir_name + sub_dir_name + 'latent_stds.npy') + latent_pca_values = np.load(dir_name + sub_dir_name + 'latent_pca_values.npy') + latent_pca_vectors = np.load(dir_name + sub_dir_name + 'latent_pca_vectors.npy') print("Loading songs...") y_samples = np.load('data/interim/samples.npy') @@ -369,7 +370,7 @@ def play(): # main loop running = True - rand_ix = 0 + random_song_ix = 0 cur_len = 0 apply_controls() while running: @@ -409,22 +410,23 @@ def play(): audio_reset = True if event.key == pygame.K_o: # KEYDOWN O - print("Random Index: " + str(rand_ix)) + # check how well the autoencoder can reconstruct a random song + print("Random Song Index: " + str(random_song_ix)) if is_ae: example_song = y_samples[cur_len:cur_len + num_measures] current_notes = example_song * 255 - x = encoder.predict(np.expand_dims(example_song, 0), batch_size=1)[0] - cur_len += y_lengths[rand_ix] - rand_ix += 1 + latent_x = encoder.predict(np.expand_dims(example_song, 0), batch_size=1)[0] + cur_len += y_lengths[random_song_ix] + random_song_ix += 1 else: - rand_ix = np.array([rand_ix], dtype=np.int64) - x = encoder.predict(rand_ix, batch_size=1)[0] - rand_ix = (rand_ix + 1) % model.layers[0].input_dim + random_song_ix = np.array([random_song_ix], dtype=np.int64) + latent_x = encoder.predict(random_song_ix, batch_size=1)[0] + random_song_ix = (random_song_ix + 1) % model.layers[0].input_dim if use_pca: - current_params = np.dot(x - means, evecs.T) / evals + current_params = np.dot(latent_x - latent_means, latent_pca_vectors.T) / latent_pca_values else: - current_params = (x - means) / stds + current_params = (latent_x - latent_means) / latent_stds needs_update = True audio_reset = True @@ -483,21 +485,21 @@ def play(): if event.key == pygame.K_c: # KEYDOWN C # y = np.expand_dims(np.where(current_notes > note_threshold, 1, 0), 0) - x = encoder.predict(y)[0] + latent_x = encoder.predict(y)[0] if use_pca: - current_params = np.dot(x - means, evecs.T) / evals + current_params = np.dot(latent_x - latent_means, latent_pca_vectors.T) / latent_pca_values else: - current_params = (x - means) / stds + current_params = (latent_x - latent_means) / latent_stds needs_update = True # check if params were changed so that a new song should be generated if needs_update: if use_pca: - x = means + np.dot(current_params * evals, evecs) + latent_x = latent_means + np.dot(current_params * latent_pca_values, latent_pca_vectors) else: - x = means + stds * current_params - x = np.expand_dims(x, axis=0) - y = decoder([x, 0])[0][0] + latent_x = latent_means + latent_stds * current_params + latent_x = np.expand_dims(latent_x, axis=0) + y = decoder([latent_x, 0])[0][0] current_notes = (y * 255.0).astype(np.uint8) needs_update = False @@ -520,7 +522,7 @@ def play(): if __name__ == "__main__": # configure parser and parse arguments parser = argparse.ArgumentParser(description='Neural Composer: Play and edit music of a trained model.') - parser.add_argument('--model', default="e1/", type=str, help='The folder the model is stored in.') + parser.add_argument('--model', default=sub_dir_name, type=str, help='The folder the model is stored in.') args = parser.parse_args() sub_dir_name = args.model diff --git a/midi_utils.py b/midi_utils.py index ace0ccc3..ab44d2f8 100644 --- a/midi_utils.py +++ b/midi_utils.py @@ -8,15 +8,14 @@ from mido import MidiFile, MidiTrack, Message import numpy as np -num_notes = 96 -samples_per_measure = 96 - -def midi_to_samples(file_name, encode_length=False): +def midi_to_samples(file_name, encode_length=False, num_notes=96, samples_per_measure=96): """ Turn a midi file into a sample. :param file_name: :param encode_length: + :param num_notes: + :param samples_per_measure: :return: """ has_time_sig = False @@ -115,12 +114,14 @@ def midi_to_samples(file_name, encode_length=False): return samples -def samples_to_midi(samples, file_name, threshold=0.5): +def samples_to_midi(samples, file_name, threshold=0.5, num_notes=96, samples_per_measure=96): """ Turn the samples/measures back into midi. :param samples: :param file_name: :param threshold: + :param num_notes: + :param samples_per_measure: :return: """ # TODO: Encode the certainties of the notes into the volume of the midi for the notes that are above threshold diff --git a/misc.py b/misc.py deleted file mode 100644 index 5dd1aeb0..00000000 --- a/misc.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Miscelaneous utility functions. -""" - -import os -import cv2 -import numpy as np - - -def plot_sample(file_name, sample, threshold=None): - if threshold is not None: - inverted = np.where(sample > threshold, 0, 1) - else: - inverted = 1.0 - sample - cv2.imwrite(file_name, inverted * 255) - - -def plot_samples(folder, samples, threshold=None): - if not os.path.exists(folder): - os.makedirs(folder) - - for i in range(samples.shape[0]): - plot_sample(folder + '/s' + str(i) + '.png', samples[i], threshold) - - -def pad_songs(y, y_lens, max_len): - y_shape = (y_lens.shape[0], max_len) + y.shape[1:] - y_train = np.zeros(y_shape, dtype=np.float32) - cur_ix = 0 - for i in range(y_lens.shape[0]): - end_ix = cur_ix + y_lens[i] - for j in range(max_len): - k = j % (end_ix - cur_ix) - y_train[i, j] = y[cur_ix + k] - cur_ix = end_ix - assert (end_ix == y.shape[0]) - return y_train - - -def sample_to_pattern(sample, ix, size): - num_pats = 0 - pat_types = {} - pat_list = [] - num_samples = len(sample) if type(sample) is list else sample.shape[0] - for i in range(size): - j = (ix + i) % num_samples - measure = sample[j].tobytes() - if measure not in pat_types: - pat_types[measure] = num_pats - num_pats += 1 - pat_list.append(pat_types[measure]) - return str(pat_list), pat_types - - -def embed_samples(samples): - note_dict = {} - n, m, p = samples.shape - samples.flags.writeable = False - e_samples = np.empty(samples.shape[:2], dtype=np.int32) - for i in range(n): - for j in range(m): - note = samples[i, j].data - if note not in note_dict: - note_dict[note] = len(note_dict) - e_samples[i, j] = note_dict[note] - samples.flags.writeable = True - lookup = np.empty((len(note_dict), p), dtype=np.float32) - for k in note_dict: - lookup[note_dict[k]] = k - return e_samples, note_dict, lookup - - -def e_to_samples(e_samples, lookup): - samples = np.empty(e_samples.shape + lookup.shape[-1:], dtype=np.float32) - n, m = e_samples.shape - for i in range(n): - for j in range(m): - samples[i, j] = lookup[e_samples[i, j]] - return samples diff --git a/models.py b/models.py index 0af80f36..2e9a94f5 100644 --- a/models.py +++ b/models.py @@ -18,8 +18,21 @@ def vae_sampling(args): return z_mean + K.exp(z_log_sigma_sq * 0.5) * epsilon -def create_model(input_shape, latent_space_size, dropout_rate, max_windows, batchnorm_momentum, use_vae=False, vae_b1=0.02, use_embedding=False, embedding_input_shape=None, embedding_shape=None): - +def create_autoencoder_model(input_shape, latent_space_size, dropout_rate, max_windows, batchnorm_momentum, use_vae=False, vae_b1=0.02, use_embedding=False, embedding_input_shape=None, embedding_shape=None): + """ + Create larger autoencoder with the options of making it variational and embedding. + :param input_shape: + :param latent_space_size: + :param dropout_rate: + :param max_windows: + :param batchnorm_momentum: + :param use_vae: + :param vae_b1: + :param use_embedding: + :param embedding_input_shape: + :param embedding_shape: + :return: + """ if use_embedding: x_in = Input(shape=embedding_input_shape) print((None,) + embedding_input_shape) diff --git a/plot_utils.py b/plot_utils.py new file mode 100644 index 00000000..7f9520f8 --- /dev/null +++ b/plot_utils.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Plot utility functions. +""" + +import os +import cv2 +import numpy as np + + +def plot_sample(file_name, sample, threshold=None): + if threshold is not None: + inverted = np.where(sample > threshold, 0, 1) + else: + inverted = 1.0 - sample + cv2.imwrite(file_name, inverted * 255) + + +def plot_samples(folder, samples, threshold=None): + if not os.path.exists(folder): + os.makedirs(folder) + + for i in range(samples.shape[0]): + plot_sample(folder + '/s' + str(i) + '.png', samples[i], threshold) diff --git a/load_songs.py b/preprocess_songs.py similarity index 82% rename from load_songs.py rename to preprocess_songs.py index a929385b..7000bdbd 100644 --- a/load_songs.py +++ b/preprocess_songs.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """ -Load songs from midi and save them in numpy format. +Load songs from midi, preprocess and save them in numpy format. """ import midi_utils @@ -12,9 +12,9 @@ import argparse -def load_songs(data_folders): +def preprocess_songs(data_folders): """ - Load the songs from the data folders and turn them into a dataset of samples/pitches and lengths of the tones. + Load and preprocess the songs from the data folders and turn them into a dataset of samples/pitches and lengths of the tones. :param data_folders: :return: """ @@ -52,7 +52,7 @@ def load_songs(data_folders): ignored += 1 continue - # transpose samples (center them in full range) + # transpose samples (center them in full range to get more training samples for the same tones) samples, lengths = music_utils.generate_centered_transpose(samples) all_samples += samples all_lengths += lengths @@ -72,8 +72,8 @@ def load_songs(data_folders): if __name__ == "__main__": # configure parser and parse arguments - parser = argparse.ArgumentParser(description='Load songs and put them into a dataset.') + parser = argparse.ArgumentParser(description='Load songs, preprocess them and put them into a dataset.') parser.add_argument('--data_folder', default=["data/raw"], type=str, help='The path to the midi data', action='append') args = parser.parse_args() - load_songs(args.data_folder) + preprocess_songs(args.data_folder) diff --git a/train.py b/train.py index ae0a606d..2fd53b08 100644 --- a/train.py +++ b/train.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """ -Train a autoencoder model to learn to encode songs. +Train an autoencoder model to learn to encode songs. """ import random @@ -11,9 +11,11 @@ from matplotlib import pyplot as plt import midi_utils -import misc +import plot_utils import models +import argparse + # Load Keras print("Loading keras...") import os @@ -27,8 +29,8 @@ from keras.losses import binary_crossentropy from keras.optimizers import Adam, RMSprop +EPOCHS_QTY = 2000 EPOCHS_TO_SAVE = [1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450] -NUM_EPOCHS = 2000 LEARNING_RATE = 0.001 # learning rate CONTINUE_TRAIN = False GENERATE_ONLY = False @@ -38,7 +40,7 @@ # network params DROPOUT_RATE = 0.1 -BATCHNORM_MOMENTUM = 0.9 +BATCHNORM_MOMENTUM = 0.9 # weighted normalization with the past USE_EMBEDDING = False USE_VAE = False VAE_B1 = 0.02 @@ -55,13 +57,29 @@ np.random.seed(0) random.seed(0) + def vae_loss(x, x_decoded_mean, z_log_sigma_sq, z_mean): + """ + Variational autoencoder loss function. + :param x: + :param x_decoded_mean: + :param z_log_sigma_sq: + :param z_mean: + :return: + """ xent_loss = binary_crossentropy(x, x_decoded_mean) kl_loss = VAE_B2 * K.mean(1 + z_log_sigma_sq - K.square(z_mean) - K.exp(z_log_sigma_sq), axis=None) return xent_loss - kl_loss -def plot_scores(scores, f_name, on_top=True): +def plot_losses(scores, f_name, on_top=True): + """ + Plot loss. + :param scores: + :param f_name: + :param on_top: + :return: + """ plt.clf() ax = plt.gca() ax.yaxis.tick_right() @@ -75,9 +93,15 @@ def plot_scores(scores, f_name, on_top=True): plt.savefig(f_name) -def save_config(num_songs, model): +def save_training_config(num_songs, model): + """ + Save configuration of training. + :param num_songs: + :param model: + :return: + """ with open('results/config.txt', 'w') as file_out: - file_out.write('LEARNING_RATE: ' + str(LEARNING_RATE) + '\n') + file_out.write('LEARNING_RATE: ' + str(learning_rate) + '\n') file_out.write('BATCHNORM_MOMENTUM: ' + str(BATCHNORM_MOMENTUM) + '\n') file_out.write('BATCH_SIZE: ' + str(BATCH_SIZE) + '\n') file_out.write('NUM_OFFSETS: ' + str(NUM_OFFSETS) + '\n') @@ -86,81 +110,92 @@ def save_config(num_songs, model): file_out.write('optimizer: ' + type(model.optimizer).__name__ + '\n') -def generate_random_songs(func, write_dir, rand_vectors): +def generate_random_songs(decoder, write_dir, random_vectors): """ Generate random songs using random latent vectors. - :param func: + :param decoder: :param write_dir: - :param rand_vectors: + :param random_vectors: :return: """ - for i in range(rand_vectors.shape[0]): - x_rand = rand_vectors[i:i + 1] - y_song = func([x_rand, 0])[0] - midi_utils.samples_to_midi(y_song[0], write_dir + 'rand' + str(i) + '.mid', 0.25) + for i in range(random_vectors.shape[0]): + random_latent_x = random_vectors[i:i + 1] + y_song = decoder([random_latent_x, 0])[0] + midi_utils.samples_to_midi(y_song[0], write_dir + 'random_vectors' + str(i) + '.mid', 32) -def make_msee(enc, x_orig, y_orig, write_dir): +def calculate_and_store_pca_statistics(encoder, x_orig, y_orig, write_dir): """ - means, stddevs, evals, evecs - :param enc: + Calculate means, stddevs, covariance singular values (pca values), covariance singular vectors (pca vectors) + to more efficiently navigate/find configurations in the latent space. + :param encoder: :param x_orig: :param y_orig: :param write_dir: :return: """ if USE_EMBEDDING: - x_enc = np.squeeze(enc.predict(x_orig)) + latent_x = np.squeeze(encoder.predict(x_orig)) else: - x_enc = np.squeeze(enc.predict(y_orig)) + latent_x = np.squeeze(encoder.predict(y_orig)) - x_mean = np.mean(x_enc, axis=0) - x_stds = np.std(x_enc, axis=0) - x_cov = np.cov((x_enc - x_mean).T) - u, s, v = np.linalg.svd(x_cov) - e = np.sqrt(s) + latent_mean = np.mean(latent_x, axis=0) + latent_stds = np.std(latent_x, axis=0) + latent_cov = np.cov((latent_x - latent_mean).T) + _, latent_pca_values, latent_pca_vectors = np.linalg.svd(latent_cov) + latent_pca_values = np.sqrt(latent_pca_values) - print("Means: ", x_mean[:6]) - print("Evals: ", e[:6]) + print("Latent Mean values: ", latent_mean[:6]) + print("Latent PCA values: ", latent_pca_values[:6]) - np.save(write_dir + 'means.npy', x_mean) - np.save(write_dir + 'stds.npy', x_stds) - np.save(write_dir + 'evals.npy', e) - np.save(write_dir + 'evecs.npy', v) - return x_mean, x_stds, e, v + np.save(write_dir + 'latent_means.npy', latent_mean) + np.save(write_dir + 'latent_stds.npy', latent_stds) + np.save(write_dir + 'latent_pca_values.npy', latent_pca_values) + np.save(write_dir + 'latent_pca_vectors.npy', latent_pca_vectors) + return latent_mean, latent_stds, latent_pca_values, latent_pca_vectors -def generate_random_songs_normalized(encoder, x_orig, y_orig, decoder, write_dir, random_vectors): - x_mean, x_stds, e, v = make_msee(encoder, x_orig, y_orig, write_dir) +def generate_normalized_random_songs(x_orig, y_orig, encoder, decoder, random_vectors, write_dir): + """ + Generate a number of random songs from some normal latent vector samples. + :param encoder: + :param x_orig: + :param y_orig: + :param decoder: + :param write_dir: + :param random_vectors: + :return: + """ + latent_mean, latent_stds, pca_values, pca_vectors = calculate_and_store_pca_statistics(encoder, x_orig, y_orig, write_dir) - x_vectors = x_mean + np.dot(random_vectors * e, v) - generate_random_songs(decoder, write_dir, x_vectors) + latent_vectors = latent_mean + np.dot(random_vectors * pca_values, pca_vectors) + generate_random_songs(decoder, write_dir, latent_vectors) title = '' if '/' in write_dir: title = 'Epoch: ' + write_dir.split('/')[-2][1:] plt.clf() - e[::-1].sort() + pca_values[::-1].sort() plt.title(title) - plt.bar(np.arange(e.shape[0]), e, align='center') + plt.bar(np.arange(pca_values.shape[0]), pca_values, align='center') plt.draw() - plt.savefig(write_dir + 'evals.png') + plt.savefig(write_dir + 'latent_pca_values.png') plt.clf() plt.title(title) - plt.bar(np.arange(e.shape[0]), x_mean, align='center') + plt.bar(np.arange(pca_values.shape[0]), latent_mean, align='center') plt.draw() - plt.savefig(write_dir + 'means.png') + plt.savefig(write_dir + 'latent_means.png') plt.clf() plt.title(title) - plt.bar(np.arange(e.shape[0]), x_stds, align='center') + plt.bar(np.arange(pca_values.shape[0]), latent_stds, align='center') plt.draw() - plt.savefig(write_dir + 'stds.png') + plt.savefig(write_dir + 'latent_stds.png') -def train(): +def train(samples_path='data/interim/samples.npy', lengths_path='data/interim/lengths.npy', epochs_qty=EPOCHS_QTY, learning_rate=LEARNING_RATE): """ Train model. :return: @@ -174,12 +209,12 @@ def train(): # Load dataset into memory print("Loading Data...") - if not os.path.exists('data/interim/samples.npy') or not os.path.exists('data/interim/lengths.npy'): - print('No input data found, run load_songs.py first.') + if not os.path.exists(samples_path) or not os.path.exists(lengths_path): + print('No input data found, run preprocess_songs.py first.') exit(1) - y_samples = np.load('data/interim/samples.npy') - y_lengths = np.load('data/interim/lengths.npy') + y_samples = np.load(samples_path) + y_lengths = np.load(lengths_path) samples_qty = y_samples.shape[0] songs_qty = y_lengths.shape[0] @@ -222,21 +257,21 @@ def train(): else: print("Building model...") - model = models.create_model(input_shape=y_shape[1:], - latent_space_size=LATENT_SPACE_SIZE, - dropout_rate=DROPOUT_RATE, - max_windows=MAX_WINDOWS, - batchnorm_momentum=BATCHNORM_MOMENTUM, - use_vae=USE_VAE, - vae_b1=VAE_B1, - use_embedding=USE_EMBEDDING, - embedding_input_shape=x_shape[1:], - embedding_shape=x_train.shape[0]) + model = models.create_autoencoder_model(input_shape=y_shape[1:], + latent_space_size=LATENT_SPACE_SIZE, + dropout_rate=DROPOUT_RATE, + max_windows=MAX_WINDOWS, + batchnorm_momentum=BATCHNORM_MOMENTUM, + use_vae=USE_VAE, + vae_b1=VAE_B1, + use_embedding=USE_EMBEDDING, + embedding_input_shape=x_shape[1:], + embedding_shape=x_train.shape[0]) if USE_VAE: - model.compile(optimizer=Adam(lr=LEARNING_RATE), loss=vae_loss) + model.compile(optimizer=Adam(lr=learning_rate), loss=vae_loss) else: - model.compile(optimizer=RMSprop(lr=LEARNING_RATE), loss='binary_crossentropy') + model.compile(optimizer=RMSprop(lr=learning_rate), loss='binary_crossentropy') # plot model with graphvis if installed try: @@ -246,37 +281,37 @@ def train(): # train print("Referencing sub-models...") - decoder = K.function([model.get_layer('decoder').input, K.learning_phase()], - [model.layers[-1].output]) + decoder = K.function([model.get_layer('decoder').input, K.learning_phase()], [model.layers[-1].output]) encoder = Model(inputs=model.input, outputs=model.get_layer('encoder').output) random_vectors = np.random.normal(0.0, 1.0, (NUM_RAND_SONGS, LATENT_SPACE_SIZE)) - np.save('data/interim/rand.npy', random_vectors) + np.save('data/interim/random_vectors.npy', random_vectors) if GENERATE_ONLY: print("Generating songs...") - generate_random_songs_normalized(encoder, x_orig, y_orig, decoder, 'results/', random_vectors) + generate_normalized_random_songs(x_orig, y_orig, encoder, decoder, random_vectors, 'results/') for save_epoch in range(20): x_test_song = x_train[save_epoch:save_epoch + 1] y_song = model.predict(x_test_song, batch_size=BATCH_SIZE)[0] midi_utils.samples_to_midi(y_song, 'results/gt' + str(save_epoch) + '.mid') exit(0) + save_training_config(songs_qty, model) print("Training model...") - save_config(songs_qty, model) train_loss = [] offset = 0 - for epoch in range(NUM_EPOCHS): - print("Training epoch: ", epoch, "of", NUM_EPOCHS) + for epoch in range(epochs_qty): + print("Training epoch: ", epoch, "of", epochs_qty) if USE_EMBEDDING: history = model.fit(x_train, y_train, batch_size=BATCH_SIZE, epochs=1) else: + # produce songs from its samples with a different starting point of the song each time song_start_ix = 0 for song_ix in range(songs_qty): song_end_ix = song_start_ix + y_lengths[song_ix] for window_ix in range(MAX_WINDOWS): - song_measure_ix = (window_ix + offset) % (song_end_ix - song_start_ix) + song_measure_ix = (window_ix + offset) % y_lengths[song_ix] y_train[song_ix, window_ix] = y_samples[song_start_ix + song_measure_ix] song_start_ix = song_end_ix assert (song_end_ix == samples_qty) @@ -290,12 +325,13 @@ def train(): print("Train loss: " + str(train_loss[-1])) if WRITE_HISTORY: - plot_scores(train_loss, 'results/history/scores.png', True) + plot_losses(train_loss, 'results/history/losses.png', True) else: - plot_scores(train_loss, 'results/scores.png', True) + plot_losses(train_loss, 'results/losses.png', True) + # save model periodically save_epoch = epoch + 1 - if save_epoch in EPOCHS_TO_SAVE or (save_epoch % 100 == 0) or save_epoch == NUM_EPOCHS: + if save_epoch in EPOCHS_TO_SAVE or (save_epoch % 100 == 0) or save_epoch == epochs_qty: write_dir = '' if WRITE_HISTORY: # Create folder to save models into @@ -307,11 +343,6 @@ def train(): else: model.save('results/model.h5') - # Save output on last epoch - if save_epoch == NUM_EPOCHS: - model.save('results/model.h5') - make_msee(encoder, x_orig, y_orig, 'results/') - print("...Saved.") if USE_EMBEDDING: @@ -319,13 +350,25 @@ def train(): else: y_song = model.predict(y_test_song, batch_size=BATCH_SIZE)[0] - misc.plot_samples(write_dir + 'test', y_song) + plot_utils.plot_samples(write_dir + 'test', y_song) midi_utils.samples_to_midi(y_song, write_dir + 'test.mid') - generate_random_songs_normalized(encoder, x_orig, y_orig, decoder, write_dir, random_vectors) + generate_normalized_random_songs(x_orig, y_orig, encoder, decoder, random_vectors, write_dir) print("...Done.") if __name__ == "__main__": - train() + # configure parser and parse arguments + parser = argparse.ArgumentParser(description='Train to reconstruct midi in autoencoder.') + parser.add_argument('--samples_path', default='data/interim/samples.npy', type=str, help='Path to samples numpy array.') + parser.add_argument('--lengths_path', default='data/interim/lengths.npy', type=str, help='Path to sample lengths numpy array.') + parser.add_argument('--epochs_qty', default=EPOCHS_QTY, type=int, help='The number of epochs to be trained.') + parser.add_argument('--learning_rate', default=LEARNING_RATE, type=float, help='The learning rate to train the model.') + + args = parser.parse_args() + epochs_qty = args.epochs_qty + learning_rate = args.learning_rate + samples_path = args.samples_path + lengths_path = args.lengths_path + train(samples_path, lengths_path, epochs_qty, learning_rate) From 5441c0e6d0ea21b447b3eecb6ac38e50b5f488a4 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Wed, 15 May 2019 11:29:03 +0200 Subject: [PATCH 16/21] Fix missing learning rate --- train.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/train.py b/train.py index 2fd53b08..49971fcd 100644 --- a/train.py +++ b/train.py @@ -93,7 +93,7 @@ def plot_losses(scores, f_name, on_top=True): plt.savefig(f_name) -def save_training_config(num_songs, model): +def save_training_config(num_songs, model, learning_rate): """ Save configuration of training. :param num_songs: @@ -296,7 +296,7 @@ def train(samples_path='data/interim/samples.npy', lengths_path='data/interim/le midi_utils.samples_to_midi(y_song, 'results/gt' + str(save_epoch) + '.mid') exit(0) - save_training_config(songs_qty, model) + save_training_config(songs_qty, model, learning_rate) print("Training model...") train_loss = [] offset = 0 From ac65ab05d429f70aaee775cd3130cbc994832d1e Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Sun, 14 Jul 2019 14:22:00 +0200 Subject: [PATCH 17/21] Include bach dataset to start training easily --- data/raw/bach/bwv10.7.mid | Bin 0 -> 2032 bytes data/raw/bach/bwv101.7.mid | Bin 0 -> 2065 bytes data/raw/bach/bwv102.7.mid | Bin 0 -> 2254 bytes data/raw/bach/bwv103.6.mid | Bin 0 -> 3127 bytes data/raw/bach/bwv104.6.mid | Bin 0 -> 2704 bytes data/raw/bach/bwv108.6.mid | Bin 0 -> 2812 bytes data/raw/bach/bwv11.6.mid | Bin 0 -> 3343 bytes data/raw/bach/bwv110.7.mid | Bin 0 -> 2056 bytes data/raw/bach/bwv111.6.mid | Bin 0 -> 3352 bytes data/raw/bach/bwv112.5.mid | Bin 0 -> 2857 bytes data/raw/bach/bwv113.8.mid | Bin 0 -> 2767 bytes data/raw/bach/bwv114.7.mid | Bin 0 -> 2821 bytes data/raw/bach/bwv115.6.mid | Bin 0 -> 2398 bytes data/raw/bach/bwv116.6.mid | Bin 0 -> 2137 bytes data/raw/bach/bwv117.4.mid | Bin 0 -> 2785 bytes data/raw/bach/bwv119.9.mid | Bin 0 -> 1828 bytes data/raw/bach/bwv120.6.mid | Bin 0 -> 2839 bytes data/raw/bach/bwv121.6.mid | Bin 0 -> 2578 bytes data/raw/bach/bwv122.6.mid | Bin 0 -> 1615 bytes data/raw/bach/bwv123.6.mid | Bin 0 -> 2686 bytes data/raw/bach/bwv125.6.mid | Bin 0 -> 2137 bytes data/raw/bach/bwv126.6.mid | Bin 0 -> 4522 bytes data/raw/bach/bwv127.5.mid | Bin 0 -> 2380 bytes data/raw/bach/bwv13.6.mid | Bin 0 -> 2056 bytes data/raw/bach/bwv133.6.mid | Bin 0 -> 2365 bytes data/raw/bach/bwv135.6.mid | Bin 0 -> 2686 bytes data/raw/bach/bwv139.6.mid | Bin 0 -> 2236 bytes data/raw/bach/bwv14.5.mid | Bin 0 -> 2956 bytes data/raw/bach/bwv140.7.mid | Bin 0 -> 3867 bytes data/raw/bach/bwv144.3.mid | Bin 0 -> 2632 bytes data/raw/bach/bwv144.6.mid | Bin 0 -> 3208 bytes data/raw/bach/bwv145-a.mid | Bin 0 -> 2092 bytes data/raw/bach/bwv145.5.mid | Bin 0 -> 1786 bytes data/raw/bach/bwv146.8.mid | Bin 0 -> 2749 bytes data/raw/bach/bwv148.6.mid | Bin 0 -> 2064 bytes data/raw/bach/bwv151.5.mid | Bin 0 -> 1732 bytes data/raw/bach/bwv153.1.mid | Bin 0 -> 2641 bytes data/raw/bach/bwv153.5.mid | Bin 0 -> 2380 bytes data/raw/bach/bwv153.9.mid | Bin 0 -> 1489 bytes data/raw/bach/bwv154.3.mid | Bin 0 -> 2668 bytes data/raw/bach/bwv154.8.mid | Bin 0 -> 2389 bytes data/raw/bach/bwv155.5.mid | Bin 0 -> 2884 bytes data/raw/bach/bwv156.6.mid | Bin 0 -> 2731 bytes data/raw/bach/bwv157.5.mid | Bin 0 -> 2416 bytes data/raw/bach/bwv158.4.mid | Bin 0 -> 2672 bytes data/raw/bach/bwv159.5.mid | Bin 0 -> 2731 bytes data/raw/bach/bwv16.6.mid | Bin 0 -> 2506 bytes data/raw/bach/bwv162.6-lpz.mid | Bin 0 -> 2821 bytes data/raw/bach/bwv164.6.mid | Bin 0 -> 2326 bytes data/raw/bach/bwv165.6.mid | Bin 0 -> 1597 bytes data/raw/bach/bwv166.6.mid | Bin 0 -> 2110 bytes data/raw/bach/bwv168.6.mid | Bin 0 -> 2722 bytes data/raw/bach/bwv169.7.mid | Bin 0 -> 2434 bytes data/raw/bach/bwv17.7.mid | Bin 0 -> 3955 bytes data/raw/bach/bwv174.5.mid | Bin 0 -> 4648 bytes data/raw/bach/bwv176.6.mid | Bin 0 -> 3442 bytes data/raw/bach/bwv177.5.mid | Bin 0 -> 3325 bytes data/raw/bach/bwv178.7.mid | Bin 0 -> 2596 bytes data/raw/bach/bwv179.6.mid | Bin 0 -> 2623 bytes data/raw/bach/bwv18.5-lz.mid | Bin 0 -> 2992 bytes data/raw/bach/bwv18.5-w.mid | Bin 0 -> 3028 bytes data/raw/bach/bwv180.7.mid | Bin 0 -> 3244 bytes data/raw/bach/bwv183.5.mid | Bin 0 -> 3136 bytes data/raw/bach/bwv184.5.mid | Bin 0 -> 3082 bytes data/raw/bach/bwv187.7.mid | Bin 0 -> 2740 bytes data/raw/bach/bwv188.6.mid | Bin 0 -> 2046 bytes data/raw/bach/bwv190.7.mid | Bin 0 -> 4198 bytes data/raw/bach/bwv194.12.mid | Bin 0 -> 1552 bytes data/raw/bach/bwv194.6.mid | Bin 0 -> 2839 bytes data/raw/bach/bwv197.10.mid | Bin 0 -> 2262 bytes data/raw/bach/bwv197.5.mid | Bin 0 -> 2713 bytes data/raw/bach/bwv197.7-a.mid | Bin 0 -> 2544 bytes data/raw/bach/bwv2.6.mid | Bin 0 -> 2506 bytes data/raw/bach/bwv20.11.mid | Bin 0 -> 2830 bytes data/raw/bach/bwv20.7.mid | Bin 0 -> 2830 bytes data/raw/bach/bwv226.2.mid | Bin 0 -> 4052 bytes data/raw/bach/bwv227.1.mid | Bin 0 -> 2713 bytes data/raw/bach/bwv227.11.mid | Bin 0 -> 2721 bytes data/raw/bach/bwv227.7.mid | Bin 0 -> 3939 bytes data/raw/bach/bwv229.2.mid | Bin 0 -> 3406 bytes data/raw/bach/bwv244.10.mid | Bin 0 -> 2191 bytes data/raw/bach/bwv244.15.mid | Bin 0 -> 2524 bytes data/raw/bach/bwv244.17.mid | Bin 0 -> 2524 bytes data/raw/bach/bwv244.25.mid | Bin 0 -> 2992 bytes data/raw/bach/bwv244.29-a.mid | Bin 0 -> 2587 bytes data/raw/bach/bwv244.3.mid | Bin 0 -> 1939 bytes data/raw/bach/bwv244.32.mid | Bin 0 -> 2065 bytes data/raw/bach/bwv244.37.mid | Bin 0 -> 2164 bytes data/raw/bach/bwv244.40.mid | Bin 0 -> 2992 bytes data/raw/bach/bwv244.44.mid | Bin 0 -> 2524 bytes data/raw/bach/bwv244.46.mid | Bin 0 -> 1876 bytes data/raw/bach/bwv244.54.mid | Bin 0 -> 2497 bytes data/raw/bach/bwv244.62.mid | Bin 0 -> 2560 bytes data/raw/bach/bwv245.11.mid | Bin 0 -> 2056 bytes data/raw/bach/bwv245.14.mid | Bin 0 -> 2506 bytes data/raw/bach/bwv245.15.mid | Bin 0 -> 2443 bytes data/raw/bach/bwv245.17.mid | Bin 0 -> 2164 bytes data/raw/bach/bwv245.22.mid | Bin 0 -> 2299 bytes data/raw/bach/bwv245.26.mid | Bin 0 -> 2227 bytes data/raw/bach/bwv245.28.mid | Bin 0 -> 2317 bytes data/raw/bach/bwv245.3.mid | Bin 0 -> 1894 bytes data/raw/bach/bwv245.37.mid | Bin 0 -> 2434 bytes data/raw/bach/bwv245.40.mid | Bin 0 -> 4657 bytes data/raw/bach/bwv245.5.mid | Bin 0 -> 2317 bytes data/raw/bach/bwv248.12-2.mid | Bin 0 -> 3082 bytes data/raw/bach/bwv248.23-s.mid | Bin 0 -> 1849 bytes data/raw/bach/bwv248.28.mid | Bin 0 -> 2119 bytes data/raw/bach/bwv248.33-3.mid | Bin 0 -> 2083 bytes data/raw/bach/bwv248.35-3.mid | Bin 0 -> 2299 bytes data/raw/bach/bwv248.42-s.mid | Bin 0 -> 2749 bytes data/raw/bach/bwv248.46-5.mid | Bin 0 -> 2303 bytes data/raw/bach/bwv248.5.mid | Bin 0 -> 2794 bytes data/raw/bach/bwv248.53-5.mid | Bin 0 -> 2479 bytes data/raw/bach/bwv248.64-s.mid | Bin 0 -> 2677 bytes data/raw/bach/bwv25.6.mid | Bin 0 -> 2767 bytes data/raw/bach/bwv253.mid | Bin 0 -> 1657 bytes data/raw/bach/bwv254.mid | Bin 0 -> 2038 bytes data/raw/bach/bwv255.mid | Bin 0 -> 1453 bytes data/raw/bach/bwv256.mid | Bin 0 -> 2740 bytes data/raw/bach/bwv257.mid | Bin 0 -> 2740 bytes data/raw/bach/bwv258.mid | Bin 0 -> 2596 bytes data/raw/bach/bwv259.mid | Bin 0 -> 2254 bytes data/raw/bach/bwv26.6.mid | Bin 0 -> 1903 bytes data/raw/bach/bwv260.mid | Bin 0 -> 2929 bytes data/raw/bach/bwv261.mid | Bin 0 -> 3839 bytes data/raw/bach/bwv262.mid | Bin 0 -> 2542 bytes data/raw/bach/bwv263.mid | Bin 0 -> 2281 bytes data/raw/bach/bwv264.mid | Bin 0 -> 1501 bytes data/raw/bach/bwv265.mid | Bin 0 -> 1480 bytes data/raw/bach/bwv266.mid | Bin 0 -> 2326 bytes data/raw/bach/bwv267.mid | Bin 0 -> 3812 bytes data/raw/bach/bwv268.mid | Bin 0 -> 2407 bytes data/raw/bach/bwv269.mid | Bin 0 -> 2911 bytes data/raw/bach/bwv270.mid | Bin 0 -> 2641 bytes data/raw/bach/bwv271.mid | Bin 0 -> 2542 bytes data/raw/bach/bwv272.mid | Bin 0 -> 2479 bytes data/raw/bach/bwv273.mid | Bin 0 -> 2065 bytes data/raw/bach/bwv276.mid | Bin 0 -> 5201 bytes data/raw/bach/bwv277.mid | Bin 0 -> 3041 bytes data/raw/bach/bwv278.mid | Bin 0 -> 3212 bytes data/raw/bach/bwv279.mid | Bin 0 -> 2672 bytes data/raw/bach/bwv28.6.mid | Bin 0 -> 2515 bytes data/raw/bach/bwv280.mid | Bin 0 -> 3388 bytes data/raw/bach/bwv281.mid | Bin 0 -> 1286 bytes data/raw/bach/bwv282.mid | Bin 0 -> 1551 bytes data/raw/bach/bwv283.mid | Bin 0 -> 3001 bytes data/raw/bach/bwv284.mid | Bin 0 -> 2515 bytes data/raw/bach/bwv285.mid | Bin 0 -> 2317 bytes data/raw/bach/bwv286.mid | Bin 0 -> 1120 bytes data/raw/bach/bwv287.mid | Bin 0 -> 2605 bytes data/raw/bach/bwv288.mid | Bin 0 -> 2407 bytes data/raw/bach/bwv289.mid | Bin 0 -> 2164 bytes data/raw/bach/bwv290.mid | Bin 0 -> 1525 bytes data/raw/bach/bwv291.mid | Bin 0 -> 1853 bytes data/raw/bach/bwv292.mid | Bin 0 -> 2443 bytes data/raw/bach/bwv293.mid | Bin 0 -> 1516 bytes data/raw/bach/bwv294.mid | Bin 0 -> 3496 bytes data/raw/bach/bwv295.mid | Bin 0 -> 1831 bytes data/raw/bach/bwv296.mid | Bin 0 -> 1932 bytes data/raw/bach/bwv297.mid | Bin 0 -> 2056 bytes data/raw/bach/bwv298.mid | Bin 0 -> 1858 bytes data/raw/bach/bwv299.mid | Bin 0 -> 3064 bytes data/raw/bach/bwv3.6.mid | Bin 0 -> 1705 bytes data/raw/bach/bwv30.6.mid | Bin 0 -> 3037 bytes data/raw/bach/bwv300.mid | Bin 0 -> 2265 bytes data/raw/bach/bwv301.mid | Bin 0 -> 2866 bytes data/raw/bach/bwv302.mid | Bin 0 -> 3019 bytes data/raw/bach/bwv303.mid | Bin 0 -> 3154 bytes data/raw/bach/bwv304.mid | Bin 0 -> 3642 bytes data/raw/bach/bwv305.mid | Bin 0 -> 3460 bytes data/raw/bach/bwv306.mid | Bin 0 -> 1912 bytes data/raw/bach/bwv307.mid | Bin 0 -> 2632 bytes data/raw/bach/bwv308.mid | Bin 0 -> 2434 bytes data/raw/bach/bwv309.mid | Bin 0 -> 3181 bytes data/raw/bach/bwv310.mid | Bin 0 -> 1705 bytes data/raw/bach/bwv311.mid | Bin 0 -> 3666 bytes data/raw/bach/bwv312.mid | Bin 0 -> 3945 bytes data/raw/bach/bwv313.mid | Bin 0 -> 2758 bytes data/raw/bach/bwv314.mid | Bin 0 -> 1894 bytes data/raw/bach/bwv315.mid | Bin 0 -> 3387 bytes data/raw/bach/bwv316.mid | Bin 0 -> 3181 bytes data/raw/bach/bwv317.mid | Bin 0 -> 4549 bytes data/raw/bach/bwv318.mid | Bin 0 -> 1993 bytes data/raw/bach/bwv319.mid | Bin 0 -> 2002 bytes data/raw/bach/bwv32.6.mid | Bin 0 -> 2767 bytes data/raw/bach/bwv320.mid | Bin 0 -> 3604 bytes data/raw/bach/bwv321.mid | Bin 0 -> 2272 bytes data/raw/bach/bwv322.mid | Bin 0 -> 4166 bytes data/raw/bach/bwv323.mid | Bin 0 -> 1093 bytes data/raw/bach/bwv324.mid | Bin 0 -> 1138 bytes data/raw/bach/bwv325.mid | Bin 0 -> 2793 bytes data/raw/bach/bwv326.mid | Bin 0 -> 1903 bytes data/raw/bach/bwv327.mid | Bin 0 -> 1543 bytes data/raw/bach/bwv328.mid | Bin 0 -> 19358 bytes data/raw/bach/bwv329.mid | Bin 0 -> 2218 bytes data/raw/bach/bwv33.6.mid | Bin 0 -> 3892 bytes data/raw/bach/bwv330.mid | Bin 0 -> 2596 bytes data/raw/bach/bwv331.mid | Bin 0 -> 2173 bytes data/raw/bach/bwv332.mid | Bin 0 -> 1570 bytes data/raw/bach/bwv333.mid | Bin 0 -> 2857 bytes data/raw/bach/bwv334.mid | Bin 0 -> 2641 bytes data/raw/bach/bwv335.mid | Bin 0 -> 1615 bytes data/raw/bach/bwv336.mid | Bin 0 -> 1606 bytes data/raw/bach/bwv337.mid | Bin 0 -> 2002 bytes data/raw/bach/bwv338.mid | Bin 0 -> 2740 bytes data/raw/bach/bwv339.mid | Bin 0 -> 2710 bytes data/raw/bach/bwv340.mid | Bin 0 -> 4972 bytes data/raw/bach/bwv341.mid | Bin 0 -> 1479 bytes data/raw/bach/bwv342.mid | Bin 0 -> 2272 bytes data/raw/bach/bwv343.mid | Bin 0 -> 2974 bytes data/raw/bach/bwv344.mid | Bin 0 -> 2326 bytes data/raw/bach/bwv345.mid | Bin 0 -> 3118 bytes data/raw/bach/bwv346.mid | Bin 0 -> 2379 bytes data/raw/bach/bwv347.mid | Bin 0 -> 2866 bytes data/raw/bach/bwv348.mid | Bin 0 -> 2677 bytes data/raw/bach/bwv349.mid | Bin 0 -> 1642 bytes data/raw/bach/bwv350.mid | Bin 0 -> 3361 bytes data/raw/bach/bwv351.mid | Bin 0 -> 1795 bytes data/raw/bach/bwv352.mid | Bin 0 -> 3091 bytes data/raw/bach/bwv353.mid | Bin 0 -> 3037 bytes data/raw/bach/bwv354.mid | Bin 0 -> 3064 bytes data/raw/bach/bwv355.mid | Bin 0 -> 2704 bytes data/raw/bach/bwv356.mid | Bin 0 -> 2929 bytes data/raw/bach/bwv357.mid | Bin 0 -> 2794 bytes data/raw/bach/bwv358.mid | Bin 0 -> 2821 bytes data/raw/bach/bwv359.mid | Bin 0 -> 2650 bytes data/raw/bach/bwv36.4-2.mid | Bin 0 -> 3356 bytes data/raw/bach/bwv36.8-2.mid | Bin 0 -> 1561 bytes data/raw/bach/bwv360.mid | Bin 0 -> 2587 bytes data/raw/bach/bwv361.mid | Bin 0 -> 2182 bytes data/raw/bach/bwv362.mid | Bin 0 -> 5679 bytes data/raw/bach/bwv363.mid | Bin 0 -> 2069 bytes data/raw/bach/bwv364.mid | Bin 0 -> 1690 bytes data/raw/bach/bwv365.mid | Bin 0 -> 2209 bytes data/raw/bach/bwv366.mid | Bin 0 -> 2578 bytes data/raw/bach/bwv367.mid | Bin 0 -> 2024 bytes data/raw/bach/bwv368.mid | Bin 0 -> 3011 bytes data/raw/bach/bwv369.mid | Bin 0 -> 2497 bytes data/raw/bach/bwv37.6.mid | Bin 0 -> 2947 bytes data/raw/bach/bwv370.mid | Bin 0 -> 1498 bytes data/raw/bach/bwv371.mid | Bin 0 -> 7325 bytes data/raw/bach/bwv372.mid | Bin 0 -> 2983 bytes data/raw/bach/bwv373.mid | Bin 0 -> 2308 bytes data/raw/bach/bwv374.mid | Bin 0 -> 3111 bytes data/raw/bach/bwv375.mid | Bin 0 -> 1885 bytes data/raw/bach/bwv376.mid | Bin 0 -> 1840 bytes data/raw/bach/bwv377.mid | Bin 0 -> 2242 bytes data/raw/bach/bwv378.mid | Bin 0 -> 2458 bytes data/raw/bach/bwv379.mid | Bin 0 -> 2245 bytes data/raw/bach/bwv38.6.mid | Bin 0 -> 2479 bytes data/raw/bach/bwv380.mid | Bin 0 -> 2524 bytes data/raw/bach/bwv381.mid | Bin 0 -> 2632 bytes data/raw/bach/bwv382.mid | Bin 0 -> 2290 bytes data/raw/bach/bwv383.mid | Bin 0 -> 4947 bytes data/raw/bach/bwv384.mid | Bin 0 -> 1975 bytes data/raw/bach/bwv385.mid | Bin 0 -> 2312 bytes data/raw/bach/bwv386.mid | Bin 0 -> 2479 bytes data/raw/bach/bwv387.mid | Bin 0 -> 1642 bytes data/raw/bach/bwv388.mid | Bin 0 -> 2767 bytes data/raw/bach/bwv389.mid | Bin 0 -> 4270 bytes data/raw/bach/bwv39.7.mid | Bin 0 -> 2767 bytes data/raw/bach/bwv390.mid | Bin 0 -> 4072 bytes data/raw/bach/bwv391.mid | Bin 0 -> 2470 bytes data/raw/bach/bwv392.mid | Bin 0 -> 2123 bytes data/raw/bach/bwv393.mid | Bin 0 -> 1975 bytes data/raw/bach/bwv394.mid | Bin 0 -> 2384 bytes data/raw/bach/bwv395.mid | Bin 0 -> 2074 bytes data/raw/bach/bwv396.mid | Bin 0 -> 1349 bytes data/raw/bach/bwv397.mid | Bin 0 -> 3181 bytes data/raw/bach/bwv398.mid | Bin 0 -> 2544 bytes data/raw/bach/bwv399.mid | Bin 0 -> 2578 bytes data/raw/bach/bwv4.8.mid | Bin 0 -> 2834 bytes data/raw/bach/bwv40.3.mid | Bin 0 -> 2038 bytes data/raw/bach/bwv40.6.mid | Bin 0 -> 2452 bytes data/raw/bach/bwv40.8.mid | Bin 0 -> 3424 bytes data/raw/bach/bwv400.mid | Bin 0 -> 1804 bytes data/raw/bach/bwv401.mid | Bin 0 -> 2740 bytes data/raw/bach/bwv402.mid | Bin 0 -> 4324 bytes data/raw/bach/bwv403.mid | Bin 0 -> 2353 bytes data/raw/bach/bwv404.mid | Bin 0 -> 1435 bytes data/raw/bach/bwv405.mid | Bin 0 -> 1826 bytes data/raw/bach/bwv406.mid | Bin 0 -> 1984 bytes data/raw/bach/bwv407.mid | Bin 0 -> 3631 bytes data/raw/bach/bwv408.mid | Bin 0 -> 1784 bytes data/raw/bach/bwv410.mid | Bin 0 -> 2254 bytes data/raw/bach/bwv411.mid | Bin 0 -> 3244 bytes data/raw/bach/bwv412.mid | Bin 0 -> 2500 bytes data/raw/bach/bwv413.mid | Bin 0 -> 4477 bytes data/raw/bach/bwv414.mid | Bin 0 -> 2416 bytes data/raw/bach/bwv415.mid | Bin 0 -> 2704 bytes data/raw/bach/bwv416.mid | Bin 0 -> 2155 bytes data/raw/bach/bwv417.mid | Bin 0 -> 3001 bytes data/raw/bach/bwv418.mid | Bin 0 -> 2668 bytes data/raw/bach/bwv419.mid | Bin 0 -> 2641 bytes data/raw/bach/bwv42.7.mid | Bin 0 -> 4432 bytes data/raw/bach/bwv420.mid | Bin 0 -> 1984 bytes data/raw/bach/bwv421.mid | Bin 0 -> 1822 bytes data/raw/bach/bwv422.mid | Bin 0 -> 2146 bytes data/raw/bach/bwv423.mid | Bin 0 -> 2794 bytes data/raw/bach/bwv424.mid | Bin 0 -> 1847 bytes data/raw/bach/bwv425.mid | Bin 0 -> 4879 bytes data/raw/bach/bwv426.mid | Bin 0 -> 2658 bytes data/raw/bach/bwv427.mid | Bin 0 -> 2027 bytes data/raw/bach/bwv428.mid | Bin 0 -> 2677 bytes data/raw/bach/bwv429.mid | Bin 0 -> 2785 bytes data/raw/bach/bwv43.11.mid | Bin 0 -> 2551 bytes data/raw/bach/bwv430.mid | Bin 0 -> 2866 bytes data/raw/bach/bwv431.mid | Bin 0 -> 1745 bytes data/raw/bach/bwv432.mid | Bin 0 -> 1795 bytes data/raw/bach/bwv433.mid | Bin 0 -> 3873 bytes data/raw/bach/bwv434.mid | Bin 0 -> 2569 bytes data/raw/bach/bwv435.mid | Bin 0 -> 2146 bytes data/raw/bach/bwv436.mid | Bin 0 -> 3140 bytes data/raw/bach/bwv437.mid | Bin 0 -> 5613 bytes data/raw/bach/bwv438.mid | Bin 0 -> 1633 bytes data/raw/bach/bwv44.7.mid | Bin 0 -> 2074 bytes data/raw/bach/bwv45.7.mid | Bin 0 -> 2364 bytes data/raw/bach/bwv47.5.mid | Bin 0 -> 1880 bytes data/raw/bach/bwv48.3.mid | Bin 0 -> 1606 bytes data/raw/bach/bwv48.7.mid | Bin 0 -> 2722 bytes data/raw/bach/bwv5.7.mid | Bin 0 -> 1984 bytes data/raw/bach/bwv55.5.mid | Bin 0 -> 2704 bytes data/raw/bach/bwv56.5.mid | Bin 0 -> 2770 bytes data/raw/bach/bwv57.8.mid | Bin 0 -> 2127 bytes data/raw/bach/bwv6.6.mid | Bin 0 -> 1678 bytes data/raw/bach/bwv60.5.mid | Bin 0 -> 2759 bytes data/raw/bach/bwv64.2.mid | Bin 0 -> 1741 bytes data/raw/bach/bwv64.8.mid | Bin 0 -> 2650 bytes data/raw/bach/bwv65.2.mid | Bin 0 -> 1543 bytes data/raw/bach/bwv65.7.mid | Bin 0 -> 3208 bytes data/raw/bach/bwv66.6.mid | Bin 0 -> 1669 bytes data/raw/bach/bwv67.4.mid | Bin 0 -> 1759 bytes data/raw/bach/bwv67.7.mid | Bin 0 -> 1912 bytes data/raw/bach/bwv69.6-a.mid | Bin 0 -> 2326 bytes data/raw/bach/bwv7.7.mid | Bin 0 -> 3388 bytes data/raw/bach/bwv70.7.mid | Bin 0 -> 2686 bytes data/raw/bach/bwv72.6.mid | Bin 0 -> 3118 bytes data/raw/bach/bwv73.5.mid | Bin 0 -> 2308 bytes data/raw/bach/bwv74.8.mid | Bin 0 -> 2515 bytes data/raw/bach/bwv77.6.mid | Bin 0 -> 2509 bytes data/raw/bach/bwv78.7.mid | Bin 0 -> 2731 bytes data/raw/bach/bwv80.8.mid | Bin 0 -> 3244 bytes data/raw/bach/bwv81.7.mid | Bin 0 -> 2749 bytes data/raw/bach/bwv83.5.mid | Bin 0 -> 2020 bytes data/raw/bach/bwv84.5.mid | Bin 0 -> 2172 bytes data/raw/bach/bwv85.6.mid | Bin 0 -> 2830 bytes data/raw/bach/bwv86.6.mid | Bin 0 -> 2632 bytes data/raw/bach/bwv87.7.mid | Bin 0 -> 3028 bytes data/raw/bach/bwv88.7.mid | Bin 0 -> 2407 bytes data/raw/bach/bwv89.6.mid | Bin 0 -> 1930 bytes data/raw/bach/bwv9.7.mid | Bin 0 -> 2839 bytes data/raw/bach/bwv90.5.mid | Bin 0 -> 2308 bytes data/raw/bach/bwv92.9.mid | Bin 0 -> 3082 bytes data/raw/bach/bwv93.7.mid | Bin 0 -> 2194 bytes data/raw/bach/bwv94.8.mid | Bin 0 -> 2353 bytes data/raw/bach/bwv96.6.mid | Bin 0 -> 2173 bytes data/raw/bach/bwv99.6.mid | Bin 0 -> 2659 bytes 357 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/raw/bach/bwv10.7.mid create mode 100644 data/raw/bach/bwv101.7.mid create mode 100644 data/raw/bach/bwv102.7.mid create mode 100644 data/raw/bach/bwv103.6.mid create mode 100644 data/raw/bach/bwv104.6.mid create mode 100644 data/raw/bach/bwv108.6.mid create mode 100644 data/raw/bach/bwv11.6.mid create mode 100644 data/raw/bach/bwv110.7.mid create mode 100644 data/raw/bach/bwv111.6.mid create mode 100644 data/raw/bach/bwv112.5.mid create mode 100644 data/raw/bach/bwv113.8.mid create mode 100644 data/raw/bach/bwv114.7.mid create mode 100644 data/raw/bach/bwv115.6.mid create mode 100644 data/raw/bach/bwv116.6.mid create mode 100644 data/raw/bach/bwv117.4.mid create mode 100644 data/raw/bach/bwv119.9.mid create mode 100644 data/raw/bach/bwv120.6.mid create mode 100644 data/raw/bach/bwv121.6.mid create mode 100644 data/raw/bach/bwv122.6.mid create mode 100644 data/raw/bach/bwv123.6.mid create mode 100644 data/raw/bach/bwv125.6.mid create mode 100644 data/raw/bach/bwv126.6.mid create mode 100644 data/raw/bach/bwv127.5.mid create mode 100644 data/raw/bach/bwv13.6.mid create mode 100644 data/raw/bach/bwv133.6.mid create mode 100644 data/raw/bach/bwv135.6.mid create mode 100644 data/raw/bach/bwv139.6.mid create mode 100644 data/raw/bach/bwv14.5.mid create mode 100644 data/raw/bach/bwv140.7.mid create mode 100644 data/raw/bach/bwv144.3.mid create mode 100644 data/raw/bach/bwv144.6.mid create mode 100644 data/raw/bach/bwv145-a.mid create mode 100644 data/raw/bach/bwv145.5.mid create mode 100644 data/raw/bach/bwv146.8.mid create mode 100644 data/raw/bach/bwv148.6.mid create mode 100644 data/raw/bach/bwv151.5.mid create mode 100644 data/raw/bach/bwv153.1.mid create mode 100644 data/raw/bach/bwv153.5.mid create mode 100644 data/raw/bach/bwv153.9.mid create mode 100644 data/raw/bach/bwv154.3.mid create mode 100644 data/raw/bach/bwv154.8.mid create mode 100644 data/raw/bach/bwv155.5.mid create mode 100644 data/raw/bach/bwv156.6.mid create mode 100644 data/raw/bach/bwv157.5.mid create mode 100644 data/raw/bach/bwv158.4.mid create mode 100644 data/raw/bach/bwv159.5.mid create mode 100644 data/raw/bach/bwv16.6.mid create mode 100644 data/raw/bach/bwv162.6-lpz.mid create mode 100644 data/raw/bach/bwv164.6.mid create mode 100644 data/raw/bach/bwv165.6.mid create mode 100644 data/raw/bach/bwv166.6.mid create mode 100644 data/raw/bach/bwv168.6.mid create mode 100644 data/raw/bach/bwv169.7.mid create mode 100644 data/raw/bach/bwv17.7.mid create mode 100644 data/raw/bach/bwv174.5.mid create mode 100644 data/raw/bach/bwv176.6.mid create mode 100644 data/raw/bach/bwv177.5.mid create mode 100644 data/raw/bach/bwv178.7.mid create mode 100644 data/raw/bach/bwv179.6.mid create mode 100644 data/raw/bach/bwv18.5-lz.mid create mode 100644 data/raw/bach/bwv18.5-w.mid create mode 100644 data/raw/bach/bwv180.7.mid create mode 100644 data/raw/bach/bwv183.5.mid create mode 100644 data/raw/bach/bwv184.5.mid create mode 100644 data/raw/bach/bwv187.7.mid create mode 100644 data/raw/bach/bwv188.6.mid create mode 100644 data/raw/bach/bwv190.7.mid create mode 100644 data/raw/bach/bwv194.12.mid create mode 100644 data/raw/bach/bwv194.6.mid create mode 100644 data/raw/bach/bwv197.10.mid create mode 100644 data/raw/bach/bwv197.5.mid create mode 100644 data/raw/bach/bwv197.7-a.mid create mode 100644 data/raw/bach/bwv2.6.mid create mode 100644 data/raw/bach/bwv20.11.mid create mode 100644 data/raw/bach/bwv20.7.mid create mode 100644 data/raw/bach/bwv226.2.mid create mode 100644 data/raw/bach/bwv227.1.mid create mode 100644 data/raw/bach/bwv227.11.mid create mode 100644 data/raw/bach/bwv227.7.mid create mode 100644 data/raw/bach/bwv229.2.mid create mode 100644 data/raw/bach/bwv244.10.mid create mode 100644 data/raw/bach/bwv244.15.mid create mode 100644 data/raw/bach/bwv244.17.mid create mode 100644 data/raw/bach/bwv244.25.mid create mode 100644 data/raw/bach/bwv244.29-a.mid create mode 100644 data/raw/bach/bwv244.3.mid create mode 100644 data/raw/bach/bwv244.32.mid create mode 100644 data/raw/bach/bwv244.37.mid create mode 100644 data/raw/bach/bwv244.40.mid create mode 100644 data/raw/bach/bwv244.44.mid create mode 100644 data/raw/bach/bwv244.46.mid create mode 100644 data/raw/bach/bwv244.54.mid create mode 100644 data/raw/bach/bwv244.62.mid create mode 100644 data/raw/bach/bwv245.11.mid create mode 100644 data/raw/bach/bwv245.14.mid create mode 100644 data/raw/bach/bwv245.15.mid create mode 100644 data/raw/bach/bwv245.17.mid create mode 100644 data/raw/bach/bwv245.22.mid create mode 100644 data/raw/bach/bwv245.26.mid create mode 100644 data/raw/bach/bwv245.28.mid create mode 100644 data/raw/bach/bwv245.3.mid create mode 100644 data/raw/bach/bwv245.37.mid create mode 100644 data/raw/bach/bwv245.40.mid create mode 100644 data/raw/bach/bwv245.5.mid create mode 100644 data/raw/bach/bwv248.12-2.mid create mode 100644 data/raw/bach/bwv248.23-s.mid create mode 100644 data/raw/bach/bwv248.28.mid create mode 100644 data/raw/bach/bwv248.33-3.mid create mode 100644 data/raw/bach/bwv248.35-3.mid create mode 100644 data/raw/bach/bwv248.42-s.mid create mode 100644 data/raw/bach/bwv248.46-5.mid create mode 100644 data/raw/bach/bwv248.5.mid create mode 100644 data/raw/bach/bwv248.53-5.mid create mode 100644 data/raw/bach/bwv248.64-s.mid create mode 100644 data/raw/bach/bwv25.6.mid create mode 100644 data/raw/bach/bwv253.mid create mode 100644 data/raw/bach/bwv254.mid create mode 100644 data/raw/bach/bwv255.mid create mode 100644 data/raw/bach/bwv256.mid create mode 100644 data/raw/bach/bwv257.mid create mode 100644 data/raw/bach/bwv258.mid create mode 100644 data/raw/bach/bwv259.mid create mode 100644 data/raw/bach/bwv26.6.mid create mode 100644 data/raw/bach/bwv260.mid create mode 100644 data/raw/bach/bwv261.mid create mode 100644 data/raw/bach/bwv262.mid create mode 100644 data/raw/bach/bwv263.mid create mode 100644 data/raw/bach/bwv264.mid create mode 100644 data/raw/bach/bwv265.mid create mode 100644 data/raw/bach/bwv266.mid create mode 100644 data/raw/bach/bwv267.mid create mode 100644 data/raw/bach/bwv268.mid create mode 100644 data/raw/bach/bwv269.mid create mode 100644 data/raw/bach/bwv270.mid create mode 100644 data/raw/bach/bwv271.mid create mode 100644 data/raw/bach/bwv272.mid create mode 100644 data/raw/bach/bwv273.mid create mode 100644 data/raw/bach/bwv276.mid create mode 100644 data/raw/bach/bwv277.mid create mode 100644 data/raw/bach/bwv278.mid create mode 100644 data/raw/bach/bwv279.mid create mode 100644 data/raw/bach/bwv28.6.mid create mode 100644 data/raw/bach/bwv280.mid create mode 100644 data/raw/bach/bwv281.mid create mode 100644 data/raw/bach/bwv282.mid create mode 100644 data/raw/bach/bwv283.mid create mode 100644 data/raw/bach/bwv284.mid create mode 100644 data/raw/bach/bwv285.mid create mode 100644 data/raw/bach/bwv286.mid create mode 100644 data/raw/bach/bwv287.mid create mode 100644 data/raw/bach/bwv288.mid create mode 100644 data/raw/bach/bwv289.mid create mode 100644 data/raw/bach/bwv290.mid create mode 100644 data/raw/bach/bwv291.mid create mode 100644 data/raw/bach/bwv292.mid create mode 100644 data/raw/bach/bwv293.mid create mode 100644 data/raw/bach/bwv294.mid create mode 100644 data/raw/bach/bwv295.mid create mode 100644 data/raw/bach/bwv296.mid create mode 100644 data/raw/bach/bwv297.mid create mode 100644 data/raw/bach/bwv298.mid create mode 100644 data/raw/bach/bwv299.mid create mode 100644 data/raw/bach/bwv3.6.mid create mode 100644 data/raw/bach/bwv30.6.mid create mode 100644 data/raw/bach/bwv300.mid create mode 100644 data/raw/bach/bwv301.mid create mode 100644 data/raw/bach/bwv302.mid create mode 100644 data/raw/bach/bwv303.mid create mode 100644 data/raw/bach/bwv304.mid create mode 100644 data/raw/bach/bwv305.mid create mode 100644 data/raw/bach/bwv306.mid create mode 100644 data/raw/bach/bwv307.mid create mode 100644 data/raw/bach/bwv308.mid create mode 100644 data/raw/bach/bwv309.mid create mode 100644 data/raw/bach/bwv310.mid create mode 100644 data/raw/bach/bwv311.mid create mode 100644 data/raw/bach/bwv312.mid create mode 100644 data/raw/bach/bwv313.mid create mode 100644 data/raw/bach/bwv314.mid create mode 100644 data/raw/bach/bwv315.mid create mode 100644 data/raw/bach/bwv316.mid create mode 100644 data/raw/bach/bwv317.mid create mode 100644 data/raw/bach/bwv318.mid create mode 100644 data/raw/bach/bwv319.mid create mode 100644 data/raw/bach/bwv32.6.mid create mode 100644 data/raw/bach/bwv320.mid create mode 100644 data/raw/bach/bwv321.mid create mode 100644 data/raw/bach/bwv322.mid create mode 100644 data/raw/bach/bwv323.mid create mode 100644 data/raw/bach/bwv324.mid create mode 100644 data/raw/bach/bwv325.mid create mode 100644 data/raw/bach/bwv326.mid create mode 100644 data/raw/bach/bwv327.mid create mode 100644 data/raw/bach/bwv328.mid create mode 100644 data/raw/bach/bwv329.mid create mode 100644 data/raw/bach/bwv33.6.mid create mode 100644 data/raw/bach/bwv330.mid create mode 100644 data/raw/bach/bwv331.mid create mode 100644 data/raw/bach/bwv332.mid create mode 100644 data/raw/bach/bwv333.mid create mode 100644 data/raw/bach/bwv334.mid create mode 100644 data/raw/bach/bwv335.mid create mode 100644 data/raw/bach/bwv336.mid create mode 100644 data/raw/bach/bwv337.mid create mode 100644 data/raw/bach/bwv338.mid create mode 100644 data/raw/bach/bwv339.mid create mode 100644 data/raw/bach/bwv340.mid create mode 100644 data/raw/bach/bwv341.mid create mode 100644 data/raw/bach/bwv342.mid create mode 100644 data/raw/bach/bwv343.mid create mode 100644 data/raw/bach/bwv344.mid create mode 100644 data/raw/bach/bwv345.mid create mode 100644 data/raw/bach/bwv346.mid create mode 100644 data/raw/bach/bwv347.mid create mode 100644 data/raw/bach/bwv348.mid create mode 100644 data/raw/bach/bwv349.mid create mode 100644 data/raw/bach/bwv350.mid create mode 100644 data/raw/bach/bwv351.mid create mode 100644 data/raw/bach/bwv352.mid create mode 100644 data/raw/bach/bwv353.mid create mode 100644 data/raw/bach/bwv354.mid create mode 100644 data/raw/bach/bwv355.mid create mode 100644 data/raw/bach/bwv356.mid create mode 100644 data/raw/bach/bwv357.mid create mode 100644 data/raw/bach/bwv358.mid create mode 100644 data/raw/bach/bwv359.mid create mode 100644 data/raw/bach/bwv36.4-2.mid create mode 100644 data/raw/bach/bwv36.8-2.mid create mode 100644 data/raw/bach/bwv360.mid create mode 100644 data/raw/bach/bwv361.mid create mode 100644 data/raw/bach/bwv362.mid create mode 100644 data/raw/bach/bwv363.mid create mode 100644 data/raw/bach/bwv364.mid create mode 100644 data/raw/bach/bwv365.mid create mode 100644 data/raw/bach/bwv366.mid create mode 100644 data/raw/bach/bwv367.mid create mode 100644 data/raw/bach/bwv368.mid create mode 100644 data/raw/bach/bwv369.mid create mode 100644 data/raw/bach/bwv37.6.mid create mode 100644 data/raw/bach/bwv370.mid create mode 100644 data/raw/bach/bwv371.mid create mode 100644 data/raw/bach/bwv372.mid create mode 100644 data/raw/bach/bwv373.mid create mode 100644 data/raw/bach/bwv374.mid create mode 100644 data/raw/bach/bwv375.mid create mode 100644 data/raw/bach/bwv376.mid create mode 100644 data/raw/bach/bwv377.mid create mode 100644 data/raw/bach/bwv378.mid create mode 100644 data/raw/bach/bwv379.mid create mode 100644 data/raw/bach/bwv38.6.mid create mode 100644 data/raw/bach/bwv380.mid create mode 100644 data/raw/bach/bwv381.mid create mode 100644 data/raw/bach/bwv382.mid create mode 100644 data/raw/bach/bwv383.mid create mode 100644 data/raw/bach/bwv384.mid create mode 100644 data/raw/bach/bwv385.mid create mode 100644 data/raw/bach/bwv386.mid create mode 100644 data/raw/bach/bwv387.mid create mode 100644 data/raw/bach/bwv388.mid create mode 100644 data/raw/bach/bwv389.mid create mode 100644 data/raw/bach/bwv39.7.mid create mode 100644 data/raw/bach/bwv390.mid create mode 100644 data/raw/bach/bwv391.mid create mode 100644 data/raw/bach/bwv392.mid create mode 100644 data/raw/bach/bwv393.mid create mode 100644 data/raw/bach/bwv394.mid create mode 100644 data/raw/bach/bwv395.mid create mode 100644 data/raw/bach/bwv396.mid create mode 100644 data/raw/bach/bwv397.mid create mode 100644 data/raw/bach/bwv398.mid create mode 100644 data/raw/bach/bwv399.mid create mode 100644 data/raw/bach/bwv4.8.mid create mode 100644 data/raw/bach/bwv40.3.mid create mode 100644 data/raw/bach/bwv40.6.mid create mode 100644 data/raw/bach/bwv40.8.mid create mode 100644 data/raw/bach/bwv400.mid create mode 100644 data/raw/bach/bwv401.mid create mode 100644 data/raw/bach/bwv402.mid create mode 100644 data/raw/bach/bwv403.mid create mode 100644 data/raw/bach/bwv404.mid create mode 100644 data/raw/bach/bwv405.mid create mode 100644 data/raw/bach/bwv406.mid create mode 100644 data/raw/bach/bwv407.mid create mode 100644 data/raw/bach/bwv408.mid create mode 100644 data/raw/bach/bwv410.mid create mode 100644 data/raw/bach/bwv411.mid create mode 100644 data/raw/bach/bwv412.mid create mode 100644 data/raw/bach/bwv413.mid create mode 100644 data/raw/bach/bwv414.mid create mode 100644 data/raw/bach/bwv415.mid create mode 100644 data/raw/bach/bwv416.mid create mode 100644 data/raw/bach/bwv417.mid create mode 100644 data/raw/bach/bwv418.mid create mode 100644 data/raw/bach/bwv419.mid create mode 100644 data/raw/bach/bwv42.7.mid create mode 100644 data/raw/bach/bwv420.mid create mode 100644 data/raw/bach/bwv421.mid create mode 100644 data/raw/bach/bwv422.mid create mode 100644 data/raw/bach/bwv423.mid create mode 100644 data/raw/bach/bwv424.mid create mode 100644 data/raw/bach/bwv425.mid create mode 100644 data/raw/bach/bwv426.mid create mode 100644 data/raw/bach/bwv427.mid create mode 100644 data/raw/bach/bwv428.mid create mode 100644 data/raw/bach/bwv429.mid create mode 100644 data/raw/bach/bwv43.11.mid create mode 100644 data/raw/bach/bwv430.mid create mode 100644 data/raw/bach/bwv431.mid create mode 100644 data/raw/bach/bwv432.mid create mode 100644 data/raw/bach/bwv433.mid create mode 100644 data/raw/bach/bwv434.mid create mode 100644 data/raw/bach/bwv435.mid create mode 100644 data/raw/bach/bwv436.mid create mode 100644 data/raw/bach/bwv437.mid create mode 100644 data/raw/bach/bwv438.mid create mode 100644 data/raw/bach/bwv44.7.mid create mode 100644 data/raw/bach/bwv45.7.mid create mode 100644 data/raw/bach/bwv47.5.mid create mode 100644 data/raw/bach/bwv48.3.mid create mode 100644 data/raw/bach/bwv48.7.mid create mode 100644 data/raw/bach/bwv5.7.mid create mode 100644 data/raw/bach/bwv55.5.mid create mode 100644 data/raw/bach/bwv56.5.mid create mode 100644 data/raw/bach/bwv57.8.mid create mode 100644 data/raw/bach/bwv6.6.mid create mode 100644 data/raw/bach/bwv60.5.mid create mode 100644 data/raw/bach/bwv64.2.mid create mode 100644 data/raw/bach/bwv64.8.mid create mode 100644 data/raw/bach/bwv65.2.mid create mode 100644 data/raw/bach/bwv65.7.mid create mode 100644 data/raw/bach/bwv66.6.mid create mode 100644 data/raw/bach/bwv67.4.mid create mode 100644 data/raw/bach/bwv67.7.mid create mode 100644 data/raw/bach/bwv69.6-a.mid create mode 100644 data/raw/bach/bwv7.7.mid create mode 100644 data/raw/bach/bwv70.7.mid create mode 100644 data/raw/bach/bwv72.6.mid create mode 100644 data/raw/bach/bwv73.5.mid create mode 100644 data/raw/bach/bwv74.8.mid create mode 100644 data/raw/bach/bwv77.6.mid create mode 100644 data/raw/bach/bwv78.7.mid create mode 100644 data/raw/bach/bwv80.8.mid create mode 100644 data/raw/bach/bwv81.7.mid create mode 100644 data/raw/bach/bwv83.5.mid create mode 100644 data/raw/bach/bwv84.5.mid create mode 100644 data/raw/bach/bwv85.6.mid create mode 100644 data/raw/bach/bwv86.6.mid create mode 100644 data/raw/bach/bwv87.7.mid create mode 100644 data/raw/bach/bwv88.7.mid create mode 100644 data/raw/bach/bwv89.6.mid create mode 100644 data/raw/bach/bwv9.7.mid create mode 100644 data/raw/bach/bwv90.5.mid create mode 100644 data/raw/bach/bwv92.9.mid create mode 100644 data/raw/bach/bwv93.7.mid create mode 100644 data/raw/bach/bwv94.8.mid create mode 100644 data/raw/bach/bwv96.6.mid create mode 100644 data/raw/bach/bwv99.6.mid diff --git a/data/raw/bach/bwv10.7.mid b/data/raw/bach/bwv10.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..3a9b5b447d13ab470305daf0e59cbbc944222d51 GIT binary patch literal 2032 zcmd6n&5jaL5QPhDe^#!2he?nyVF*6~8Ui6qSjj?rH;E=Dn!zwW0Pa}!(&fB>iI3o0 zxb;cI`ns84NqW>RtYHA7>U^Ki6c1EU@B6-9_IjygUq4>EDmW03;|)JO_z3qHPydzA|HZsO+7K`zMpbAAoXDN{)B{C7t1Gq>*=^_u5M{)1Y zrJI{MaP#Sh-?|k?Gv~~i<-bg(-@cgHTPs+S*kro+ZdQ1*bm!g2`On48?cDyFJz7^k z>E~ivu=G=s6hFLQ+QV?RwELk2pr=UBBLjiKtEsM1T~D0}oP`_;BEJ&nD&*u?AV)Qt z{kHp&%f|v^2NM;XtRfB+87U&pwZL^4AvIQNgN((cQkSm6J&sT(RuMrCUO!U$ zD^s6KCm3izEgW(z-`@Pv(n@yn;;x@O>HYYXcW+8>7Yc64Q2`zG+VRdB0*$am3I^T# z7klIXs36BZ zGbyG-0La@~X4}1}1ISrRM~&$g0Xd6g*9qQ4;o0BBo9Wlv`6A~}fJ&Sf&{U62cZ(y( zN*#NuCQu7IVzL}S<*MXWm&XNTQwlb<1~t|e*w`WqX5}qev_f)ADn+nh2>`s}NL>Z% zE(gS%SPmIeKwbT)U`;^FWE;)dpZ_QDls-Pl4UrW&Q9maZUj9Y@2K}46yPU(b`XlL& zybux2!*%2CAy?JM`h*TP-UMSXDh07Pko$qVmj%jU8>nzc9&dqysOS*+p)3wp7TY~% zOSFemaZa5>9j2heiZ~VL1O+|v`a5Po$a|9SxqM$>-$6;B(Hq(%(-04`jx^pSiNpQLoo zmHzTwK5|$0WWJd*XUL0YnSHVYOA@iT|ZZ)WfIU7yXb z!ruei{7jOC5rN6rM!(qso2LU^Xi zndTFc90=QXpQ!u9%i)VD8{TEiTfC14U+vDCb<@JdE%(*Hb2$785x#5$jG?L(^%amg?(g<9B9AoD~r_QC_m5g+>uPe(F3sVxpTfesUgsCP}k6P2b5z&4j{Rua=p@AY>ctuq|dKqi0{T6K3`kuLWCZ%CYCPXsCO}C>-l(3f)WWGYSFp zLI&l`g+K9{P9@{i!h89uf6?&z@iFIIsw%6x#EL-00TH%R*BH70ZUP-eRTaZ3=0PIE zGX|%CQ}il{u;hd>GfiX117R*z=L;cK%tbkR*lv*QJhG*x*>$x@MLY`Wj#1>$w5++x k&Qlekn9Bl+Ffuvx+AdYjd%2Dbg}92(aSjT%GScJt2Xt>+>;M1& literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv103.6.mid b/data/raw/bach/bwv103.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..3503731b2551980b82e24842937b214b10afc0d7 GIT binary patch literal 3127 zcmdT_OKuub5NwYpagLBnU}S^`1L6}tMq}A4vq;!kiX}^lOoVd)E6Rc;tDGlC$xS9z z^Il4C{LsitvZB<})t~C_$IbHLvzfiMBTG}eS#G|VCBLjVKDk|g+uS{_?YG$<8}q05 zlq5%1d`#2i{kyI0Caa(JJTco%38nz^)z+Tp01JXeXt|>03KoH!mOQk?pA_es&ex?g zaxqTMq@?Gooda?{*uqp{0MG@6%2z-BsR2-FaKTP1VoK*3Wto94i-1zZI?J-4bS}G} z#eqt2y!)MW@=Y5`=W&zSm-0pjMzjN?85aMvfaH~|cO}!EKZ;RjLNL ze1%Fe;vSAHJf0Db=gso|alNT|*!$#Bvo1jwphM6B$XH`mS^#M2(n238EmjN^xyOLL zlI3%WuF=&DK|Yc}O=|^|OJ)3zT}TAAtiH7MLGPFaS9?Ht-THfZMGpdcpTGiog{2hx zeBjI_>2U!#N-eus@sw4V0;+h?HLusL7P52wE?C9|fanscX0^mp7h=hhQOqnnqom+} z(B$sv=`~m6`N0*nSZfQlwh7t*`|b)^*;s?=8vrc=vYG_Vk_Aw?M#X8zcfJ$-76sKiU z#BoUhTv7nW3Emx8I07lJWsQBb8_KSG=rE~!d=Zec#Jiz(6i12$bi^TD^~fh+`I`OO Il>a7w0rnS2MgRZ+ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv104.6.mid b/data/raw/bach/bwv104.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..2aa74f7f9fa982704fdf1fa9887e6757e5c3bd78 GIT binary patch literal 2704 zcmdUv!ERDv5QRs2wS5F1qJ%&Qg%SwdKnP8{Dhp-TM59Ji4D|tsalx{W;9I!$J>2*v zIOpEquYY@+KkdfY4V=tBbLPyMfwRT?H)i(2o>`XJ*<$_CtoFfnd;90B&+CiJmHjmP zZ6kf{Uf1^g^HrABULI`idb<2(o2l9LOkn0PI*A5Jl8cGw&KTi*lF;!d%RfNcl*j)oUm)bU=hE zBHY$Q$!Z$$1kF^@9e^)X!Bfp40^z?DPg6kEpM)M98!o?=t_}nSh0ktO>GNI3AdHL( z`>M*wMW|Jd1;)iLLNYvnsJz-e8~{rpIe_?l-}(7IU%b6strP#216@ZsD>oHpMNwZl zeODbNSEYq26!n(hZPP1U49xI6#PWg8U&5lM|Ek^TUayoHx zPZ3!MfTyQj=m|41s-q|IbOj`X@`vP*%oOzE_k@f<7@ylO{afZ2S67K^t81`&p)8Dn zR$OQ+r|mfnfrf*o=4m=;3A7xLlO*(H+0j;&2q}lKp(nMd3rN_ZnjShJho@@OWOwH& zyFa~gnDjo!!cuURvpbS?M{XUfWP{a{O6(m%ayU)yj}|1OrzIIWlBR&phAp$xD987n JJgwry{{ZkE))D{! literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv108.6.mid b/data/raw/bach/bwv108.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..20c50aea1fd631c95c868d082948715ab897a6a2 GIT binary patch literal 2812 zcmcJROKuur5QKl@$>Rt)0}>$H2pbT1!fOP=Y{DX$oux#ILdsnHPxZT?zsJwc)aoZ@~xUZ2b0tWTxHidu^Jx_A+ z|K`KKd{8u&bYK21rW!)BO3R7d#_bx1t6JGr1+PDSDLbiwW;d|e4F!f-Fwnjg8VQUH zOavwdGIL3lvE7OKVr&YfI H|Cjs$%<=TW literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv11.6.mid b/data/raw/bach/bwv11.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..abcad137d36a7fd0ba34042d9695c5a8ecdbe219 GIT binary patch literal 3343 zcmds&&2Car6orp~Kab!uv>_CF1EmzW@>9|#9m&AnSrbh(nqsIAK#VaA9CYA7-^NGr zO>lqr99Irpq|P**v@84U-?i7iTufiTbk03;4_u|RT`YM7a2Xh4=U`{pwX^suZ|S3m!x4HXqo^BQN!fPSvPPYOStu`s&^RCo~#p_e>k z!eMnn=1C5WI>0HG)7Wx`<;*PSfO7)_c>WXN=0jr|M;n|_of4`Z&1L4txjgZ`&d8Qt4Dc)PaD{-++|VVUxm{}!;RQD%mU`?9ZyTW^D1N}%X1Hw0=HZ`^_k9D{v(V`OcwGt?{ zx~=-%nS;jS1N&|V_Hg>@dN$wjJ#RvJ)244SG@t=!7?4_ZPx2Ad@{uJP+Vc1l3GH`b z8jGS@RBz=LbLK=^RQDEh_D8e%q@Go@%?D>KyorMRT>tHW_I26lIkfsWb7?6@Fm@EP zDtfgGIk#8=^q#={iGdE(acYr|QHPJ((B7l%gr%s2p5&ZRBC$OBUC_~VDT)#l-o@El ztV8-a#&VqdgbtNiQBlu9Hu6cJh3aBs2T}6T6w0hx`budE`3T54N@!C+W)Nh2pr82# z99-Sp?6^-|W1V^GmZ%0VH3L;Z)j$I_xmeAt3sHEDaH0|v054U554Su%+yGBa5^_96 zI%H9aXl5(1CTR5|I-;IUWE540_jN#xER_^FOduTQ#l`{qIxveCSH;4<_5geNQ&55= zk?_?ckD|otA!<2{qf}Hk6E$Wf5P&wQ#_HrjhY~;yAt5bUwtZ79p+AGWGdC!)_6sBq cRiXuBBowRCp+;8E`!Kd|&XMMG`Q_L63sUlW^#A|> literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv110.7.mid b/data/raw/bach/bwv110.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..53e707ccb602dc52b37d49b2247537c9353ad2e3 GIT binary patch literal 2056 zcmcJQ&rVul5XA?)tuA~3cip>?KnU_DAVq;-)J<7fb|y73v5^M*04};<;ewax-bd+k zbc6G|UQa&w$W1lr%9EKhXJ*bfSI);b-^}cz6)Z{Yd_21~EBvNz57+oiK7^9O`Ias;B z0US0}Q|+Y|eK<5dLFdGQA_2!!aN<$rh9(TE)|GV};=~hbQ~}MLwFoYt_{lHe!}$7c zI?MTZJFJL9@=U|_Nb#yl$?LDN$Amy_0213CNe2Q$eTVIt{?fDLCL&L>7>aEq7a&!vvL(3e?+$;h!EVIy3KT@8v;+MNU z+d2R6dFtV^2;{|YU&j7ds7~u(M(+@n7uGwhszDJhkiu$eJ{i5Eg^rY2;SUkMxp&3h zP-lgC5_X!d-S%xcrbpjwOry!?uaC{>7+%IkM*xgXEHSjk1`+^sJONA$h`T2Ng)3qG z3LT}~gNB$H;_!t@=eL(-I#E9vb@QQ|k8s(9EhG@v8BY;=Kz`YeI_bF!8$UFvAe8vn8 zmc!^G7|D_i5hd!he5X)%YQ2l+`e=)m5kysZ7W4Aa6?zEuYHEoUrBY>4sRJfqa3G?D z`}C8aT6%GF^FQmbu>j;#&vQb; z6Z07WDjMi6MLkrH{n4qX#kjN#XgCg~9izoRb_RIt#F+SzMMU)>6K9RMEOM@g%c49Y zyhTFj?Vu@>(1h@c+`)pG534IJGypyFFgChN!zR5HC5wDik17oEl$mwcUJT@J8~*`H CZG;{G literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv112.5.mid b/data/raw/bach/bwv112.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..15dc20db5fb661bd845f17f474e35ad34cf49b5e GIT binary patch literal 2857 zcmds1OHKko6nx_NIf8dkf+8OY1c8xYOkBxA*_mi!q7j20z!+m#xbQeG-Fgd8;TEf= z+e(k%ti_E~Uf288E9bC(ab{-AwqQ|YhyBr|S?8S_CkF!(*M?(#x^N@d+{A!jM`Us zSw?Jf)h1T$5Ok6=>)sx8=r%sJ$Z7pT#uHtVQ72}d9~_@0v&v*@8uKcttS0Ml<~bi; zTl@qqE=ZjN;FWLi1Pwg33EBzAKZzVjhdPw5&4P}s%04T&mvqJ_z?~a_W9%}0H|gcm zrTi>QpfZ~VH$_(Jg36k%qlmw9Xy{iMdZ~YYJsf3xTI&?1j{cHLevv{oE>r_YK%8ly ztXWT9#b9bg=uLI6vlr(HmWHm51Hfa7Gv~wmO{Hp;yH~NGzz!ojh=?Oq8+@V~8BY>Q z@=AG~sl+-Z)Tt0ulI}PP$EeX8y!$Mj{o$(QkX#{f={S>%05DSGlWQRk{(Dkce$>#v zpZp+qPH%5B?7PmP*U@8o4lPzBrwC4-AP-RBKm~wJf=vK%R8Z*| z83~&Dh?)xgk9Fi@d8^D5loMG1=m{w=S;`cO94RIZbwNETtH8>XP|MVcE!nezrS<7Gn|gTem1i=wq{Xer=!WaS?R!Luikzbf18|Lj_uCu zkG1(T`&25e+3aH!mDb-)?Y5sz?WS)Y=rPjsBLhYTh#V6f11OR&*OS1IRYO#r5S+~W z-2SuAldMs+swjV7hyXwlJUYq&piq)!g<{dKK#Y>*M?C*kyA*R7WpEE%;;D)!QkExV#JmVaI>Ro-j%-u# z;J8h0*qooh?W3F`d0mct{K!)}US1WZX9mEPsYa5*zDZ!;d)W8&=*#7Jvf>Z0MIJ3Q zXp$lcH3%B>h@+?+j~S%mSdmtafRgJRQAcu%otMpW)0Lyn-j{(s9I6p7Xy-b)Q-mUU zoh*6E9ZJVL3y89krG|i>b~tngVU56S`&?`vi+Kc*%x~_H);l%9q~UeO_RBg$g{(7jvd#ePTqb8mDg?~YK2?sO^#2D7$*cbYX(*;1 zcc?+`HOfL&y(cG&uA@Hcyv?d@RP7S%0%(LzS!4ht2PfF%2{uu_MX&{+p)!ehc^jfn Vu)H@5eX_67vCuv-EgokU{|kls>Jb0{ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv114.7.mid b/data/raw/bach/bwv114.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..3dc190e2b1df13a14df671798599c794d80575c2 GIT binary patch literal 2821 zcmdUv&u&s-5XGl>{qqRELeqc*3Is~{8whFAl`NE96HQDs#ZVuhF)moR=;OHTqxb@S z1#y1&ew=)GFRkum#mUTkXJ*bE?#2AWJ2QJ`N0uaZF<*T&E3ItvR}2>**wrG|tOC{p!t>9o6;i*^rUMuG?F#+(2R zhk#)$W>oCb{c-m|sJrjI&e}Gww$8hA=Ox2WUmmhuexN>+^?kA)pcezB`irmI8VA($ zu}kr*9w};yruS6lNbkkYQgg^F1X5G+bV+qR)nUR;`YJq^tkJ83*+RqTL3i;zTUo9Z z7;_7x8v#azYUs*;Bkurt2hNipV}RhKx&TffljtZqlXylD?hF>q6Am|mkeWak`}l|Z z`04!p)pBL~zn>aJ{WXznBG8~)!@IQrEeCBt+d)3nWc;S5B9D6nM@KC@f)m>m!y{&a zCN1DmZR^AikYVhPc`Nd^Fa?^X0NjERbf*Us{*o3!|qZ;`baTZ zAupyXlbsf|r@Fc;;w}aIa$)JWdZ6){z19XV!85X&yN$43?VyHw1$A AzW@LL literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv115.6.mid b/data/raw/bach/bwv115.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..ea926d4383927c77a5d810f86a95768384c1d6ef GIT binary patch literal 2398 zcmd6nO==ra5QJOuDKFPzw&h^Z@+$z?NWOZC}^>=-T~HUbe1`gCP!0I4l1hNlQgodN$dqlmsn4X zF>xGH(mavIn%byM2&mePlyOoYM?kg|r5{kU&k|>(V{ee<)>T=%9?Ga)GsBz6{U)Bx zKiw{tkq>;#!dXHJp#1@0;9v+Ch9Kn@(2N0OX@?`kBaaBEvVfjY`iMGY4Vj*|_Qg-6 zA2p_thcr*m0|1Vl0#3K%i1N9hG_pL@>N2v}yeNs!pw6}h>s`o=0gh2QVz_z^D*vn& zH!2EQChbs-RQnXlZuju!6EvZ9(-WZ=q-H@JsM+Q@<)!zs0gKgB3Zj9vHe2+0eZlJ AdH?_b literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv116.6.mid b/data/raw/bach/bwv116.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..e525481560bd05d1f1ab7cc56d5120c7896f5b6b GIT binary patch literal 2137 zcmd6ov2Ges5Jd;PiPNOdPaq5i1VW1!1VSLYGDSjXDUl*2G7-)PxJW^ff-;|zPf3}d zh{&Af&+BEjdftI-pDe_&L~Ql#-x)PD1= zGP$|CtJsMKIvRd`8)!Q;fu=(b=sC22Rvgh_15&70M5j8WI-XKzMH*=3(x<)s9EImD zqr+w+wFfYAAK>MblJ!cdxJz+2Kkf}Ven#gr2U#bOKXR;#aswn7@%OW1+HDdDr<{}HtI}!&1|qMfvaRf13Dd+na+~N7|6vGH>Dsh z4#mO8DwyK}b~rcyc3iqmsB{-&7BLuWi`YP4pl@IxFbM0gE&oy8H&b5Jd;f8t?1oB9 zHId{yar8C4D;+j%S=!dDE6`2m_>#`iTYL(4y}xrXkYsniMOPN3BSd!A$~sQ^|+0ep=B)JCvd*{+)7i{1AC>d-V6xzZM{bMbZV$#s{v;CoMrS@e`J z7@PtSKnA>Of0}9^&)?iES9@Md1PH4w&DgTGO@XF?qNSnD8s;Jk(2`5(yJj?()LIN~ zDoec@YO2a~$HlH41$Qh4%m1>4?XLT<4hnMLuI-+a3F;t*Ebi0MRdq403a9V|DP*;k zrB@2NUFD3*VtT9xOsYQsq6ptYJXf zs>)I|a42wS;7F1>GEf#M8>q-t@iACj!LMn-y0X-wCQvhgh1;QHTvY{Y3|L_>*W#a< zxwt757Qa|lKGmI1?Fa4knDLLTN8%(n*z!qH}>Q zafFPDBNT}uDuQ+$*60XyF_TCRASWRv>+(J8e#^S2v-h|2#ffjLP4BikwE(SspoNHJ zY?h@@8OcPNfTn=^7__LOyaRxK8xUvhp4v#Y7dfV}lYE_sZ()6Bi9{k4McYkvj=giT zfv1|HNxR&4V#kNUZ&!B6s$)A9iF(MzxV=DBS^!-ev~CDk`;2ch+cWqV z-)8^j?(T%Yb*R<19R=uU%WR@&G?|KBaflZNJ7cd6X-dBSWm&Z#eu|x&p@u+ z;^0UP^r22ymAh$EI0FzI8n_}=EbxgIy2r)gDkA3NApnhy9g8nwB%~J3mR=%+NlK>SzWDHx7ij@aI6!FVd3s5_%8q&5s-c&F(eOVZ zxdj*NVY?J;s-V)buvA(!RIuSORIbZXcS}{E>VOzr4OLcFT|mL4lLa6+^1%i9xG<

0_(UQn}SPBeJ;!Jn= WBsx3i{1@Or2N^X?7PqIdKlFiwymGv-x^yJ0GhuPWr zMfefI&oJQ6{8gp07UnOj)ylJ{*WqT6eF;~C5N?Kmp};|Q9j*>ya75%tk#TktuEqib zB4qi=S;Oo$uj8jNmB~5*oCr*)Gg(Abhscl#|%J&Qc zpd%gL?tL(1b6km^`egN&BeH`?kEfnMq)hYVM<#%+HZgICw%(kw%Ej50k<|+sPWKcK zBWsFWvjCcVENrD<(cQNAGjP*BS-DXHvrqcIx_1Dq$&oTWU+>mb^orJ`4bt6N zT?%&Nh&9`&LpX=xi~u8narQkwUq>R2T8x(N@3Zdj@$}94#Vqk#v`g(>)ougY0zOHD zHV4R4g52irR?@W}JoA$m)y`y9PF7Pm2|psw)B?{e%%IJ$69r9<>{J$~)M1JxJ>F{6 zU1YATY*J}nky?Sa=^{9H6B}pqM>*Q-yec&Aa%_zRD)mfK2My&FPYbbuB<^ zp{MBHV()pR7;ulsUd-`;Jq{3m9Em(s_wLdG{^AF4cy@W2xW63)?Wke|)SgHa9Zi7- zoQA+QV0%F>I96|8JfREL*+E@d_n+Kihh8*|3M!I+7;4IGxuENmU5T<*u0-9j%)J`) zVw^gk0m2+HC(@(ttS3333jVW>IC&j`l@DGKH1A_?{&OeIL_DBvu?Ys&yv1Bw%Blm< zvkBM~*Z^$A5p$f?#0}Q%NF6;(b2+QV$6OQHk)(&J%;D0&+OpID literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv122.6.mid b/data/raw/bach/bwv122.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..9192b2461818e92724f41cea9e7bc1f05be3ad9d GIT binary patch literal 1615 zcmaKsOKuur5QH0>JdThnSjfb}HfRhU^UxrSJn|welG#~Gq)3TOgtLs4Sws7f z*rVnvSXcg(X7`q-4pdRkB~O=2y3avEPb27PB>*IbIK+<}mYd}{VEJTNDRZ!K4Y&>~ zJ9gI`Mc0Skclv;Gr?=4Yt(K7ZYHgBX6i*mp&m0Z zUc13hzrnM~hui7Qp8gQdSmWXOXfB>sphczSJ>`VTmB8~dv%spJ1f&%#=vqY@4%X68a~sd?wQKz0 zi|F6n-R(F=i+oul0&MKOs;H+)KuvGf@^wdg4&|oT#n@k`jNA= MjzEopwc<|y0A4${)Bpeg literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv123.6.mid b/data/raw/bach/bwv123.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..dcc0241e3e71834cf2a3557ec471c86b53df0eed GIT binary patch literal 2686 zcmds%y-piZ5QWFa`FVsq0|>1^u=d(oV=v&9k*MM#*$xRLBqAJ{Jb;T7Rw~LADN<4A z5%MU!iJ8y4Il9&o_fYN8%$d1!&z!yIlj}<}dut7Awd{N{yD@8ix8>HmkJGQSi`%LF zHG8xHpXKLfvti3mt*yp~_Y1o}EADN6X3v3f@zdsGPvynJ=DCAY$fv7_10u&njvZuh zG6w^|UHt+og_B81pD~5OOcKd)sE@+ ydGYs>hSDd{(A|de;wYsxN%a08W5K#Bur1mg_7ZVY;#T;r8-h$&q?hGQgIb~oUcskGOUx$?SI?tE3ZF)J#_dM zxwMQU#WSqpaIDrt99Q&Q85jXZ2IObN9x4(fpjefQrUcx$9Ud-?J3U6abyUSF3N@!Q z+k>4R!g>Z;oG^E4mE39crLX^z=1bq)rNRvkhx_^Bz)!x(%BHQn09<6W2B2+IK}Z*{??klg7{JIm@POoG0x$;prqBw<#1JQ8_YD13>CF?~Y4Yf-uHa5rq~OrHVpl Wav2(XZqPPkP@AQvio$CCmHY+t>ODCC literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv126.6.mid b/data/raw/bach/bwv126.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..0281d6aae45f11a563d8ff00e9b637fe1e77938d GIT binary patch literal 4522 zcma)8O-@r`6#bO?vjmqwLI?#~N}(lfp@B3s3}m1kn2=~LyIlY&Y``-6>FyiF?o_p^7UYVYLe4kQ!o}Q#eBTY{)Kc%$vH_ew`yuSEyd3Ju0 z{-pFT4ftpN_9?>VZyJrKuU=lKoAK;AeH*7La6s3=!u7*q4rc&|upH5K1aL?|i|WWV zp=$z{z%ebyF?}+-u^72>5Yo||=@Zgm<80)=2I&P2C8oeWrQ0u#>{O3Q^*&iVM#PROID@AIQveCBn91ztoxCo>(d?J0 zpAYY*sc7^_qX!y$1l972k95{J0wc~fLLFJO zoe?Y3mD5mVfe?cgm_7ie7+TO0f>D_k_0n7e-Z9mXP~rMf=Yh|b4j}OH?p2C`MnU;J zOWnmsARItV9b8oDS|G~<18Ns~JNad5Qfa75sF_qTp#=oz{p|7*b^$^*7%d&iS-*WuQ{Ki-2+3AP#i_4mS9(v@+s~6bik&<7jxG(nCP59MsUr(?e4b<2WHk766+IBXcfoEOhr^6|A|1Du&)7EF6}CPde(jZUR7(jL!ovSLU~q)8d?ju$WSo?8c;yH z5V79u*3v@^DpQRP`BYCKRaH>R5Balc?;B$BtDv*#v7m|Robz;@M4KbG7c_j*HdQTI z(2JH953&W&Ca@T!mrl#)>a()xj9|NPrz#P2En!l`*c${Wd|Ub?)=%*RcFTX0MrT)7 zHQz5uwn0K0i!lIf3~;r<+@hE!gPRCmBUl4i@uWwh6W?W3=Yb)C+2^Hq#4D^IjpQJl8tY*U^20fI6%48ZFeY zNkCNt4X=||-lB9i7eHYysi78H!6sX5qJ?7Q${%xh7-&)WR*H|Znp_IWcL^*Qy?Fh3 z@Cs?Hz}4i{GE3ir$E-;w5yV7Oo?kAeRDB%4q}3~^S_*>go%^I=E>|NwT?E_HbuqWO z!NTHnv^q#lnp>*)pegxiQYo)>D{GzI?I5uNd-zDV$B1!Cp8^Eir1;p`PVoV<=K#Pg SF;t5dFM+OAZh6(dP5%K?E5U65 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv127.5.mid b/data/raw/bach/bwv127.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..6f73b789fa6c1b8272ae7eb4d8fcd202b418dfa9 GIT binary patch literal 2380 zcmai!OKuub5JjI!C-D-p2aAs|AMFSR!_I~bS-dg;6~ua08g=;C&BGLSSKFE-()x zWlz6y@^WKfX=D<{C6-E9;KXD)qxHJ&Y8ShL3 zKx2T3d`&D50LuVe&?+tfWpZzMqE=M`d0c%gPQE4ssSD5Uvz^_`^~d||?#SmQSc@en z>?iP%haUmf+WYciK{Y(sGz`>~ux6ktP&Gh_;OvZCZg3z~zIX##JUut` zq!KhwhxE*Rhz!(NAt4jv$a*?5%?C1;8D?O|TZThFHPw=Lrh)e}HGgJLRdFg0BDo literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv13.6.mid b/data/raw/bach/bwv13.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..9886b43669fa8320df4118cee39d212f396dc572 GIT binary patch literal 2056 zcmb`HOO6sz6owC2J_atpRUm1)nm`jC5(t4Xl7TYo#7;WtPGe{n;J^VxhAzh?xCGbW z0;JDZb^UY6#fm0Q;Lmyd|9Rb7u5Lb<*)ywImf3Q(y)~bua_W9L(2WO4kCgaLW?c(!pZAFD**12v%0a zEK%n<5*;Bia*0#*gsfC+w*LCNW-&WBVotME*ne+lLKhS7;&0kn5X^WrObsdwVP}We zVXyU~ zsHa!(IDn^*1rUk41;WVU+r<(QdJKe7Ovq9@5|t$iPHT1x3!BnKc{dJt2C__W5u;8; zm`bSAD8|#v`2-&AqJmlDjaE=hEV_x>Prr$$tLyvC*8cp`RmgymvrGZGRCSk_uE(Sn zxl$mW6bvC8I$;OUiGg_Jl0~4y11C%OA`n&Rb1iFjaQey=d`TIXPAG{U>m{oTfTsgM zv<+xG$N_n5QO#*R(o&4HTBx_G2^FmLoUGiU&6i(;H&+i26^j>9bVA++k4_~jMq+Km z=vfxUG?+reT}?pK!5QG}q@{(cY_+JKURm1W(uRVKu8&-MoE!^ZGtVV#5z__>#H)DYbU=l~1V^&_QpzES4Z3=%X z{tPhN0M!6YDaO$hKETC%wTo46cEmYm{d+;@Xgx2hcVqkgOp5P2&vb-~1nFd%jP>nvI zFEC*AL?YmvuXj0FA&_lYO1@)hD+X*;4xjZr1)K_;0nP;MgO75|CwWNup}?W4|CzEO z{h-yrJ$tF`t8<2IRf*-E&9X0Elp}N(tu9l<+DaYpYB%$V4AvQgjAJ(|D2S}c!ztWqvWb%8;bNLP^#Bku^b0qr;^MQzG9nHGr@A0OR+#*J*F z!3mL*IO2N@?nj3uT1OT1P~VgKKBn`!`a}Sx+YT?9AFy*$=y-3sXYb}yyeB6El%90P z5VFz`x+F2Xh_>~<+QzngyfS0HNcrXU^^uKfQKO|AUW*RhvnY{jMNr+~s3FioYzwh1 zLhucmM4E~uT%8Cs0YnZJ(?t|ZV3B+%M@RQ3$ot_b^yr6;slF+zck^u;uR;~^7%5X(tH{2(hydeKxSYpFg7q07#g5vkgvksz@JQ1GqIDY zz|;e-09pRMprGNuBt_vQ|5|9y1WF^L2hCHBT$&4iDCPvm0I5cny}RsFv8(f?th+4N zL{~GhOCfr&&QVygC=R=w3OId%@(Lk|p1L7F!s>nn< z8R$ec`(8z5iN;8*rYDI#1B?N{O~8eUFE+)|#C;SGLYPaE>Dl^tc8#*RWG^cOq%yPE zrGe6yhEc9K+RGIQI9Ke>z0X_`jWN)R zpg3m3hxM0*^~vnr&3tj-A1o2A!j-6{05KtM)HqrzE@j-kiqdG<6-C!NyM{K0xUhj) zagi%WYHJZGdZ2LZ#wBB@anJv!W|uOPQTpPYEpZpbt)oxBW8-w>p#Td9oayS!kId|e zf-IjqTCSes7^DttFV0!_<$m1;N*@+d0W?Gg;yLN%767fOD`Cn8S1~O<$iMZkJG#ET zJ&@y?8r7^(U7&8DA63Q1LDW>~Phz0||Th z3bCarqe_l3GA2;dkahC8p;sla?^WEzi99^9S8hAo_PW%@9K(L9=co4E)!2!$PHMS2 n@QN!|$(k7ONOK)o=VO6m1Jtl?OsK1-h+lMr8eYY0Y$E;_B(Ba1 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv139.6.mid b/data/raw/bach/bwv139.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..9d9e592d9fff4263a54f2af35050c6604e6a19a2 GIT binary patch literal 2236 zcmdT^%WA?<5FKs$_=N7d6+wb%#TdjiC=%3FU9{N=EfiX`Xg|P37cRQUC-qbM5#8H4 z$>nfEZ0OQ%^e}VganH&vB#7T-8;B$!K&W6C?_@hvFaj7U7z2!LKo`j&I0z>>f+bSR1Yn|I3NTGA zS__s4MZt;UBm)dT+Q!(S^&Im+KAD`q2z7|VSt!WOq9}L(RRh_{-ZitYhB|xa=H;zy z@IJzPmEOc#t1!S+26$;2^vY&{r@(LPT*DilAhuVf>LT5IIc9qQ~DVn?H0; zDpYn(3UE$*jzv}%=548}mfS2T%Mi+g%y1^OfO2r&B{OA0qqDt9SGq~3^T*|CUGfd- zqLHo^@c=vpoS28DfTarn4nYT&PHOozoUQdi#+LN}dJ0&g2#TEl(4ou( zw%(=Tner;;;kzt~N$E;z`M66Yw2G#!+H2zBgA*<`o02W5VRAK1)COoPur?sgC`l8p zrn*`HEt~AZ;;MyBbIeqsgZ;}^$|R(v4Ogyc9SQ52keQFaL%yPg=RhAS#+OnJt_#W6 wh`QD&OL?{6EPHU}?uv)ngex10g4|FVa5Yj56<|8-$At?Pi(@8ebWRuO2k>K75dZ)H literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv14.5.mid b/data/raw/bach/bwv14.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..6077627c0fbb320180918f7961024d6a37865dc4 GIT binary patch literal 2956 zcmds1OKuub5NzXd%n@=2#7AI^!I-bX2+6Ckh-YUhks>8B5%vMBC<_)@aFyI3+uR|G zoFuqv-b?Ahj3!&hD@r}p-PP6oxL$mCXJ)VLz@o^m7psqEh3~dKJbttMyt=(x+7Gke zHsH_prts&$wr``T@VdCR%{cyQk7KjVgkS&o--qPuZ54OPEgq^%qr+VrG-5=@fs%(wm333Fu4CA?o_&o%AS@)~txg&qTaNmI<y(IZEG(6CwErY`~jYuAaWEH&Nr;DU1vPjk^0j)rF zq)?v(M!XjG^6BA0|H45ZE#BWPS2_Q~9V*&8w|!~yOd4CvY9%9r%$Jq+Ls{}(ssl3W zxF-TYKcpwf!Y9|_i@W-M46yUClodRh|8I(J{LQ_1jiV!#;Z1UyFiMetgORzEQ*P%p zF%uCk_nc>P4xk5-UZv{fbkE_m*@Ev$e_&a4yuzRkR_V?U!2R2S<6Z_PCD2a&6v2%j z7Wt<=y1l>8Iq?>i(HB{EMuX16NRtuT+8}5E)CuYUHG&#Im7p3%L{^I$dyyzI7N`|LbP-5j0vgBBhuI&K0 ry#sKSIa!iXrXFfm_pIv&hj$n>MdTkRp~@w;p!j;caSFY#%zpHPtYaHZcJRd)5q{pd=Z1^ z`)4@Z@;8N;xROnKGIQtNx#yfa|LpSPhm_LO^dz-fX?FSfQ%c)!()IS%>vsB?(y#QA zzw38fzxDgJ)!KUg>?$os^JQ9$Qd*7yV}Z&1Yg$ZdaCHN;l~)Rw&cCI_w2l#&q$S77 z-Z|jB-t&qQu`-(r%mgloxu{nJSn;Vdw$8LN1w6Qhqus{|#ZHuH44|`$jFrHM>(liA z+)4Y-B-g2wUVFK_BX;4Zd`VaH0D=bCs@N+)USZ zrmNaCU40zaUu(1`8yi+C3|qmEgVsq_d~OllyMbGt!eO2+U6J8FW#v@hwpifBLJ43C zPfimIX?m!bKDVa(M;b&!6mQHMo2N^p^Cb0QAFc*~fq-coK;wY(L-t^H1mFR)9Rko+ ze&i$rF+NrFs1p^5MqFeisJx8|vijixEx9Y|Q^Z@%;NZgYLGjAQU}eUR4xUhp71uh! zU_2Z5doPab7smB+)429X+*9JFVXcO1I>z9Tm#rKf>+Jx9&%>K6@jdRecF_)jnD|xL7)z1^m}Z{ZGtv6vYa}G zoZi|Y(T-M}u}EG&AKJTPZzal;BakPjHi)9_W`E$0D0`&bHkiS>))Y*!4yPD6yV{fE VQ_U3zHyd(76C3!bZ(lz#e*nMbCj$Tg literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv144.3.mid b/data/raw/bach/bwv144.3.mid new file mode 100644 index 0000000000000000000000000000000000000000..c5f15e78f8faf8594417cc25f577380c82dd50b6 GIT binary patch literal 2632 zcmdUx&59FI5QS@E`|}8HU56n*goKbE+Jul0W>#jQy&F&vl!;_~fFLfia1rnsd=GsS z-y~Dt^!0E%9ouc(%p7i?s(b3x=_c2!_ixSYiCtKd*!61j!L0Ve4v(I`T7TNy+^+4X z*>6kvcX(5~@V~EGpHevt)Lp$^-!!B_OhZ=8~Br>(PWOCVs^fTUfyaz)6Zf zsRP-f&I_sv_Nw!oauz4UkA2?Rq46gu-#sYF%a5O{QZk_9z&j2B!&s1%38ZiktuaoG z>gpNw)FUs?gXka+q66lc(U}uf3CKjr_#ZWEoHEdWk*mi>MF9$tN=XU3D1$L(^5%~K zBL}js3`X=RaH6}sJP&KQOP!-61U(gVg-hdT{_>UXejm_xFhDG6 z?E^UJ0pL`UL%HP32Blt^QfK)pvQ7llFzOQ&R_Zx-@$xyE%RMYOFIxm;oyrBYCUMH3 z(y_2Xak}ii`>y~5&6+||Bj6m~m0|WJ|NadCg)ic9{Nf=0;2S%+xx1^#aUHGoSZi5* z6He1P4YJ;F&;)SO=26>$`iQJY9mpN$bOE_94tOziB2F6)4a*=$6St{+h<%@E;^z_NxE#h?U?qcT_=K|*j5`iSoT!^_a1~3*g&NJZ=aW2!( z?(Q-({^a9??&Eaf119M=pM7TwqpuK*)v07jQtMP2(kb!+hSG3oHZTApb;`H9jNWF&q!UhIFobcZ9;s|D>9rk5dr)xW$=#dgbskm>B zO>WlrpV_QGn!LW5&h!BP<{fUS`W+ro0~Zg6v_ZBxReqcR+47Odr4cE5)$Mft3yK-$1*fS2IpO`U-mjYjN6Qyz&M# zQMhvjFg&PT^{)4Z>?z{aMT zu{P~U?njxI0eMx$2(Si)aV)amSo4w!Y&Bln>aitMJr(Vqy7XRlAKA4G?@ec{r&L^k;wcuum*F>&7eC8UJu0I-;r_92Zr$Rp zlsuH^QmZRSm@pA+ZDSo;?QHDOdv>8*pNdNZawR#60e<~{;_Kj#aMLSV=BX?`c%{X^ z7=OH*OlzLJE1j?eBtJ#_Q$bREf3yg&v>CcB@aYpQM4bU=%P2L1r9&PRs+3r5)h(4; zt2~vc_38?zx`+QqJ^Ne^UG(AD-QsYLnCEi&;iR0&vsb8a4yWc}d5MJZr24ZE?DDga z-`?NX97jxxv1&LRU^$Sb0W<^=5D8j9Yw1!kT)y2lE;iQ$nu3@K$$ShP3nG9#N5GMw z0g&eqI9ys3j>Y>~hi&Wdgpp6wv+L7h9E5TaDniMHQ2vce7qP-8I#*^_6k;~XT*|AW PSUj`8nV39rc?$mkEHN); literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv145.5.mid b/data/raw/bach/bwv145.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..b8acedb2bf108dad7797c76e6cb62ac636122089 GIT binary patch literal 1786 zcmaKrO>P=d5QG~{5+5O#un;mJempRY_z^aEV-^WJONkUIk%@2)z#zA{X!- zaud=YZ&G?=2rEk6)vv0nhxy{u2QzzZC970yzF2=YD{XCe_U3N&b$$P^vfpNZEahkS zzFaQZ?p@`q{PuinPuX&7o6L@Z>GH`oQ*YhCxp6Q9%;L(F3Y^LEhixVfRMFHN&fHtK zJa`*(q6fW&ghcg@IM=*$9gk0_AUXn!91H=&xRN2tf+--~1LpunRG88`QddPU&mgn= z3C<7>>KSQd<~OMRyT`NNqcZsN?bI<6+$TOS(5KS(N(#XA;lYN>??H787&}Mq$4pVl z4ILkMPKeCMLmUo5ta(KeQa=n@l>sRXVylPIM_0-B5=Sd{d8g~|C=CJGP%J6ChkP7l zJ{29qB|^npFE;g7*wnQOACMdl$dGjsj+zvX`pb{{YVq-5wLb9|Yh$hL4|D;Ag}S^= zr3Gm1MI7)6s3ma7>Enp6L&1nFkdR{Gn^NTp(W||>b5L(n30Cv$RcX>{?v1H+Vy}Et z?cTx$652v9_h|LJr7h$zAu-JN0C4n~2=p*k7+20xR~j7>>lAMIlRsv5|M+;~giYjG zz6E%Zl*@C%NW&|gxT2lwc&&R&X;v{*^-71<@hPb{P;czV|LaFul2D~a(6v}ySJ5#p z;aoaLR%;kz>H=`#pbEfq9Wv{P)1(rDa!w(r2CZP;TX1x5Ic&oT-=A{|f0f9*C)Nxn F{0sEj;{yNy literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv146.8.mid b/data/raw/bach/bwv146.8.mid new file mode 100644 index 0000000000000000000000000000000000000000..704e1be92d5d5c95acb9a868e62a833ce3ab35f3 GIT binary patch literal 2749 zcmd6n&1zb45XGm~emp{7A&6G|KyDB}QN)l{U8HvxXra&&i|GS|(uIo_e1NX|9C?(! ziJjxU`7wGM>7tNqlEciIk8}RxJzsoyXJ*gsiIvNCzF2)UEB&zT(-&`+pI4VxOS?7u zZ3F$=zAbJ2??t&>di8Q`n@PI1n~B+GDlm006PQIn3i4Q-v2y^VAkWfoS)ZwZI>Q+& zqVh@l^=`TYacDS9H+D0ORiX3a+K`P z&@rDn(D;FKdICKMM5r35k2nBQfYAAHC{fNYpTKz}-;J3o?QThNBcfDuBbc2q|Af zr$u@Gxba4R`HenXyuVtm?EcRt$}q1hWtmn7nO2`Bt*EE!2nY>x^B{**ah5-(X8jxa zAr~udh(8=4ClFk9fpQfxr__=29Z$7&W$nlb z_d{}`JvX!dP#px+fgOSJO~De6Ky0P=N6oeZ*PJD!1A(jy0SA)?2gT_K*;Z;~9>?|cxq(mmdIe-^gu*kx<$u>vH zMI!P(rc-WcY2+29*YCZmuIk}-_4%W7?v-n}ByqQ^?HA`7zuf-p^}Eft?cM#x{dVq; zoAI;%&^&9n{re2u!*2)G9e3H!uf~Z(J!jBIq2WbMl$7 zab~3%X8_GBI*sWlUj4i=XJaMA073!|PZqzyxJQ+s+22fplx7U1UVGG|>{O`%;?m`{ zIRM^Q^~5FwxA3;8$A=j_hQ?oe4Ckv)_nU3ampme}kr_M&j1A~nj0xeWGNCfDo|NoU zvL8`mULd8ChKn?oF_tkVk_=j2;{?ENRisF(V<58lNR@!zl))t*m21o{h3bhxyhq{b zQaU++{J zrMeGC-=-w3&mJl*0LlcqG*|MyMCqtqXcCVW#tywq;VF9$g%~6m5+C1mfOt%lt$|~9 TL_UEVr(B}Y)Ftef)r0v5Td*u5 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv151.5.mid b/data/raw/bach/bwv151.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..b848d277c8306864475b0a0fd8caef669065cfa3 GIT binary patch literal 1732 zcmah|OHKk&5NvS#9Kk!VfD8me1}5W72rz+_ER-FICMFs%-~n8?V98Do;SpST6mNoE zGf;VthvP;o-Sw)fyNB`Q;Z8)(q$Hjv*0mBPX(!ZFPUM zcfFZ+_4HD7un-=hCJT`aAOeUK#Aw9|cvKg-9AjpEj+x0Zl-0sgj*%Xfg6FO~E8Ghg zO;ZB4NG4#5z=+BvY!1eudjX((hyg?EJYRaA)5-mOu`KvO1vo;Wi)jP274T3U9IB(0 z0010TcvV)&X@hL(kWA2mSIabIj4oQ;tfd24I)>LSa|dK3q;iA`J}$Sy0qNytW`$nV zp%fCIIH5G6$^Vd0kt_$bZgG V9p>?2fhlSLRvvm)Fli+}&o6*N(=Px3 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv153.1.mid b/data/raw/bach/bwv153.1.mid new file mode 100644 index 0000000000000000000000000000000000000000..d94d06866dd234d79131abaa1f7e9b4b5f69421c GIT binary patch literal 2641 zcmdT^OKuub5Nyae$q{l11jc}|K`{ITLiQ>w5_Xmn$&w=zVehiBtSne^faESdif@9e z=Dm~}Gs4O$&Wcj?=T%oXb3VKLVrFlxU`b-O2qpkxMr1}{&Iryj@H2qv9AKJTHDz*sNDap<50Bo5 zN2hau7pu_u|B$*n>4+oK%mMuw0Q3p^04YOh#sH8}j_VU=ccIwOnTedO4NllOFaWep z4TpSv=oy8yZk>d7s*o7v#Isr1ru^pw7dXMB_w9Dy{q5?=W1v20)y&b3UGG#bpurpy z`wVChm(imgJ%Dt+4$DZ%a4W6~3|E-P{7Z!$O6@>chvN`*3AzB9qRX7XAjG*`PGsap zpXEG6*{kvv`?L@`AvgiZvlk&6rPu!oXcxM5=^0Yk*44(&{_K9^><(sMuNTWb-@RQ$ za#11K+2*rt45aDBC`VP2FGemZxlQxfP>(kGL=%jB6{BR=5aryV$`x`?yb8@4=a>T? zX9EK8aAc+f2!-Q%o+A?)w61~jJXcW_Tm|6&K(;u5P_QoMsIz2<5l~3u2%J*Ssh_LH zNo!yvwaJ{O`6Ky_ydQ3W;GCa0rS$xb@sZW^=%V=1k#0o%_pbDUz zI&2ci8&=-^=cJr2fDuoN9F-(t85QIBs0y#qNfQ*g782rcBmW74H3NMn`A%PSr5spj_fTAqC^dgHKCr8Om zOxMit={XP0GGygay?(E%t9yJk|8#3+yY|MC#IEMc&t|n<+wAOJFTO5s?icpk?2o1T z*?g>d+2%u%)ZV{a**eWu_L!Qjrvg(46M>0?k-*3SHN$LekHe6;P|bxiGl5wMI08(w zUxfq@{!39D;)hPL!O={eZnYB^$4rozcdAqa(I3x2Inc|OO6+pGrVMi`b*{1Ql4RhayWc1}*)hhJ#P|qJi41mT!HG^EWTm=}4&sB3CzB3jx z&KYmMFzrC5`|{d%@Ve@0RvH@%$SP^lI}I`eYG9~&>FDp?DMn(TG>UjVG3CP%4^HGz z-)C%<8Ulv_@L*p!ZRgN;;&8GhM#y1ZS z6|33O+G&%T0!;^p0*4MbIu>*6Oj|&Ucpz}#pe|5%!1|tuIdO(tM`Dgbrmintw~%-h zb+W@e4PqXLFx22VKH~F^!=!hDLVaIB?RzYw+7Q!l1}*$h93SB)mWV(2vN+$HCt$vN AyZ`_I literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv153.9.mid b/data/raw/bach/bwv153.9.mid new file mode 100644 index 0000000000000000000000000000000000000000..b75a0887211d8aec6f982abb7f27dd823fc8195c GIT binary patch literal 1489 zcmaJSXm=!-7&Tyk1GsR(!Uao@<59dxeM52b zl>#d!Z{EC_4qr5Vo{Pw}6vVP5nyy|&3Uf(HH}}i;)oihpACX`2@RK|ibv1dgO2xa| zt?WkeRz5~@3Iw16rG@}Qb0@?kG$-5%;_p;-QNBAbR|=+m-03Trz-w|6Fg){cIf5$M ztMnk`Ar59T=T%{R9E=u2P-zKzXCzxms{dWTXxCQnZF8w;4}m<*(FeeX5%e(WnG;e0 zT+=!ZDj%QW>#`3O0GAD*s*Hs}@ebvOqPfGU16T~yBL82GL5-DSi6cbCOX5GrgM1up zlYkUW>D9-<^egrW&Biy{_|^1jv0Pnv+f8I_YN9ScR{>2paY4Bz<-!&dQZ6b#nw(Y9 z!jONZ@^1W@#^~T+#|+j%3`{5|$iI&KgrAeYT*u|QUS=C@Oxil3Ddk4yLkS+DdYRWg z!)y0v>-B}|ZFtz~Q3I$c;G~Xz5r|X+lZH+h(SfU@69;ktQdCu;sw&0H+;KobRmPpN z0)Al&2U|Mfoi>(HM+HyzO`5ck2D|9eMHei29G5 ze!u+W$GbFc^knAzb7syA_j3N@&dk2pC(AOsoUeYGRc5w5I=))|Uftd=?b+|p=lS>h<*MYHM*CPr`+c?F_x5`lvFD&Kpa`!@ z00p~x)h+6H!CjqD8Lh6g#32%?yF+?~7L^Z?KUS-0&os|<^fbE$BofUP499sux)f3X zI32B^;}Q{YQAKbbGW$xKC&CAV2y+pMfNSX|f>t!3r*=11Y&pK)XMH~hw+{~`=gT}T zP1tgcxJbE^xJ~h&&_(pkT>%xZ{>2 eqy-s?rq(2N3PO$=^XF}I|FY6?!?2qO8 z+P`nL{PSIwwO*g>>~UW1>|t&ZSSYga2w#56G1 zK&7SvQwQh*AP@jUK!dL5_&6~w&BZXo0E!|1KAQ4`@L(U z9q7z?`SV}I$`vG9!NRMN5IGGgz{GaxxT@k}@lt>rE0+{I4O5j*v>|ml>C;|vn zXc(>U${86OpiJ%NHl2!5pW3Va(V-<_+SY!o80(Coc0vM`zSP62=r3@M= zfDfKw!&EDD%xG7*A><=sfgvdXHADttIPl4RJ&L{qY5)|cAQgyXk-(IEa10Lt11S}s zogkrUtSvsGK@IH)B-N!-^=QqReG>O93vW*6HV_>ejmjdQ1QCUEAUtt;!e Lr@Hc~RlkS7qeXmu literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv155.5.mid b/data/raw/bach/bwv155.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..85fb6599e0e50cecde2d2daacace2ea51eaaf9d5 GIT binary patch literal 2884 zcmds3&2Ca*6g=Yf=Mnk}q@fZDB@{yMrGXOKyOM>nYodvXrWoo27-I~}u6zuiq3_X+ zZ{ZSW?)^GB^h1oh){RciH|KB8aMOJH?v0r}wMUjDmQNS&%_`q*_4wJ#`Nzfi#oVsV zep<@^RXzTI~JQud0Qs{1B@7ToLp51(`89HX8QoE0+zP+moH zDpqm;);RI*DySz(r(5Vc;^>09g@6v{(lKFqT!8Yp06cD=Tl4`^f)pSl$ZTn=7q{-b zfjg7z!>4W53~9=bE7DS-t0M<*9Z|9)KTwb49wIT2BekJ+)>BGHmixewrF{`84ILtP zcYdhD2Mr~HvqBJDPfj0XQ6D|^cmfJ8Rr`$49O5{|;--kuTQaNaDBaz?Fqt!ndZld2 z!3H$I06Bx)+M4kz$WPEcj_a+_l2)|&l)@C!dUzr5Vy z{ubq+5o^@92Czr42Tnm9i7QVP`UirVIF?|lpZWm{9W=Jp#KOR literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv156.6.mid b/data/raw/bach/bwv156.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..4ae3e386e4ca2f22788f1ccb4c3ab55661d8eb99 GIT binary patch literal 2731 zcmds1J5Iw;5L|-!9DzGf5QTg|2`C?;L{TgXQh+-okdQzG1sX&{L6L$YC8yvF+=GUj zgdO`aTKie9fhwc*>~CiC!pYTzh^)(s1c8K;*|kXNNtUY{C)2yx`R!CbM82erpXFIe zsms$KC~a-dWigEA@;nq-3;+fS7#Sfl(g=b7X$;O-IUzu(fDu1y5WOTV`T%_;=QUj< zO^4B2G8miYk$=~OBkTpm#sC>vT!b9%Wg^N+dC`ZeDWQ6Z^t1&5b*Azmx+h++sS}D# zk5T8?`jwaU`r}1*FxDAGX}{*O-1#}dPd&k)bMsJie_X==ZH5iISfguKJ;KmO8foKG zTR{t;WjUr!R;eDysN4bQ#C4Q|Iws;OAEMWxtxPlW>gchePF{D{^na{F5%_Op!~k6x zS4*L~5EE7sv=M<~w9?my9D2bBfiF0%WOqI{1)uyny-2S=b1kvU_QW6c#MdU5x6@g{ z8_Qw2M+@8IY?}a03wY5SmK@Sja}Z{V?Q#BMlSn8l_XgMht$?Wn%; z+>3zg7@+qHQ@9|>`|xXDKM^pC5t1n#>ooE3pfbt+geEI{B+e##fbV!?yXW`!1@~9R z&}Hq~0D#SG-@rhK)BtJrm|jJs&XAI>M_SvF5~_%;U5~6 zyHgFSx`ze#Vhyuu_`6p?t|)mIU{^sEUciDnKq8ca#5h-wO%ITDpk$t%>8_vP1<84b j=n5LYGy=aW=#IfS50AtrlT$_(tlY*cv#r3H8(-}=0VCq` literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv157.5.mid b/data/raw/bach/bwv157.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..d9df2de53190d2dbc9e602cbd9e54dbce28293aa GIT binary patch literal 2416 zcmb7^&u$W76ve;NQTqtKLqo8XPKyLG3=jfoSF%ucO*Apl6hnQ0#<*bNqL1Wjxa*tX z{V`up?l>@soA%`XIrrRiKjvof`C|y-WjG2+5^fgjFCiTL3ESgW?^fT|w|A@XJA|i@ z@o)Q~(XhYolce$bWD_1I%T0Kg1P7)>rWO&H5t&&;V7`0|4|9uLle+d`PK1=eZ27Zj zp8{Z3WKM+QDTJgZfRY|5lpX=4MhqQUdro`4PUD(<#mX*{(fCMnoXYAS5*a z3=C*50ofuTg#tBuIX$Mi(DUngsL5bxoW2R$Ry=UyjU6}{e*Io|-Rgz|oGKV2(5kN3 zQtUjz1x$1`|N1+oX6%c#vm>+`2s5S^%mzy58IyuXj^{+MLqJYBJ;qFpPB=gh3o6nl z(zl3C*oT=&576^K3I(c;slCga=vuoJIuL~onLaGnDD~qxWq>VYrt6A^JLYK1e<<|t z=B>S(7mH7Kt98w1K}&a$&x$D^HE;>IG|&TJo}8BVvRpM?oQ6l9iCH!B)kSPXaXJHB z)urMM_Zefw#cwut^*L0*V_l`^uT5pAlX_6IOi0=mUpkdKlf psj^pBuBH^ZV4VwZLVS_#lcW(fyXzt8?wYQYc$Cua(eT~R;4gSjh2a1I literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv158.4.mid b/data/raw/bach/bwv158.4.mid new file mode 100644 index 0000000000000000000000000000000000000000..c33737c0bb6217ef90b0295f14f4c653762cf836 GIT binary patch literal 2672 zcmdT_OKuub5Nycga|EBk62_kq24OHB1Q`D|W)aU0$(Af7G7-)JEX#^mvh*#IBjhN# z38`WxrG{tCCRsQumwM`TS67$t`RMlA%-&haqR7ri(@$pQu`S-bznpxTj_)S+)9jaZ z_-AodE|qNYF^b9?A7(Zmq%(UMn9chHeSkswlvRcVLsU-q=>*`6;LKNstdOHV0$qOU z;!}^H=Q%xgW~EC&PLj^;Apz)+-0|esB@C8HVz^Gyz_zFr-WpJ2Z&*X%lcm?Q_624*Wh1RvM`6 z6YMWv0q|A0s`@A|0-@u2u5`#~0jCF2>90med;z(|1zUKfJ85@iT%VdLlGt2H;twS8 z?daxiGA;PQQ%fmo(JGErMI6QKB>=Guu*gmt8ghHx(47UZc$Nlt<)Oq0%@aq*)GSH; zZ^R?gT0=lPJA>A9tH8)90liX1z#VM;PGLj!kuZT8!%@SXR1vws|5-d?jUeOX*Nu7I zczIm_MnSi%Gq?4X+Bc*&)~gsFGX-*do~S740L= z9yxp9xDlwV?5s}}k}JNUJ_-D#!cC6Y^dtU_LIg0hY@3#CFNXopvI;BNhIvIC8SPeG zcS=dF8qu^eB%WhduADKHQF^{cmRTSipGXV`bB4%vk HEVjP^8t~1y literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv159.5.mid b/data/raw/bach/bwv159.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..d3e73d8cbd898ddcd2c182ff7ae83ca4fd7a11d3 GIT binary patch literal 2731 zcma)+&2Car6orq7Kab!u*aircLT-Tz@{>+Fl7Ze?6HQDs#ZVuhF%B3wVBo_z?9{1G z;ENdCi*xvLE*EZ{v@7TAv-VnR@5|Nv!#n5PQ}@VKtL|#P{ODZerQ1Ay_ImMod402R z_s;!sL;c<^BpWZ>rVGi{~r19%n0eH+F745*Qgs1=9G0nu)F^b~Ve^?rvt_QYV+& z69YP-W}JQ7F&hx`NUwYg18M>DOgwwf?c}hqfp`Y?yhJL@6BSGISU`l)m9_A89`4R_ zf&$=lD$7%AfgQk92K|-EkW;SEQyL~|*mGq_(}|iMbMep!R&G<@ZOkv*nCj@$m$G#s z@qzqk1_QMh=n3>S-rSoPV|BY zX0GtnlT_Kc5aERZPN<@i;3{s5Lj?(bk5@KOnn!0LQ zP%SCc{vbYjzMVz9zrXc^{ObDlwq$)_tckj2)D3}#fu=yND|;LTZ8h3;a$#~sht$xk zr3I3oqE$RMWL|n2*$)ruI;n3@!WGXE#w&(V)bl@y!^5&7tR@*s3>QSl)v0Put>#4F z!~h=;gn%>EoLLPyH1_nsn{&E|I=`rzs Y6Rd@PTw3}i5+S`HEE&qtCE0HFKZ1YVYXATM literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv16.6.mid b/data/raw/bach/bwv16.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..85564d3cf0862a388ac4482d63e7c480f287fe1a GIT binary patch literal 2506 zcmd6nO>P=d5QIBq@^b{AA(9mvjlmd<1~394dleSR>@3+%q(mmdIY1U!u*ky8T)_9p zQF0T~HGX`0Gh?AB3(G4?{ZrLl{g|`)rwcQCY0oT4>}*ufDExs<#uNU^) z?2l#oS$}AF+4_BwG~@^5?EBavFi~XUk*UDc!AxN0V3Pmbq<&OVr>Z%PyI_V8 zFwTEfMC-+mpw7%Jh-fsb?{J5g-oz#aiap-`-uyv%A7G$tYkxG|up>?A6;19QquIufk%OO!09m*&T zhVu^rCUl^CG2uX?DneHj30?K0Ff*z8b&%*wqVE#NI_0s&ukEA1wiolu>&0@**Quu! zdrko8DP5_(URPG>Yptq^76wOJh8ddD=2qCUgWk4%n0<^pq;C z+*Rb>jbLwA3o3#e0BqrzKnPDq_DUVY>wtSve59_Uc=%`?|8j_sF#xH$(xNMfLU^du zp{G)1#&5QVP^iTwz91}wA!A#9BJTmA&XG@(f7EG1H;L?*)N(pXUniWC%nptO05 zyvb%hUwm|7*Q-Oawo1>bk~dZC+7;^T=L@d&Fahg=62e#b=QEirFHiv7}&E;oCzH49Ro02;)l#Wv=>ztNOJ~| z2S!$wUSdLVSV!FhdyRv=v*phN%~PC5{G2*)1eC6V6VeaHvGlRqxFmWy!QXa*#op(y zdG{yLS-_lPo-USk4YX0#HqZz34P<3mh^!#At23Yu-i=5f8PGDOg#6|V>jAE-zLRi=0AB~^O0A$&# zI%*MQS^AzEm#pA2OmEQwjytjMBL@7^h+4bz8xUg}AmHe`IeNH?Za3(yg+$*MPUz z(y_OKo@~P-LY}i*N{Oa8pEFn1Nmw1fWdq1)PzMtP?VbVks6HPJH2dIe)mRccxTdtxV+B(_{_KboEVwEd&gSDVk<%d3t3FuSvt z{O#XVe);d~B&j@qy0hDh_0DcC4Djt9%m6dD%yG>f%m7#vJYC<~&D1RuT$4C>fn^bA zmDTzF(A0zfWB0#O*367^&TXPcnPFDgB%Od zDFZGq!6S4YIT)hhFt!YE4PuvK)Knm95h_O-hQ+1pOy~GG-uiJoUcJBCY!7@E)ON&- z3|s70#v=p|;Q=!d>QkrhmLllk>g8RYPH>MpxQ6hc;1LfNC`%S8rj2PoDZKu;g^)f# z4NgEpNuQ#t7$e2HwCH-BE(HM{Kqszzj^*4fT9Xzh7AmM-Wy5FNiLdM{pP=#O_4R=x zQ^gi@w0w>_pzfdzXgkpK4J-|}GyzQq$|}aRAy0Y>K;q-_0s?w*UYD literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv165.6.mid b/data/raw/bach/bwv165.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..0bce2ff78425a5607a39d00d684019de1ee8f203 GIT binary patch literal 1597 zcmaKsO>P=d5QH0N{Bwld0bvYAAjFR+gAi=I3X7PXB}a;s$V50xFD%QESY+XIGH*%QU@6TW&$923Ya>W0cH;7fO#JBaza&Q zF)Ej!EMz*Sjd8B?8cfxgfCL4mRE5SI(Aae8zKr9=*ZbA_z}agI5pXx=+NZU?gC6tf?FC&z-8dBKcxXpQTh+*;a`(bQIgxu2 z>f=Q}RSO-CKy|Joo)d1tb;5O&nS<`09NZn0ZnF^7CCXi|5L3S2cw>)zKH2TV!-0kM zcm|W|0vLUVxpW*f0Zj)Ngf1Mk0qr=a&A$Llo#eWMeS%(vpvqh5w47-IusEmuJZB2i z4$7g*87$OKhpHVxbtu6Gf(@@yV+{mh+Jq3i1YA0hpoX9uRnJw6I&JXe@(}VJyaAb4 BsjdJ3 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv166.6.mid b/data/raw/bach/bwv166.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..d48941c736592e2854d3c1ee5bd5873971d40083 GIT binary patch literal 2110 zcmd6n%}PR16ot2T`+0A&YmQe0mf*|?dFY}hm#cLX{P4h0S!90?qSCow0@#x_iyL!Gv=+I|9P>7*5Mr~^pF zQJqfql8-?_I14gZJjStxKlb5I1WrOg2*6e$$01sDvgaRB9LyADWRvZw_QfUFK55@Q z&Jw<^S?i%HY&-^#11(*6`KG2iwLj}L6l!>g^t!%BO&bCV#l4zxfGU&q7so4$LkRLb zCk$Nc^XT$mdI0tX5Q;%u5C^2%SbjsMy(mc5bQ_@+Hrxu!-Rt{af5szFl~C1i<)}(% zPn9@3+`hEfx4epdyzj1P4InO_4X9vn8y1%(TWlspA(S{{Ug zH!*X(n@|5{qYWLT^3lxvXJ*bE@7e0ZJ2QJ`2Np$kw%U9&tGu$^ljpD3pEu_hYx`;T z+xq(1y{%LZZ1*OLDlcDb?Ru7M?P_KLm?|<2BXdRO9yt{_bwH%}oD^WGS4)4j5LoPa zt{>$2Cu7_<>fM!tE$*gJqeQ4l^3|>;F2Yz~>|iJ`3?mZ>r5Xqk6F>{*Stj3Zb#}s3 z=WN1-TBH#N=>`1+y6G(WE(2_BSG~2)jaw%geEL%6o1sS3(0x(&9k9kosnI@?)f6KX z^Sq~5y*;4=5t5>~$b%enjiG&}0y+EQq{lcjRw(+0$V@BiKTPpRk@N%(bS8Gc4`eks z5}vV+l6o{dWml1INJtH@7_2x(Fse6|#e*6*;)9OLM#UQ^vhPXGzQ5eQPgn0R)|-;= z9(LNRjc>QN8R79EKoefWPP0swvR9Xg{tfTN%fEsBD}1AwO`!F8slfDRW6#12T&0%ia+ z2iErIIcxL0tB27i1}Z3s@Nu*d1@d zgC~x3lp_}^mR+P6XR0fuQ`Q7@T$qbzq8B><-Qk>Bj%31P^*Z(l69z`YHtyPL>e@d~ C#NRdm literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv169.7.mid b/data/raw/bach/bwv169.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..f3ae9db05ce6738d340abe4feed2a2f72cd40c25 GIT binary patch literal 2434 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 DyT*e@ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv178.7.mid b/data/raw/bach/bwv178.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..1509e17783183278124fcdeda6e6db7bdfdb7c63 GIT binary patch literal 2596 zcmd6o%}!cT6oq&3*7^v22V+XeMIiiy9|?x&NCuXfNt-ljBMo-YVFw*BaKPhq*hleA z=>Fiia^&ERj>^cD{j>Jk>ufKVlP{ml?9kp=mf7WG{?)8Bx7ESBtJ(MY&F#$onmt&T zKdX-=FI!z_S?T@J!j|XLh5b4=!0!zh0Y)Af0)`G0QO%gt*i#p@UpN>8hzLZ?VZ?}< z=a@r{+DFsnW3i`@5fSdYRBa)D1a_I}3u0ZgU~of@DJAAzue04X#Bi(=7!Vo6voxZB zP|vLc*nXXbtv)wWuCbattr9?E*IOcDjs;xu(e`&qoIx>BIxE?wQYOU(aQ zk7T5v!~b5#HFp7smsG7&0AAAG!IsU4;7^}O-)E(%l(3I5iltC`bYuf+IK)VNSVx3y zhPExftv`NSZzrE`XY+z@nx<*KC|itet@m*7#Kk75rl(qrrADAhgjB@r5xg%LA;Jdj z4KI#%z2CG)!otvK#I_&%FJ4B;x*D$5eD?+b6I7D|8CA!z`noGvr<4wG7jt;Q$W@Q< zl<8Y&dI3)x&24YjP(49P*qHj8vS6Jq#OG|0Ke^wZd>i{WcXtKnt5rk4Evpb!*Nje` zJE$_9a&A~>$p36T?zM1=n1x|=ZPcb5_B+BZGXf^Gu4%Z(gc5MKqbpo-Iz yDpRx7?ncqBW7TnpP$Me1$`dGZ3gKxyR8OGdW4exuyTqeQdZnJQMR>vW_wygVe!3(8 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv179.6.mid b/data/raw/bach/bwv179.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..c1e23c92265fa073b91afa96cd85cf92b1d37081 GIT binary patch literal 2623 zcmd^3%q3E>$Ed6eKN ziCIL-=JLWL(p?Jybx8Px^Z|2zcm-?Kp#-U1sh zZ^4K;^H)z1Sk4e>4$HKEb=1iUzQ7sc8f+Gpl3MtCb z9-_UTEf2MNfXol^uii^@)(_fcO>9t1=|~Tl2IV~lHZlHqF{LA+ts@ov)l_XwJ6rD1 zPscKgpBAfR-72AewA>I{c3{gP@ri!TGoD=E-tGZf+;pf)A8jCOn-F$YELF4A5H%CW zh+`8?M04xB&YD(~d=%cmxna%?Y9Z=~x`{R-D{6wvdzmc?OBGmY<8SO)W6`hc4ZL`F zZ$5T+<|9iBT$n~1!Nip3h#4N4rOup*lF;PKQ`Ndp2tTo?CL-IZ32Gf;IW&>4atql{ D`Q5)t literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv18.5-lz.mid b/data/raw/bach/bwv18.5-lz.mid new file mode 100644 index 0000000000000000000000000000000000000000..e49705e9db83e127e8efe651b6020a0e50da7863 GIT binary patch literal 2992 zcmdUwO>PrG5QQ7ZK#sr_qG)2rvg3bijOEyhl2yC_?;?SO1d5Tv0a&o`f<=~GBR62p zDY(f{Z)WnTopzcX5i37czp8%qs(O5}`0&m-_rg7M)vCK#tUo$expUdx%gfd0_0{#t z{dDfPOZAhztr#tPQ>|8B?Qh)ebh&X~r*0RR=xE{}jTISNBo#;vj08qG=UY){wlpxa z$XrKr17`wfImdwRnkllyArjHU(bEc}FArGD>hx5-pXQyGZcG%BhhqU*M(H(zLONL^akSZ_!vT0?vqR*ed{JeNAcp`B zSD@z~DD8VwpuPsVV~^TGJ9IjbhYzx>&en&6mP3G<9EDee&wvOU$&=$K z(qLbm_N`Nv9;!c8VQu%NF_L3A0Y+b5AYz z3=CwZR-1@NE{D<;Sy`dsMBwyvsVYZI;0iuY%!_ooz}~i`s+|+*Imz{u4YKUi@#bEN zkIb|q&BX%P_gtNN5!>jlztMa9`mn#gy19ug^sy=)TcL)uHViZcng&?bnm9F!cw~!+ zoaiVq&=61rfYDgrQe|yFS8!=vM|C@@3FxjwK$V;N>yjSs@?;q2|Io}P?dsjEQ}4U{ z!ROMABiV9fDYUy^h3)^1gx5QT5-1=7;-22r%}kL>v0vN4XWC{ik1z;=;9LITCe;Q=TpTu`LsHFyIa zgn}o*%-LOiy3XA!9TAm}X3qSbnY+GRy?f)Fd+ZKe6uHaQ=Dl;3?`~Ip@^bxgb9KFT zKb-sJp6h4#y7K$L?OsJu<=NrZ-OiJ(`#g6=U?$hhcTHuPnq?v|F)$Vwr<^ZYo<(9{ zVV0#_O9STu=PAd4YAs~h<6tT22iLVD;0!p>qyw9jX8f`_7>gJ~8#2d=kutZJu+BDD-Xc^#Y zYvR<*;*rfFax7PDpeY~=0HKk-t;~7`l%Qx`uDZEu0;&}YD054HZ|a9yUK_^wKYHep zie@+IG<%Ug=$xx@B3Vw1T$kXAIubZa!wpE@P#@$a9C?ower!>(blzK~m&Z8LnL93N lmBzRPN)YaG?%g0gb0jUbnq8(v-8rPZLpZU%`Em9h{s80dC!GKQ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv180.7.mid b/data/raw/bach/bwv180.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..f0b369ed154498a6f25d664df068a722964d728e GIT binary patch literal 3244 zcmdT`OKuuL5N+dek|X2_2=NgDS-=?01c4ATi^wbzc9s$;k|PsgAHcG_V37q!$Wd~X zTq7&;o_qXM;~tM$MfL`ss;cW%zp84OFTQ>3I0w>a`4@W{-D5hlDC$q{>!lJReeP{tdjzXlWQ0%6anp(6n_t+J2 zX*Li{E@c)Fg)SI!$ui`O?LS&ro;bHWAF(_~i?5ffb;)msSrM>tHv6RQ1N68(J%D3^ zV}LGQ-FpiFEhZ+jm>8WxdwI%m!9}ic>O)IRQePN)=nDg2VSN_nEuf&qQ0NrEYrT%< zWk3-IxZnxFiIvVMmR(uFdT$04ipOP9_5=wa=Uw7A{spg^5m U94(EX*yRduS~Q1PgQ{PHf0FrXeE=zuvC`&+LMe@%xWe=bLH@sm*RAV`K)Nu{>k%0W(l&;6qTH zC^Yc}r}9io!84us%tBo4OkjD^>}yVp$`}q@q^CM@sen9G@!Ur_NM?qNmqGCi0K1S4 zQ(p&eeWpQayiA_-sdk|?VYp{tb@C@y6m)znOY0_!r&3WFaD^NgmeH`L(iJOZ2(I$+ zk@y$#++N7T^_#2Bw&DxVvG;YGeQS${E5ie(CveY$;}9N>lsXmH+Sj5)gBH{w9b#0b zAYd>99fe*q>0t0Uu;~&Q3^V}8Aw2K_3^79Vx=W=t!*a>cfLKf(4BFin$SUWbqQV$y zU;45l8G)%n0{3L-S^#5!!C)){W#zjt8JZM&y80I?51FA51Bwf_Rj_TC zmI}7aIF)gF@K{Kmy7Y+HJ!069u7+`LN>0;^SeMgo0;RO2EEx=wTjy9SJY=z*j=F1K zZoJk)|6ovmzrcEB9`>um1qE1Ayqai3J65^trU7&?RODv`j5K0#=vdA)z(>_G^ zeG_|+Gx_+(KMbL?rRhcwXU@I<{m(t4$Mbh@oO93I6Bozsc)on^T=dOfon@P5ER}<%fv6!(jM*>F%4h0T<%~Z_Pm=l2$10M4w zXJ*-FcQvy|rvj%2W)h3>s!W{sp(@ne7-n9kV1`>fhe+KeI7ED8r8XHZK(YCBt6@6-AYR1$B>ISH)t6U5kBF^P$ zm}K^stT7sjxDNe4hR0rP!FfFF$f%B8`9R>n0Q(9Z>&Rz`TLM~TQ&mj^xO$()#L_SZ uRr@O6-!wF!hBYx;JGF8xrKv;JhttFBgjZ%T*3I3?#_!5c@e{duRel1c97EXv literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv187.7.mid b/data/raw/bach/bwv187.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..2c7f79b8b0534c844b9ce1f5ed505a48ae492079 GIT binary patch literal 2740 zcmcJPOKwv^5JfwQ`7D7gL{UtX_#=Pf_#<16V~_9vJc|Sp5-33q3qXiLB!ZM7t6&XT z3M;|XdEL3H=Vv@)^scI_Zr!TB{buv`Z$k)A!%irb!fd|$5W?<{u-bd}>iX02^6EM~ zgz!6b`K;dT{@Dqu*QLGP7te3Q{a|q$z6=83TLeSE&>|y_Mh1q9`xsGjpPat08Z7Q& zd4KWs@yGzo!^O{7?wG9{<`Gq~g(b(P28fJlIyNvt#w1HF>M`cn!j32(lAIGS9yd

TTakz#j6 zocOfNO)b{NUm)xv(_;W(TL}Nx?c9dd%STiGGEFw6 zv>`;iWH^te7S0M5!9Z$SJkr}6(JMYVtIGLLd+uRP^e7@30$Piv=%YDz1xhaJaaATG zSG9%N8Nd`q18n)-q<5t$ise$M^{RWiQ}5dE=GrIocURZT@b4dKljSvSd2K+>fSVj- zIT%ODO>9DW1JE!~ho_!J3=mOHjg{9d(&1L&Q42?CRgo~2J3_Uva$3}A3Skpwszg`> zn_7s_K-8QfD%ZPg(1LL^X^ZYHi@2AX=5i6sVbU%m^Pc28JtMsXMck8JUzFZ%QK9zS zrWaQ!@j8JJemsqe^yqj1Z~rPAwAk*fm8xNvf(vg^on}7% E3p4xY>;M1& literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv188.6.mid b/data/raw/bach/bwv188.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..d08d4fa7d955157c947eba926d68bab847cd0205 GIT binary patch literal 2046 zcmaKsL2epB5JlT$>|~X7E@1_sF&GU-0}L93Kwg+d!p>46MM`8MoC8=<7A&&hHreJV zxe2bvG(Qb(&5Ez8U%!4;H8Wp)`Q)6taAz(_+fG5Mw|n*aZuNbA|FCj@o%`o< zes&)lM%#TzlE%9?8@C-VH|}Zd0#FhuEiwU23`_x21GDAUJvSXi0J`i0FOZTDT(k1 zlq!f6$B~0#fnt?2fKbrGH_~VT%FIh~$8yeZ(zlW>zoF9FvE%7>3=& z32c}{Y=|7}&hIDazaRZkHz$?tw2U3vq%@v4ME0h$aoE6 z3uMelS-ejzKc_yYK7M_I5e literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv190.7.mid b/data/raw/bach/bwv190.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..d9c942ce56581f4320dfc40fac3eb2eb52137d20 GIT binary patch literal 4198 zcmd^>%WhI(6or4`czFb$pmETamNuo7LXk^JDQyQbP-aauG0_x5eSpR|V93zN@i`p% z488#Fb-*these<9cS%%F;DUPoU?YE(ViubK#%h0FVPt6A~Sa4b*w>rEI0=6zzu_Q4Ehk&LQ zU}3m8be!b{h&`kFvFOB#0Yf>`@*kz!Yhbp$2DH881IX}$!};?2??ubL7kB$Fu7;zG z-vc!zQnRptvMgn@R0Jvp4h0TVj?GzQEP$#w)s$mE9OTP6h6&_~ZdW0y0t<3DfSNe+ z>@MD7sb_SEpe5x~vZu0CDhD~0;<>EFnQ`XH!@14fpmrt*py7O>-B4^v7KZYx{4f*% zo|!uf8FR3Ze5}IafbE7>6gl8`MrT)v9#`S=u@NZe16{#^0m{J-769`3Ik<00{)>Kl zG%l~NGd?9n1uObaF^o7yNxwaGpIcIG`4r=%_r=*a4k;FOv5JKS&aTM2{%KE^y)?wU zFXRJ2MHP77kbJ}B1ck#e{?|&Woo?`9rK>y@HB$|R{`{mIKdbbaQL^Hwb~M2qON=R# zGpd3(g_L8frTzJ{(c>#1=XeCvMb6tQXWOcvu1#4sy=7gNb+a(0HJ#O3NH6~@8Gv@y literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv194.12.mid b/data/raw/bach/bwv194.12.mid new file mode 100644 index 0000000000000000000000000000000000000000..0ff2fe2119f54a05dece3b94517a2a1e01077785 GIT binary patch literal 1552 zcmaKsO-=$)5QJOBpCfn*Bp^;8gx_E$7+11TT$yNMq7j20z=aDICc1R#Q9Oz#5&N5Y zRvwPJ(Mok!Rd+w&aC~`gW*fF*rIHcKmG4< zX>E0TYi=+5les)CS*+_mZ9v;Wmvk8U^kMqW zXjD0ONN3bGJwN1b$Y6>X5Rq>hN{WbH*L^svJ|)H7)vTF2I4@mH6G|Sk;&*!XcUm7` z+)QWo_ZLB%wb_*w726`Vlgr1M+%Pbbw@~3DMq`MHLPN89 zG^##I4Gc+_N}$0OloCLa^*G394kgK>h%kI{p2#_@EauN^#Lsff*QbAWclXb$$T49t zhOTnos)HI#ZJF^BOr28QK^ahXAfGA>@?Cs(vt|c0Con|l2@`(iU}UIt%~L}~Xa(nr hgE9=E7346I?@`)wrkJG(HCVA(=?bl57;T!}_Y3N5rau4x literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv194.6.mid b/data/raw/bach/bwv194.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..d0d1ffa9563963d1ca17b9a4fbf854e1495e8db7 GIT binary patch literal 2839 zcmdT^OKuuL6nw^$#7FQIyf8svga#pC_{jnhFTx_8oux#wl*mLl2Z*95Vvz+0$YFex z+#);Us_Aj5hZ#@2v1D(c^!k0O>(%sparx2AUfZ4pfz21I&t{c(w%vd8e))BEakaD? zv%l8o-}bz6i{B4HP&qtU+h!84?fb-Rb4qXuFeRA!5#@||G{(`8Uon)s&4NopR~`~wr}rU^#`sBqA%adEG18P;J0&0pBL+cS(mzW z0XmFy03rf9NkGZ!qbfxn2XG(P8AEr#vmmBj3V0TWEd0{O)Q8_*K1ci3Q66{=AwuTU zjcAvQEECS6fkp%)fcytP1w&+gZIF@Co6@VA7V(G)7k(b0V6FQwE&uoG?NGbBVqjO zz6w`lm5khCvdd9t0M~gp(%}f&U*)19AU+cBMU&SuWdYsY+dO3X&*mk9K#yXwN~*RQ zq4EMD4VYQCHy!?UZ&JDxuS%BCa?^;nCOE;_1|VaA7KbvTh9$r=B=|VnJlHw4glGT# z13uA%i|gwW_iKEU0@2x3f+|3bpaxKiQA}4@6ozURAxl@5U*Tf@PT+g4Ti_c>imQ+au-Cc_9+9vrP?f}4){Sp8G literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv197.10.mid b/data/raw/bach/bwv197.10.mid new file mode 100644 index 0000000000000000000000000000000000000000..3c79af825d14cb45eed87ef83fa01b9c6a2949ee GIT binary patch literal 2262 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 B`ZfRn literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv20.7.mid b/data/raw/bach/bwv20.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..24c0fe2863518aeddc6c81c069fda326a95d1a98 GIT binary patch literal 2830 zcmd^26o!xVwsr~Kf-zctLm-6k69^$Nl7VGLQWF!680-QZbik06bPe4{Cr(@k zJulEF-{sRgV5XhOlk=Vb_jt#X>+fdv$&M^ZY&==qnB^9>{&0LTzhBJm=Jwm{$y)kZ zf6J}??`4wYzI+B!NCjFD=TS^x?o6*cTVM3ArB)1L;-Zj$N+gLiZeyY1K<h72Qw8WvU9c zdO7T!-|oind39sqvH#I0x-)xt$hh^2u0-VlI%BOo#e?z07-fx7_Jl=cE;{68$vd12 z&K=J5bQb!Y%5u7Savwe6oY#}W3xdKX%6*iXT2wEpgr1lJOVEbrQ5$4FQRWl31mn16 ztBOPFzX+fIXB%bhN1B!dB?rU}MDZtWo~J-lf7)v5klH-z1X8+>Hjg^MPNvO?{{?m5 B`ZfRn literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv226.2.mid b/data/raw/bach/bwv226.2.mid new file mode 100644 index 0000000000000000000000000000000000000000..e923e71272671e1e96e4e5c44d2222c15a08b9df GIT binary patch literal 4052 zcmd^=O-@u%5QVSW{w%>&AZcu%u>(8^NPvz58EDTinwV(BfD16j0RsmN9Jm~(?!sL- z6VG|~@=@=H-hdN0sasX2s!rAG>CxNQDW!YqRvHY_^yu_mN_W1d%RBdK&(oAHo*6t7n9jat%YngxEc*ug0$7OJn_Z;O zd$o_k?Q`fnhXPYSP16k=g>}!Vb37b+%B&^ho-^8K*I+k-x#1)faKchhx(EsN+^u+fKrf%A!QdEB%`%b;@)P3;^Yspb8fmN2)sEZG}1T_g) zi~rfAQFF&?Sl>Pk%QSh~wmx|W^kn73nti#t1c5AXEv9`0!j_(=%STtY_)E7qsNR2? zcZkpfx$j_f%G^3T z$`Eje>+Wz}VAIlV3QXMU#Ah?HX(Ce}hn{lLA~Q$OP8OdHmR)nS>QK1nx@EF0lXYkI z)L~ESMDn)eb2G}hu}n;earV_wq7W*SQ92~goGG9W&H;2Oeq4=%Aj

HZUgc9Y87jv`6urAiK1wJ#R*qrSvFV}z%ur+*Q^vmX>`VSsG4bWTMN>rM<2Q; zPiRARI1hvAV=tL`>T6zk@|p=)y1u2*lV#yFX^_lV@Zs3mNqmU9o?TE(MQ6nX@-B4; zq#@dejO!k2L&LzKaPI<&l}iX`6WH|?bLMV%P(_00Efuiy*dL!vA>cJ(amtN^^B=tO z@A=m8+1Z@yhpc;Sv@!IS4n?+PkPlJ?`5?R16E*U>j(j9TuX2tTXdE;d;aIfuqEchQ zhtI%*eHLnZfjk(2JQ$VO7z`aUsuj1<@WC?jlN)<%@Hm#SV2eqq@VZ07sI^-?mPIFW zhoKEw+{UV(Rt1a1Sj5p`YzV-%9E iMfK#J6v$U2o${?|JA7+l|I3ZgJo3yb?8Y+cFU>zrt4)~z literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv227.1.mid b/data/raw/bach/bwv227.1.mid new file mode 100644 index 0000000000000000000000000000000000000000..6b596fef84c0afc2e1845f9e0eddb5bdd2b8b336 GIT binary patch literal 2713 zcmds(Pi~S?6vZEif0p1Lng-GkXafa=Pzt4VAOmIAL=zKDG1LWg;DCXHF2I3H=^osG zJHhkg;mP|7eu+aF_2j;L@4NS$^F4Yw{qQb?@GKNUsT3}!i;p1`n_>0j`Rn=T#r4fR zJcRHobojG+TPzg9>P@LseEDJ-?gz7FxEq87^ojHp=>d8I-PwJ(>k4!Loiuq!&QOsN zV3Zz>NggY50k{wt&%VaU1TazLimEGt$?RK<_-H))5tIMN3D4Qf>_ZjlXZ@WA*VxxVOs#G zIt82xBvtAYt8_$_`*@6m26g^N8j|nH4fkv>fAQPEnpy(y?nlK{NwP$F^p+?RA07cD zNJNovQ51prq)DdClh#G|SS3Ioe-PVpH}TkRYaR0f9cQfl!1LR^zP-(Hc9o7*-FgH# z5~%P?QxPaLSy|waqr-JXfJl`OoGO=l);d*~wMJF^FdPveQYDA-Zt3H{o;yy$Ru)h~+MGMbu(* RF6Kh~Fz^+^YZp literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv227.11.mid b/data/raw/bach/bwv227.11.mid new file mode 100644 index 0000000000000000000000000000000000000000..52e3122e4d7beca64974b3c36651730fef5d5eb0 GIT binary patch literal 2721 zcmds(&u&st5XJ|*{&@r+p-Iy~8Uk%Dg)4+oD5VQo=-oBZ#6(jJ^#QtY!NNr!z=eo8b53;N;v=Z{ku`{W51}&dm3H_t1;kyEkU`#445~b}?JLH>^#a6G9r272X((Z=&(r$+qfdP?$B7Hz#pqJm-ZBHNrWO4F{oRK19 zz&JjdkUUZ39B?i$$v=n46fjlflB!FAY5pZd{AiMY3(5cEglFt^roDXl0Sm(FfZYSV zq6KGJ@H_&*{0MphLqI`F?;L5Ws-UR=nnvP^@XVIBs{QfMS9vIT@!?aM zfg+b^#NZOO#wA@w>8m;mr8yDAkE384fr3fg0FhfH zQ(ExoPkHq5?Cte@QS!=prvBH@B40^v!MOob<{hwhP#A3I_S&XSyWb;x6RATBQaTCy2)D0@zg8|mB#Ns3CY+9-HzIr!ak*<; b5wzGG`RzWBmv38ZFUKEJanHDF{qMwYDtz8; literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv227.7.mid b/data/raw/bach/bwv227.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..54bf4e965d6a8f7e5095689477dba058bc0e3c79 GIT binary patch literal 3939 zcmeHK%WhIp6x|>`KEXdQv1w>2VQCUH0m9M3W+6a85ctkL`t)EqBRKPq z`gHEYa!zm#&>!78%Ya}2%O#^O0S2QxXVFoA^wl~4iyd}3R~K`sd9fNf-oWOz%tngIe1c*!FFxFCmCGG9fz7$50a#TQfsn&H zxxj~V2^dAt7=5-`1E5AwTUp>ti{}I9m?dO56E+#;#sF{@95wCMi*Hj(PQP2cZP8{T z`g905hNz0jL&h%4x+MZQCjgfkAV!0n+l-=*Xz0+w@D@P}K(orZ#U-{3RYjx1WD!tm zB@(!2csIiy!6IKk1Pka$Ku6y580lR{buPN@FWQqZj;I{@M0v1!X)vjC?N>FFQ99AJ zKjj5HMGYM#oxOR!{Jc|JuWg;Tg!Aay)>(oUjS}lznU<*>`3iRh9@reu-5s0a38-X9YRwhDw4E##V{j_ zi4bp%|1XW626ejx#H)bRAfTgwcgfuxFzuEIze{64NWp(1GmWadrBMY+?5u>& zbR{*sj!JB?6nk}^@i$L+b$z|#(NRV*Elac?{Ek*5JDSb1$Ly*{G?F)5X=PHFifGsz z!*U2Ka%X%kw8cC(#P_Gl(cH@l=a^8Eoh3`C4IQZ;wUNvtVim5aefGS+8Wj&y-XIG( zsfH}~G_Fe*?D5{N)9A5yM23&xBOp2jw7Vqb2Mj+z_#wd|K#mfk%=Y*#*)y!HNYiG) zDYd6gBy!FGd}E}K6V^C^MH)&rbWERP_!L-_;aT>PwZADH=~JzVD;=$KzWNvG2kaFl AGXMYp literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv229.2.mid b/data/raw/bach/bwv229.2.mid new file mode 100644 index 0000000000000000000000000000000000000000..17ffe04e6dd337bb59b57346ef3e426f66872886 GIT binary patch literal 3406 zcma)-OHWf#6on5DA3wplBSOIPDCNY0@`wzyGZIZqG+@9VV2lF>4j4M{$M{qH zCF1(-xvZS)g&Rg)*=L`<*IH-q+wtj#cOitQVJghdhVkj;#}H=D!|lwo*B75J&(1Hx z?-2fkHb1v-r~gic+c&c_(=VQ1hnvylI(!|4aI+8C7Z^>x$H)*c%p!SCkDQ(&!^urN z8jv$kqz~u|IO6Mlk~#AAq^WMvbjx?OgzyrX6fQgkQkC79TC6MGjB74~_ zMR+d@bY&MD(gGE`klz(>B=PxMwC;E!aI75DaKU6GRFI~w<0BW`=XDBC-~l*<&tcla zlQ5k8ic~AE`*q4Q)}tvtmyg`t@8uRgI^=pJmb-C+8z(9_!tl5kxvoBu!a(+zv0k_i zx3BKDuCA?{?R@%DwQ?43;At~xV_91~x=`#2BvN%$;BjA$ZjsYv0=V9yU@NO5fMo+B zOtwLXWQN{zZ0nQmxeGoT-~x3_-oOG4eAGr40$TuxHSxD8;3Fp+*p?>bNwzMlF!>$@ zQJNG~F9arXa-%HA*ApOtnCXc581%4?UM9AKuAQuxMv9{jvqg7r(GDtNPEOU|xNVNM zv+Dv}H|K*E*msun1Tbuy`wMpqU|CBM0&2I?Ig0vX17-nNM?k zy-po^t&p=KP-kOfL`Otc$N?+^C}`lLI=v!ix$qxnRla{QY+_lLiLF9xH6tcau%$** z9GfF&E+ZxYL%ZPxvxiG0FI6Wmkh75GNX|o&bL(v8I=9xd?jlzB1b7WRE`H?(DoFMK z7&Mu67UMBS`7Qi9_ON_Z<0-Mu^W$l0FaYqWysjLsFH(o+cEJTASXVxBi+Oa-$5r_U D#rvE~ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.10.mid b/data/raw/bach/bwv244.10.mid new file mode 100644 index 0000000000000000000000000000000000000000..7ee5b6406c9a451cd3ccfe891ccd640c0940150e GIT binary patch literal 2191 zcmdT^yKWj$6g=RK<4?#Rq*-AQATU}C1dKqIt57)GS+b=_i6FxHfXH$|;es-s(iWF7+a2zmhf^!O|l9jAZaq>2#WeRMHpr<`ig4lJC!?|o&PQ@_q~73+)!KYthP zQX?CXdH^Dgb;K3Axd6EBB8H1USYA2^eEN`pdy-{9i>u{bvS^nA=M;91bXhvIbV5s) zmM$y_nG=960WHevaq+woHK>+@81OJgu0R+FoeLl%{({vnkfmYjYSpraAZE!BkgHF^ zepY9uShJMP_I5%sLafnv7{8xX$!CfGmoUFo6~ihs+7HcwCxvVS`?n zT2^{sK}_yiVaXjJit^m{P1Wns6VX@_er%moX%@&ARXY-<-UW1LkH}L@O@oh_l zr}UYhpf5M~_XU@v8vCXRMt3exxivSr4DM1ri$|_1_gzIyg`ff;OO2KqEOi2&f-F@s zGporVX3nKX7qb*op@qybd18RVTDTbQkKAOdYgJO4@0-! opvzSUa5DtRJf~pIkikn*%lnERtQCwGJZ|6s974w&=#`DqYD$wW1nrV310o`~S|K^31|a*QZPf{!WP zc<&c-f^m;Qy{aBjL#I3@q$wkgn%J!zcL{q3{YC!9MZR2ox?Qc0{Nc)ZN;ydS1bqNS zhNK~n$S9zhRaNWf$PY+a z6iS=sdk)wsDHbEOe$>*#(N2E#6^iOR@ zn0%-leaNNh#dXH2vwaoTAgQ>X+h96{E@!3(+Crx(o0Zeyzd-J;y#%zNB2FJD#&c0; pU6MZL`T@xTjp1$-GxG~^TyYC$Wwc4Yx40=yQO=`zFW+LnVr2sk6)f`v{Xs!$|!mSV|LA`{^hDP5#MNkf^>$*1H; zB0R%;8SV2STD!4F`*wGBXZGyb{N|IHy|NdUWj33yKAY9v*!Jl7{qpPT>UL>=%>LSt zzqTK1|M2remepRLtZg$|tnGeewkZipfHA=s;F91HKsm)?WA}xROqer4WJ)mgV6ylT zo=O6CR&u%c9U|)dBbf(5t2=-$%;rrff0A7;8pf1g<|I!#hj%%QRkBE ziI~#RQ6QNV1^du1%@f(zwtf5mP=4Z2vf|6PLsv3jqX8Q20~nf51*a#Oz<`mYs?R=s z-$x@VS>;;H0W=JYMXmwWOemi1g!&A|l;zO}R^2NKE>i_YEKfvm`k;zWE;&Y&Bf*E1 zZn*OcIl;KcpjuUpsG(CH6VjAEM@{Tjj=O}NgZ?6a;UZtouWy&D1An-3o>C5y4nYS% zksfJ#y9fYt+!K<+Q!Llh1^ZkexlPap=n*hkKsh~%m-KnsF`O+}nP%#HlG0UKIut5M z7lqQMIiG^O%881}LkEzP7_L4JM8y=5^5W`}w2R>t(abs}J++w}YyzMcUHTQu*5$O)sufR-Nvuum(xR_1p&2DYQ54nKrx<+ rI_r}3F;@>r7HAB2qnMdrh~tV|I4h$~^1aSYX^L|89RQ4LhWmQ}uKlTm literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.25.mid b/data/raw/bach/bwv244.25.mid new file mode 100644 index 0000000000000000000000000000000000000000..d386b912a423b65664865b6e5226b12608968502 GIT binary patch literal 2992 zcmdT_OHLb65Nw8lW*pGPM`kv0ZN9Kt)b&?*HNdi>$(GhDTPhbUI2V5r3y90UPv8M zJT-@o$rb^T1^P^<&jLD<^QtV+suhf|c0U5lKoTXuCy z+{pDzsfX9C1qi|0m2kU$m|)kB7T@ny>yoc-hrV{uq(#sIXb?02>g-=nBLIxF7$K)a zP{?vaznx5%pli{Mjo6EydI34)BIs3E9Buu(7B5@6G_#w!3ODGgjB*?tk<+DP1+vmZ zvW#*^c`s$@Dh1lq(?&0WCL>Kmv=Sn#vN&xjWV*Ubv&c#hkDRdF4Q-|a&{Nn$WhIoF zpt}~*^}-RYldvYGaxTe87)i`Mqv(}?8N=I$hyQs+b>?Sp27qs-Nz! z-WAB4=alKEX%+ypDvVV8QE43%%zQx>H>t+-tSJD6sh}RuyV8sSv+qtmsn$-eYUE4K zeu&_WDN2E$nxF(q?d$qONHpdCaK|yY$veZIT XXk>9z*?qfFhu7^)$Rqg_>5Bga?|dde literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.29-a.mid b/data/raw/bach/bwv244.29-a.mid new file mode 100644 index 0000000000000000000000000000000000000000..4835e76890dd32b51e02032b7d07ce46cf49d0e4 GIT binary patch literal 2587 zcma)+%}!HM6orpie`Zd7i-u4dpfoK_3n>&PGSJRQG%?YD0S68ValpUeULIRB{GeO;E2dkLUAmq{2o4rWA13GABA zzt_x1^P8G*2B3HfA)*I>M}BmuAAzX}qLXMJ(>|_vBJzmG8o`(@iboh5Rqf%2$OK~$ zjvyp81PlWxD$tL>kp*tdt^-7II7N%u4*`c&q*;_T6N>8r1N_r-%$0e*P514Gv-lQg z(c1g`b=6Ib5v#ZGSJffAV;$M<7Q1}!Wn+}@6z!~IANBnJ+4D5>lv-LH(pCHU@i2T7 z8Srw0Ak=dSyoqwrN~pdE;a(69SOUytjeZ6gtJQTFfakHx;>=i6+^4;tYxPj?MIs6bmxMZ$+0~iypgZ_sQS#U&p{cAr{4895 dMA*FTI`m6hG5h~$c_igHikfm`&4AUd{{e8ix1#_6 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.3.mid b/data/raw/bach/bwv244.3.mid new file mode 100644 index 0000000000000000000000000000000000000000..146535174c9ecc4fa325524002e6e747bf6a0e8e GIT binary patch literal 1939 zcmaKsJ#G_m5XHx4`8Wb+ND(WEwU)n)9mlfeI0Y_XyGS4*fnwxvfCy2zph(FfI0P5q z4xE9K#?0H@{Pf@K%9WpH=FPl$^Iu=CKfE)uXI8T)vdi`Mqgm~z?Vmh zvp+V{&;D(_UbFq1D5}4Fv9tSGva`FHRe_7-o84V_>RjO5!C1xPuz0S>+#?HtMF^IP zEW-%J09X{SG;8Ior9gpxrG{6Y0+fqas>$g0kLb)|I=fHBntJE4hHAlyz{CM5K$$g3 ze3pvwCy-G#!HebCEcqelceZal-0ZjCEPD0n%b|lYVKa4=H z0D zpd*Y3_Z~{m&^t2%z^p3z_skZYAL^*X!cqVFQJ=2g-)y!AK0}5uwyPDpuBb0*x?xv9 zk&aTGG?Lc@k-P>Lop}p%h6Nx+F^`Le$RNT9!~;kH=-k#8?QpNQ7F49AR4WA@5r~zF z9W(`+4k)G%Bg&wshCOF>6TevI;nxQb9b`UxP3E%$McA~Xp#{S+3hQEBJ}zATpFZdD z_3iC}!_$bxSQQsysn_zPC_Yu{G)?6-4MiHMdI#0dC1{wlkb#?YZfSYl0LLljmIq!5 zEY>NHKr?%>DXbIib>cD*#?YP=X4iF~m4l(Vcp5U|Osq36ZtCw_PwH4Bjvb&U80y9H S89E*wiFK5+`~@_!7w{j2{R>9` literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.32.mid b/data/raw/bach/bwv244.32.mid new file mode 100644 index 0000000000000000000000000000000000000000..86b2f7f9d32984ca10fb404ff17dcf73c5e04000 GIT binary patch literal 2065 zcma)5&rTX)9Q=vf>Ld6P0s#Rb1XvIxkPQbpRBk4kn6!}w`v4w#;LwA|K29ISS7_3k zi8!_bt)#_S(!o+nxo1Ma#`sv%P<|+dsHif8Si)t?iH5lMVQ9 zcUgMD-!DN>Iy&6i<7Bn9hlzP0A`^iTn6G}?!yL?vUxgiJx`c|k*5Sn3gvQ)Y)C6_%GvO=9FrX{=+S+m)vx68 ziX(N8k=4hyI1ruK)^?S*xBrW`55jLhiXJ}XfkIqiL@)vv^Bm*!flx}FOg);?9>o}Q zA@``H<{?W%ztpE_KV|?@enOsu%z!-u0Bsh~W@+j4^3$Ve598TpO^qm#I>I@p&M}o; zsLf~WIs4CM7e@hml%NeUA(rC3|M1Uv_)p85yY;5vC$D?tIYJ;h z${xnkM^Ex%uDQcAbmFOOXq1xBZmQ2_j>|@iObbkl_aJB!v;jH<+}tJT0?4zNF2`9C zD45dm6i`5yR-86Br)HzMrVa@l7>!MI*p^ccdGMM>R@z*GJDEk>I5tu6C49n2r2+oPE`SF z1k_Tq81C+; literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.37.mid b/data/raw/bach/bwv244.37.mid new file mode 100644 index 0000000000000000000000000000000000000000..ca88468e0e63d9df7a81b74413f19331bcbc29f7 GIT binary patch literal 2164 zcmdUwJ#HFN6osGh#K{u81T(?!SJw{It5dTe_dl z{c@SUw(nb8`@Bq&*5RAA+sw+f`!aKGlMCbq3W37Fto-I(bAh>8&gD8cFfTXWLV80m zS@p_=Dyvtng6f{BMP?usNGq3tKN0)-NX&pI7O29fD1SW4u{!^q(!iNP%}P@$6>|YC zg%vQ~u*$XDz75x~_uH-^$!|Y5odOpy(dZ{unq}nLlixvD7+nFo?W2<-JyRWR7Yo90 zO%$WG+^4${|$Re_RaqL&r3@Dg7 zF9V^)SOv9SwANcNp=dDHRD;0QpIA;vVA4`%|v^<1zO z+<9R}OsCY>5JZDs@WBP=p5*l6ESmC+xJ2F@F%YA2TH11V)?H03KBayAm`tzk?;9?O z(MNkSVSZ0xnte5s)Sfg;Mpt^el?7o26az)Z!Ft+CZ(B@9pkv@fbxsVl1?1}L4@Q-7 z0UDZilgL1J6@EQ_Pvgu%}~Lj^iw@q`qb>tcO>`5Tc2hWUtGB7$OIO Ws9+lKITEp>r&*y+eV8G*I)w*LS48;$ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.40.mid b/data/raw/bach/bwv244.40.mid new file mode 100644 index 0000000000000000000000000000000000000000..0d010e54ba0384abd3abb29def6064d6a1f9e947 GIT binary patch literal 2992 zcmdUw&uSWB6ve;j^v@#{`U(-zh*3nDj{i`MS=2@AF3>`uB^J{MD5VRRK1Ls-+q^}e zqFZ~chCKE&b?zURv+Fu=bpL~7e(%3wf*Q^<%c^|pS|9E-d~{X@G?}3p`~Ll1!K+Q?KR-HV?cX9*5cj` zmfQwouy@8Fix6Z0)-h@Zg6prowCjJedVjsymi$&1+YV&Rz_j)S`UZOPqnCfNkY2jt zbW=|DLKb!I&gk~M{8KuojYG8P>lQRBm4nbDR)L%n?L%!RcgTT1W{XxCq#IeMUG!(5 zIwBM5X}Nyy7LvVP`K)z!MLxdw;99aQ3Nje;+gMcH7vA6<;17g>GP(eN1v zK9S0;{y`*HH#a3;NL%@B%f}9`wj+Z&7HSKK(-OHAzQDmUH~>QQYN$@b>eN-aZlESm zGtgA1X@K;awxSSq{{K-KzA0Uj(-82IO`s&7OX+#26o2ZHEKXe<0UX00(y^r`viH!^ z)szrxVwD|{wOlIGy`@pL1#&5QQgX^YaL4)7r8SKLTS6CJWXIWLKd`wzHH-krJ5*r%C5XDJW7Pxyj?? zQSv5aK6ZU{Zx+$ojeRut%*>fH16;k$D6j75Nir@rKPDZ050w>ft@uxljP89?kR~^-PSQ*uk zyUdO)dfKxw8Ko>mWP&0A$Bn|?V9y?5&!>2Jy3@lxCmGqR6;yjkylzS|s>iOYSHbF1 z^b`Qs)3fjZfAHOyUfta6xxXe8Hhn_%=n(06q>lA<2Ms{Ofyjq&4n1-NI0~N{L?G`< z_d4`yQ?Ttoy$;Aa*k<_{G*z$1CajKB6t)4;6gsI61LC1LO@8^9U2_TS$}0V7QKz-7 wBge|h%F-q2B99Sv>{&VvMP#^ywICNQ%5kbY6aDR>Hq)$ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv244.46.mid b/data/raw/bach/bwv244.46.mid new file mode 100644 index 0000000000000000000000000000000000000000..aa25b7a03aac0a7540778f6aa9592dfb9a0b10dc GIT binary patch literal 1876 zcmaKrO>Wb05XC3Kd>nyWSZ&fYAI%5Ohm|T#7i0n6RRReK)S#3DbipDE7F}|P9)b;5 zU<)@1^NY>X-#E(3PtP;+-psSFRv+G(*)ywI6xr2k^UowcGiK6<;7h8Ksv#s5yb_mRPHS<>qAPH;cFmq=v0hb|Iz$`*W#RBS5@iO~r z_e<|u07~uG47~PN0@dOrHF^8Pf9=wex>lZ|HTB73z}P_oU{f(uCQ~C2v=^_&nTzJ_ z&d?tCai+A+oMKLwX5YE|)^_o~%zk-h(W_5ijs+$kW1OKn0Zbeyr#?*InI51QzEX|W zsNSU-yt93P_qXfKk^fQFg3XFum1-Aj z-Oy}M>_!fs;n4QQg)~s#i?jx8#=t(H^i8R_s;*)MC7{V2w&?ie7NF&zjYQi)7r=s& zXj0R3MqL^hfWm6yi=K1V^S!zQF5ZOUtStbHYC15)6AUaE z<<#M<)JQ_$&}6rP`U!qc!Y+Me7l>Z$MI8{BY{;0bN}@qmerNZ?Ix!M)2m(KfOnMuA%Pl{vSC*t7ExDO@;Q78 ze`02Q&FJ1nSYkt2WpwU&%*;7*ipBdkX7C5G()z$UVewh8V zF@LJpoodIbS5ee?{%mcVtX$h|X12)*a)1kh3xFBH3_v;4a$~nsKQd>|9Fc;c@WH(N z=ALo_c2;s;es>Xdevs+nyiHXmh?vM1G$ByBovg@=+MS00^x1P2CNQ#1qhJ+BT+-Fc zFsCs*Cyl^Wndyx{GDl3=hl>-jj4Q}&ZB_U8#oXayqV(hEwsT3@C`F@`6bYsT!A*=9 z8R2P6Fs_qT)qpYk1W#h$3eeE$X@;hh;rM6-p8g|ZlA|5SF?lFgwK;)|9tM)t&;x(W z(X0vkOzM5XDDG=Q>w<_F>PlL`IX8HYKFX0C?fow=p+Df^tFPfQnMzu`mEz@F(w!i7`mkW`0t1b`7K9Wuu~ zHOW%yl`E$y*PhQzN&>;oJS9QaR%j2t4; zBgG!T5y4TN1Hf{z*N8nPfe$39te&=0Ab`j}uyBykOqzfSD<dqYa1NFW>;F5D2}-~$IAIq)(0 zl>CWPwL6q%J(jO<+EPzXcXf5`?%DYF4>Q}e4T~Z>8&5CIO5bep;nUa2pXtT*#QvK7 zvzU*?c?oHY?@?6x@_A zzD6GM$S4IEt;|W7%%(~DoCEcGCw#)W#92a#s;35oq8hp$CVLSl!hmWlDGyn=9o6yV zMKW8AsQi+=ZYc@(MR`R`@~&DgZgIID4YbG&kkOdgqVj657uYN6UEQwpR-4S)sMzLU z1YLrHftrjoanvGcWy!kbK#O$>M;b$5)jY13y0>YvoR3-{=N%E#IDL-XhZ>4#Kmi#@ z5hZ&71JXcJzC)cmek4wxmU6o6&NX#tASTP=YU%+Lq-*tJ$fI(Sk~NniGKrdok(itd zQ-sORB)&)Q;L(rcpVyP=nh#);v(kWToTzSfCfBoMcS{igxz($z77jF6r-3?ETC(aF zd}|s|nrhT3IVY`=Y7Ibhh5OMPcEaQnBsX}S14>*MnAPwCLcj`8nx$QqQXsg-) literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.11.mid b/data/raw/bach/bwv245.11.mid new file mode 100644 index 0000000000000000000000000000000000000000..e0ebf167102531864b05be9c2544bd275963512f GIT binary patch literal 2056 zcmb`H&2AD=7={mY)ZT!JH_=cirBFf{CXflFUCBac*F+N&O)=C9FvbN77c9LTFQvE8 z#65n`%;}p$kDY~a15dv5{k-1~TrEGmbIv_?4VNVDYPtUCT;sRf9lUtG`nwR*li=rO4Dc!kQG7e61mu!R4m!6&B?cdBXpYl9lN!J`I! zJDRE=)W+>ve)r9nw)HQ$VhXWFYK5=-) zDIh}^Fhtlev}6>mq#AH8s-72i3YAm?_8pg)auY;JhI&^~ft~~t^h_*V7J;IqXNpv6 z1wLlsvd2gr8;pQa>GQaEB@|px{i2MrJVd3G*!!ty;A+r^2glL4v*UQSe1EfA*ZeKS zWmR8K0~8HRh(H?~@l|5`^NdQu1kx<$ zA>rIz>?1wr2s>F|uXoEh}^srC#`nZjvlF~HKsr)|&zTA`(brDK*ZQC)*0;HY#q!1)-< zu|XRkPX{1MmKGMA6)vAHYbJ9nOgm7^TH%m(*msZ2bRqa#J6_lc&L`%qb_DU0#P=8i ZCAt7oWeKjhk4L9kehB5_{{VwkD>ncD literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.14.mid b/data/raw/bach/bwv245.14.mid new file mode 100644 index 0000000000000000000000000000000000000000..359fe0e84830c3831172bfce623afa2fa128722f GIT binary patch literal 2506 zcmai#%Whgh5JV@KJU$^mVIdG;9tQIi;$b#nk+6!TM2eKiSU8I;ttbl?S@22zl>7af`w3uTU1J9j9Z?(B!%S+W1^d)|?0Pa`H|a|6J@Ko8K1fu4qt4dY~$k1^5TXc)Cegg$yo zllExnbBr``;z||}m-O^0@5g#_#1GKJfYLJ};%5&}x?@oYbV%-4xvJDhH=33j){|wg zlB0_>6B6el3JH@5Di;{CIJPrHs$Wx>OSW`ztebSqa#(@<$)d0vwv)~Y8;tMo!S3(n z>ht|(oAWCd`D&{1wS#;>8_+h;1T>SteWig_*pmj={XTsh@w zg_0p*>Z8tS$7`_rNz+m-l6{&v!Zdr%Tvr%%Wh1Lk6@PFeQfN6`iHs^!h0hvLhO432 el~ZECQYKdgQub8_(76N!$%-gPGQwQP+xiQgKBeRU literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.15.mid b/data/raw/bach/bwv245.15.mid new file mode 100644 index 0000000000000000000000000000000000000000..f9ebda25914dbc8006f727321ce94d3bf07fe75d GIT binary patch literal 2443 zcmdUwO>P=d5QJX{`8h(aU}FU4$NUV&!vMmv>{VDK>?|cwq(mmdIRJ{hVCf^|2tGoN zlADnJhDqs---Il(%8F8VS9N#w1Fq&D-#O==yC<$(c31P&C+A8{w|)BJ_43Q=`ex~V zIQP@Vd~DyAtZe(HTrRzOxpDWGi;Y`fy1n3nnhUEr2b>$2E$-cV=0{W$3Mv)SrwC3{ zK?6BKrKXF!UCkIUw&D@2k%5>oVm~q_MU6+#S|}CLRXl+{@#!-nxxo~f(w*V8mp1*c zOnAVhC>%Mm*rvzl8XHaInQWGr0-|6XS};Mdcz4xkc!478 zOego~HAV<}?A7!4+GB#63P@0H3=kZcV6^z|)=};yeY2PJZ2tacx!Us+6d@3$0vYfm z%{)>AT%^emz!7AFMvJhMVy)Omxo;5xrFs-&Ll@9B;5E(0=+TRs2=J#dteAHfDk~!8 z5cE-ILT^D6WI;_R9T_E^@YyO7-lxa}>&1dan_6mTxcS38a$ciqo+7&K_2^#zWR%x5 zyM=7&a%C>)MeHSZb1(4&ziG+!?d_h2*g~jfLIP6kkm^{f4QQt|HV4HGPS{8z<`j{T zbqwp+QUVPku&RJ+Aw677-HUXrJ33OXqg=Ph0pP&EA>hzJ1yC_?1UNEKw8wj#slj3F?F+ju{Ue;y3+R(AL1Hf?4OcNw>g5ZgP(4Q)- g+&o^dth+WXGRo)}RY3=TLP41zdTa53QRzSEFPYenHvj+t literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.17.mid b/data/raw/bach/bwv245.17.mid new file mode 100644 index 0000000000000000000000000000000000000000..b633a0d1978c68de9277d372718d2c5b64468063 GIT binary patch literal 2164 zcmaKrPfpul5XC=Im-Yy~M3evq5)w!GL*yumSIwgJ4ylzYwIV2RfU4>uOP1V&3vdQ@ z?7HkN(s{P?)0ck8D?iQ5n|U+ubGH2U#W{EA4qOzuY`OmK+`)_6zIpd?b+f*@Ub!dd z{GlwA4^w=+~r*q!yV8%zQ9cWL`vmm8mp0 zP!|8*MJjsOXP#S)=nJtH1~P%Hh!{%|hGv?j6ks8`YUndlL<)(_^ZT7bqwk4F4`-Q( zJ~8@OU~FJ0plcABNQPK~I8uMU55jZOBt#F%OtTJs@fT)NmKTNV9YfYC?cQ zQqTdUrdm)kFbsfCH1t5VDfda#C$T<6ykgU=vk)0*3tcr45G&M!m%JM~bA&LJ$nRv& z???0d?egpOYF+a?cO}1TLV5x+voC3S0swsODAlo4S3oQlVnqOADJB&HMlci>BLLKd zfIi^}&(+F9=&(X?p-nIRl@Zp}zosJ)p&`E!SEUBPF=JU5`_?s{^{bArZf|Ryt2}7R zxu)r83A7Bf1=XG}fO5l)J|Dq&}eoLQtMMMH|ip+s2lNS%+Y mGp1k@DT<+oTOgjZgnBxfRsQ(~bSU~Tg6VkL)XQ#`FZ&<95=2!1 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.22.mid b/data/raw/bach/bwv245.22.mid new file mode 100644 index 0000000000000000000000000000000000000000..14f707a004ad85dafd006faad573129597aef81e GIT binary patch literal 2299 zcmdUvO-=$q5QR$|e~#eF6JYq23?ML0Kth0(ER-FIMiY$~@BqXZ!;&L;6mNp>;qcPq z7~IMRzEoFLSG}s~{^0(`%=T@^JkR=r$%9#H-uJUNC*MV;oN3TK#R}-CgLXn9w5SHZG=at}kWiYAbgom?I>OHgX8`F_X6EwB0^o2RpU9#wO`w@ZdE8C9 z!zS$wZlA`J4X=vNYkl12+>g?De~mTP0IIr1XIiR+n2-7psA=VKmO|lCLiM4}1Ugb4 zW!~!IwH?|!2OvxAG0{#*4e6sQp|0EW@*I<~%L=RXBi`Cc`7k H>QVXv-z#V@ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.26.mid b/data/raw/bach/bwv245.26.mid new file mode 100644 index 0000000000000000000000000000000000000000..5c3d44547e660a011a8709ed0faf1a5fecb8196f GIT binary patch literal 2227 zcmc(g!ERDv5QRrX>kF8;b7^8ypilxOl?5DAD_Hiep_ANEbW)s zZ+pX^?T5-A|9oGqR$e??+a_A9?JhFgi~-{iOo&W8G6hT>%oZEFn`OWwfGbj04pKlG zre;Lo1kZowk)w#t7C&DyL#Nv2z3>+K6mz+xp*&dF2;VjlX_BbS^y#^}LW)DEYE# z!nx3yIGRVG{7Nk*w8-LkVia4M006R2Y?F3n6S4wugo_# zMuL>=Et{#7)U~*WfB|z2T%t!Cy~4S?^mBPK|8%ol*}s2YIuz(+1soI(NBR=!b1!`- z_jv^nM-c%XMF6rMZF3Y+wV|E`pnipx!B*$#Z^H-d^9{9=MVg8m;WT1I|Se$=Bi3 zJ=Ne!8X52iKn;o9hTQg)nywM4d89>)Xh}k&Dxy07PgIK^;2jI=133B~09!BU`NBak zj?Yd?P=d5QJaw2b9kp)M}QF0T~ zH8XsAb@dNiufKkF&b@K3Tok$M_4b={wU6#__V#A;V|#bMaetlr=VE;w zKGn|b^EQfV@89j*ewOasF=Ym0Vz+#%1anf36z&&J)v9Vw6U>t#zwEOO7(gAEBCV$$V(VKcW6K*uz~rP_?gK@ z$sseO`a(mvPkh1>agcn-D|4@0kQhhIlXXL z90j!i9nm|c)0U04fsTM8U4gCvJR|5iGT%wZaBZ^d5p|m*SsN_7{}gJv>xg60Nq>M$5c51)2tk)D@{)q#@AAo@@t7 zW@M}o7Ru*hotFiTE1ghf)P#0ZY zwB$$AXbY4M8bMgpVstI(h<>R-UHX2gjvrRQQlO(ugJJaxmAJ?}8&J`ri|lUx16k>E Ae*gdg literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.3.mid b/data/raw/bach/bwv245.3.mid new file mode 100644 index 0000000000000000000000000000000000000000..b6588cbefcec544b7de30b463293dd95c0d81f8b GIT binary patch literal 1894 zcmaKsPfl846veOhwRQ>J1Cb(%2$Ba60zr%;8Pqp3u}Kq+H0T11>3~584qZfd(22Wn z>N*@q?*aSE_xubKJ-PSXKj+-*X`M>Dhart5nxhsX!WX`ik^DG7uPqV5rD2j6eoZ1$mVJ zvYU}t4FwA2hiZ7}DZoe(kq<;Z2&;zq-J5b|F&)X7`ea_7s*eP=1=|*TG`#9VwMA{E4+wMd!F799#vo^4q1o zO@XG*!tkc1D}pXmU=#okQ@wz+@B$wF1$-QTznn~0e6vggG-QnKToe;(+g+p_ zD8<%T1!#+0c+#X|06BIs@XYtolVsJVHe8zbnu1IUtFrueba3BLpDOzxhY@J6NlvXe z-6NVFlZj9T;JqN3>A|~mIa;hGfs(wh^X?bU`&S=$_w?#&#dYgiT6e0bQN=-3pz2^- zsqIC?fg%+}#3>7u9c&70Iw%R09MCX+3RQ8`2LL&?bx-8IcN^l=jyOBcsp)4<*0UJ< ou=AG4Tj6w+qP;Bb(nSOgDQsa4RPYqIE+BRz-lwD!mX;^{2NMAR_y7O^ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.37.mid b/data/raw/bach/bwv245.37.mid new file mode 100644 index 0000000000000000000000000000000000000000..8241e0e162564b03c5b4f8c6e0796ea199b1a100 GIT binary patch literal 2434 zcmcJQ&u&s-5XHaZ)%pS^K0`~PErIaoQn&;NO@kX*D2aW2X6N!iYhOkZ{6K|xpkYlD+O0@u8eaDxHK?Z-nq@pkBAdCR4Oc= z(r}tKG>~hk)O7i6&lv;8MjlZ$GLRr6@grkWaJ=$tgi>L-$P>yZe))_@PS^|?L?mpA z47SjMTDjB>>$5jAYbaNx$D96`ERJOS2Y>Fdck6cbKUej_t}04Ce=R#HnJ6Hw+D8$A z2_|BFg5$-HTJ(e&S*M`#5O@!tRSlRmu%Q=Bzc8SPz!1*RQUU|Wxhl<4l_KF#FJ*nW zW9=0J`J*EXjZ#B_aHxcZn}$_I<=M)8+~}L;c=^L^;@ok3x8r!a_;9mYm;B(wG>Fp% z8Sq-#k(2846=TQ%fYS*ecN8&?0J%%Ut`B-ddVZt}8BPb#G2ji&WONw;CkFgQhRELZ zY=k0`p;-bwMxfB!)MT)!q>3!Z)Y$`><~9x6{$71H#X~)>`lz!&iO>3CX=n#~@lYoG zE61d#2-t$GBkPLvn6UjT+iiAoxA~4AuF>`FZOLgiS*&R@1T>>f3V&OGR?0C!kQ-Rv zNF(Mr5mkwNPSv@k1R6xBssU<+<(|>TVX?5G*T<&QN0B<6>lQf%9Q&Y3q-v29z=?qx z=R&#koRT`V$Qj_wfI7<`rCOBlZ80(?$T6L`u0(gEtJPjj%q(_QvoyV=Pm#}${ZYds bh8~&bDgaw*0Nkhp@K9vWgnOi>|Bk-_8j_Ok literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.40.mid b/data/raw/bach/bwv245.40.mid new file mode 100644 index 0000000000000000000000000000000000000000..31bbe3ea72134e8ac5aeb0ea464de40f7fd8db27 GIT binary patch literal 4657 zcmeH}O-@un6opG{f0p157|35}2+(Q3<~2W|(}6?=+A|VOOf+D?1rXwZfdht4T!=H5 z;zkUf^Xl=XURT>fLQG7Uz{#z1|4!Yy{rU&*-h>byhXpYT_aQW%hpUHAULJou zIXpTJKSKB!UijbD>xp0b`>N5Hc=q%nT=oVR;j9dL=z?Q+5KzHytoOJ~X zgCgbRY8RVkWp6hY(eS^Nho@?GKEdsXm2A4w(_6A?0<<3jJ^ML=LcWUlix~N#C z>aJCdBO&0Cz=9WmO960n%g9ysJ!h|7C6T%193;8aj%R~1aKDL#VdDw_n-*$Qk+D!l zo}Hv{_TAUM-17$EP$7UgSjK?73}!xwQ@((EB8 zc`hsoXLyYBSxqb=J89lK9A@bLoBARrk4+y&zI zMWrERK--@K&ebwV-dDQ7&i$3Oad>(dkky4mE<6LoC1UxNCJypwyKtMF4uSE;xPV*z=C32pW zPT3%+vET|9%EE?IFsrlX%!)& literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv245.5.mid b/data/raw/bach/bwv245.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..19d7b6251ab18a6829c8dc204b3c9d120133a33d GIT binary patch literal 2317 zcmaKsO>P=d5QLw}B=!-!$_b3Y2+TiXzy^$96&49QOGy+dk%@2)5Jg$A@FGXbQF4<> ze>3CK8$UFwDfO%FuC8v)dh_L@bMB2haZ%*foBdbkD(5bFb^31ieSiP3bAO%t=f-@J z50&J^CGVrCa(;Gje{Q!2_w&{PerI3`m|7&}DK;<#5Gmn|;f#$l0*q3!fvj>4RA&Ka zQC?8wP~jYfb4yp9C6T2?R)Cd(H7(X@!~l^c5jb~%J3peQ6;B1STFiN(sr1|sx$z^a z6J{+C#>g|k%+FFmjV$N&G^1CRW$CzDvL>a!T*|>EwdeczZ1)kx-+q)GM_6c#`fSYx zSo4s`(7D~pT)aJq=@8tB34r5uYCvcw5{>5?=?OdT#Vlu`1ebOG7wIi6PzPh7pi z7AiPl(uoQ4wj!zagc~{_WgRPMSp|DV7LaDIml>Yfk~<%osYtwidM4++28bW{+XeMQTRvHJdOUH7 z15`7#cfXcim_vGoWO3uNYCtd2)xA%of3%>;>fWayWC;_{lM1SZK!;wPG~K3P8(zdJ z6Hy&$_98FEd)C<#)|D78vgVR_0dZPLrC^hhn+C)Q-DpD2I0l&FnyhQ*pVC`?T$B69 z$C68Gkk+vLE5MZjMWjPlqEV$xWPv($>Q?6xaA}~5)~bOzfF~8y?@kNTsA{1n&neqw z=2Y&2x=Ue)?%CoEU{J`B)EeYkD%Ai|8%V_#87)|8f2*W!YXATM literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv248.12-2.mid b/data/raw/bach/bwv248.12-2.mid new file mode 100644 index 0000000000000000000000000000000000000000..6b1ae15e6e206fae7255d2218e5fc1c75855186c GIT binary patch literal 3082 zcmdT_%WhIp6y2p)>nHdRl|Wkpr96tj4UfJCGEinsG%?W>L;V0^958UuPx4dzicWDY z?r~+`9z|!$iU{;vhYIpC|?9=@EW@g{beprY9 zR&NSB`1?9Z3eTS{?XEXn+M;I;q-0VsgXvdW3;;$1BY-iF#vY8wm!4-f@2Kc=KpH7OMNm~0QjoY>9@>weIE7K z3;>Pj7${Fhp6GKI4A#g}{*-x6^G9KWiiz70BhX`>tiw=UD^MFQCiE<4$1hD!PPcme zxUhuwr6aYW0pl1Yj13?r0O$VQA>99D^6q9f-}2RMP~ZkyYfuJ)CYdIH+^VBGW9m4n zGv*HL&Hp{u))6* zJls+q8KA{2x1hXg#Xubj==E%>9`>bLu?Q_XfklV3H$=O(5t#JyvPW@D; zUu;nYQz57TR9TdaOSo>;zo!@cHR)d8-fnqLu13gMVR_a#Bsc_6L#nD^0Z4u9taKMvNN+40UmGfT0|cHEv7^)!}2DLUYMvP8Nun$pXL+nUfa`<<-dA z#U|wuOfiqSonruP@Py0>7`>SinUc@Esj=Vg%k2U&n+>2259ovg)G86MsF)&|oVCR#UG9y8_j!Ha)^Fw~*OHKk&5Nve(9Kk!VkPyNr1H;IKKnS0OEOd4xnwV(7fP0N`!NLVc@&cYgZh~F& z9+jEA$!xGvue++c8=TCa9z^6^O5%AknXjKkO7C(wy|`Vyt{2Od{D|x&#Gk|cNl8EN zJn!V{ax1%8yp@lc$ZiTSRWJq^rJSRqjI>rXfI>22uQJOnU%5eM;p?hR-lIAqDg1 zVpIj@-WKF_si|2sW2h-&a6oq(1*Y6#YKrgUfEokJ0gf7Ej=I;Qp3NVZt98LI%l1(K zKqUi}>;QBUZOgR5w3Q+7!T8D$w7|5It|U=L*)k!*;$l4%oBJrh*CdE_GPv`q6r=^+ zL!1{nU4U-VWtC|`9nRH;JEovuYEql9fnW`-;eJ@tLOTX5ut<5SPX5L?1!It5yBpqz zyPvu9AAY>O#b#4*<_6j_^Ke4$w~Cso4#wgNn2IudDuXE}HFiODY^ttI4No-%Hlpn6 zVDLn*8j4ZFt|pkKGF&TlSX@O7f>i)a9?P(XPYh2B?w7@UVla0JEOu)s=svm148|#_ NOvbITdrtmG{{v)q^BMpE literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv248.28.mid b/data/raw/bach/bwv248.28.mid new file mode 100644 index 0000000000000000000000000000000000000000..fdbb4b064d58bf4f76f578f3329182e1aecd6c0e GIT binary patch literal 2119 zcmaKt&u$V?6vi(&Y8O6$FF{BtDG&mMp%VgWyD1BuT@y`AG{sOKpfN63xaiWoFXE&0 zJzU`VxHrF?$(Y%|m-F{K-#HhqH=jO)5MG5=$g*&~*?kV7^*bD1yuRIj-QC@9!=DhI z!%Sa?_wBZQzRR-q+mn5GD$0F$EW-c5Qm&YRA%oVdz%t|h0)q6pVrVTAzx>eRVm*R72AXkgrz)WD~0axG9WJr76UmzD6wW(tvhZFX%-087IBa zq!$)E*1pFEm>rj+Q9q8P7;3l{$wi&Hdd;l`F-%%WI+0%pXcvgdQrK7G<8Gq$*KXqF z=HvZ#*YJ2J8c|yXP?Dj?;wTwtiwnz0F(Zqas-P~2n33qq#oZwu!B{Bhf^Bv2HVwqe ziStOkVrA>DTOi#Pw3zs2Ek=NGU`Q4&#u=)`(6X?cYtnPGI9H-kw~#edmgnTgYRPM;qF-uRUAQ!=|Manu=@TtXg1-iZtB9cW53ew%hr1jKYWKo%dPFAC# z7vk1q7A=EU%nDt)HPxHxOFHSpvC@m~P(9PgXU8l96;;^|!K71=?pTN+3lY$nrU>2; P>{gjhqN9JKPCUDRBuO}> literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv248.33-3.mid b/data/raw/bach/bwv248.33-3.mid new file mode 100644 index 0000000000000000000000000000000000000000..a03912c1f7d4bf1dc6fa4ea753d79091de4c9f36 GIT binary patch literal 2083 zcmds%J#HFN6onsn^0S0=S%3==;>Tz(g24#Ova3)ebe0k+QX&)KEFg+fP^9pZvW;|E zM;d%S=H=+&L9>7~_R)Fg{+)Y=o8`y%A%y3l5wa}YEH|G*X#5VllNWE+UpBXQ>+mat zKVibZ-MeN(f8S$W?_ z`mqd}044%v4E!`jGnFPWF}hiG-1|+W(Y$Y4tG&c;YHaW_dMh} z%J5ji34OM%<=Oq@gvrRtbNm*PHopJ6dVvEIa{9?bawd(x{9+Wh_xCkd;^EtDr7b&r z6UnG?VP|O0_Liv_wzjECl=E0)gStd@rD@@KYab;*REO}+9!LYQWqrgPtHV3wLE~1< zoRa5s|K!X9h?8(L0`$`(Ave*b7EA|FMn%SL)C_2&T&p_!vCQhZ{2EmYGm``QS#CFB UquJXRDo=_mO?me8I3XW9%dQgj;SvMijt202%^FO=S4a7~8`yZCwrL zEZ6*;$>`(fL$~b7&0c)4ks_lw65Y~MIx3uEIrkoE)~!BN0g9a|A7@`5&+K5w&2R(A zk(Q_Or}_Qys3C$D>i;)9qC+h>bT z^rlF4v`0>M@VDfHRo+Juk!XnESzlwwyrGts_o;v!;!tqt6U`hJj5uL079<6rye;+i zX2MX#IsnKt9LOl$hj{=krCOfq3dlnM9Qtsbq8o?~)kn7A2IV|JQY;838Z|6fTp6vf za{S7^=-(;5y}v*3$k@51%W3(xfNbpu+|Y1G)~E z;!f~>^`0lMQpnh!37p*DbMHO%ma8|foO4gyBUh`r zKir7F!^_ISeqYq8mGiTm+t0F{+s>TZPqMw+P7I6zV*@F!)W8%lH89IQ``~%@(QW5u zxdvPtm}g(SWd@+&oGfCd6!hr^aFr`Z-7TH&e=M;Db1ia)VH}ay$XCQ%S_-gv7rSCqR z5{F8soDeDKawEEqV#^TA&@5v>K|m=ye0l(?EVUiWvN}HNlLzC>0F}$ZBU->mmH#5n znk!{MM%I93pc4ovMzc?;!zVWZ_^&#wE^1-YWSJvk{3&&&u=#T36I3OM1OX&gc>ov~ z5LE#+9nu}yMCnE&DTwu(iS_a7_5FIo8}^&0Otll#O8?#y zRbG_D)o0I~pa@Jf?r??rX_!({8)YHx@uWjemm!H0rEqsVCLmNJ0_{@SK0htlO z$O31Ofg#JN0z4oX_)MRwzONdAp-+a^jLnNxf#`eG_Y5t12@+-iCbC)(MSuM#+JY_7 zDwhs9tzd%0iIHlnnz=;AFn<)ON#)91L)&vSI%%HJFv>7J7+oUl49#bT+4WF!X=G=D z$=LE|%DKg*CNt9)id1dRj*HFRA6M6o>&f!{)oNYxbE0MHDs(x@2-AhFYXfx%Iu^K$ zNh5R0=1)CFN8uXUne{j`HB!)~b-QS7jUriUEwU~gJV~p&H!J7f^d$3l17Y?_GzyNq zq_dkRft681M`{>uNl$$y);YX?qG@vXXs!gTP5WhkTTl0xU9fpM&t+X=Ci z`x7dDpN5y$*CiL!VvJT%ZvmF6wRC8y9Zq@cOj>BAyh+fsK$!-aM)72wd8+aIRO4_O zu<~{c=-7i!csj9+8nwZ2Q%+FIh*hHNfa|{DZk0N#Tw0GPKeF;VGGZUgpne}Fan%6V sJgG9O`X4SWL!Y6OY7|k11z0DFX8z-W^>R$4k1}D`!y3oM=Iprs0v{u6-T(jq literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv248.5.mid b/data/raw/bach/bwv248.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..f8062907f6c048595d2dfbb7956351850de58f8b GIT binary patch literal 2794 zcmd6oOKuZU5JexR`7D7wB$ge^-}obc(z0bKBRqhfMFI&46eEWPM2LY03_N5NtbwI4 zfOVL<-7iP4^DK)AA|qeb_tvd??aS4>H_o}I?vYCpce&cUcdnAU{o`jZ*B>`m*K7B~ zxu0&VpZ)8Kh3#J@N#(`!t=o;Wt-BpNw@U?512ch{fr-Gx05PL%=Wa)#Wv-aHSr!6| z5X`eLcdpNcYnd5XS`1lf_N{12i~mc5DIlL}ijpiaWQv7kDb0?C1Y?<~V4wrpm>-A(qqFx_#~Ln10zYC6f=I zj$e|WXQYZMJrEe=&AbKIST6AZ-~y075LeadE30pyC(z3+=8}a`0Z0$HP@RiB*b5zZ zrztc51OspZNdI@7gNrl~?mbkmYQV=!#{~f5DUc38@VNv(50z&H9l1K8i|#``@1eQ4 zHURH|`O4?}Tv@O>lcjj*#<}#+xw4j| z(^j#t0xUs{S03r&?Zh;OYEhi60e#7WeVM#kcic4CmnVOuSJ2dg)quLZ1 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv248.53-5.mid b/data/raw/bach/bwv248.53-5.mid new file mode 100644 index 0000000000000000000000000000000000000000..506fa367efb6a250d27976db2432e66c9f546def GIT binary patch literal 2479 zcmdUv&q^C%6vc1j*mmc(kKiT*HH3^|;usP_g07lHJ3GNbp~Xn_0aT=9(M2AqkJ2|u z?=LeseB;Pax+&S{;m-Yg&iQgV`+99=Z|#jmkzLLf-^>~Zw%&X9aelkFx|!QAv)`8T zZ~eKk=YKy%QRBn=rL9KU(jG=;t1)2gV3IxC!^FW9Fm-Ujrwa#49ugUPWB?dANC9aW zQI4u=M(EQhTjl%wP1S!{Y{I4RBcSCKnUVu_B6AFx&?_(^Qes|Y{wsAw!y%nfr{HjD z>(Q#imcudVN&P`*bpIWku-`;kXt4x&$& z5#2DkreRDnRc%1qL7e^E_VHQtN$?#z@AUFj3+Sa*eQ)^ zgcI`t@Z^#cx|Ab z(xQr-YD70DSQ7&UkIwt#&%gnO7Qeb#kzfB^9Lbl- literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv248.64-s.mid b/data/raw/bach/bwv248.64-s.mid new file mode 100644 index 0000000000000000000000000000000000000000..35fa61974e7f8767d2d6b99b6d9106ee372399df GIT binary patch literal 2677 zcmd6n&59FI5QVR?{dokRK?q?&=p+-mX**<^gv@HP7<)IMASe^b_yD7bWZ@#<#z%2E z&)^gICb3R;=i@ea$VzZF$)RrDs#E7w-}BYGH_o}I?vaZkcfQ)Zcdql&?H@n8SbyAH zU9a7pbAMc>zy0e@$9^xPsPp3a*6s3g>uz)Bc7;G;U?wm#Fcp{@ASWw#?l$uybLGq} zvJhDKU|xPZ9DS~jmZgEE<#4Mgf7VTD@qcMB1q@LGVjL}`Mr-6SnFwM|%dZDj4M_Q1 zA_#=tmr_-Vg-3eebX_KWt;7S06qdTbERYQY(~d41r9b zwG$IXCU%qvBvmrE8jz??>*!38GfPJ35Rijp4~-9;5qc&O>d)!R!FU7m8=u$-#7xWY zwY-I{w?0b><~nNC!EcTz$Oa_ZHYx8>wO(RKa<1;G>_wVhp6}+De5W$qSpcqwHYKHr zAQ}^adRtftW0*RBHGkP^K3ToJUT=;(Wn*p7xGHI6?_a>7a)y=@CJ!a2js^mQD#w5d zlFWzz^g!~^Opd${q8ibwjAmYrQPmgr&^Ti_z_YjEjPs1cPBE#cVRI|2Gm&4il3S;8 z=d?1#G?Y8g$h5XvNs`Bk)DB{01IQVv#i%N1K*=5rOO^%Uwz3lUfr^;FzrXdg=2tg2 zN7lD59(`+u-?1XGMNoleyj57B&$kWp+jmj}U=^EJqmOx;K|KmAqaHlSNMnk)9Yz z%z-@B;{u4Kv#v9R$ER6ej$$pelJV`WgEg7m_(}pwSFliX+ihNzisP^lZ`7iMU B&)EO~ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv25.6.mid b/data/raw/bach/bwv25.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..87747e0ec7ee9e29094a989d7a10d9994d049216 GIT binary patch literal 2767 zcmdUvO>P=d5QJYG@^ggT0a;)Rj4>F2u>m0?%L7rV!|}gbpf~#aKt&$d?b)LJK5lp>zDCS zQ5{`h+n29L$(nq+%4`KiYszSN;HFwsP{fM8F=k)z$?DvNWo6~XM|rW-`|@p@5$&Wc zz_#l!ppKg5fv=y8s*}zS^=<2FP zmlgo;)CD8$;xWjJEcA_qR6*?&aUGb{quF2G;G<830jsfdAxaEx(| zb>#VUNKUV7yllr$#09;Rh45MBdA2W1|CcV&ggcFVgYJi$R z9Z(m@SI!&BDtwfABX<3qzxT=2&CM3mSLs?!x(c8tU%E*Sq#FQo_5u5G#4>#3$`z6; zN_M17q?|-F4!ZluEuMsin_9AUc|CiO-xFsm-DRn}ia6PFe9OA>hIZ2ib=FqkI_~8b uu6zKW19f+cLn4QY*lj*4Dk!t2{u5a9Umc4RsR78T0@zm>s?i1$+x-FX!0qb* literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv253.mid b/data/raw/bach/bwv253.mid new file mode 100644 index 0000000000000000000000000000000000000000..83012eff68b254212aacb29314e47db0a4de54e7 GIT binary patch literal 1657 zcmb_bJ8r^I5M02Da)exhL?H7M!We^vu%HS>;yOj7bU8t!q@bXn%vI9mD7gvQv0p~} zjO8i~jAnOdX5YeY|NJB(SJILoklp_EMWppE=T7_nR=!1kB*xeIvE9+nhahO*Tp#4L z$q(|j5rB^pWB{2mTa>m%$@QdQQf1ZvYg@{|V2Xn5;Z&L*|HjqA8#hy~lp==bmFAx% zW16cm=#?N(qIp&TD+Meu750OFYj~*Gd4eXpBYU zf>GcxF?vvn03ro5G|!6W(?zq>iE*yVlwJT+jKS9>FnOHm9A0ysqTn1cO2&CD(6jJ^ zDdTNHr1`%P^R1vwt#&k$;l30BR+BNI&F4rPK%Wm>Sry=Dl8gj|_SLuTqw*@d?^`NB<- zrkiw;y=z~EdUP0~XQ(|RfRSzPgXt?noe&J3aEP@q6#{_i1E84h%wL-!<)BMW&Dn~DSN2g!#LcTurad}tg~=?(V}iI{i))8+&aYpe*w;F Bx=#QA literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv254.mid b/data/raw/bach/bwv254.mid new file mode 100644 index 0000000000000000000000000000000000000000..2d91e01a27da552f38245dc202659f4784114759 GIT binary patch literal 2038 zcma)-yKWj`5QWEhouoKAgQ$c@R;okC z>Ogc|8znG?&bgG&J%=IW#jjU~p+Q*m4r^06Q&AlvB`~%L$N@yvnNOG)eMLDq4Aa0^ zXeT~}_kIcoqc8X4Ny%50Niz>z>}m8G1?&zZ$X@j<^2A8#KYOKzeqTH6f)>Wb7o(hz7kXbH3& zurL-6tEQZq=akT^%BlWC$NQ0umTp3|8Um_b7m%NtfJ#&aq;o96<2XVNEOh9i#Pg8^ sk6dt<)H!WE z`Ae0!>X-Rv&Y77`G=IDoku#}?Wl1z&KZ{iEBsn?1UcIgt%aweJe2I%sa$D8Ze5z1Fv#9BeWpQ zU^-KsDFie3T$wqX!e~RQFe%$$`3yP`i~v!ptQ{J2?IdaZtoTY-YJ+~!udc{+bsuGUA+HLt_+R5DwYO2Taj$)SP+6GR4pfkGe9 zSFi!LLI=s6G@^irQLd4~?l~F3XhQ}6YU5CcRrDh8hZFwu#KYlU0}O~i&n1)vZOm>L zcK?J+_7|JYk<~X*)-+evLZqdU8la}YoDTZHe%pYy0+X4;syfQ+n$tjXBh^uW7pwB7 z4GTU|rwyIoy;x4*f`%}~-SknOU5Ns2f`VNP=d5QIBq@^ggT!9rLFj1d^|;}Hm%RahkKEG1H;L?*&HfE8uI(#OaySMX7C z6Vk;ze|qpHMBYTKru6!!s;gTwn}7OXW-slTWtq+9tIuYYpSF4a>h1FD>iTAB4`#ou zug~Uv#nU$LvaIsv_1f+yi?!WNECTuBhu!7=G8PzbLk^TP)yveum8!0GU%nSFvxS4% zHsm=Kim?=>5I`F7}7`#Ocb>lg?O zVr2tK+<8HCG=^7c49feeQp2IZu(TmL^Z{I|>e8#oIevxMl7gOG?QO@w=in*>rnB?H zwT;wAKI1CoP>=(_I;wiIx6tE2Yoa_#b}lV0-D$4>g-&ySP4U_N^0Rv}|9G=p9r#Ih zC8X<}o&-9o>UdR4pyi+~(00INfUZ0fMMpqYBy-vfjSUxSc;U%U5=Qd>R0tRBElpb3 z;y|{L(^jZ>32xvIvvX4^z&h+L;|iVAhP*(EumgQahLo3Rr(rHaoGqjzv+l6v_-r5a zw;W#I-X6GGTxjS@8t!jXpy{9?fAvxqs5>}S=rqpZY6;Ph5Tmj%3~H+L9+y*y3q4hl zR{e#}gpO9~i8P;V9rFR@7#`v(vttzFRAq}st_jrs(#I*Zoz&GcRh@YVuDbLTu6jsS hCEM40y6_g08!_R zV(OgxI%heQPZyiJWIb6%)bOcGWeWTO{m@}xUB<>92v!2 zP!u#|-5kLFcGh8AzPr3%y1ZoY`D@YH9SRy)*+9zrzOBAM&!8vJ^;0*FkP}rY$5lfo z4+R)?=su2&4aNenGxNw#_9belNWKipp?F9Y<2;Q6t30-z;}Bo%4_)nx`G>3Js^HfWX~<`*9BJ35-bboTyxp^wG@&?n>&b8IenkEZ)2Ng#u0(53Q%)<_#fV5`zn#!y0Qx!nikt0WOXPzjhArz7I zD))!+D4NR_Ulx1C1KOXeK{{YIax{gKZDzwc4S|+H`h5zdU%o)P3xU1=ZYuZHVgk0% sFwbZ8vGe4xxWhg~4()AtQfsCh!y&~4M&=1y${yK{vE}RlZhv)e0ATpxZ~y=R literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv258.mid b/data/raw/bach/bwv258.mid new file mode 100644 index 0000000000000000000000000000000000000000..c4ba96a1795ce16a554c45cd5118fc8cf799c646 GIT binary patch literal 2596 zcmdUvO>P=N5QWQR@^b`V!a`uouRsJ02!y=}iknr3$_^|^>};I6w?y zm{G8!+u3_C)ZTx)ot15hk1y|=zr5t_=db&oU5_>QypKMjA9vQL#jO)H9gX2xjG^=% zSs0!oPICK7Qx1QS%{(HU4+uJ>_O-3Q#)-{Z3siU`8bx~ok ziioH*uZ|E$E-DDpTlj!pq-vb()C$4sM~2U+)e<9@e9|%lLQD*+ zoIq8xi=lR@Nl)-O@nF%&GOT0BF61oWI#G;j9pikQHWq+uUjkmjd1s0coNYtnsA$xN MXEAbcPJfBN0NU8SGynhq literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv259.mid b/data/raw/bach/bwv259.mid new file mode 100644 index 0000000000000000000000000000000000000000..c145bfa05ca9f6df6d3ac09b7a0c940af233c5dd GIT binary patch literal 2254 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 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv262.mid b/data/raw/bach/bwv262.mid new file mode 100644 index 0000000000000000000000000000000000000000..70b7b1872b91ea513e3fcbe8b3cb364e3e8f93c4 GIT binary patch literal 2542 zcmd6n&uSB46vaQ&QTqr!K^HAyXb1^uNEjyxA%(hW7Ik(76+vkvb>XszNER-#aN*#f9Cphx?uT@7$9)nZJMIoO|Y;xF~Wb^W_KU8n4`D=lSX4)AIac z;eI=J?GpZNUN;){_biGUFLqaMJ;_$?YU14b7;tPrktvaB9{J%pqwJfz8d)UeDGhnsT8_=i|)6k72s3xx;!y^8a1?MlWvvQmG)>U83Rng0jpX)3&q`klH zpTPj~z?QGgD(o^qM96(W-+&^+tZ-6Lu!z)F-kvZ>-+l_}{L?&YA)v~N=-vsNmVPth z2#6!IRDx`3{M9#6e6B2F7l+n!p0mVq{8A2C3rMFbGEu!wJApwyxd8I$(1@3&3AdQJza z{Deii#(1=&O1c`Ll?AHgE(Y{Mna>D@$92jTi!9KRU-_QVV>)~wFYyxP}!iXhjKeoZDYG~!V&TK-Je!5K-WYac)!^iB7@`r%K kTm%C?%K#kxK4Y>VtEoWsULvchILfLylRiNAo+)?R4TesnP5=M^ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv263.mid b/data/raw/bach/bwv263.mid new file mode 100644 index 0000000000000000000000000000000000000000..58a9eb34221e8d968f301cb7aa77aa729db065ec GIT binary patch literal 2281 zcmchX&1w@-6vt2E`0)rnK@~zs8%ok4X-H-o5=y%=3!Pm-K~Ne=UAQbFl7)*tl8@p; zxR2-GJN~%Ig&+!Uk{{>mp7THV&gJ6mYcqRf4a+jST&&)iHGbOW!Q&Up538%|rF}R1 zVPpMmUNsy3`!dU#PoJ#quB_H}TUrF?vYfjGn9DMcEi+kWaTXR}s+g(A0Gx%TP)y-5 zBf%&RCT3QB31>|ODp(5Cb0JXrxcX+dV~3F}sxzwY0x(4i7drI9ga7A%sR#@>SMxz< z2dw~0q^i5NL?|_BX=~eb>fJY=`R=pH`;Yq;kKz&3+95qcV_^qK&pgz@l0u<9g@t|o zy)XwYY^>q6!c)Pi0|j&KDUU6yQF?lPIrLO~WGP=ijQF}d_v`X-@#cED z+Vi0psDN|@SPPc1V!|_Y2+yzvV$f_a?2gD;Ku>4&yq}(SDCi6N4!J-Jk6a!cTn=*O z+OwdqJPR#jU6LsNiloA^@n-SBDxWO&>~@ zp}Tk@Sfb#sVR1vL5rSQf!Pe*HlRhuS)y>VG>p~wu)S_1mihDy6x~tB*4g|L}M$0WN zxdd%N+o2=qI2;NN9Y{Zx<=8DO9v4}}94Yw7gQ?urp=#qmaPWtf>6vu4(pDYy+|?&Y zmFWk?*#TSO2ArtF6VIY&T-^0^Qu;wdEGeYve7zAgz42XuTpe5;A;r{&s DGmT+b literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv264.mid b/data/raw/bach/bwv264.mid new file mode 100644 index 0000000000000000000000000000000000000000..2b1af0b981a8cd0ba32df91455c77e63d579e117 GIT binary patch literal 1501 zcmb7D%}N4c6usK?^9VhG8xchZMMgiS8AK7>l#803P!JRv+5<>LxM(4*dYm4mH?ebO z#yg*AS{psw@7(X4d+s-b;r*?MoJdX_M+U>`gGerv)zRtIDr~>HDv{K~fP~<+eq@)VlDt3Q?l>#bR zTal$AN@ap_e3n*9td!y-B*UW$BT8|}xpca%lT-&#BWlg1+l`6zNXahS R$+5&B!SOBoNS0G0*&p~Gm4W~O literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv265.mid b/data/raw/bach/bwv265.mid new file mode 100644 index 0000000000000000000000000000000000000000..9b4bc1034a389eaebddbd4b054c173e5e90f79e8 GIT binary patch literal 1480 zcmaKs%T6L;5QR%^FOM)!U^Ik_1SE|@ngPU^xEdBSy)zjT6O9;P>B1OeSh(Pke3W?; ztgjnSelNp{lT)WoRh_@X`S9wmnQhscMUkBk$Jb_S4O?t%{~FzmFK$QnYWB|(einb$ zUAFigMe9FyW;XAqGkfTp%})WR4#b?moPWOxR17BYi$o@+EK zL6f*fh60);pe_N4+xWEI=c}RGB~Dm_q06qBEz0llO+3D+b2D9)os7EaOP-6EBz=0n z$7c{w2L_Iby_-gBBncFH2gi zO(_r20RaVKA3-Tb6NiR6M_|Q1D#h#^TNwS+qu(4}-j2pAzFS?UX#!0wo4%TuK>VCX z-b^2J&2oMq4&Kmxg3lvJI?yZ=Qf8koBdYAg05o74zM)qAsu5F1Tz9d$lzp8?pwt9# zasz;K%s0jR)L?2E;{ZmQL!1vkWPi_R|MOxpSrL7ewrXbW0PF8o^b*5#p&mnGZLbyO zTwz4T+slBmgCd~lK$;p1(^V4K<>uW`T!G0A9bl;TDkaW2030|d1JH;m!hD#nHRN1E dQ}QmYvB!pc&g@g#cTfNnGL8Q&1cur7{|33#iGKh9 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv266.mid b/data/raw/bach/bwv266.mid new file mode 100644 index 0000000000000000000000000000000000000000..2c0bf3387b1b3e47ef3100530756a12d1b7b4506 GIT binary patch literal 2326 zcmb7FyH4X!5S@gu%O~&&5mA(<97PVc*HPqRMYSow9TG@LAc6t~WeSQE6qNfp`ziYo z+h^zaULDeAi}l@&hb6z>yORT_WE%nzeIjZ zf}g`xyVa7zW#_1Uda{>~B;U&}kvfp&AF|8zDMJpx3Si|%mie3Pmc^3-?}^C-Y`8=p zRHXo^0!EzVGAVPG5LPO;5vRN=UL#P*9QI-7H2-Pz&=x9;AvMkn2gq^vEzMc^IIE51eP_49MX-Au73 z)Kfhp6Fh-q05EXLMu?0w!W>qO@if+_AtVlqas?kqR7q8(M$)zew+DBDi%XV~H mc~^}(12`+JQveg#nc}-}70FcS>{P2@OM_H8ZyOf>g?|AgYi)-B literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv267.mid b/data/raw/bach/bwv267.mid new file mode 100644 index 0000000000000000000000000000000000000000..27b90417639e1485e4d907a157ce528244e5bf65 GIT binary patch literal 3812 zcmds&T}oR~6orqP{tTf*5LBW;6XQ>aiNPQAsXnxM6Iv*=XweR!6d!yj=om@|(xJ2? zv1{FX{5Ur!Tr5JNebL4KU3=|)ZjMjhy$K;a4Ktz92*)QE??agT9`5Fzy*&STae8(h zeuVHd^!@Md_3VuPzG^gPUp&7Kw}<2F@cA%=+arS`fy41tY1uc}mu1gjPXG&9Sdtjk zDYFEeHFD)qQ72mVZE;LZospY5YiKY`>kOT43+ewNd8U}A&!qBs3>NAnLPhEJEL6F; zNx@N!m;(nNq^c%6jeH&^I8ARSE`g>wU>sU-BrqhV#)TUB{p@(a9Sztw=nM1=dMQZK z%E4PBIL&p!(6)2SZb8_tjfc19qyXhX9(QU7ke@E-ZhO7z}$>!)vB{!bjUJPa(#TwPks?l(lKFS)>b8?uJWB zZYwH3aMMz70e`J>3pWZMx+5KceeoVRvR(JuRSRNv&Dj=$aUsH%vpis~PcqKr$jCy$ z+H|$3$lD(yxGH-o+orKy(1;ca!f?|uUP0HOE6_3M2&@^b6&9u2f?}wOB>{Sk`)8_?o)ixEe%4z>+Q*?d) zRvryIw)i@_KEU#VqNVK%YRg5;AA)#^-SL;Qasna^_;lReG-_`=X0gG(e>?n)5{sHv z9u|khX))=#2V5^^7x3)FB(B&rx2!sSRav=E`4k)0d86o+&n}B+Z#%|<0}z~j0T{Vw z5h`Etq`L}E|B@v!nj*RR^r3(A@9*IB^0MZgLvh*cm&Lwi&=OcRm=H+K%4?I$iW5wo zWcV12z7%Y_a#QI^Q>oyl3wA9CP%w#+>oLT{ryZ`6kL)9vF)F9j@=Z-p6zR$|s^xQ0aNaTVML_{)(Ui(7F1R9B%df|RuQ;o;2-rdvvvYRz!i6l; cPC~t`GgBmsldH0eq^Vq{!M^Af(~Fn-8&@&^xc~qF literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv268.mid b/data/raw/bach/bwv268.mid new file mode 100644 index 0000000000000000000000000000000000000000..27fe193c14f9764391f07a64ed05fafd2ebe510f GIT binary patch literal 2407 zcmb7^%WhIp7=<^8mq+jkIw)zOKuQQ#p#(zOkqnes6HQDs#ZVuh8V4jg=o1+q#W%tA zagHnd^pK-YVCBEAwf+rP%Xe==2v0&OR4UZGiS!j2 zvYk{HK$n4+9`YyEH9=tVw?V zZ`PZFKNEW&an#z(eS8*!4xV*Htqo`kIAY6tqtg6GuEbFUPtJyfmVks_3zc?Oy6Gt8lvo zMsuVcH(cD~cfi0y0+r%vchH_(P#|OGp=YZVJPAww4>RK@x#qude0_Uc@FEW>Or2`t zR8u@!fR;cVP~QUy1Jrm5HGvbri9i)l-A7cMLY*EbQ2C2rrMv(_KN@Z%I zE)~;NXAXQ!!vm{K{_FO1&KYygVm^@xN literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv269.mid b/data/raw/bach/bwv269.mid new file mode 100644 index 0000000000000000000000000000000000000000..ee0c15e0e0beb909198c0c2f21a7dee3e2b863cd GIT binary patch literal 2911 zcmdUv&1zav6opUJ{yajTAtG1g5(!u2dgWpeGK$dFS)heNODv`j;GhEs9c0+Y>7#Ve zXXw=K&vUvsdW_AakW6&3|M%MKp3B*Xch0%z?!>iP?sB&L=v?Eq+caNXEj}-=Zx-%{ zb3a|l-{x)O#D3qjnvGX4*Y0jSU%S=V0q#7QVwsv{GXLgQ69e`9t6SCE7zLY)EV(9R z`CzLxR)(mkPRh@BAETqF z`ynzz!5Vr!ng8cHYq!b%%IlZOt2O%c<(RgH3^cS=1xhSsY#BlaF$J!|K#AIXi~(G- zRJba$NF^2NJC?LpMP(mj!KhXibyt?aqaAgO+WZ!QjYItGD_{(DJ6S1*T3H|>Jfurx z0_i+b?Fi;a+Y1`=+*D0#w(w%rVE3L$V`x(Wxl}ooMD)t2mw}^_h_v3c_p3mcVN zM0Z!ghXjX}HFGpZsH0I!p3j}PRwNX-3Kx9`jo-Za)%ES|k;R8T{+{8 z{Rf9RByb(kBBGSuF>NeRr|XDk&C{haS+YFjObS-7oL+uH1KeHn91=+wOd{zs U#?DilL(5*lpgJ`T+Ssc94+uvL*#H0l literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv270.mid b/data/raw/bach/bwv270.mid new file mode 100644 index 0000000000000000000000000000000000000000..9545d002fbbc163b1d954a898a0029afcc3ea30f GIT binary patch literal 2641 zcmd6oOKuZU5JfAF`7D7oAVpRz%is7zJ5kG4GQxx4StO8T~PXb?0jK{;iokwIi!m?P|9CU{-l)o8xD%7oV0lw+s7e z_S;7Kvw2gg9NFf&TCKczzOr>TU)g?I9~};2nNE<|$~LtJ$9#3iR9}7ke8?^XH5z!MfhY=$ z1hzcUQ>5oleSvl=4Gwm<;t1I@3^!?SCRUQ+endtIicUPp?BVAn^vbh=80jpel-x zI`Wr0^2zMo?P7W03)Yi(vRh&$C%fZ2kH{4G4nP&4t6jTA!`Qj25sCnkp-kURZc6E9 z+J_NLXZyqpkvut60sa9)A1Vzy+P&kTrIlMn#6gJolOoXIn2+inJ`%5NJ543)CI7^#4HTAqP;CKsA3l6*w)b9H^?Hi29HWsL8&n zLb6B0$5)mW5CP7KP`+0XYIi|$kPg5T4bi71p@O`-oqG~Wd=g7}j;x7v_@=2oB8E%w k7BtxFM8`excd&hir$JAea`m)O|19cpD$1-48Pc=QS z=?nB75CK4XCvdJ|4F_6dAnmHB!{=YpfP5rQdp3NfT-B}sF)O+o=cW< zPZ0rd__1bXnRIWy%5sAhA z`{w?8ws?QDTLN14uo zXb%k}N9n3!*C#0E;K2_xk94JBK~K*$4>mEFX8C=_I8I6TT-FrjkrNa5w&g$v>i~hugJbf4g?P3)S)7W z9%+hM)4`FzQC8zXBif3nAtM@k)$mADit81#{u4ep05u?w$v6fzE&Up`GV1`UUgfeJ zOP^zZ6$#}L-GW!7@aTy&Jn_F77la^iebnW?8S5(NrW1R(FX%y KiCntOqkjP$Y^e?a literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv272.mid b/data/raw/bach/bwv272.mid new file mode 100644 index 0000000000000000000000000000000000000000..6dc8f65a39788fffa42d3c24b435479060a456c9 GIT binary patch literal 2479 zcmd6ny>1#o6otox{5(S1NG^d^q)3TOg!2H%azT-TGDRLH zkCHbb_nRR{yCNd)>}rqh-<&z;&R$JFeQ?gbaC@#;bXU{)XXgrU-1^zex3jPF>zkST z<=k&K;In>TSns*@yJE5M`qk2{;`H7vV&_%^z`#I~F5M#W5d*o%h}6hZ<8 zn2?$nxBy&aQ)433oB_^!>PLt??&%^X&bq}VYFrxC2_Sc`N%}oR&PkpB^QIC?VhRip zA*gC1p!1kH=raN!uZlHCR250E;6FBL&VXVLjZ-@`c1yRe{#}%zElM%@^6f!e(uZQ- z53*~pH(l=2H4p(JpRyWKJ&JoC*zo~aO%90SkoKV!OP~xe(t-VE^5fFbQyFqWIA=E7 zZjpN!GE5+$3+J}|R_c_RQ>%%Q1u+GBL~Ob+H+ zF^6V!HU~pwQxkD$l-r~`+ob2yk2kaVjvr3M%~+E*plv{l)8>34EkMfys{u4AZu*E3 z38_tux;k`qtVRl*&~@S?22eHEkD4RMUa$u1%?8^q8 z8lQ-JA+&tbi#>+?v85E*CNIULVdf26JIYJ33IkEK3aA>W0T6s2uNkwWH&-HZAPI3C8I2dWB8hid?;W1c?-$eATs}lTrHP;QW%4^A z>kG$8o*b>@tutB4V@E8|L#3ycERQostYvmpUx zghBWgrIO4(B*y@f33`*)O$bk$5ELM&7A&`H(1R}|)&~g0!iJnqh16_Tu#)xJW_e$_ zJg0T{5VyHHbkucf9a90C08LMs0!Zwj;)^zw1}Y8jmbo6oX@MND8aB@dL_aavk;6W` zP8nSc#j|5l%(pxFdl~HfKk(ukY@o9r%iAVQ%?DvxId3NxB~>|rkB1yOZNp&ux3jhQ z;dOQn z&muWIlw`W+n+m@~Cf$H|Y$LowYlMEG0bi661-8i*eBgc>8Vk~Jkf%uUEY|zx=+cdW-7j zqffrP`0?`PtBdOIs`|HD`k$MxZ_D)Nt6uN+=bv6x*Qe{N>gUs{x<0XRBH?uXYiOQX zcqYx6pUxyaxA45SxegoLS2kYh>BK@K4w{wSZL_q^Qo_Q*qSojsG>W{agbZttAuJro zZbuf5B(#k|Mm=pD1njU`Iz=EWNtbIuY-qr<@RNZp)_;YNV90$t(NE37Q+aJ8x_G5H zzrBg`OA!6xs4oS!$%H5>eK+O-uL7fX2_BBsT2;ijlqx8Y>>rAG0zxmj&dj_gn-=gy z$+*AQkl;leg!kmIO`TW`>LkRb6`o1@zo@&aZuZL+x$~K>NN@GSPhBTuwfX|4 z2h=oL0>7~jMT7g&NgKlkLIm*OMakHtu~CY~9AZNp_JS77JazU0JYFPaBp8xJxLRp? zS+tq!ihz3BSXkwX^%R-5dFxmF;x@gN(Ghb;bY>XGV!$};@ECuxh4PK zW7HYjXU4EePl6F-%EpyW{k>)(v0D0`+>3FFtT@p)3E^HM!x*fh>8zpzOva@O znv!~2@X#g-Bq?6l5Sdm|Ad%B#whJtHAb}5z=-B;3w@M6JD~X zDumDj$+aX7xl&Kx8fRNMGT!)UE{u{V zG<|Da1u*ukX+Y%(Hv5ijFD8hFPt1ndOd17@YbPOQN`hyTRpWaa96^%p;e_0*rqpCA@`tHf-&zq zpqH7t(t4K`Fl-5rav2ZP0v`JQ$n*S2Hn^wS%S5G{Qedz<5u>a0AhP##Q*>R literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv277.mid b/data/raw/bach/bwv277.mid new file mode 100644 index 0000000000000000000000000000000000000000..196137ffda4bde2e18e44b88fc7a57b6d0029e95 GIT binary patch literal 3041 zcmdUw%WjfU6orp1ULL{3c@s(~my~NM0fEvs?MMd7tcfNjnqsIAV2lF>4tRtP$wgth3L)ti8_9<>>v}5Way0!A!p?12>^^-p`82({o`fGE z{0bd@7H@VGws@V%>^y%q3-iHv7QPHZnD+sFfx-A&!VCdJF{d1z3Y-JZV`d0LjPn?D zIqK@D2k6ByJu<^|0mO6w9f3BWy<~JNVFX~D`G0R!vPNU1gRRT)H!+^sz&kiY)-&m1 z<^t_5mW;q3_TwI0!|U+*j}keE}Mv9$MW(4;6^H4}k!s}v^*Ykm#W;`OtQ+$V9Am~M>>D$Y zrPC?=yks(TrBH)u$e5uSp`2Ny^fO23Gh*>5{%300N%c+vOluyQ)_=&LLe!jBmB3=Kg?e8M1BKGPAhN# literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv278.mid b/data/raw/bach/bwv278.mid new file mode 100644 index 0000000000000000000000000000000000000000..389dcb34214dfa237ec86989eacf5ad89f2b4a02 GIT binary patch literal 3212 zcmds&y>1gx5QVQ3^YaM2Llil2R{n{9u@fhboHV!qcacCs0wu^n)Cf_ypm52%(C{cU zJcl`7c5`&siwtd2`DpIUotbmaU7t_iz78Qg4y8~ohx6(DT?ku0!fN};i|Y^b%d6|~ zGlXBE&(G@BR;d(LFU#evXHOSlc`{ps&nF=)M}U#Q$?R(y83V?OoN;s}Fab>B$e0K@ zzQ^UqlppJ8NX}5;7(ir0&VZ_ca{7S2z<{bWB0$8w?#;|1I@%}Ou*l2*J2L?o&b zuW622kW;6;F5uz4PKTq1vY_5b9WSwJ6Obb)Vb$dJNFe3K$!0U-*NoSws;SDa#v~5V z0KJER^e*s>o*~KH>JCB%fgx+4h0#lS901gD)%QCy%RgM%bY@4@DtBG$mF z9B`DfnK2$!iRiQ{quw4jo94I1JHVs~Ag7#@8}w=@$0oG{ESOvP<_%V`U{ySU+jeNN nBd`nD74XU?p$b1aYkFmm;fLkn{T+6W2lLIvrU~yUN#D~S_90&b literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv279.mid b/data/raw/bach/bwv279.mid new file mode 100644 index 0000000000000000000000000000000000000000..96efbf3798cb49483f6812284489dff5c80c7b84 GIT binary patch literal 2672 zcmdT_-A)=|6g<#v?IZXI#sop#AOu0W1Q7pj@kXzloSpBSIddj>KD_y6W}mEJL15>@$#=8j$mSn5F2_G7qua6lH+!-+ z|IEJ@3k92B1wnE1^VDYjcxv~3vssUz2hfjyCzS!g0F@JdIsrH%IP;YOE99t;K!=|? z_|zrndQO*}S?Lgv6U8&Tj{w>vw>|l734>*lnB6evlY9}7o2T6Q6g#VO!O8_HvVNV> z>79;g;;|=dgr4gL(j0L_;yA2day*y(hvccv%P&EDK+u9OKYrz2xJ}CbEQK@3phQHN`Ey%;&aGNF4)8?-ATJEj19LO{?FnGs{{!ry>7_s zhKuV0FbcY5jk&EY<@PUsL8H;#T~2I6>R`tzTXUFZ?6I(okH|s6x^%FfrAVjbm$ZK96pL~ z68D$?@8VBSJyH?Iy9zJ=o{FZMtPu{N zT69%I;|jL6t6pEsYrmLm^x;$4xeQtJ&|8;)0XYND5ttx;;*l|6>|jC;kzyZ_7MPMe z-6#7F{xV$+HC^D2G_Jzpi_=AHh8&J#3V>nhQ%vrX+)d?Zgv#ZQfSv?O5={LBYU)bd$Hb>{FM5T?fY1P9+93$x&X`* zXv4AXkrtrkKoL2ua)IQ@tLUs*iB(eXfQ#<)6F4BIs-*M%Vpv?=2&2L+M1jekqtXsa zJ1$v!7Er@JeQ;v{z#rvkJ4!BsHmhWDx9#GOoz+Jp5&GY;h;`ceIIc^ zqzh@P?i-CNRI5&`2Bl#sHLg?2}xiHQab_yEMX=)y&}zKxIK zo78i9KYqF8wx4xHSoLIP?#!7pGyTraKYa)xJPS`kr4r80uRn*d_%e(ZpTE8OdVO(u z6@G{CC$#-DdcUBs(Ys1z;nj;l7`FO9!fh*rVcVcB(CH7tZAakH;85V$;5fCM*m5FE z*RQ(c7y-wW2J2M}zMqhyZD%%(mVt>q28IPy6a&x>vH*_U;8Cg=u2Z{Cx*>ZQ&Ibio*HW3FEj0ya3atBiBFIW@es4mx!4Kyle=?-03|B zJ+~9pD1@5X*C32G?oQ&hPNLHJ@~!M18cy91A$Y(nR{__5fsUJxJqt|idc&@X>P=gk z;sY_jBVu^qE)LYizQMi#mgKypyw#XT%zSI-S>L4k_sFN!7w{e*cMY4?BLZJkQE_abw8D!+6pPtQMIUR{@bJ8B+g zO$q7-bpiG_QM%9-fl-kd#M`xIyUIiGzAfGtVtAEnwq+Vy3f?x@7MR9R34LKTXEyn1 zF?#M8YQZM~ikaAG7(Q$l^uFZ=tw!Cz(*e*04JLzAa6C`}H%Ksmp_Gg=&x|bF=HuyL zp*o8+&rp&D&@AG|NSS?4%mP5dL?6AfKDhQwY%hJj*B?d;uWJ6oh&wM}Raqnir+4(> z_;ME(r~=TZP%J&ruD@k(E^cm0?h`_QO?SANlE$*>o3SgoqGC>KezhhSlY=5Fg$f(a zv!URsL3Nx^&n+~0;FAORkPyoQF)X%(>NL3K1})2~^;s2wY951h%MM;n)yTJh$1yvK zL0&SmtZXD2QUaZ^Ft22|A|L-ERm%&VBrIC4n#QaN-j`+FYOIg@5}1%>#d%ibDv5#f cl7p8NoQR-=)4wkKUnKg>YzH-pTH|y23)>cjwEzGB literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv281.mid b/data/raw/bach/bwv281.mid new file mode 100644 index 0000000000000000000000000000000000000000..6fbd7d5ca454bd1de6fd516f6fa178b83fe33566 GIT binary patch literal 1286 zcmaKr&1xE96o!v>()I$n$Sn-PAB-ZSgE$p~NL>voA_|v^Y^`HGMWDRVP+q#WKm?3>Egz$^u@LxK7E_tEv{#C`(yTEeSWrA z<*ojHkD~JF=e2FJd~K`DY%>Igf&nlHBNs$26dC0kTa7|#j5OX!0whm9)KKL^)6@}V zWPAN3kxNA;z(nAYF;fdOy!DY`{){aD%?sDIt?j+($(ty ze*S2y{w^Xw8W6$7Kzdu1<Do#=HmL-r>;rw=4E> zfrq8Im=;{D$i1gx5QWEy`FRB1A&TrcmN%=lH)~s#Eo+k$xPa{{pXMWC^nY$N@S1&~5p){n~l#9jcwMZkB&Ecb`%eSlR zo2C2``6~&3o971&{e9LvJb3bWEyXxnOFkAUrdc8RRKWyhQe|c^GiB!47s=<_kk+T! z56ROqrhwQi`{uHz*+jIm@H}CdsFQz`;*4I1ksD8Rv{oquSOhHoh z5#ubDJ1K_QZ^?%mOPFjY$-6GEr`vObC}5BTM=skK1u*CIK37oRLw)%bM$6s1P~g_+ z=a^vMF$$awmB2An?GSJ7f+lMzF!ccBgn4gHwk6o$sdxwyQF&A zG4;p)sn^?eiJ{g3;HZs0Y6e<}V8oW@_rR((*}W76?hPn#Z%_f3vggr5VrN7v?;wGC Z-OmXUCmK2hoR&EX@N5pP-0!12&_8~nq$~gc literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv283.mid b/data/raw/bach/bwv283.mid new file mode 100644 index 0000000000000000000000000000000000000000..fda555505b112ef48db5f560bb1f18e5f30cec58 GIT binary patch literal 3001 zcmd6o%}!HM6orqaDpO~^00aVsLR#9=pR^QGLSQ5V?Tkbd6Ac*f0gPe5z!)CMNAU@K zg}T0bk1OZ)*2bZuuI#_H_uBj1UR=I^8$x&%o`h;OTwLCM2%&NxW-HHM-F&*ey1ofN zLiibm{LJ1|6gGQZtyW&HK7_~f=|lK(9+rYLV$KwE3OE&*OdrFSiNFb#6Ml0+2N(W^tW_ zR56g+vM5V2IlJ0`-7(He22^lC7VqN!7s}&!!1)zCgxPMq#g$dvVs-TK^Rh!cW*PYb z2_Uo=pSb3C;8XBYhwPFa_!N3n?#VI$u$AHTTOMNffuYkr!Fp|KYIv;;a#(aC@;fG)1CKp#-Z@;K$nJ?b#~h<@@mzW%vU zfr1*zn=wVaW3yXcb2-bd^1HHh7Rq-sMg)ZN2ECLdMpF>ub-RwaobG-Ml23r02Mc0=+WD!=p|o?gDYzPVlUW$v;%7M@HN z+h5d?TwJ{u?sU)Un`%?JtzcUm>~yc!>}93B@Z_nfa{kl=P`bz66&{~S6Cj1yMw4wc z1@-~^0u5SiWG(?*#WH!9O$rv;aGgb)*A#5f zV!C-}m9H!j+)p+xcK~~?>R)wEJ`ZsPWu0wtKMe$*(^=_^>{ffz@A)bZQG-Wg!Mj+P zv;#n~Hm$bPt6zD+zrfMe-QAL-cOM5dbdVJi;8^WSSmlD%@4>Eex?MFY*Rq0Yu`shK ze1CQBudd)-vUUY(SV-T-vYlCC!8#U#8w{UUmW6XkDl2{QW$#gWPr>^DVrtZZYX{3t zW{F%|aBa!5iEC3}1IvcMI+k^TH7skXYZD8>u5617TAv+)A+7Tsm}?KqT!-SK!*yDP z)GzjcHrSw#%+K2~*4Z)UvfzoTVn@{$T!nv0rP=N5QW=>{2U=C@CJz>{zhN~3ET_qT6z6y=k|;B&fPDZ+fM;g12e$Pz$M_)z+%1kHN|2@<`mDfb}OcR zN*9DhW)+`m59-Bs6$_L&RLv4&OS2)Mlx)nf>OEU=ZV6G%u`#7YD2c1}4|ji+i5fs% zJ6xi5+K<{rD2d_@k7wVx!<+E-m6g4HHU09f?BT^YUH|kmPcS`+A55u~C8m}dQ!~zh zbpcLwg(Xhtf^f*p!wgtEU_@$^MGO#`!|V^pfPV}FJVsGM5i!eH3J+GJ0fV0?5>8XM zKBFrq8u0`hx)NEP(uKp60sVeV%kRfhNBb%6IoKG&BVB9S3#Of~=v3`7wdnn<7N`v!W{ z^b90`#K3@5uBONnol@9h)MfTz?n4MryF?Qt(296|J$e5Aq#k$%d@Fv6pcO68iv6Ua zD_Wb4>ttAR(wO}d&EsbRWiKx1@Cb>m2}>ztbNxV?cx zY%~Edw*lU2FfWN3?T9u|r%MCsdr(9?rOYP5fIUR{hSe@YIqV?H>Pj~j2ficOmo-XCSu?b!lV~%6xc>?9cWe Ds*a^j literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv285.mid b/data/raw/bach/bwv285.mid new file mode 100644 index 0000000000000000000000000000000000000000..7e81c2ae26a63fb37b57cd9cf55e133855f58901 GIT binary patch literal 2317 zcmb7^O>P=N5QQ5;evXhESQZu_MhF6!pMVWAVih7K>?|cwq(mmdIe-;q!NLnKa-bX~ zd!NA~_0gTDW`>O9)jYj=RrRW>HS@*i56-z~uHZ@~H(#v3I9IrL+b7T8tiG);uU782 zbAQ}`&-Q)sq2RXfN~Pk<7aMmsT5jCU$Q=UbgwErTmyP546 z129tYHRn4vL!KtBe`5|H_5 z8fO`NMne0lMGU*O%AVId7}R zQEQf81yl`)sl(KbN$8On5F<^L^~={u*aBkhPK!<`NT>xkyy!?A>eMNS4K>_3MRZr{4_W`Pay&LNkdbO)1V-lsHti8-b95K71PM7K$#GJjseF8jwpC! u-~{HxK%}vd*H{RRLKU)Tp=H*X!e7wD|GS`t{G?wuh0W}No9aCP-O@VlVG7l`Z`LtItG?*Sq6#pz1?>`Ryp2cC7ayu z{@=R4(|mkBw7kzgzV2gJ=mqc5^rp0fS6Q~z)5g37aj1!>sU9on2YLl6CzQCCDJ=@N z)YAbv3SGMM7##}kQ`C%S*Bn<)Tp@L#S2!NuO=t51-$0H2H7#kQ?Lvdm8tSP9FOk^; zyikeLJv=B?psG+|kBUMGD20leQ7SYAssLsK4<)LsSq#=7o$mh)rshAPCh5^@yhV@D zU{pMHLUl=A=#uZGHCZeU94Jd#HXLz#u_}`>eHOrz!<>Ia|hEL{Kq literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv287.mid b/data/raw/bach/bwv287.mid new file mode 100644 index 0000000000000000000000000000000000000000..9308eee5a02b908e70b432325113acfa9a23468a GIT binary patch literal 2605 zcmd6oOKuZk5QG~uJdTh{#8`gBvNdu%w)~K#tndP67YQUJP>dW7U_~svVBsal;V7Jf zt?6(6N$F1}G1&mwK&k$IR9E*nXUh-o%6u_Upx<@%#p?a1~|U%Xy@UY}pA?1$M; z8}i@&ZEf%WzDbhW(aWvv=K0n(bFVK`&~a$gjCt7H7;t0FkyHK@oKj55+!a%vONK9078t?|W2X9) za!F~SM|Hf{V^o;p7*Yp-fddVgGHG~nz>}CX|91U!J4@-ZMQhR}i5X)Q`%;!#C|%$b zJ*S0K?;fOjcXl!2X;eIwQdLmt0(vUf6rbIdpWUj8QW`pg;_HxH&-@c-)RqOcna>%eph@jh1&?*Q=%?s0&DaX`AVsskQ4 z+X1&3uEQM*U#bH>z9HuZ6E$^VH0_}f5ZNoH)EqVSCt3{10vz13r}G*8d6n@c{^AF4 zbbfhx;1JuiZ+qzu-r;Wx&~nfOG#xYm4F`3C>jmQgrU^q#RL2?W$of9%w-)A1SdRmO zwVnnAsocS6o}$WS@Z(eH!tk)_nD+e;6QW5=50A0#*elloH=K`*Ds5>KbGHobLRZ_s zUVN_BX|aNE0Dko0033t^C}mW?v=h3Yc)>1!PrW5QHDbBpiV=B=T=;j~)MH#y@frDJ#4HODrORganF_!vP}1!V4BG*m4(+ z!cCn1#?PfU88k{3tX%4@?yBzBlpp z=l;5wpY7X{(Y9~O<P zbCb9LTo||nT&ALCl_}rYu(8v?C*oMH9%GF29e2hbpr6n-M z&(v+)wzj{9cXkcsZtub>40>aRlHVho@2nVfeI5=3}|H{*WuJHRfR)U4Nx;sU)sMVDLqC5 za>F7OK&GMYPbZ~E?a+`X)Q6#lvZ4FSTdh-$jeup9LRU-#;*+)o2O`%j! sWfI($tm-ZFI=Z$Kv`$j8b;g*iYP~f!##SY&*Eyp6$WpT5w~-#uJ=>Uo4*&oF literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv289.mid b/data/raw/bach/bwv289.mid new file mode 100644 index 0000000000000000000000000000000000000000..b4114c6131ea46dbfdb8d8ac2e67fc6e84f31ce4 GIT binary patch literal 2164 zcmchY%WhIp6owawmx=SfK?#&nD1~zE0ZJQs8OcDIHPOUGQw;S1I&i?ifde1NM{(#| z;QBbnKZk5{f)hu4S?gc-4cyM&zcsUGma{^^ZfDC6X8Ao^KY9LY@o9N?zpx)>KP}>8 z{U)Ew+4^;%kl%Z;vTv93l|5cs3MTU}_Be6N7#KT@(2RD}j1d#{A2Ls=HT7E8z_r5- zaI>lI%`?}ODbQTuy4qNhD0Qej85)T*_M_P+)MAH%e+pL~ZGM*yB~~rL1^ryu%GTB7 zedK=m`zQ=Qe$ILv%BY4S5=B1P02nyPC9y!_bHwK^j^^M0g!@$pSDqf4o?Chx4Cn&g z4Y&(XEkRgIMdjKJzQ#{{K+$+Ehxqk7@cNZmnpCSvhbfI)wg&7oVBhnc0cYui(cG)Y zTTQBmJ%=NQnjx8oo;h))?wx<>_kKEicfVL>{2GL<+SS<&9Pf_Z{?{YCj1D^kwcjI0M~)LDnP|yAJ}&&0!0U9mPQ9V zMRV$!)WN)Hd>)6b_g6*C6o_n9jVKPMdnu3htPV@`T#Eliegjx(L2Up4 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv290.mid b/data/raw/bach/bwv290.mid new file mode 100644 index 0000000000000000000000000000000000000000..049ec87dc9f4331aa8bb3a1d6b09705f48cc8bc8 GIT binary patch literal 1525 zcmaJ=%}&B#5L~eSJc6&l0Te<*N}8tF@DoB$a?svLFfq}90goPtF@%E$9?3`XP3lg+ z&&ek>Ty*m7?9A?LNvDr<5jm5Jc%G!w)sskNF8Rs%?eb+cTP)>EgB~w_PuN;o1VzN571XI0vNe~C6W_x61R(`a{CzMv63eM69sAZA)B;#QGge6%I$P# zsZ1U~d7wHZb3%6YVTuI@03fsEv|COB4i@BI6tpip$*+F1e$%YI-t+6RphJupx{8#J zQHr$`XP*W{u#fbGU1h*_PR0#~Xdh}jHylA3M`ej!2})+wck?O4nF7p1i!xw9A-u2` z0m(5+(4iMgWxx<3xMTP77!S&1^0+xJm z{C_#r;bvTj-z2Y^V8w&TRT)uH#{qgD1l)ytw{X{7u>}VUvaNaPLKz&VUAxSE4nYJ# z^Oe~fc5$%-3l&5xK9sS02rn~_^|C>^*O=iKaWh-5j~s((64YT|SC0ljL%}shyjIWz zXewv{v=p=f+6vh20F4Z@wxI(Ky8^tJ>=c;AR0m|HNz<|gC#*rIrdHq)$ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv291.mid b/data/raw/bach/bwv291.mid new file mode 100644 index 0000000000000000000000000000000000000000..690480848a69a3b7c9312eaadaffc777fc6f7390 GIT binary patch literal 1853 zcma)5O-dtS6nu&8&k^PTA_mEi!5G?fLfVj!jVrTodMC`lz=)CP0fM-Q;KHT%@B(v# zxq>%otNLq;FSazUx~TV8uin>Zvp>JgY|APZ1a>xC{57jQTDq})KEGL9UeE2H*_#dd zNq<(;ilrApQ2nv9vgbHi*)lc{49N^L=GleDWX52o1XF+s!302|5t$K~B8V7@5E>*8 zwj2Nq3ET*TN~dQMkBwOy zqAw8^1Ij54^8_KZcGj3>WMrO>DfJ3Ts~8VJB41ANE%mA1d5`JtEMN$34GICKsn@P1o0$uLP&K>U2 z0XQOaF+s$-t@*gtDE;2(KwJG<8KnE(I) literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv292.mid b/data/raw/bach/bwv292.mid new file mode 100644 index 0000000000000000000000000000000000000000..14bed88c9ab4e101ab4e8a4b5e14844b0987e869 GIT binary patch literal 2443 zcmd6n&1%z85XEm}{CET(po^9e5<=3D4?;c&Ewx>lg=SY!5R^t*AE1ax7B0GQ*#~hY zK8kM=&oB3SxXC~5#*M2SX6DX0b7uZIpS^n%LU8YR6s>hc0P!BM#T29(05rELrpB+DjMG#kTd(wNP`F`H;Xi)6cB}}z zWgkF${`EfbE%qKw(4_HNl80SJ-nfkppBiS`7K3~J$?x|C|FPqX>+1*3w+=^L95t-3 z2~?3-6{rxY2pj?q1rA6ZtRn(M_Swq5K-Nd8*hjB6`c#>aNDV+uozAdV0i+sGZ~+xM z!+t;t(k3Y`z%JB@MDZpSh!iPOrw=tPCdK+)eUgj@!eDO#;M#SXDrR%`#}t_fs$sy4 uOM2*R&BaOWh6nU>%V^?8G{FtGH)uV+wj!ww_Y{Yi$xbT(oKMSLpVS}Gdx}s1 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv293.mid b/data/raw/bach/bwv293.mid new file mode 100644 index 0000000000000000000000000000000000000000..b85b8028f7f91fcbaea036fa2fc525e24fc9fff0 GIT binary patch literal 1516 zcmcIj%TB^j6g*&ke1iW#h|m<8@@QHK0T(1Dve52GG%?YD0hca_alyg`zu{l_DgH@0 z)7Hr~l_n~#n9QBtnKS1y8sA=v$bpo^vSc)#--(pYB;Gr`m_5uV)0w=Bd`N(w_^PbZ z_|me<$44t!_oJ08`y%TeKu>`W;426LLi31X0)CZe{&>#-?gMon0t^-8E$Ggu0mQ+# z;eV57CGp8;p>JBK72ZD@dPz&{AW%mGwWDWQwiR>%x(W=9ic^h>q2U+>8b5m7 zk%gLK-we+-Ls;MiouaKm1&$$LAfqjxP&mAMBNRJiHgg;0vO-jeF8MvkO~bS}JDv zJmAd))VR@>NzGoL@JBeEEEWZ|vLFXdIU0y&#*t>lk&V!3vj%Z3VX}TJU@9iFs|y=2 m#o`@+G)8917}PYO!R9zc4Gf~z0qSPLDl%71W;dCW9c%z^%93*c literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv294.mid b/data/raw/bach/bwv294.mid new file mode 100644 index 0000000000000000000000000000000000000000..f36cedc1b5684b7fe8d2d3083f42339cbc362972 GIT binary patch literal 3496 zcmdUx-D(q26opUI`11%pK?n&UX^06S>5yay{h_@w7dm$Z1wm;f^;Re%k_#{TNM89I zzDe9`&gA1vCmlr;>y0k<+54Qe_gZ_>^Tq3z&bfzf&sD4Le6f1t+f zF5Oq>zPpM3+q|gk*}u=L)yk8{Yj+bTYj+*HU0|-Gxg8w|92q!HKDq1TG-5yza^mF1 z-$Mj2QTfD@X96<=JW39c5P;F>u$XB+CirY(wzn22_qUi#bH*5>ClPa2qmVDF8B! z z5)EBAR;S*FmOOId@_e)9d9ZkOxm=a}h%hq%uK^hFRIlY0oJsH63>&c2fc0&%63SRh zgpu~iOJ_ilfm&4eeLdPwbJ7--d>cR&aBn#?v0xh3V9vHE&*%WSmCqHO7B3`14tu~6 z5r~n@qfzpCYd1c7nYd6z%C7Y4rV5%&UO}spf<39+OEtA4AF*T~$#MqD@m2OjPItrw zK=t>WiM9B6(?t>Bx}F*o=b@;2ufjR&i?INDGOe#Npemjqr>`8foJGQI{-B@2*~QgW z$uiRhjlmUFI%40kH`)Si11-JUGSC!g8t4cprz;>WoBEqWM?_jGR~7dZtLT|3p7^h* z+7P@W4S0F1_uRLMP6G+=%wZbEWR{S%WKftssLF_OAu^Sy+?J-&{XpO#uc<|(X-#t1 z4E%Bb)MOjoTo-Pgs0!24JAHNZ%dy+xC0oE-T$p(^UBVxj CfusKb literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv295.mid b/data/raw/bach/bwv295.mid new file mode 100644 index 0000000000000000000000000000000000000000..b9f02e82d39707a51e6931242953ba6996d67599 GIT binary patch literal 1831 zcmaKrOKKZo5QKlp%HslooWNkqvL5Kc=rJB?kRc1NqD3-0Ljr*WE66#32_a~ag_pTY zHaUuKqVzZasQ5>oc%`EM>aObQ(bekH2j|>#S96VqyIO5NJ6C(-c1JJXuD@=sZ`SUw za}O@zXZOCotGV5~#!>zC%dNYQv#q;}T@_en_wH_KPfIv}ODdN+unJ(A{q|3DICHC{ zfHZ$nmvKC~sHE91&zWaGeAk@G2knKr2BvUIlhq~l1V4$XYp(=9RK!W)Fh`XHKfcTS z_%w_YyRF-`_ksSgKpXQf-=0b{LM*b;0*`&DqI^?Qz|aD)FrZa~4b36}C2;V10k|*_ z14<_pNBLGIZdU!kBA_YxPIC!GR$N5`r8Prz7OE@gggK=&1F}snS)D=lbBd>`=nl_Q zb+Dp+#t9f0aptIW!UsFyv(?9&^@hK~fBq2zHXGQ05nz;0GQd@Xia9D()YYe}Z{!|E zdIn-vEG->ljYE-o+Jk_N!$4hZLKmDqfDj^fFL6W`2(%6dR&i`E297e@ix7r{ISlVyf5l&QaeaIH z#F=~S!+CVD$0t-p1#&5QVQD^79CJ0ymb0jldXzSNs@(kX(f#p|g}okrJ5*=K-uJg^LtaQ649c zk|J&Dl;nJSm&1j1sP^d0%$YMYcdw`K--ZyLg@aJ3gzM?zLkI`o!|KWNSMyJco7;K# z8N#p7<+FNosMOW#O6Bn7i-)ir%pSu1AcW-*FccU8Mgrs6GTe`IMgYb+23I6srJ)g3 zFOp6f8*14d?Mb1dD z#jt)y-k+E4kYCm%ikGTSa>Q(J-Ot$dW-`vd^Hyb~jgj&~%yc*nFS`J#?L=F%#XqC4 zl$cZ~zIqAeZ_H&)Mq;(zRvRY%K827&uJT6O{PXzVoc}lfeE;U|ZqN07>vJx0uJ#Q; zJg5M7bg0SrSUe-=OrQo+6F7xA%^3lhIt=9}%Wm3G6g&|3@d^C`M1-IOkp~X3Yz%=!$*L?`?;^EQrB^MoU4 z(3=iIMyl;q%_3B>m=iK{;W4*Lg%Klsi->k2Tif<^@tpM|JZF%6{(9&w2edlK`@u+} zn2e;>I;2Bj%&swNWOd9g7m-y&=y{xdbEy%*D328F+OL>JD9=;Qa(7c^R*j?z=pq&I zb_W@5cL2^Zm>C&z)(}ANEpWxu6;j$*!Z&b_QQnw*Y3Ko|o>j=Vo?V}fG1aB@6A2L=zJY81MkbxM1OeBX|@~;2FFL zzTqpA4{9n4SDn1ho0<1sI~w2LipYuN#BpRaoma;xNy_!AEC)1gHihN6e$NDC( z)b+LFERvWnuRyhL&+cr)Z~te~r1eYE!#3;+f;7@{)N3IREm=|2m0VTxe12vG^` z3OQEzl?mU&TsiXq0_;lItrN3hXr;>K}#nIMhhQ0{?47g^iId)yXkD6@z=Cr+g1|~z_Z?&7;ogKh0Hcyj_ZDKbY_e5Jrl1aE zuswYQ51TfN(sta3bHc)A7D*D}^LP0L-5}ZqY#q}~q+QJ2SXY($; INZ0)PKQoW-lmGw# literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv299.mid b/data/raw/bach/bwv299.mid new file mode 100644 index 0000000000000000000000000000000000000000..489d43b49d03b89c6d607196aa944eeae0fd1873 GIT binary patch literal 3064 zcmd^=O>P=N5QRHHevT0325cq>gfJKlOfX{v8nFnAgq@{Cij>GiI0s;n1&b^=QntB; zH@QYgebcR{1{BNdu(6-2tE*nUdOZ}2Pam9f&)gGNtGQya{_I?};`Y_&Z&zQ}H@7SI z)46*$BNKS;DImvSav*pfh zW(Eo(g#p!>5#eY;4s~=i;fRQGrbK+xaP$}&WB82A%7IwE{NWjjyt<#yq+`VNvKU}r z5?nfu$Qjwu91Z;{4fuT-U^~|wU6My&@Wx0}btK#4WmK0PI&# z(EBGO&xt^+AcrIM5)Exx&df1e?zV3KI=qC+FMA2K?8~=@omkx7(zi$oBlOT@8RFq7RhGGQOO+LgS_G6=kuLiLP^6eVjjt2`|{qa+VUb8NbAtcw1WPnn0o#$h@`fU!5!Epo W)KM=jSGQ!6I`(7B3B3~kbMO}&nmsE3 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv3.6.mid b/data/raw/bach/bwv3.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..2ee1866055ae5a3af73b767d2b14142f1040dadd GIT binary patch literal 1705 zcmaJ>OHKko6nwz=If9oU1Ox&hz&PO(NLa~2*^y{sq5%WOH47K4jCb(@EXytXiSM{oUn9U#V%?6i)|ec&hny3}WPp@b zGFfv%c9E?12`dv+1cn?)KXRy}DaliptU10hb@?2T(|hghQ29&$9q9*GPcM1Vcj>hY zLp_2XfHrK?Ydbyy;8B+qk~;()m)vKikBWfiC_CL{pIRh~{R!-*ktMw-5i)b?;X5S%T(lR1h zg{O;BSBqUObTt`66F?Pll&cSveO6c6kJFwUNuot{+K^QR?A#bQ{AP0&bjXnS_amUm z{@biGgnAqTz%hixj}ps@7aZrYyI1$k4=P%2x4Acme%@S}@@0SuK?R`7IH~|OR%!sg zMO7|IzKl5lT%*DY=g71ZGzKzgztW@@m)B%fvThd=d~MRIQQvq4V*TcobMBFQ;A%B@vEIIOuJYC$s*j&y6+i_AOb`N z6jS6`k+rgzW6a-t^^$ZED(270kV0ubNBp^o*NI{zY>5dtreJ|f(l5iSV?37bo&W54 zR*3-|6Hkzp#Vm*+OSTmC%n`AJ4nLxxzE?rpzlnv5gBQ*8s=Bg* zqDF|}lBzN3L_AWcbOBuzv-H_2_N8=z5}tYT^=?V*VfYWCfn2BAmoa=HV|yVF*RQWP z+ma9R5YL98uiAP^6OhIsV2~j$j_8 zg!X9Aqw2+Abs_NYx1%m(uZ-%`d*52tRfm&~o#-9Ns6NgUELX)N$Bxa^2>nbAczZJt zq-Q5%s{0SB)jIwGE3KaGp=PQQG3(E=Pbe`lFr*#ys8a>2ixCUSZpg!9z?hM$q8W4W zj4D6*p^2|4a$T% PQgK!7)G?~=(xv|eFLE@f literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv300.mid b/data/raw/bach/bwv300.mid new file mode 100644 index 0000000000000000000000000000000000000000..58e1ae0e4c0c8811294ad6f3ab2168e3442c173e GIT binary patch literal 2265 zcma)+O>P=N5QQ5;evT031eTCJ7$XoGV8|eZWy!0sNZ2__q)3TOgmVBZiXs+Su*`9C zlw2b#Qr}GT+_>?`E1s&WUcGu%!{z+b2j|=~S96VqyPU5+J6HSXwojhFS$I2=>L~W%_gNzry8Ex&hi9dk)D?5P3>o4D`wl7CU=pUK>LlIkJ>6!st zo3Mw;LwoSs&)GiNW5B(7YqocDnnOC`5%a~b9if%)5oQR=5G45mVw8>yL0O^9${@;^ zo=6Hv4X8>WCLEGHERv09M0?F4pg9DBrz#t5SS*r_LA{j~UqRrAEWYoNhE2JUbnimC zb|FvaAFr3Iia!Whl42X)^Z|VXJwPvvD0zT41A7{=n!=k3CxdL$&l#%6h#o`+02tLn zgaYv%#hjvp@$c&O)DmpuN|~x8NMOjRav2q#brIA>kmSc8KDtNwsZ*DG z0rlNJVrPpJLH5txs=x16ZBMv_-rOMZ28Q*k^Uob8wq2_P}h0<^-&F_B}7G;ySf zBRVYEUrA(hl+*^GZbQ^A7>&AVK)Y(QPo7$UJsoNxK?ytwf;wa~M_eCA5|R-lq7z0u zv504c&?2QVKKYcY)1rkvAu*`32!yKg6PmI%L}Y8#@rTkUhYwcCJtkwF2d#c^)_Afe d)Hr-V(HRq+*_%dFL`0fM2Xe&!)KPh9{{bFjV{`xj literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv301.mid b/data/raw/bach/bwv301.mid new file mode 100644 index 0000000000000000000000000000000000000000..63aaebb3bebb2944cd754e87b89371b622f93108 GIT binary patch literal 2866 zcmdUv&rTXq6vnTX{&|ExfsrVJ6A(ebK}3W|H+9j@&ZJG6w2=mV0MaxKi!NOB0s1I? zlrFmNE70?sJASzX##NKr)qFYs&v(8%ju2aCNfkATPW`i`# z09jpJ-PDrR>0#-Gt~mMXX0cg1$!9m~q~N;;>h*8O&=wkA^9Y=<*GYa;Bf)QK022OI z9W@=$6vA}^xkR17kn0RBcm&TJ_YA-V$J80876Vw6B`_q$r(2zoo4ZB%R#m@DRfX<{ z>-!|7@SS*FFH<3;-+^0}w|{dw}Z5CEc{yux&9Ng1wR~9nhwZcV!k8RJyX- zq!ZjoOo)xJsb&^<_`_>2tt<`$V6>o7NxTbVIn^q?1w*_NZl-0+@DT9I* zL%}%tbo<~9kiJ?u7%a=`QP4l9<-yccl8Bkmt3`VmAYF&MYcT7T6WbAWj&fT6ZCZbP z{`PV*z32bgfDbR6tiMK++*%L}X9vkQH#;!Uz(SVN_o=gQmMVi(LziMAvZ6cFo1`~W z*B4*84)=Al)R1;9EV#~SyccMFF}WQS(bMh zz*Qp#>dO?Q@-AT4fa+`!vt^bNz}GRYQ|Et}&}PnYxWj@w={g2jXA27p76C;An}AIN z8-R__QiKFzb^z3=0Ju&Oo^gpfoj^SA5xi$HQosH?(v759qafF*F$SOt;BY~U%p#Gf lSMVMz25IW|rx$Wp~y z_uIKYF4N!keXVA{?~TvBg=Zm$wId}WOWbwn@OzhKCU}|6{=UL%w7DdhUNtUTT z$!8*m7ZaPNwJJI*VyKoEH<98iYPc_ zv z06GGa1eZZAEI}R%Pj^n_P>+9pd3{}RA&g3k57*FE%3fOnEo%`=U6#688UhUiO@XF? zme%Z@*|&Z2qngF59|e>?M3I@IPr7;L3e;b+fd!wYsJq9ZIqNX$x)2f0!x4vfv;war z1A1fOkf?@A_1#&5QT5>=BG`UKBa|_F~T4WCj1D2q`YwnOwW)3-L zYT#Q`=2kw3%5aTcaIEVigOR|{1&0CygF##w3IKJe4Ew?b|69*Ak3M-dCLVC20m&)4 zr76-~2&B8vt#mGds@s7b04dTT=Gcv;OA+u=5FB}{)ltu-%iV@uBXjV{YdJW1^W|Ha zeQ7%C^_T-ok%PBNLPOgnwVi-%$4TFE^mQ^aNIjY*N0pIGp@STj3ZP)u1-r2W=$Td{ z3RSk6$#$l#hz-I*C%VN?+%?qt3B(}(+NUR5P(ns))ay7=~5;uf%M6V z%bzX8oS6OKHS!DqQ9+y_VB1`|)hhv(Qmvp!i`{Z;lK82#^;DiNKi;l4C7*g4i7cQV zZGlVAdMVH|u)xU4=NHMl&ap{51|0!HZJ)FYLlLQROv*rzMhnjxgX_YTFLbMIT}|=G z#wn6cBU@+ek3J}dszquX>kI{AvN-AhFaSAKNUQ9WaU$1gr*<9hI}h+-9#9asaJ^;Q zv{ac;=AZcWyz~#v=;rRO!e}O5IA$MXZvJ< zgJcRq0V!L_hw3h93fLdV6iv^S>LXxz(WhfE(@&B@emqgKLQc*r&vopQmyVo<+5fh$ xtRE;?chN2N<0;PF^SMBjtP@j|dL!dvK>QOmuN+elqK#8eajFolW+vG`j0aw2Og;br literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv304.mid b/data/raw/bach/bwv304.mid new file mode 100644 index 0000000000000000000000000000000000000000..b1cf375b4ab3505ca04b1b30cbed92ea520b0427 GIT binary patch literal 3642 zcmc(h%}!HM6orqp{yc*3KuAM@($dhBHiSUJNCw&&i6$l*Frae=4j4FK=-6lQ0elqS z1lGFe`f+a0%?ZY+6J6PN|E;z6KIQo2?duT2lkg~XyW#lc;#~-xy>Q!k`r`b<#p&63 z_z}X-F!g`8uU1y{@5^p?<@vMgaI?R-4p;jj+{_oB!_{11W-t>t@TY?m9NKay3*g9> zBUu0ki!U*1-+5wY`8ac-*3`~Z`A~hbxCvL2a@7Cs@Y+IlDj};@CuZTE6FTBd5NT!xW`u0b8^okvoIiG4t9NV4j&tg1+Y*eX+sH@POi4#+!n6P z@okc`_iyeuu5pA(iP||ys3>=sH;)Cup_~Jp3xMYTSPk{;Gq`WMZQfGBy0m>-R$=7v z#91n;@kS=(b$p}7@qN?rJwADJc79R#4MPw_8+&uS4Ef^a5)qYyZFjw`JhV?{KpurN z;RB!Hpvt4h8oQ12z_si{6eWiKG}NaZ^V$*M695sAlN})8rt@r8Z3ry2Q8zYFiThtQ z_mekPpiEJ8<`CLup`!741w1e4JR}c)E3{=6!N#+I&ZvQfqHVltSqf2`9*R}9bkziN zKnVb~5=%W4#*GgEXQs>xj}L+~g0bJLD6dKwjBN1&;KTm(&7xoV)Z7sY5e5rg>Y#C{ z-~BT=JH5Ot94e^+Nk(<%Z9~nrs`v<4aq<8P3EBR>&%g}VO?5rZvu4X$Wzog9`)t@} zLq4>+Wy_W<48CVePZq$cEvvFnf=|UZ(ra`-Filv9PGnK@f@$G&X@k8XYQy?Of&y`~ z1sZP?(_tf_!|CGln?q48)9JYlYe=g(<-|wM9$c<-qL@YyHI#E4F16};J*4@eN9pI7 u1wg}Olz9nRA{~Kb$Mh?Uc4TB2Ip;O&661Bm?KJRNwR248(yPCAl-W!6L!6HPJH2QbDM1|4+d1NbCP zd=K9Q_u@Z(*(V3FvnCz6vd`MLwbxI*n7(@xLU=w8L z136$~#xvXQQXVzfVyqL4*BTl}8p6RhaImHm%9M|ltxnY0K-AfQOmeIi$Lq=&C(*rP zR_1j$tTRxS>YT`ICqA7q9N7xynzohIwk!Zy>^@YB+)FERFaSOzo#%uaq%(ZxG5^4R z*aLeyeS1A$Z29qLYD@}X>0&oGnr*iE@}yIc@!2)eqsjS&EC;?t$$KLAOzE!V>>B7R zqRV#$6zS+19RrVbudWuz)(sNrBPl;`u$1N+KJ8RmWnK!g)OT)JeG^J0|1Drseq6iq0pCXrK1+}sh z;s1toVls2Ka%NHgQh(`B;rQz2X3Ilu>dacKCF$d;1{C4Cb$zN^gd21e(R;uOaL8(k zqdHY-S2aKcPFOy!oyn$TrgME-N2W z#Q>ksnOjsOxHx=*OdTR{_EmY`vJM0ee6M2Gp*V-e;Zs9RbyIA!NrcP^Mk(6&sJfX2a0d87|p(h8gJpCw{9}x!_i?-E$ z=8K?xgM9Yoo=`>HUVLtbJkc3Yp!u9#=bMgrq6>jbnyp8ecqertPcfC@lvw%{eHA^J zdnxmP=t@Bqu^h~Bcb9nL3G|eO^n`zO!bj70H}l1TFH{d9Nb4b%B2is*x;%CD)B)U4 z(ZvuQUp}LQ5Ift45f2#e8Zbo+&Ma}SU0b=D*_vDEX=%I-Pg{i*8k5bw?<|#!t)+c< z;-L!59W3K?Um60(G_(|qcXi>}ip6%Ep}m_q;|Hhoc@fV)ZsGCb!#@orP+`r^w*e1N?)V12t}VM$V=Bg?qU1{*WSoLIO_y3v6Jaqi2?N{$ oToNxkQM{f|SZAuP!rSXi(XopYI!q-icA1M z)h~z^)kY8V&77GzbGU=y&83L!%Z>zr42H8?k<^*2b`MUc_p|Y2Dz74Ma)Q6rMe1FD z&x0U!bhwaZXS9&VjsQGGpbOB|NDogv1zi9{n9K+PlRZ3r@br~ufEEJvQ-W@I1 zdaV=V@d2cBtXkI(y5N2lr}#un`iv2&*{84{y4V)$ymj zuGL;aqc4c?- zv~>(Jn|c1;7F3>~j9bJstRjLlapk0#l#b@|0#y|zHPWqLu!N?i@TP8_5{?^16vQUv z@E*Xu3ScgXwe2%LlFjja?s07f?K3)179gu22cn#fFvs z3AhFgO&+en953Pjm|3@g&Ut7UlWvnsR7|)ehvdywMF?Kh9G3HxMrSRLOr{|AabZsK ZrsPSZMcTG7$!-fyNJr5CTW=b=_5-Y*$TR=| literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv308.mid b/data/raw/bach/bwv308.mid new file mode 100644 index 0000000000000000000000000000000000000000..12fc8a69ce2f3231c177db08ec125705c21ec8e6 GIT binary patch literal 2434 zcmd6n!ETa46os$!SG({5e1)bd5(uFX0{jvPDPbiG{Z}^8#6(jJ^#K~=f`yB|iLcW_QT=COsYv4?V4fu z%rBh+m_>BXzlO51^^3clJ@cGp`KK?3LZ*HM`t;oQTYG?B478MryNJ6k)=~;IgS@y6 zsZBLvbl1I<5e>d9b-*x)LJxo~YWV=j5%YcOi;eQXPsy}d!qo%2+Kd2= zKnG@P1PYEqs@Q62AMkpJcAvt+gW+Ijl;vH~P)a5$-n-a0+&H#vp0byh*VhM9Tcxq8 z7bH-FsX0>z)Ey|1O_*jZZoo905zwwPmd^Hyn>=M(=je8Udn&^V!wnUGN*AZj)EF4H zQ~^QbAT(Gqs`-RnCoXOxrqc!hqv`-$O_}rx#V&d;{A7Zd&LRq{Ux7xu(h2J1-C1k` F^atM_kNf}t literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv309.mid b/data/raw/bach/bwv309.mid new file mode 100644 index 0000000000000000000000000000000000000000..d1c9b71bbc3a4e6eda15fbdb2c95c381a46b9e7e GIT binary patch literal 3181 zcmeHIOKuZE6nt?8$PqX}Hdc(|uRO7Aj~&O}WQ7+nyGS4*1;xnW01?W<3l?5-oE(Ll z3{~z~giaHmluRaro-(`pf3(W^E5ty`yPCus{jX zB(NZHrKh-rEXu4_y=7~~8?VK~BWN+nK7Xwe;)qp8Xh<1l8L?MB4GD$-DVPSoJVAit&Vbt)dBSbz$lgY ztLG9;0r2b1xStG@W;rYbScZO>a7ZDQ&N1G+D3G&6qJ+Wmp{VN_pp;oY z!Bu_jJwwm+95*ZN)j&8CJ)rb?$}Wgy00ALC^qb5;Or?bZ!B( zX=(2*0JJpuRPs?~NmJqCpvyd6gm(x!0J;!eY>Q7Up**Lobqb3Ts+QV_eU2G*jHo*A z%8d-m|JkwL=kng*4k?K?|InQPU~%mDPi@Sp^rNR(KN4H~q;M%yym#0SWz!{~kQA<3 cl1-&ZyvC%%9uvAh3_S6Bp*B?AC)}UhFY7c^>i_@% literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv310.mid b/data/raw/bach/bwv310.mid new file mode 100644 index 0000000000000000000000000000000000000000..0a8718305dbff17e9560c4dea44e275519e14590 GIT binary patch literal 1705 zcmaKrPiqrV6vbca_~#?|5lTZyn+{2bNhV{4kW%Q%EOd4S1wm;f71tsnS%`G!*6-lb zjUUBt67O%`%i)bJS>WTjx3--S)xb=d1VYtLv5f zMtIg1J12-!P7 z^LE#*?^@Ib7&wOvM<8ksPg1|jnbAJ8_L6~kE&zoA%@L=<&ws|O-P;IO#Zi|gM-?NZ zHDe&^ceTp;C!CGj_IK(3w)B%{?>_8{K4+iYCJK~j+%KklBOgX)LsfK3RU)sSci9>6 z5+Tis5Sdfe-*y8PbnsJPjG$#hAd)Z+0m(*2S7sHp3ruRWF|nr{KnN4kppxN-F3pLK zVI0isNnlF*w0R02M^p)0O!4D6wkdPuC+CED>x94Tgb$amuUG3mf1eSuBbzj0Hb6^9 zR}HQU$fPJRCh~D?WXv32v0xyVB;?JiJ$&}szNo)?@)$DhQkPZ)Oq9tJw1`|WMCR>@ zvuLjra%z*a?-B_$d;#r-l<>|Dkm=>FM@zXWX1JKn6^bH(y-Q%WWT~su=%N)9n T07nK6={ju4p*`h1sXxy@HK)je literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv311.mid b/data/raw/bach/bwv311.mid new file mode 100644 index 0000000000000000000000000000000000000000..e9370413ba6a6d9745dfbfa784b7cb6fd9172857 GIT binary patch literal 3666 zcmds(%}&!n6vYRqACKTOltB4PftEro(53{~h>3PbqKSzH3>eoeTy)`rrH|la_!{nf zlX?zQewkrvLt;$S6(@J@*E#pze>pmN^D2b!FwBHXB^;exybWRQc^J(-dUpQ);`Ho1 zd<)@6X#3CT=eW}iGBhU@-d7_RyuTpt)52w>^i(z~&Iy7dvT&!L|V1&$4l zQ%jQP+EJ>3ck-sNtSZI!opE0oI|CK#2<#f{3h=aRA6q(uFVTml%MxVnJ5Mb7x6+uz zP*kl#+nn1soX3`JTec@Y{iYnHh{>F#ohN@_HRHbgQdXqD4=;R(nliAmL!zcU?Yn31 z7AtkXCHv|T48y2)dtBdjT$QKqK1{o;j>qH4m4N+)GZq@!bFX^}?>bLc0EXRxF01Ry zV$MB#`&JW*3cGVP@`+a?knPmA!{aImWLwtulP&nPd~_{YN@7^x^G6w~v&c}uV@-;U zpOBODfd<5A8Vf#9ZFvah%+UdO0wm#T!%>56xbnmm5Xe5sgeM7A%hN@T zJy-WCVL^=qD04Pu)M$AFGVZY8X~#Z0Dp4k+!}92Of;%13GrZ`BD3%NhK1`?WWsSUa zG+uFfZo21WDCvP;>A)YHygoa>nDX1%u&xcIOvZ~;0@=5D)6SbW&XmPjPnk2MJ3e)P zdnOzkQbQKN)22CQRkz&7R@!vK5}C&T#wU?noIPnQ=(28s*7a1kF7*^JRdfOHgwRYZ zSwUrv3#ZK4SD?&8LONtSX?4RLZsaUv@pOqQ0Z|PzjoT^^_x|&3V`B?+092h!bW#>{IhOL~VN{X^S1y}X=qhD?rP^s#QqvgxkbvZi7y1}g%~2Fn69 zgPK6yE!KT><)DbCDm6$%>Q!f4RmLPrw>Ejp{-vgC9+{WOVEaOI3ca%c+oOlH#gm#aXkud$wiGAnt-d+=VfnlHh`!%?qZSMv{44 t>pq!FeGqfiweIYVEEx;dB{@v_WWUq2x@5tZ)I75&t5^LqP>uiQ{seE)-j@IX literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv312.mid b/data/raw/bach/bwv312.mid new file mode 100644 index 0000000000000000000000000000000000000000..ad766e582e36f61defb4a14c60b02fe16acc0c6a GIT binary patch literal 3945 zcmds(%}!Hs5XJvO{aCtm>ka}9rDv^x?_Of+D?2QbD33l}VX1fRnA zD85NOhkN;DZZEmIR92nLf9A~0nUCJ%lee!^N{`Zm)M%vRlZ$sL%^#)d{NoqrA1+SM z&ePA7ex=Mm(^qpco4#x`=AJ#dO4s|7tMq9)ZrxIZak5Or+mv7kp5MiMd$nFLa-0^$zffsy}#q-*Nga$#FH z6)IO(xaFj+*|4w?HNm)s4tbg1J-fSyL`M?{5>AOA_zmq9jvEe}!Cg-!cX~k3Y740X z8@y_eYx-UDG&TwOBuU68NrHJE`N-2EE^`&769g@rM&1-MBv99e+3>g^@Iq3`n&F7$fFi9;JkQBc)CknI$V_FA^15aLlRwU$SML4Bz0{HE?D-N+{VNC*noTo7N!trqRZ0uV` z8uT(WOvXNi3gi517iM%KOlBaFE4A(0#ic6XiwL-IiDnDW)j=hv?Z*%g{wCj zMYX2sX=_U8_~W4Cm2X?+H_{K#@-Gc(*N8L0q`5m7NhAE<**9Ih$y>3oBB5obTV;)& zN*cVD?6oB0MKiuAVZp+J1PE#x@DCvXWG3lK+acTx09y{>d{`*b04J1FB>y)P#N4zT zbf#nl&8JL4X|LG`lE*zHFF<>R`%q}uqn?TKb)t6G5FC)Jm4?j_vKd=;70VK;#^8Y5 L@xQybM_c?Gmfavd literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv313.mid b/data/raw/bach/bwv313.mid new file mode 100644 index 0000000000000000000000000000000000000000..229952ab738173e21670a64a69ef36158459296a GIT binary patch literal 2758 zcmeH}J#Ugx9K|mbUuGwF$EJnS76KuZmqJMilMKq%L=zKDG1S4aF%AqJ`jPx7?tTaH z{Bob1T;%bIlSvb&p4@x>Z|D5)Lud1MZ$b!ShnKTBcrs!}OGf4UC$my30{y$pq50%s!5cyS+Y#{wfxM%z(eW1i_kV5+Mb zoSDEBz=>;3$U{P({0;b*Z6vkS{MN`r#u=)4i!kP7i{o*8W#G)_7hxSX)y(qpXIWn9fB017_mFtH9{>gdo+mlUI3qaNT);`9GF=9AM&>@CpN9Kn zvd}znrBnj#EYPm353%Pl(#4(lUBe->=UdPrsv|Y5e3z51PI`czfaM+WilRHZBBA9y zgM6lwbHKTPHMErm7TiTm&NEjDleJ0qZ||A*@6r72^>P*d{K09{QCl5(R*%?Oe2LSy z0dQJK)eat}hlm}FcE7xj6CUcw2v4m<-qDj%Fz$qP`3iJW_`)j2O8heQ2crI^{ z-RU763)n&y6zif`lvjYYP1Nv-K-9S)${c~{g~)i3=V@lQJIu2wGtS{&fMgtT;(HQc zqm#LG!dx!ls60H;T# z6M+VxAFqCdK0Yt?n>;2H^{TKHV$`Y8|OBvv{6-cJJ=!5*2~{ro85lu O{BkixlkjHzC*~Iqz~?mp literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv314.mid b/data/raw/bach/bwv314.mid new file mode 100644 index 0000000000000000000000000000000000000000..7528954b4023c9b6efd51cafa5b6928664e19f84 GIT binary patch literal 1894 zcmaKrOO6sz6owC2YA?Y}bOrG52fYw?;KZdk z)K%d5>K1=)HG~m=?s@!=Q(Uh;zBjWMR(%CyS?#Cop1pjt{<68fTib85KbG;c zdsna5Z1*-v>aWhW_BhM8_As+!U`}ZsmzKON{pAX9aqXgF+Kv0^R z6H6sJ*_ly_0^i!MvA@}0zghD7^Vd@c8$vd8vJ{XykTF>uQwp9PR6IvIyo8Pk%@YS> zlvSp*XF_)L$g@g{Ln)|7K*u;CRWc%lP8x3MAl&lMS7~sBi;*iFAa&qi2q35tfRcb@ z2&DOseVFA!g_*IL3}tyrP*1)sAEzhHzwP%p2vg1;Qgx77eD8mL@8_!zck9iGe`p{1 zecvsR^1|f>2W>xomtz~Hd;80>0=wYx| zSoR*I_Gsp%L#b0tmE(O%p{Ja>r04QzPnS}+*yB^|(PqV)kq@Uk_E+;MN?k}Rdn7|? zl=;L5|HU7Ce0zU?;@)!DL~GN@T7Xu;>YrI)^`oM`&G*)J&_NI{Edb5()51^XB}&0J zhZG!y#2t`k8&Wo(1J2{kO(+o7pww^>X)a5Wp*7=dA6guocvi?B#YHkJ}8QX&)K8~{aGu*hPLl%wP( zq-y4+(&ix!V6Q0k>u+^6b2b0`(afG($;xHBnyqHaXMbr!~OQMfD)<}Bf|_8naaS7rezN9z?q0($Ckz+O&k znDpt4EH<&^;-0J_q{=;VLSir!JdktFZ{Q z`?$j=II{S00QB-U&dKw+=kSb{Ggw5pfS5lc^ACLV6qW*!Ydsx`d`B+3+m#gJ^1G>> zSexvl$%~Ti;%3!{6dn6GOAw$e>MRJyf5u+%Gd8@vzdvwd4ffaopA8aAa7u7`*rHxl zUJYr~Dl=E}JUFPLga9a~rOsM)fEqy!Ky--LHuDsR3Bbdw(L(1s0mDxSP5>U+IQlmb z;bKfrvS@>{h*h@>5Jl$2YK7EQC{me3z59E@dUzvRvlg$;4wgqar4Wi)riKDQ`S@xp a6h$Sk3cXMQDyH&oMAZmUsu4typT=J|#MT01-mS3l=^DC*de8 zI0vR)xB2vUx6(o^2`fKUy&C>kRqg5Q%_}o|Xj@jT+H|&fYgSp?I&D9#Le;;1Mk=!bU!a1~n(IG*r+i4e@f->&Hd zI=dzP68YfLFOjcA?n|`c1bLY9CLx#4YOxzc^|c#)ug*-1L)i>2*!AtNzUvQWudn9| zyZam4(VBETcUPdB6!B_WoWSBPS^DB+8ev~>5p^u`agxvvB2DN(B|3UgrYLO?g{7D< z2=_c`La(KSgtt|qomd>GjZy6L(eVY>>@Hc*m0FbeyLT0vM<_~AloD7V<06U&_Vk&# zU#fOB)69x;8Qe+{1c&8{>4^K1E?r|!C=C%Doted-jPgjUe&l)D0@^yld-3Pom`?PH z6ALf(nf{fctDBpWL#-)w%~RI}>JA!8)Cetb_T<`gS4}`sO+__Ba!amO$k~x)$1S@e z?>2o#-X%+Im^6V$!4%Bl~QF;y>UWy3+ sg(??{=>+n+su_7prp#fqG#y2ehs>-ffT6HRCG%p+v;jFk_vD;@0nxEm<^TWy literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv317.mid b/data/raw/bach/bwv317.mid new file mode 100644 index 0000000000000000000000000000000000000000..1556f45763dd8a3b22acab07724409596ab28d4f GIT binary patch literal 4549 zcmeH}PimS`6vbZ?`)3JVLP!Xr5ygnc8buP4Q603-0xc9;VlZ7m2pu@+AiL-`x|FV@ z_8i~WA5XvV*%C@RaH5Cz?w@ndz3=Mz=)=1Z!n5!sluF@zH2oOD_Rlcie*SuLHNCi; zgzq8z2wi{8-)?Q`^G&I=_436m+zrOFa5D%A82V(WlM{mzfm4Ii6mW$xHU#Y1t0%8x zgJS_sx<2XZq%*z?Hyr`I07NDiDF9qy%oTA+`X@9xCT2b`?2W(1D!St@zd7e^bmB_M z4lz#79OrCdqc|258_2^s4~T;oHbWD0zXk?wWkIERH3lXYz2v^8O&fhAFB&o=jPV2Y zp{IF3(t_q@G-hF5&bC15N?V}x>eJ_<6+mbJIRFWvY{>eaw*F%5H2rJFF8_Gic5lnQ z{Mlt~ZN;)=C%N_Li<=-Grk1M8*lf*_;R|a6Yx#`~droHoY^!{=(E%@&N z$2?$^?qjs78OFqcJ`a?+Yxu1+79**Nj*nRH$)Mqf<*T|kP+fq4c|g*~WmtDPrb>Yc zP=8`w0PaoJMK*vxS~eZ<&B0C>VX>4i$ah!g*G+ZulN|VE8GigSZT?O$vuvrfPZk-_dQ)# zxBi>dySTnC*j80Pm8wDmU=P=tZE6b}@vw2l6;=ewzA6js8|({U%vHr#HYNo&q#!9u zRlTj2h~bVg?gXrw*rPGbSBflU6N^F#Sg1YAvL~=>uq%LKJY7mAGFOzmWA`1olZ$0{ zpHRvkTPZIKg%`OF9PmI_q<|PSFvbRAJULpKq*(1~J|M;$#nb{`0rKV*D`+=u;=yvl hOR0G>JrcYo#)b~Eo041_lDOjp{0l_mGR})l^b7kQ!YTj& literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv318.mid b/data/raw/bach/bwv318.mid new file mode 100644 index 0000000000000000000000000000000000000000..650da22bd68dc55152fa1f8eacd05c3fcd25134f GIT binary patch literal 1993 zcmbVMO={av82s$2KNkq}4kp+!!9vIpvW#&O^0TNHt#*L~0xfZIdVo;6@S=+>dVn4! zyRLeNoFNx*XY^i%Cpl=*jXiw7GxI(Bba8!YW^b%xQDmo!)n~KLAKSco`(gQYb#b$_ z2eU`Z`L+4f?cnoc6m{RfTigA#T-)8$2!1#)BbXsFXKD^`NN@;nOmGZvLU2+=?i-Oa zrp}N$CpZtgH1LS2qp)2oW=y@jUG1uwme@}61-l9W$x%(v_0vt3Qg!8Q&(WThzwIsy z=cxGqY-!;m$pJ&J-RoN0rti<$-N8Ad$(L_!x6CMm>~o%wdJ2M?FN&xpV-35Mnlr+~ zOLIY^IY+h%Y%7#y8Yq7?M-g!r7*oXx7n5O-i>0+dD%KCop8kjE99Y+>P5-~)yU^SjyMC5Moc*|Krj#{xF?PjPms}s z%!0?!dBWp(y|}tru3CQSDOuB@z+mr(B5C>kxdy-;q3N05UptG}A!X94rQ2swB%vUu z9=oVsDfuy?F(ag6s$h-4h!K~o^ctrwx7 z##0>fV8hBX3?%6xCo>{9gR3A_yNcRdij^9YDkl#JNM5^oq(K#msB3%s9vSYTc$Z)| l>#l#&TCRmAS+{11Y{7q|cb literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv319.mid b/data/raw/bach/bwv319.mid new file mode 100644 index 0000000000000000000000000000000000000000..ce4b58acaf9a7509f40ed233bf7aa2460b30b736 GIT binary patch literal 2002 zcmb_bJ8s)R6kIvX=LkN60YRWXgam`O$WRs}7;qI82|EK05Wt2N$T>g|q)?HmD-GVhnK$nZb+P(zWsG@YIwncX#cFeHOy`f;J$w0P{c&@7 zyEZ?K`DIG}?A{%8I%fAaNe&KQZO#3n-kQ$~6M(O_vaA7?cseII2T(<5l$yoUUC+##>Qs!LmM)to{FprPbER=)1O>WLv=A3tLV_$0H6(3w5fpT z0*m?w^V*tS`k4I#vQJ*$d}<3`in@X-^ZMIfgjN0J(ISAg=x#UV?WQp8(NPJ$0B^*- z4MP>3e#W6TrT@ab3*$kjeSSg zlU&Eq#e!0n4S|w5^Y&8q=q{F=HfUa~oGez3`E(30;ewM!2VgH%^i+6KVw&YG`2Bx^ zvH3A)jUkwEdIm5iU}Zu;8#3m3b~n^e-B6#2S3%%K5cpsIi>u4KyOz8&I-{Wx!3aPV znbxKH?CGOtNH7HG5_AF76YHexNgHLi{E$17KH$>;AZBF@Z0}NN=A{OtTNZ%z?37#2 ziXMIeDe3g1b>y%|KfSOA&B4mLPnSB}y+>eKZqp;`9N|gLBlgg0Y+in{8lTkO%3yJ2 TeK&pT(2rQ&7We{E`vv?1v2q$} literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv32.6.mid b/data/raw/bach/bwv32.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..aa6e94c44372c02e7a8c890b84f62309ebc23b4e GIT binary patch literal 2767 zcmd5+OKuZU5bT)Ya|G^SMYb%*mSuZ1j1}36k`1q&a5!?5KR zY&eIhn)g!b`7pagY?4yH>h9|98egqHyfd?Bc4A3lSL@wJv(6hkK6(Cn`+0YByS1NY zzb)gxLGc$5uZTDjw%lL}ZcJo>OQv7?r=~hcFKu4wj{NQZC;%jD z8+92A>fue7o0zpC;0c;4Lt*LMZonuk7TnvhcWC?IDm;sAv4s5uwKk5FfJ9Lz6=hlb?WIN0|auNgY-}kAaJ51Gq&K96zXt_q}0RfIAN+IVG(F!DJ!Su zJ^BY8eY$>syWO??08VMHDZ0sJV@Ae^j46a*L@+8M@k!(fpXg0T28ZOP%GH8HrVkri zxPr0!lp|7VQ|13%vpzlejH{a!+W@Fs5D^|u*O`(`j{BL3m1Q?q z5X&TaMkla^^vIGfOPpA6#xs?&l&+iBg{iy94tx(EggDU&-t52lgPh;o-L-gK&K_~F zlA#BT3^3}DpyEhv6HoMd6S-PY*VXE!UW1Lfsqm#CJ$z}^I!(QxCy0LpVX=jN0<<3| z44lfw;yB`TIcXQGlLOA^$g^VMF@3-YPtfNH`sF>hv_NHM>9}2{v)3uXDL{{)2he8= qR_+lnB2Jf)kOdI3B1cbsPQi5bl95_|$TW_cO2&W%DL(F}F!Wz03FZL+ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv320.mid b/data/raw/bach/bwv320.mid new file mode 100644 index 0000000000000000000000000000000000000000..d0461aec900a8a4520c944fd9e05f330a195d066 GIT binary patch literal 3604 zcma);&u&st5XO%M|2%@PKpH9`r34Cu3!$Z?tYl%?HPOUGQw-I87cRPR(WQ^$6Zj0i z3C_no{&Fruuifb6JKxNF=bJg)&KDowhY((bXQ5gR^Tqm82$fmbR9?PaeOX`MtirDl z{)D0a+gu%N?B93Q%E9Yb_u(O1-iNy^golZOi3R5h&MlZOe}=p1HZVlNnU2m zRGh*nCu)(KX@Q1I!Kr!`7JziFoXj*D1(I;Aj?5$-4?&QMV;tca2;{MB(Qy3{i=D_Y zg@u{2eq))CuT3;OQ{^n&hs~RRFY3x(R5knjwd^_dg5NF1 zOm~noN!67>m>dcx%OANLewK-5<4AK~^X^-~Ee2|lAKATh)RDa%3z%s~R~C|FMHAq3 z#p!N2vEWn4JUOm|2^@jIp)wa_?quBBXfg^}$mmFh)(wRvEvP({uQFlZ46UFZDEl%{i~SG6r!)D!tjk|dG=VE4l}+@$ zK-d?=Gu)PLq3Lwws!ZUB7BuzgZ7FP9)`@}>3rdi-T8K;wDxWI-)Q&(HL2?wQOba+< zb=4wYEi3rgYQ-aVY+oJYsE#**Ud)s=W}`sjZ(I6x`>n6r==%1ytIaSS(TiglPt3lKQmf+NT%L=PO&=?>yKO+8dC0KF*q6rXvYC3+}`;gD%j zaxXa4;T9BZXtgv8$aNvwAC`>~l-PnW^iYuZ>C++OGaRJ0^yiJ1zpkHb2}2JpYMMnY H|D^r}=fKX} literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv321.mid b/data/raw/bach/bwv321.mid new file mode 100644 index 0000000000000000000000000000000000000000..0ce3dc8b056235157e1b73822f4a10ddfe977356 GIT binary patch literal 2272 zcmdUw&1xE97=_;$`*R7s1qrc|M1sRG&Qu&E;;Js%*##O1w8Ub10a8kF(S^%iPA;YU z-b3yC%nXNbnpCn&vPll_|2gMVXYUY=hq?8fYu zrTp8zZ~gJV@7nvVS1;GLIV;w-Iy2kkfZTy1(_&+*X&9LhnS{lPOlT*i_S;}Y`^am? z6pza}9$~4rkBgsGO6^K1^00?x9H05kq8xx)pWCNS>8iwZf(Sk%GP@H@5uu^H25MJM zO>S%3zOF5A&E4{L_UX$mzjeJpjw^T|SCkrYB8FwfkBW0ze6v+r7JC;Ks!Kj))F99p zK+OnH&8br>fHo$e0%lTb8{Q*8E-3VysgOJ*0cG=)naKk|NSzFAQU-80U0$UH4NED zI8X6_)S%f_KMJ)AL~x}m1|VlbJMSfCU_)S~bdR);p-8b(0^0RxZ9}=fHu^=)kb!5f$$ksO^vBX5Ay{ l#7n7TxF0(~@#-N$!-6g%;MaXbkeD4N-z}ZC*OSYix4)OGXqf;2 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv322.mid b/data/raw/bach/bwv322.mid new file mode 100644 index 0000000000000000000000000000000000000000..358ef4513599b86775c81488408541eda866f748 GIT binary patch literal 4166 zcmd^>&1zFo6orp%{CNX?fKn)-B!t9}CJp%^v=lnB1I@^SilDU8`T#{lI&jdTkK?2G zCULEMPCw4gO(TM%I_hHIefH1VYwz^<u@ybofn^QX53Xk3bHdn=7nYAnoC_&=RWb2qfb)Z(7k)^BZIrNp~%rk zz&=CgifU1uLHLu_|BCS+R_%3IG}5-!o@(1_ zh;v^XM94^TV4}Z`9Jy5`uVrEIz zU`cg**2Z4Z^0!<4D5**4crowNm|ocjK~i&;UAf{}5QxfDz|yOxnQtmi%b+FDHn3J1 z94RuOQe%ZGH7Z<@+rA+@tE#`6gDqNHbZQlq^yj)W{nDN3``?hs>E-2`GgEhGb#=CD zuq)6o_l>-1N^JU*iJ`={r(t4XD05aoJ2xEJ0eN0`94BoVnBZ-LZGpN2mOkzJQ>ifK zLu7o2yyI6pML+=u+_Gh>u>5x|!+geA8aIr=Dih>FuNf1{Mu^!frSNcxjI@{+^`JwX z5hU5s21%>y)bKA@NxkIC;v`9ApQO5_Qj=)$p?E5!czm)HNygAiJG>$eyR)h`MOU?J)V%?Unx~> literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv323.mid b/data/raw/bach/bwv323.mid new file mode 100644 index 0000000000000000000000000000000000000000..d3128722b6bdb71e36851db68e365ee0d5aeb919 GIT binary patch literal 1093 zcmaKrO-{ma5XA?m$`M?pfBVjnOj zi~#{d={zQ|;)f?{4i;5^*Z#)Z&gkVWZ)czVv>pQd!DLtG(o z7Nil{N9_Sa&lXE3^uzaLR1MbW%zaEa;GqYAw34|(p^PhBEFagKZO%{MrBfFM9>I&9 zFbKUpPQ*%=Kuw3x$yU@QjSM?9OvIRx?RpZ(@Nbq5qf0AG+pE%JRu2&#@4=bVO7_L`Y`uuJJux)b~E z*FKaMq3OuO^ZtA9fBbd+cuzzZq>--EI^RDLX_r)=jc;}@`^|PoA4H!N;Zxs@G>z(8 zT_0UdN~*G=qGLu>tpF>AtSFnw04yP1Dsg)}#U$m4KvKNZG3ja~B1J?a{ue|DjW{9! zAS(vM3=z^JDycTVH!|jp=-1D$L+cR707d~D1?UP00im*HKx&Lh6V^`TRD@s9{AS3_ z8fO6(_p&7PPas(WA#Q=rKGxy))-mCAoaYbQ-G1PCcrftTU;$VtCob!&2?Hh`?h1_y zaJv&ZB^ohwVF+gQXOM|#Zz`3o=g$`5`eeEY^OF#+M}U#QaC#l)LxBNcAmErWG2_A_7g-Z5 zlN_94IhDm=JpF!~^(|(dP?_{~m6eX`h&o3CBZ5akT!)xoHkzssT#o_A0xo25OmKAl zwV8VuScS61-IFdNs^Fp z{q|;l>1HZ}PhU12%m7`PaKKst{pr^*?+f$*y~3gxEM3Ov3Rt`h$Q92l70g_+;OfJk zIs+=xYY2!Zpzd*=WN}QNrZLM@6X-)eQdMQBc4+~_L{(dL*CDjQ)q`)ohup=DucQ#7+|RLvZ>nxt|;XBlivFE7EB1>zDCpDt^O zOOOkYos#5;%e?ow`#J!0a)X`mP^Kya3xEN!lwtPbhKwCDv57tCm=DZwp*iD^QkSy%*O zRzX$gkx6aM6EMZ>^28$^LwTFZ!quZ|9PDmEQ|v(~#w4ZeN+K4_eneq1pDM0Q=4J-v zc|3+)9ppsC`{?>0fqgh`YVz6Ps5=Wkga*gunf>x^zu@J4b$)fV;YzEhSXKTmU{_!d zuqRLh)C3ybNkgCtAou{+LE#d>WoEA9tbKy_^WZv`x-406s^iL5!Igc1E@)R)CsA#3 zL7Zz15T_7;s?*)8$y`l-4K!dzQ09~6&fUurFGyhJ+i>ZP%u+$OaF!=@x-AYi!?MeD zvdyKLcTizRbEOq(R4bG%N_}1+og+btE~g Hf#pF@fn)XLK3H`OwgGvGlgTT?KdwM&nBDse)K|Y6v*0BahsyJTx$u(8Q*jI;4sC5pYZcOd~A) z%9t+KZn_-Pf=?^%qlR#1uohxO8rMbVq+t__K~x_APpOR&vHS61h!Urh;m`&&h+#%3 z17|WGG@e~~dWRoEXSQA+*?1Yr%4$>sC@Clc6fHwd1*M9XssL35EY-l&l<@#O1$BVB zf(AfzJqn`Gj-iHK^x+6H)Rb{lWG-Nv1qIB^u75f6TpYonG^B<{=ElfS!!G)`>%m$y zb8Iaf%FM})u|&h4M(9>!n@?(zQF#iAbGWZuxK-UVUIHH(A9M?v=x3nduXoB*@W{#I XaEFY_U=&kBpFHy9HL80X;s3!m|L^~W literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv327.mid b/data/raw/bach/bwv327.mid new file mode 100644 index 0000000000000000000000000000000000000000..ecd22ceabf537d531e52da473a0fd2a686cf9c65 GIT binary patch literal 1543 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 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv329.mid b/data/raw/bach/bwv329.mid new file mode 100644 index 0000000000000000000000000000000000000000..2ccb8ccf1d06a7801e8fc5553f445487fe4a1832 GIT binary patch literal 2218 zcmaKsO>P=N5QW=>{2U>xY%R+O2qOfH@Q?{VLPo5@BAK0~M2eKiL^ubqqAXZs;UnZE zQI6t^SfoC>{nVo&Z0x7%S5>cG)v#QB{^*>0=1yF_?v|^~7w1m?xZRWI@7CWoSJ!Lz z*SUN5hJU*cwFmqAzFx1re6e+RqhjlBM=k<0A~TB!%!$k`atXLJuqf`_?P4GK^%(i- zBTG2TIDJ9HlSBHPbPCP@^b$uv-32DpnHX7MO!_$PRV9zff|Ene4U7PcobyCPU|iS~ zkf(sD0TmROlI5R*_#^%(OCS!*B3r~;AF}i`r0LMIBF#S@ z3mTwcb%h!^N2;GR$k0=UQKY8`!!bn!L{|66LunSUI;AP1?OJyni|h@PRymPotL&`{ zlMV|5xFLmUVONrtuH>~{$-C0D{6AlMkLi0>sfWRUKA>+P1>lFKzaVm95p6@9 zK6QLna8Y-62-r5LJfPrU-z#Jds6(X7HoE&Ki}*thdel8*tE^6uA?X+sH4T+BdX>l# zM=b(S!7f=|M(8eodML!P6d5SglWb8PEh>rxJ+fC{hB!L6DBYU+??4xAnh#%x28?W} zPGN`BD;>_7pO?2+H#bM_CSm5pW|l#^q=X&tBs+9lU7m0=!8Xc`A8kP+Q1es%z&T5#$k#>W>za(R>@3h)+Z-_^i{WL+OigHti$N_AS%nS1&>c55m1rtA*+D`RfqYKZp7H!>4C&&reRz z!nY89guegGpRdVv{;XD8d;I7sTu)|K;c^nf^~hi(FrIx3mt%ngg9Cwyfqf1Q4h4?v ze6+9#*fN=2N1p>f#i*~*QsyilC!_>LlQ!hDstt-}jgbdBv@v!+&cjnuLgA}Q++n5+ zeCmBo#r?=&X-Or8>ivr~MK7Cwn2RMZkhhkI^gZ(&h&Yjw}- zwxw$jMVmd9CDc<)nE51aWKToqv5XlV1aTf)&;G3AlRYIzSgY#@?;pQBJv*=XacrAV zTbVirodpj8^T5(}NA_tMv=%@<2F399?88k$fu)2@5gt7!^c4FhoL=tCpjah z@ab8-@vH=_pX3v(IY&ha*e4^Hd^y&?`{#Rja&b}l;Se9Iw&7(o1eylTg+-}tsrzE< z0-Ju?6yOWO5U~I@{VlL_MO4FIhg=EOauicwE~stSZS2a2>UCS(AuKj**+_kO`dv#V9)5aS8h%8;WlGX892-!i^&?Y zg6zbc&ub3vY2!FJ@=$fE>ei|AoJ>Ey4 z@F%qR*}Th$wt1V)X3k!(!n!|Og=Ig4b!+x5EL#E{Ku4fQswZI1fYd;d;p}Tz4h2Sl z(KezK5pxEVLw5O)NaXCNOg3i(na<h%rQXb98+b%7e7CeQ+4 zAXl}iYNt~>PM;LE>jJt039=%oK3=s4IXZGz?pba)z>#rh0Y>yN5LG6h#yXb8pvwsm z(`r~=M@DGKch#MJkK`_j#S;jm?sZr`pbB{pZ(;J0QzlaC!+JP=2O{1vT%zg8b*C~I$OiTO&gF?7px#}Wvh?M(Z@D<%4PdjIvn8>7*rX- zEz0<=obugo{u?`YkB>)em*?Jj)fWH-fg+$NPy&>;tu+JxT{G-jz?MpwLu9Ows8WQg z9DQ;EdCHmPp@}ubiI&>+u@Mg&y8MF97ixG;=kx6>88OaM>Xi4Yu{(lS0GP~*l~Dub z6A^KUlt{&!?jq*6k5w%~#tBZD?7RCqhqiIV*7D&ldGn<@JK{cme2(eylyY`HI{Po( Cz_soG literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv331.mid b/data/raw/bach/bwv331.mid new file mode 100644 index 0000000000000000000000000000000000000000..215e0bb088ac7ace4f357755fddfc3ab0e610ee4 GIT binary patch literal 2173 zcmd6nO>P=d5QN)!lK2R@1Og#2Mqo7j34}migoQIZONkUIk%@2)fTAo|WWf<~l3Q&37|)e%r?%u+)gFGwA61fE5Y6bg(OdE^Qe znPfl0L5~4UAp8 zB%Ag$lDD?VrVG$jFaQ|XNe7dTo%Av3+vOo9!~Nv_K<`Zz^el@yZ9KuW1Mo-L?5N;j z=h&T5xy;N2enPT(i27eJXUbYySZ--lH;H7M{i%4O6$dvj>$rZK;5UEyxcTF7v+>Xt zj0eqRLwlYYLl4nrs9sF~n9|(`RAvkxa3{nSP$u9LmH9+>3Ub*bbhVJ~fbDm!{hp5> z=Zj^`AGnTa_4r$lP0SrN&}&L>05neOFg3l%s)AKjRt1$;6mZ8k^(Qs3;LgtKnBbf$ z0F>!PKvT2hbm(p}J3&4XP|!_m_h0yLw`QwVO!a9TpVo*3DNIuPiMrw`i!-tc3V13g zU}#oW!c)oauotteJLs3k=b@a}NfDr^pacLNDs!3cjA|yzLevcC83oKtivpey-na07 lFz)aQD$|sAm7!cdsm$<xzF=`GvIn|+syLA7f?f?r1qcH#g literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv333.mid b/data/raw/bach/bwv333.mid new file mode 100644 index 0000000000000000000000000000000000000000..45a12c0292b71b7792a02bf856c6c1b884d817a9 GIT binary patch literal 2857 zcmd^=&uSA<7{zbXQTqr!LqcLnnuH|7B$F_u6uL5tI=g~`pfr;D03sq;xaixs^-+8Q zU%~kOW^NC6Ix>Q*qN^Ofd%i#SeCJLs)~{bW=N`KQ7e(%3y?x_ctL^rOPo8hyZLh93 z?wfPp-GZO}i`LHrx4(>{*3+Y%yItiw_hID#pGuGcGK-vYbZS5maZ--bD#s#~tRUSV zsn;3lXVvuEGF_YiJgmXa8U8#RUf0o)A`(F$BmECT)yaVxmd?JG)LDjOsItiQF|xd> z^Um#`-8tr~IVMWqzHhQiLf6E)&H-}+DR#jMb#ugU;(}uUj(j7q%D>#*$Leq&MS}Zy z2dKp||5%b2fQ4mA4oxWV@JG!M0Z(XiQdL5w`R7u@Iafyc1m)R9AcB`gbtH=-DZSXm zob*Z^ah4pFyYR}_BV#z@VhnEyMH=epURp}9CO=P1Wo$D6Oo|qEFK!xhcaCOQYvuy` z9(K*XkJhiQH`|8K-ITnk6_`>Rpl%vO5pgDDF^D44UK1sZR(ToXsB$3r{R^q`jKOB% zU_q8wS`m%fAXRYX|M%`%fk4bVz)I3b8cum?r8m6Yl+^(AwbLqP0PQQ`^IIBO9{1J? zDqHu8*;P;z>Z!?@V=T&Z9O1)}ffK+<5wRm8eK`H_(X@W>&0k*K+%&uyH5+2hp%ofX zXi!wNNWX{}ATmVOlH((Nvf%Upy@F%uaC+1s(gAb~9K$&_psWFr-}e%^1BZ0A&{3D8 zZc)%$Fot^ltM?iqCi|8rB bbbAlwa_?_PO$Rs%PMgYY1Anvb;-BIdm1zE) literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv334.mid b/data/raw/bach/bwv334.mid new file mode 100644 index 0000000000000000000000000000000000000000..470cdfdce76bd646bd5e128f96802bc9d28fae08 GIT binary patch literal 2641 zcmd6oJ8lzU6ovno;jx5lAsQt(cI=TK@l%d0OQ~=Xri%m;5-3Iv3!tEIK@kaxG^~S` zrLYprJu~*FfBYwdM3YoLx{q`3f9}!veE#l@bMBejb5Z2Z=garbRl08d{OM-~rGD_`eNV6}N_WZtGq82H;<=%9Fzsge|q}I&|?0 zriYdsNN{~xTlyrbommiuLx~^@fLS;ZYlnYWiHxjMHnoOqQ~gmJY*zYin>X)2F1{{r9v1f3?4Nb`*~KnG>Y*#Zl>;$KF3MG6$Sd*(I^gX}zQFJz8isy6nSLfbnGUA_ z+K@a|U)!eqw1!{4hOGPL+pZm)QT5D?!t9*MXXoI>SW`%yS{tTE7 zQ+QTFds0XxWGEm*FfX4>d_(*XEmvuWV$@g*XL1x$vKFpA>t3X4Bj?I= z0(}_%LzJVCu9y_?l)$DYc(r|j0pfMW;R!4b?+3?0B6I8#(fE}+qCtQDS7 zarq(OF#0GtIC~EL1eI4uRiO=hwC_4heapCt3n(s3C0>)e3VD^rxY{}ZMpvRED?Tvw HydC|2hJ&$s literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv336.mid b/data/raw/bach/bwv336.mid new file mode 100644 index 0000000000000000000000000000000000000000..7568b12949201f781486066dd38ddb6c2f8ce348 GIT binary patch literal 1606 zcma)*OKuur5QH0hV*3cW1VWgH4G5SFU<;bE+>l{v(ngByZfK#KNr`tx&1Z!XDOf6 z*PUJe{gNa*9}kxHGMX;!eq`G~Mkw>pDd2Q#&XCa1Lu0^rE4U(b<)I6}MGVei&SR#a z&l$;Qv4o7B5IXUYn1Vjac|W_x38AH}DsKz@?F&sl-To@tW{Qv0eWcUJ9P|J^XS#r{ zgASnMpha@aK?cL3C7(?nawY}PP{)WQg4X*n#HgWwv_^>LhYw%~!!4s^m%x}rWn+N( z!P;0bKcIYrQI(b;V-a}DZA7A>p>`-yF`;vOo@YPLhspQZd{OY)bp$z*M}Z!baj`z2 zA5Y(b;dBDJp~_`eIsXG>EP5Tj242T8dp&m0p8BfVv3i?O&N#rBHq^yx{@j9RITVmp zJqp=SxfmG}=<+s^=mGLKz7~zo@`ry-c71nOaFsG+l)X^}P;pQNRAZ*hJmee_I^4|h zP+sMLsv5~P2X#Q*L5tmOY_mz9<~qj#IZ;($l%pH8sG^UKDv1VK4G%Q|bUp$c#f*|Q nMV*GItExg3<7i}w%7%=oyha~JZU8oHXql0yOCTB~)(3k9fiRIlr#;rg#v{Teo9K3b|eF3)* zJHhkZ@Al-wdqWs;a^Aml-uJs)&p*BoA-o8Cp;`^s^VO#i_P&JmvzKp{UspG`%kV3N zzhTJF`dvk7>$lZv<@KwF@HkvNg!^Ggz!+vM<{WS?FkL)``)S4qz&K~c=SL9r!;1cFij6qSMM;Lg7!T+-! z!n*#n^xs-~b@ch$wvG4D(UXoopf4~03{v2$IAmiECE$DXJYEQtU(SAfunEa5(N$)q zgt%qmSqkHR1=z1&iG|tDi1L^$K=J?vgMC1>oHIk1n4``HtH3Zc9-YLtTLmpp!8Q!4xmwBZs%(s(gNu zT&ya46n6jPX`Sl4@umg~h2nyxhXs4OhgwD(Vc2Qmt0iEA$Apek&0TUZ=$tlNq}-39 z4-U_ z8BNWw=LSn`Y%PjAq0qpHbJ zTogx`Ii>1UIX--mDL&{Ee4S*S^AWq)u~aY0%n>q<)X@8}9p`wf4SeC$Ij*uV>#;At k3BMADih9aA=T2)#<)+rNTe+&ZMbcRf`JD1IW&b??0CiUtkpKVy literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv338.mid b/data/raw/bach/bwv338.mid new file mode 100644 index 0000000000000000000000000000000000000000..dbfc341c7dc09c976dd6be5e89652e748f250c05 GIT binary patch literal 2740 zcmds(O>War6ontb6qdju8YRtdt)#As-R~rSZJTtE_I^uJv0D zUrh~B_V)cDDd?7JHqSqKaZCY~!)N)IJq0AhBsRwx1DzRA!6g6eU1|Q&%OxY&3&?;M zPzff)cmWxx2uOp87qt*j%sm=jlG5V|EXFfzXu$+};W>rF%G*f0WiS^O))y-;s;KMbBhOu?i z(kUwQQ(J!+QcS{(SYo!13t;Jg0aEmsh3GW`jEc%u2a94fhNLamh^Ayo{t0y|6KYh| zx!3Dxi*wF&UhG~fXoLkeM2mJ0XxS$`hB5A?te84jhJaz=Dl4md0PfUAP_WcSFkx9x z6Ur5%D7x$1dX6e6i-dH^gPK*vBE z&^FKlv<#d8PKp>yCq|Xq>_cz|qJ6r7O1fIqD>tdkgmP&Nb=S;lD)67}rA;LTeRqZs zg;)oGfdR4F#nLS-<#7jGnV3_+sew9CU0h^!0F}Gz1e&L=mOfctKL*f`=25zCs#EIR X$IN_eSvsX!D80x35-OK5h5CO1ji%ie literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv339.mid b/data/raw/bach/bwv339.mid new file mode 100644 index 0000000000000000000000000000000000000000..ccb3478e00088c9fef19e36e69b05ce2e8a8ee1a GIT binary patch literal 2710 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 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv345.mid b/data/raw/bach/bwv345.mid new file mode 100644 index 0000000000000000000000000000000000000000..aaef9a5ae7b0a442f2346c0ea050f40daf1e0919 GIT binary patch literal 3118 zcmeH|TW(Te6ovm%ybQrPG>w!(Dfe5U6gc5Q9+bBxnwV&cp$>o;A9(PAI1tCsF?0lu zz#)kHJLh-hC#MnL$&2}i#r4hH z-8uK&wfNb*%KSWVo0r*a=GoJgTX$zGx9mE%?g4r+_?&?L?2}veEiwQM4D@G~BGLuW zHJp8M%i(s7@9I&*KoxhO=vYKteIf~k6+z#6P|!B870OQTvEuy3*c|lrqu|L#jqL*3R<0AGmUx=l;#ie6u$* z+kXFX*K65e#fGie1T+mO(!l+s8ayFDOLvIyf{9*TdiPY^W^&t#+YC&AwFC4#dcqcy zTXC_vJV+00F_~hq2ko9hU0O`V`}4^1pRN%A6NN8qlgnd(3$A)$AgHkjHM*g6Z_|a8 z(jx7R9=bpLf%aO2uKi)IeKdV@GhgsG@`rzu3OiPewg!LAKm|agOsZ_41Z^pfSc=Hs zbjck8H3lXWHgJnnH6_^L(mp|#UsdedFaUl-y=nq={vhf$xeBNnsIw0dwQI82_xTzU zB@Jp=0x5MU$yDX4oL7;D+PxFh9^5&tpcV7gOc#5-Lf7B(t?pdk-tI7ci4`%Kz!{OV zIO4rt#E3={RsyJZDu0y>rct?}?_+&ABcBVPHS`tdNmT121d^gS+~GkOmeZ5$EpmK-78UVz)X`?`Io#rh99 z5hk7}OzVt}QBz*^SulG&MnmSoDHG^unUX#%W{0_L2oB{ELk)Zf-U> zu*vS4(yi@b=*;i zc4@zxQu}>}%g1j+?fEuZ=wNyISLf7!D<;kKY=uZ&A#$@8&4?V(T{?@W*g?;Zij(uoRNK*1{{UsC BdW!%6 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv347.mid b/data/raw/bach/bwv347.mid new file mode 100644 index 0000000000000000000000000000000000000000..59288d4366fee992026bd59c223078f9e84c83ea GIT binary patch literal 2866 zcmd5;y>1gh82oS!!XxkqX{?hS%dumfbDVv#961#(;JQd4A%SA#@Bk5_a6u7?hAywd zqfk)u3eJqz9_`&GCnO}GNk-q!_cuFx$@%>4YcqRdk1UGpe7<~V*0{Cx-u{clhvmiP z!oHjRu#~^nuNr&!`7(+c&z`RACNEZYom(xKkTU^iL@)x#2r___AO#R-%E;7@sKvPW zY}eyWIsnthB)dqppt5R!n*PnfW}JD3;m-)p0BTmwxiaOQ5KzOAtVm74Q}#OD)cNM> zNO|caHNt}4%oxMX3{bkJn(njW%WmZ`eY@B1Y?>DsKDU*via_R4# zM)e9Jt5i^1+@}u=z!qvMjw(yuwD`0m1GpC0Jt=*VfAWKzU0hw&m|iy*8oI^XZDF7` zK^x$Z;1HlgK<#3J7~p{5z(49ULg~Go5xL*B;;5in{Qnb5s4guI5k@8l@PdUGS+LA0;0hci zCyA-@JW6jo&XX4iv9U}2x~r?}^_$W7>fFpe+LlF;jmFa-W`#RjeAxLmxtX3_PwdI; zueJHN_+I#j-_s~6eEu}I`$00d*}#He$ebZ^dIUXyE6^4n$&ze+p}CTEV+UCfGj;O&IzGQ4*M&8aPr!DlI>^wLz-qhsqIvj!As z(Tx@e*Hx*P>)uVUqm;4EL+6h)Ykd`wW_6dn-W2G?ca>ifRdqOE#soz)PLnxJ@H9DK z)BLS{#MW+)FRmw3emMX0{d9FCa7--%S|uThC`ZN!#OxoVszy))@Qy&39s%&E%A6`d zg`namdsVB1Y7tW*2^$35aZT|~qKq)n`_!#KB4sqzMlgIY30)R%E1z$S%Pyz#hRKz&^n~fO15*36GN1U4)8k z!t?5S^yG90(i6}u$CM*mv^P~=0Uz@rtvduzuOdIB^f}*4Jn}~o^-`5&h*^;`UkLZO VL>cM51EiY`J=|>Fvg@_nwrBq#)3X2o literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv349.mid b/data/raw/bach/bwv349.mid new file mode 100644 index 0000000000000000000000000000000000000000..6ae005ff1d440111fb9bfab084b68c817dbf3817 GIT binary patch literal 1642 zcmaKry>1#&5QWD!`FVuAf@PT?euO|P*v*PHvgF35NVc<-NRbkm2&YVeq7)Pc(`LW;OM)UdW}S cVo7Irmg4B}Y8G9K+NDQ+wv(Qc;xt_DAJ>As-v9sr literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv350.mid b/data/raw/bach/bwv350.mid new file mode 100644 index 0000000000000000000000000000000000000000..c099edc0666fed4d55434693af1f44379450e9e0 GIT binary patch literal 3361 zcmb`IT~1R`6on5^e}>=`prIBJnwF-&X(c2)$%FQdL=zJY7+?Uz7(r+YHUjVST65|6;6 zMGu)!$9kDe8%AhPpIIewP1FiD@^vOm=K!V{fL~UwS;>*yhWYd2UN^3FueIUF>s7~^ zFs>O~?Xnv!Sm@5ahnuc)Isod(aJdOeC=-b#7W&*o$>Va9IHof&Mi}wL3y(*1=>v=| zIT6q2h^IS~fyXeC994nYeVj9(;b2iE1HBE*MuJczR1m7F^x$39gE1N=FoZc$Cu4cY z3w8ij;@OzE3U6E7m;}=_S zn7+L`y}d`L@6InS`HQ&cpTf^57b<751=yCr?z8m14CmO$A832_Efb+2&(o6=SRt>b zL%CH=U?_yV4z)lC)Z{2cXUq|c97PK{$!TL$&ZL;-y$m%WN;&cMsJ!$IFpT`}I-GWd zAv_UA0rdcS4;H{=0L(+(&=Ry+kn)^_haoJ=O_Uqv9+S`pdd>+zw`I7&{(b?72if37ej=CUjV{FT4pm#$?9V3Qh#E_^byNXNUI4K{W4Vz47#15Vv8M`D`W+_xzP#zlkN^%%4 z!1F>m2N?0}WFUN=yiE@LY+^*rG9rinGCf&P!4hVB%vdg^J&8K^;&HMUTq#qr uvSH+8x{t;6X(h?RgI*TbAwMv~Fwe_|>Js8fn6W~FoS!XZdf2Tlp3@)qiGbYz literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv351.mid b/data/raw/bach/bwv351.mid new file mode 100644 index 0000000000000000000000000000000000000000..5344c0b3214ff0c26b5e748db980cda1a81f04a4 GIT binary patch literal 1795 zcmah|OHKk&5Nve(9KjQ?A^d;g&p;q-Sjj?XN1};|3I;rYF)oO4;eFhA09397;kwPsWqQwMgPt!u_Mu`Q2hVo6Eb%mvr$Hp6`VT3C}!l z@8ozTul-;p4}JL!^w8>QYX~q@FaQ`>GC47T5?ws+>T{P&4kZXicr~)>J}SPoK{Blp zutf=1-K~)Pzvq>N*=^`=8oKA-+{Y!}hWoa>&A_OY0|&3Nn3GlDN~FO_+kq)mAX)~1ReE-}C}DERa*Pda!C?^`Z0eFLXjQbu ops3CT%|P|DSvdk}JcoHE#+6xdchBS1j|`L8G^ukU_4S#*0bVcR!~g&Q literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv352.mid b/data/raw/bach/bwv352.mid new file mode 100644 index 0000000000000000000000000000000000000000..c6e237f1c016a48814606a2234fe98bee7b7ae53 GIT binary patch literal 3091 zcmdUw%W7I-6ovm9dl`4sd52LH(Wq$5@rFTk6bGrZKnsPISWF+Flnfk{l1Iv;^iAyk zJU@$V&f$!cQ5O5GeOr6|X1V(MIfU>gyb9%VSgy9;LMYvb{mI*_&5!NP?It{i@Gm6% z*?%e-ZGT-Zmp;7Pg@?s@7k({*12ZBsi(CRO4a@=aL*zb<%+?0rh&+We^;t^Kawd=` zMpo8r{g4)XZu4k(tutr$Cu-O_M~X?GDP&~Prek&=d!Z!n0y4L7EsV?wmSimrNFQZs zu)I+%i%|=+qVk&1)vp8IL9sLM^ELwJ(bt1FSna*!H;&IZiv?d^bB;7vui*e z7f^qZm99@B>n!3ZtINZpMTe#x-&CAFn=zPHR2{vZ3pf{tQEhuP6GwGk^g0q#K)w^u z%GnbrB2JIva%B}%#BrWFLA~0fw=F%-zxIg}h%5sXkcSjJ`mszfGIcbeD;T}1y_|pS z6OPikJ5$Vq3S8%)PU@wI_?(6K_3^1im8q?6h|+lP7AK1hPrW5QJZxfxr#8LS)%k<2aTb%RggHWF?A(gcmToNFaegF>*Kn3l?6m$PqXS zN8tio0jF!`<k&&bq7z-3RX3c`xatiwz*t6jg z3h4kdZ7O|gz*ITYTp!a}`s_+JSxP#iJUY{~3P=vls7Va!y^j-c>y&Gjxzi1>0aavB)Fu5a3H}I z845_l0C-i=nco3~2#&P_LVw&~RNn%#Q^h>HfbkSxGArK=suRM@6SiTCGpTXr!XLyd z{S`>AZ*OaU59|yha?p%5h>(Loc)cU(J0^WB5F2P}vZeug^R%s$kyhEl`Yg5b8uLpV+2B#Pm^wDx_;m!?rzjq`bsD7B~)* zdm_{cI3>r$QamwFRbHMrC1cQ{t?rtK2yVeY^r8jK)sJQ@Lf!q}s!R=ie36b(V+mDq PT}u&p3{|~*^WW7yV|X&o literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv354.mid b/data/raw/bach/bwv354.mid new file mode 100644 index 0000000000000000000000000000000000000000..46d335e3bffd9fdeb523c5cabbd3885611b60f00 GIT binary patch literal 3064 zcmdT_yKWj$6ugGbqfM8OunEXo3`cd;5XT{kI+rT)vjcGqI$y|#jopbiNU6j_FkW4L136LqlC8I6@ zv>!#Ov8q-P#a3&h{N~kRRi5(5KmQp3SDZbjg0b7X!y9kG<||k*h(3R<^Pj3l96my# z8Nm!dE{Qliug1I@1Bg83)zqGdGvd`Kz4GA_W6nI(U`mh+S7zlA7?M1+wM?rRK4)m< zF&wl(&J!9(5=bTi`B=-;q`I0>0!le1pm0^;xS|$ib#$WVB(JNeQ4o1(5>>APUU!oj zQJH-K_)r)0aY0I-`TvAFXTo#)FdDz{FrKYH+-!IJBtP(F9?@>}uY5P)76&+yx#Z0n z@{m!qZJ(eI5E6s{N@xIzvP7TNN!FF}40uJ3DT)zU!kmD^6NNw8o~5dQ+$x~Cv~WYl zq_nm;T9igMCIvb7B{NaQjj4K%3-6`N1mNaXLLWJiO=D0wYYc!!Dz~8yCoC}mC!$-~ zq4Eew$}%w4LU?G+-n`Y;F-P$kr%N~l#$5ps!aLnn$7S>aD{u9}|DsMnd5Kzr6zNKQ_s z4%Nxz2B6%>JULEx=!I+ZB=ZIU$zA3t2#2f8EfUUidJN|)QY|%Bl?PGGBfX4*zWNCh ep4bkhd)2E(!or8upVYRYaR4$$!CI~Cf&B$br#rU* literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv355.mid b/data/raw/bach/bwv355.mid new file mode 100644 index 0000000000000000000000000000000000000000..8058f6d8a281fd06ae68379c82a3294f05b18dcd GIT binary patch literal 2704 zcmaKsTS}Wz6orp5z0IIQ5HSQ}2#LWMe-p*qQ+;UjCbUp!F-1E7DShyvNQTs*bOIeh zvFr037ssBzdC|q$d#|Qe|Sf5QFhi#PKxR~MJ_@H2#8 zVa&h#ca2s3ecNm{UcbBzi=)|XxH$@8F$GKo4grTbaLxNOG^i*R#Vn{!Ogu|lpo zBpJdfpkCsXDhLhCV{k+{R!fIAKY?eWoQmX1USF8#vhm@=FO0uyG&>`^iAsZiQ&HD$&?Q0=wAQ&HHkLyD$?P(#5bgr=lF@ ztR1~PIp68*+hfZDOv9ZTxG$UEM}1$(e#t-*9ivV=4%zAsp`BbSbLbUFB7Oz}bg@U( z-UFdWm$b5SCC3w22v8SFIqoa1GCRA~S30|A=N~TTS4)0*28>}KkrMO?^=m^OgO_PA zqQ#M_hJYtq^)l;nv^pj|Vwsfha1;#K%oz}KOio%(9^x5MgKb{6_2NtP>YU@30iKyg z7E(Dj+>UelIE?dgl>q7{tgBKERXwzN0$o5?AZt*f@iUSHz=R&1zg@pL$D)0h|8c1C z;&8y6>9p*^JZ3gw_CbibQh63CH+c6rI*Y0uL`N)zExYAX%Qi~UGI>lpb@!8f5RKpb z4p$e~*Gs;K7S397wh7o2=m0tbT>yK^E+EafM=0)69g^dvcGv;sCTx@3){C`Di59no z4T~-zw0avYm^T5@d{TFL4`!@-b6Gnw7Ejad2+)qL+I$xtLe{c+3w6wI05$~H0qX*5 zfVKR^Ij%B~nLR^`mLHFE>Z&A))v{^}KU)fU&e=<9uPrW5QJZB^K%4F5Gk>2EIW>6$MVmNJc=Bd4PLUo6e;8#M#44qJ)!o(AJzjr9=G+fA;?L%F>DQ6lysDH-&z`Q_I!@Q_E_QA`NmuS}Vjuw|1}*`Y2Bv^%7BMmr zaVDgb6~m#9$X7(JEHVSk!mNVIdP>r-UdF>$xNky%nF)?zuQ(cTj8Wsvs9lZ>mp}4( zNxf90$Xb)StFp*?idjMIR&Mh=zp8TEuBtNr@Tuse1_&Bt?Z5mvj?ex$ z#;E}&90G<02FwgOP_~<;rwDQsW(Df4pg%*NBlo9|KcvffIi@EqP96qE<=w^6PE|0dW8VtS zYu!?)opw1%e+gEZYgI1+$t20S;=q)v0|w14t{A-cZ3Ex7C|`BlqTX;oB2 z?WO*Vth2Da$PJzvnIHpA18Py{scw-1P7O}YI3l-*w8E@5k#@$hnJK6ilJPH2al%|D zHjW0A&x&Y3Eu~2oKJSy|p$u1x{jB>q*5b(6MSg7n`<&>03^>l7@<@XSmrw_=rW(L6 bcQ;byi90+6oEp$hC0@57@m2Ix{n7shRCE^o literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv357.mid b/data/raw/bach/bwv357.mid new file mode 100644 index 0000000000000000000000000000000000000000..0a070317dab15727bb64237a0ac531185a5cb193 GIT binary patch literal 2794 zcmaKuU20QN6opS~{278XC?%x{O+!Kw5@Y&DL!Rt|=B=P0D2=oZpomBxd?+Z6$Due9 zynh=)coMcktrlh%*B?UI{uP#wp1xXqy1u+xgx?|j z2`~7we6#&`D=c5vYTM7B-G%$f{Cl{agm8a0{~B)31WxC7;r6s(1Ypi#&IP9AObbQ; z=6rtt5K<1IGm@#A0cHYIK&%poRo@<}zN}Qad_on%3>-QkbfVA^;Hb!v9+Jl>92Y>s z08UQ&C@0QUPGN=4ai0+lN9r@;tqQPp$K)I<$JQBGvpsakAkVQLhc=oiVYupKPm%be zoM>jbZVxzNgYf{AgDpw9=2~y>Xs*TK#t<+Rus=iGfEfS=1<(_Na2J-1hwJ>I>#U7G ze%^GN?r1?{cED22tOMmdc_^7#%9#0x>t{lXo*=q%NtTfSNr-pml| zacYbV=1Q(Df8xKwhS)-%9-x;3zhz(cT$Rsm4+qS}CE2lj zO=jH3on3Cwr(s_WJFK8nInAFs&Bqt-t`^rDKAY}j;3e2;GtM#a`(~^SiCYtT*gSYckCj4bioZ?4%pbjZMSnXy!R zm^`6hPy8t9t@u$|1$NaQ`Ux{hjvCUZ&j*83N^)dog>lHB%i>myl83CajfZW4LvHi1 za+^y&n=dbKZZ@1|lh#euw*W1H1HgfRLk*Zl%G7zRo-%f`$Aoda`b6K?@*S#n zQm{^j`XH=HL*}xKF3gG>Vk+afYM10)mA3)WF#$ZZ<_@9gYMGPkal;15af1Q~bNRZ( xY0~vly|_AVV4Yp{wX_LUw%lbYv7rE(bE#&mIiKAgCLz5QZ7KDX7ghZC@DI_}@ge{K literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv358.mid b/data/raw/bach/bwv358.mid new file mode 100644 index 0000000000000000000000000000000000000000..4b8f135fede24e78449cebb7fcaa053a871ba829 GIT binary patch literal 2821 zcmd^=Np2Hi5QYC3GaP{vSc;s)gFLmTbYpplWv}o8dKU>KBv6bT4iKR%ykLufi{&tY}fmNPrcz@Na*UobF;hl5tnLBdDqFb&uADt`o-R{Zr*Xz%l%d55f z;oL75@@Mz9usd?QH^pM%<%_Mm8^>FBGj<*r5gAz|0z?MF_|Dyg28Mv4Up%E|YLOXW z=BMTq&n;#tA2^GqH6vyi^s4kOg^FlJ%%JWshwwmnphjba@wa=E zWL*QEz#BtS@C+bKBUz2!640XpgZOLO)dTbr9-BFJon1M|S^T$I{ORib)p~Q_N3zKv zO=D^UFlm4c__s@>n?wu{@lsZkOR2rdt`K^9SbOfHk&60gw4%26j$nkjcKKI8JOO5B z)PHp^tt<_7rat$=zp4>XO2zt>(oMY!8c%8oyK>GF0Z$-r2hcGfo({IjMGl;xPJ2CR z&j>X}j}+E!02+RcCTwx#R?h6n@A<3C>+1tv*Q=s#GBm5!05t=30F#vgWdo;xQv)TO zT}o=Q=^yfV5v$3G*kYfSwM)B)l686O@86XK(mZukVATI`Fa1l^?p5Tini^+-GXrG+ z7p$Txsbem9Y(RI{y~NX?7~83)LZp)LWKVd-Mo94~%$USWS@9l^Mc}D1Sk7!GJaLln N7)Z@#$1SB6{{vSH_~!rs literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv359.mid b/data/raw/bach/bwv359.mid new file mode 100644 index 0000000000000000000000000000000000000000..084ad4f569ddfd0438d0a48d98772a2cea688aa8 GIT binary patch literal 2650 zcmd6nPj1s-5XC=I^XCX$B8?J7O`%r zB+Sn?Ph+`Q>IS-Lo@U<6_vX#i=c{*bLI_X7qYy>me6@KWLhEJNA3VKWf81PMufvZJ zeubEy{p;3&{e2Zht>@3SVRx2o!|hoJy9HojUn3%7I6aee-$9x0S~2@_CCAY~l<5l60GVBLkK1e6k3P+oDY-p7%xVTCNs0utu> z+^(s4P`rMr7tAbB+Vf3{XjlETBFDY4*J^T78sKRg9Z) z_0dw8II2>gf1pRNpJ2<0Db&L1K%9he5+f&60i1Yq12fa?OJU0?;M8~4fKv>g=6%YB zF%2t5#c+ru0N$FyDXPkdjH;70pn#KVeF~}8hkq6IsdH3buF@akH#@|~tGCzdO~Y4C zlgTrQoiN$N-XAmB*uVrpL{$yIH8k%FtIYDkDg%X8){w|ukDB*9swZ4S6Gp>_rm!wm zn%$Y0_{y2M*==O(mCtqOl@btV#QBe`e8ie6;F!p}a8;2JTZSz0b)YF4Q}w0f z8}ujnlW${kb#v2jky3wz=p$3s1#}H4(jn5xQ}!yU9%J+j^hxzS(1b%cLrba85Hb-x z+9Oiw)5g}e=cxRF2-CApY)w5U2cW=z>i9NC;v8(0!y;!fc3BZ_O3=sOv^6$2pftu%EY%>Q~ z5G(*@j6+HR1w_s1Q=9_eDOqMr%Hs=yf&!qkCv|}) zWAIb9qnI}Un;2TuJApCVN=*oe5(ug2Fp!=4TQG7(3b1%eipGKS$hNj`xeYjajtxj& zeE1xbf6A;W(uZJ3Y6vPL$N<6$Bc;~e)$P-i(q`+W)=Q?ighc_R%{qYNY+1%QyjbX? zJBM|JmVc^JNV~M@PF$fS(lYff;&aY{o%;i;P9%AKRyq@=nB$Hmd}8*!G;h*F>? z1hV{VA&wz|r(>sp@~(Wut~_48ym1c<>Qmj&vRC`91oE>Bb;K@!artMQXTKT$Mh|}{v zP_Oxcn%vyoMRu;kdvL?r1Z@EAT$^g8rA4X*pfb9oyajF1LLaHM$y3ckK$k+B5yp{4 z4N}dz;h#lDuF4bQvNtIg?>>tB;A+P{wb_nh-T+iUsX@*nDQMoBlQb?RYH4JVk4}Yg yl%h!iaXiuEm?dRbmkX5lw02k^>yms=sK^soP6B&7#OI7pqTZwYRoCdi8GkWp#DCv_EEltQk`0~iAy9c&82rj(xH9NJL2 zKT2P=uM266itdD18U>}p+U81rRTDQT2*6unyOwpSC8?{kMUx0bGuv} zc;r3mv%D^IbR8ssq+mQ07zZ#({wsh}G^frq8K~)?2eac-W_2lnk7~7GTF!LH>NrTa zGbPRdX9eTVFdf8bDhGeIR)(01X&miL&qQrVvp=%#)2BloX=Om~FpT4Xk)=6j8|PL% z!f*bF^y=>JzztMh>(GLllxM#ufD;D|K*K={h@T8etn`@95XUSCkO0Dd-G}|QFytyt zLZPUGP}BiMTlfTxi=S@n7@uPoH}DBra#mL9tXk@De;aLl+C^hZcR*truuV}kdYbat IEm553A5o~JHUIzs literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv360.mid b/data/raw/bach/bwv360.mid new file mode 100644 index 0000000000000000000000000000000000000000..b4159a1c136832b9dbff28185b8781fcfc41ff79 GIT binary patch literal 2587 zcmd6n-EI<56ot1q{yak8p(zpwp-=*j6gq*7y^xDKcTF@g(G){{fTl5q7%xbCp*~8V zMBHnbemQ_n^p2Z$vM922I{#=^d2Or5&)&>F&o8fLc4u~P zFZFNrw(`sWUPMvl;Q7Lq<7{C!W3%N%VB#PZNJBsgaw1OR8~`QA=uk?s9}it$*I<+_ z?PlaUaCY0#p#+)f07{T)r&O{=i4KBexlm$BR=7yyLTSKZ=(&PA_Y#0ontfa6Jjrg? z$xo!CD`3@K!I1=&7$wLo51<5@>69P?7*T+QtzJC5s_*`)qWII7vM06OZ_A;U9{SQF zMW*eC0y-H848jxI=>i0$?eDJZ<3O6N3hcb$ze5hT^VHquzIqNv+3UnP%0{oXD$UO;a1j-!^)hs|;C+&Qw=PEKo_iZt5qp6*n zzG_RL<)AB|=y2MWclkO|=_Dt+!3{D_Nh|=~t`~$L0&glbWAY1*#6X0{|t+fsV(a=$pz# zH`kC(Bh;xXRw?h>J{ZJKO)iv1T|hxK1lD#6gM@h~r-#m|$)LJ|OLekdQt({-PrG5QRHt_&EY+U|}4`j%CN1@x-!aCGrX{V0Mu}LITCe;Q$e0;RTBvfunE~ zuD}`zQ(t%MsV8GBvPqt*>(#4zRpaIA{afeU6L;jY%q>@&56-n-xZR_tuhyS7SJ!Lz z!?~Ys!oS^{)*t)(I?GzmpKaaUMYVOe7Y^_>fJ?xoMV5f20Y#L&sJ^+|g*`3E3E(aO zdn7GXqn=G>s@(T8hkQKCrAGSfWp<9O}fJge9%WDiJM>Ucv%s zihZ_N!F#qC9S=32T3t{Oe^l^6wltF!(RS3KL={o88j}h0>O0PF-R@<)n4@2IFe0^>j5Stw{EO(>n2)T zfkfx@6F#sAL@!xk3QBMt#W1B#4^;71M!ONbE}BOv;K za+`*5BFjKE>klgV(HU>F5pnW@tbxvTNc$NWJZCq&k$bBuT zC%0ue+)Xngb(yHSI!Ms!G3v(#k}0epPi>xPqdC_pPp9^zf;wNVN9vkgk)%~?qxPjK gSveY6H=3v$ou%mel!WSt-h66G?AwK1QafDIU#qrHxBvhE literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv362.mid b/data/raw/bach/bwv362.mid new file mode 100644 index 0000000000000000000000000000000000000000..5b7df32a865770ff37f600a923939e7df91247bb GIT binary patch literal 5679 zcmeH}%}!HM6orpa)JJgU#0ity@Y7Ntl(tZsHXX@8J0sD=L<0tV0An05aKONUkK>aV zog?0` z$>~}66~cAc*T0)LOMmR|>qcYg+0)B#HJM+AFO%Smkvt>wjAe}d(Nvyk;rSM`#&a_i zLvU_TaHL>W9?BS+aj1faW{l=P7nUC%RwJDx2)eoxKN zr!7CCGU-*?KsHuKvOya)FsOs(QH#5Gt1Mu|a73^JmUlN#B*BdMb`n&wr~_s}CV zfnLgi;Tf`o%^?aY)6?=SJ*J^N3o(`zc``V94K;hr^~`&vIsjxFyZ4b(XddC=ok2#` z=qdO>f{LS)p5~$sMt}ZeVH4D()4eaE;{Ld`1;MVD1;@KB7Np1`h}^Tzb+EN8rhg9oDEN?O2D7R)AVT z4@uO6m9BzIO5f2~sIIXP8?eH}+yHmNM+$ZU#-hgqRDwx&1&zzn=YjV@40XWl zJT`LNRf%SffZ>{2Ole8D;9|$PUHSOAeiIK)E-q?UrJ;|@!3SCXS-7*u`0E!ngz2+@ta=@zolg! zN4I)<+zgRFCYrlxEK7BGXRdiV%7dxnS{Q|;C6U)5i(Y`oLsr#C$|j8;DFdcuLl(@j b0Qe-~xyu5``Oa00)))uE@uY`Rd?x+^8KwI~ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv363.mid b/data/raw/bach/bwv363.mid new file mode 100644 index 0000000000000000000000000000000000000000..ff7def1f0fe5098b0ce78f45dda19634deab5c69 GIT binary patch literal 2069 zcmcJP(QXo95QTpbt&iX%kdPKi36v~d7B+;2lq%NwT&3oH)0c0;VCD5SfILB>U>gW5C#+QaI^BFy;wP zl5Koe30X44DRx&xod4OvG^frCnlZ-A#<&7p8JICVkxRg(fhhp*CIBo;0r;Yb{4E{h z4yV>`+k9B#A6sK>^x;$44kMIB)=WT)8lq!pPcnE2*+=Y&%@;W$C)xK$oQP%8E8ti` z>cmuz4GaK-Fd{v{;aFu13U-*+k)C2N*{V8{p{D8;Gdp?|QC7-azPoWa(wMno7Ooy6 z@<+S;T$!|rBdzKo7Yo6fV3vw}n4lyuDejO1|124);u27tl2jL`*f24)Qx8 zCnCb``hdQHl7qRR^2IJaFBoNC9?}hv-orFxsE)QEJpr&fko(l}-SdLV3RY%M{-_N2 zqcXrzNydOFe8i;s`~UWDg+_*>EGIxXr3bgedH?u^X9#o`FuJ5{82;>q$WWim-FQpk=m`~uMXcWZkJa#3waiK zkujhA!(LvK{CyDYy?Om0t6BCS_cM{z1TgV|rBYI%IThy$6%)ue+9>Fc4xM_~9Z$h8}9lfEgN-a=R{z&xo99am*TG*5Gw4HAWPT3NZy+ zs^(*Ty&2W+Jt*Kkj4->wx6Mo`c4sVEJtDnAY~3*-gsi!>NOd$XqBFW-OOHm6F%%aX zX1@fU*X>l2>8W_2e^2#OPqjb)bhB9Q_(A%p^;OM4%s}Y(0i=4=Fm;zmSAkbk(g)NG zG}WP|Q`CHOeR`P!N7towIitffR(>D;5Hp6ku z&8ReHtTys$9xMKp<;E}RR{Ss5I*^l4fY$*h8f={CiN9%jb$7SpLLmzcmEQm~6f^-% z1uZ~JLBu{H1swp}?*i~@$2%o*su4S$HH_F$#D*d|(#Tpjp&?cW)D?sP44G;OKZM_g z-!5|2NUQN!rL}3~ir4zpq83H)?eW+~Af#Q%LTA@Rjftih>IF2$1q&Bkf|t^r zx8a@OdHUItnNGu2yPA{t|D5;z=6w0_T?pY>I0*H6IA5+mg>djI?4CS-z524gxLk#s z5PpY@&+ctap}RNrdhOMVP1sKIO}L(fu+0FOz!WeQm;q)2bHKa^X8AU{rup}~V1ZI_ zwepBMBh_)Qlsc&_!~AEs9tu>m{_Q*-b8;peSqut~PwD;AQGDR9GQPOF+H(^fnswB*!yJG%pe@kC)e<-Y9Nk*v z!r~Zb9g}q|R~H(rut!#0ssI*eH3@FY;_fXh_bMxkc@C*_D9{9u)!<4R#dMG17LQ?g zQHEdx?j<^Hn6d)%@(Z!fX4)kfd0Qxth7Y|fwIIgnuIxIt_zhQ^`qn%2>cngN1La3c Am;e9( literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv366.mid b/data/raw/bach/bwv366.mid new file mode 100644 index 0000000000000000000000000000000000000000..f41ef8f108c30db1a7ab0b09ac31676cdfdf2fb0 GIT binary patch literal 2578 zcmd^=&u$V?6vi(t{&@tSpeZ3BB@hZ7CBh8 zf{);vjNgwtJsDs!ZW~?k<(%)Fd+v9>xyyMikg-E6*m=Um~Ji;thYSbSLC z+%DWt=YG3BKk=)hxZvWK#p9!APuFhKi#Bf6b8gd*)^61o2#JIOLn1?g5s{I=l*m-z zipbR#C<2%gA$1MsT3{A^bE}y^NW?e%>KhKD&mM$uNIj4-hTMWHAKrb!Ehb8h;fymm zBRB{(fdkp9OrIGXWHF&qsw%Z3W|CUF_<6F|qlNZb4BvmuTWXu*+d8AmVO@bNeYFg~ zm1G$@u>=5ZF6#y_rN+Fed2Px&JRuz%dS`_gqaY$Ktm(#uL1-#@* zL*oQ+IJ5&`j5dH#d(1;s5PiAle7fhzzi|Gan+BKyp=?b-q)&fOIw|I*6WL3rh_Bi& zxBnNjL;fX*6p((Er0pv`Wnn!(@=ZuDD+p6ye z6RIH-*67U4CEj5M%Q?cn;eTEPlf{2WWQ)-$gJD?G+8B8O;S7H&=R)p cDrDAVrZ=zK>v<06TpUZ)IST_M!*4%>KjNUaP=d5QN)g@^ggT!9tAj;1L4h0gONhugoH0XDN{)B{C7t0jwws7FnRIa-5tX z>nw8<(qCp=dibGPO{u%9tGfHm_430zGkaktmLzt)+)nh9VMf+=)T zs*!pO)KH+JyJ_(kXkbV{)dF)=8AB`q)duCb^s$c7@b)lb&CwSDXHGQa&Y$?(&c zy0a7vR=DY6^{oU$z|bS|A+L&z8I@xOk?&<>1buXvatVq@XqBm_^Z}`X*93klV^SBm zLjB4|4dp8h85+`&F$4lGj zad6c?e%0s8_jl_}&EF=q8X%8-_K7t`1VoPyq{sj|w^Jmh_t`WO1Hkb^7xZCPe+2%R zc$BIZzXzWUcL7}oil|1ZE<2}2&SDThI7L)^iPoj}(aH2+f|P5Oo*gh@j(Yyzp#wZ? zn_5uLee>|Xjj#N*qucxYn)9Z#PQ7D_Ge8^Ac94O*jZ(&9E5{F!4uH-X04-USpB5=PHvy$q6;X{?8Cn_7q^4s~U8$;( z49TM2i&8QD0%sSYd#zP7OCqM%q~gw6#~Gq$E_x0)cc7HctSMw(Yl$N=rW0z4l$V&6 GFYzCbMIW&M literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv368.mid b/data/raw/bach/bwv368.mid new file mode 100644 index 0000000000000000000000000000000000000000..758569c8371784d8a452f29d592ed454cf3c9b8e GIT binary patch literal 3011 zcmd6n&rVZe5XC>C{&@r+fK5ZdrnG5VN@;D{5E53h(C$byG0}i2Jb()pEL^bkF?NqUrOwRCbi|B%wgJS{e#zPk7{ zKRdrj-&6XThWuN+*;wfB>)PhV^Jh2db~L+5pGOIBdk1o4LS&++DLGStBO*rv$3%{c z$k&McVfm`gnak{x*_S&#*P&-J6F}h@FczrF7^9h|F`5CM%Mn*OGMQ;EI{&xA2Fx{( z!U1yuhD3%1Py{f-7M42%+>6*TdpIR0ww!lrqb5*<&&y_xX5XN=NsAYEm-j=LR~vo2 zT6cDRI`*aPVPi;8+^B)dW3W7`UFhRNbk-BTm}>|rE_lsD)*Qa5Dkzpa`wMZ^0eub% z@tMM%J&vmkyn_Ko$HKB6-=F)8xOMb+PpfumHf zw&ehO!zks%v1ZW6gjkc^$bBrMPdPc>;3^YD8jDl;y_0bAAzX)ru*_9u?~&6hxC+wp zLI2W0KR$hTelcJ3L+a_f93VFI@FQ9(!W@oNbGpn*)vBlLYlns%<+K590Y~i6K2Q6_ zlNyp-ZRliwG(G`O;XXcg_o>pa47fv{B|)-1r9yW|k@Rval^mvZ71T%|8PsuWq;u2(4Uf=eJyD!XYHY?-Y$ zX;nrCsWF8py5*nm%`1MsU!GlFt~queV3TueYUT!@A+QVB71#mn6cLd{M1aUP^xH*F zj?{_N6|vEKMD`SE0)j#yCPJ`(yeG9$)rd{- z3QAX^K8$SACT{$b0e6^`Be7HqE1i}GjMI{^I4yxVErHmeKsdIXQ@tohTCj5@Hlg$+ bQl4zMS7}?U&`%a$%8_+wu5)Ac`1XDSi_|GG literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv369.mid b/data/raw/bach/bwv369.mid new file mode 100644 index 0000000000000000000000000000000000000000..d6bb7a0ab9de7228a388f113a8386c7591cca632 GIT binary patch literal 2497 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 K@FKFsgZvL40iq-T literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv372.mid b/data/raw/bach/bwv372.mid new file mode 100644 index 0000000000000000000000000000000000000000..d825ec784c15d65124a955eb9deb01a999515318 GIT binary patch literal 2983 zcmchY&5jaL5QXmm{%qa(3_}JO7$D7%=5HXANoFMr?cF4rm}myW_yEQjLyU`gBp=0% z&w=&Pmy_Gm&@l#GaZ-qAXbETsO`qkz2p4R7%gEuH5}3S-DRW7l1LAacG%hnVMw=m>HNR_o-z9$b>85-{lEP z_@YW!@HB=7oJTMm85jTt24X;LKzRfLhQ14xxFqV*qOJf}A<$FcY~eW1pn*QY(_!*x z1R}2z`KQCEv2yFWU#9XiTc*nB{l}tBlF$WUkbK!r#Q;-@v83ZMkl7@SCq~xP+0XLd zm5{y@h{0zJ$lQaTMm(k4W+2@*15h2ZH^WVXo_vIJWR@PFXP}QyKWnikENU>n$5KO7 zwE^0R86{Z63&4eeJZGJX^6YBIlb3TLuv!n)@bmhU5^7m1(T9AhkL5wJ{Qk&CQ9+*k z+E_xS(@#EcGaDdt#4MPO!uKj497gGv9mb>io7=^bkL#XqY>(U&5l}T*^1Gmh0wSU> zVXVbWW+gm$2?-M?UvnxNA7}*A@RQH?r8|f?Yb0-@PkSc_+WEG<9zQYF>XC=)Vpy=G z+8~8X=b)CAfLNC`=^6;cd{|2jDq)W(_(Xv8;{5^ydG@YEn|4s6i!4;{06L*XPx*vW zRXzei9-9}L^(l&y?s4;HYN<~ECkASOnt=wOVW0_U zh8FoK{Ft7P&8G?=VFQqc8z8&}MKUYue-@RjO^Cs#1!!%E8Aw|;0OwPlP7O5SjB|kq z`7UHpr&3I+%13;v)IvH@ZKFK9)dE0u7Y$nl$Sa|0$ywp5t{c`+YOK`mJffkKQ+O9* ztfqXVs(e&JyP=j_6s4~-@|=ZvI#|*x@+BmuhEiutb&G0{hr!jj;j{|_nSEBcM37?Q J<43T$qTgd~9zFm7 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv373.mid b/data/raw/bach/bwv373.mid new file mode 100644 index 0000000000000000000000000000000000000000..53cd0807aabd2d8ecc765d5f1048894a332bd152 GIT binary patch literal 2308 zcmds2%}PRH5FPFI^9VgaP$1$Drigm+2N48Uxv0Acgo2>Ruof*PTDWN8BlIY}M!Vj` z&bi<1@R{MFO+Onu%*;14=bX_7!;3RB+p?4efenU}OS9CgEjG4~#y6AE_1Ip_-mJ+# zi<5K;pT|Lv-rbqmycf-E+B2JXqeq)|0XhVoID!--eb)2=RNP_2)yzL$B@v}oL6@)C zP<^_Qo~(6^BD0@dWBrkz6YToTZ4Q5?2YMeZuI$b*>YzPc6bJ(TzX8 ze4>Wrl|G6{Lq#NuxRlT`XJxXI0A6mklO(HIb?QRLEqxt|jRadZIr zKp^!~S=}^0->&;xTG7^Z^95e@ntlXRtg&eN={`uM2@?ptg*1v-pmC>IQo;` zSu^m@rbE+4cQRCBuZBLN^}q%IRd4T?M<~X@k5l3oYYSF8EST)$ChMd}`c;0Ejx$RGtoi*B}3Y5yowo^yc<1)PW**i&@wOW1ljyTJG$!;Z1 zANBFuP<2xkc4)5!S;sPEsltq-u12R*%}YmF`4Q`DSu*9v{5BidE^T0kAFAT)>gt{a ztkbHx?r#CM1hxU&d8AJHaGJEUDbN5ksJg*fY_$M|>~VijAS*vkNa_n`{@{I!Da0R@+f$ nmg>xsRh#4-j+o;a*x>$#1g!(sA3l^SnvUD^1{=gs>tDU!1PVvN literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv375.mid b/data/raw/bach/bwv375.mid new file mode 100644 index 0000000000000000000000000000000000000000..b795c2b536982b88d2b85d9f74b9e43641879a53 GIT binary patch literal 1885 zcma)5L2epB5Nz-|@e}d~+X_O+fEJ?#gbc`>!Xe(9B}cO4$V4~~h%6sC_~2t6kssue zgCF9b;HsTTX_i621xnL3T~*z))7kBfnSHQ|C5cUEi#xN*A6p%K{4)QsxW1p;KeIQ> z__w;MR`B~ZNvfZYmi98pm-cI5_A()uYzLR*To#-sM;_$>Bb;2YbOA6V7#1fe@nlTS z7$BAylk7^rcdAd=hYkZ#FQJo7oONTeF{1ir^GY$GDCaXIDCG)7(Wf-J{W>G^z?Qc9 z{C{V!*jdv1{&U;Hx-{K|p)L&(WCR&NpQS#4mMZr>a(W?IrTA759t{~@oQx9G66ofL zK^x*oJvf2-<{@gVx)m6EbaApApcF9Z>>UQTpv57`VNBLZk8#{sluN_(efH_>hY;+t znqZfQvv2qF#g?xxrG5&tZGv_IAWM)kG)ogBYRGhx0)yk1g`@n_e?wpIJnNz zIUmJ&*jZ00SPMAr31H8htKMCQ*GtB9vL9#Np*E&zq?A~Tj1xv~v*ZTlITBT$cp4o} z%y|Z2XRRPMuRa=!IDvY+CJZVqeb;~aUH7ja9=1FMt>=su&)}?1PzPu->gLQUDVQ?H z4I6COC^GwzDTc@zeVyMm)%URx^m&e~`a#DIHTp)5TQpW@Qi|3HY5=DMr(sDu&~T$gn6w zk;t{%Wp?X1WU9J&CEoNzZu8w?$UGB=#9Y9CGuI?Yk z5ns^}AJ22z4CIOzfC~XfTyqF$4`eu%DAa*T*&o+<@;e@t)kn)zYJ| zj27#()a8Lr`5L}qVy3!yzfQThi*?+vwWaOH*8ScP_etJ zM5<{dq0pRYp>L;RZdaqLw(Zgyus1m?paFoQ4ydOQ*R)8*YYIT&l-cW0#CCy_W~cV& uw6QS0zhbg$&LKS)m%TJ;qPZZwg#A**er=w!-&JFByoS0sLKSzb(cORQq45I% literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv377.mid b/data/raw/bach/bwv377.mid new file mode 100644 index 0000000000000000000000000000000000000000..0bc4d64ebb5cd041124f167aba6eab7a87dc6d36 GIT binary patch literal 2242 zcmd5-OHKko6nxCE2EKCH#B&22i3 z&l}H6UtX+i?T=q=>6@)v1TBDIys~8g&?aaDbP2jH(2~e4a@a0%kCh%OeS$u~fMDQO zdgFD-QP;8Qk+3B3(E-KzjV(zWIS;VseB5529{RSjO+HFGok7yx)zizNnCon-!}_S- z0ZLBRH#rJTkQ)RI09Dl9cUlIRmebMwbT&WmR;W;G1zM{FRRG1K zia2FvSq7&<5Ox9Vb*WuIVs*keaEyiwzFp*t=1(#tOk1cT&Yz@ei~o|U#54hQgu0uH z?QBS?wC|QNHZYZ!v4N)DkEj55lCP<}&|#dt(ZzWbN1)2B!u;Msj^socyAu`g{S!XPw3m{I0 J&S%1ZvM(CsRhs|+ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv378.mid b/data/raw/bach/bwv378.mid new file mode 100644 index 0000000000000000000000000000000000000000..27be1fd5aa46b9b6538d567dd611bd7e9b301a79 GIT binary patch literal 2458 zcmb7_&5jaL5QQ&@Kab!O%!VNlhVT=ZPEQj8Au}skD7#5CF>x{&#<(WNm|3{sk$e=N z!wuHg_j>Qpszvv~j3Irq#}T&?DA7V8hrRerhMljpBiAJ@0{EBC{> zpDyLU-J5E~{(W7mRbRe%bldUr(QU>q0tt~Mj!cM5EHYhg-Dc{HHYYT<&^6%NfFiTy zcek14k*_|dgf@dl(iAW?pe9l@q1%LRO48d&zR|{>W&)@^TN?0^g6v3bQONPO>MymD zHbd>fM8zIutk8ZAeU9prJ&uSK>(T9+;R336b^*1kyHBUquVo7iSjfOkQzXT`)FK%m zGcZPMZt<99b3W0VB42!Vx-{VVR{B5q>Sll*J^J?yB=k=(D?=?M)j#SM`j4T(m;H(e zh`ukaJ(Ph^QM6)CP!?-U5sML#wIQOXl+nmhBtbsk;}zg4e=)yt`kmPyFT#8Dwbv2LNuZhcj%p3+Tp?5s{Ha z_M4G?(VHdVk#05N=!lE}o*#1dg@)8dNU>0YS@18>cxfPGGZ{xGnn2XnvY|<1vi$a! zkRgSJ6pE4pZA3TJs&tvOKi97$IV!$Ni$7!{@47jH>wT>08_+keh4j(ElQtuu$^y}; z7L-MT%$FBm-4dqPNu5)vF+#n7sU9 zw|N+>7=eFFL*oeK3eF>4Z6P4}}h_^^PFaf(1OcOF%Pk$qA|j*+(p z?mVFVHLH$vR-N`$r_NQ2@SXX_JCj}A+;r^L6c47(>=%(0ReB!&i8a&X2KZ;I-SIoUI%T7YUJ{{XRNS3)J4<;n|acUWeV&7jIVI);G7S@H>P* zA>(KFuB5cx+j6<|>g6VEr^{`)pN6o_mYZ;&2}}V*W`Nl~@*_qjOM!_ZBOZ+eCIBMl zF>v{uoVjvlls_WO%S|{Sd7$JBVNuViE1V#;V2fwBnKo*U36I>+$QW*(8HCZO{E-Q5 zrX4$MF`}I97`Xf}*?Tu(vVvc%U=w!LhpYOit11t^em{0n-khn&EOoq}P#`)b7mzr_ zj-h~)ha?jjGX_-#Hqm2vutc=Vxtl)BeSsdJC(wnkEASsF?BfPgWK6+acFYS)Y*9|U zBmsQ3^B&np=JEunilq$b6<+q%Kdci zw;S=ZeOvouf8Rt=?ZxwryP0MicRh6;NQtBt5ttE~S!9-dFTgze=C0=!SpXIW=Go0{ z#EOY5=qgeMD4r7mh%kkaSu=PTA?6f9Qd7Vkh0-jA0!mF_o>==BFwTMT08}F|K^VmX zVC9>v2okR?G3%O8;X)oU#bpBP6-V04m;##C`hR>-tD|fxW;>Tno>2~r8Q}SA5!M+YgH%jc?AHuP-6LZ_7d1U* z^$f^ffrm&{v3w3!mSYvdcJ=sI^3|^7$@2Z>YRw1cKi`>ftY=K=t6Y>KMI=prC{j_Z znwWnU9-$BD8_@I~PGhhK?0txIc&Ltn6KYNjw0VuTpXyT6wMY+erz=cpXq)1Dcw%Ou zSI-#O7W5^AU!gn1!2qI zR7Od&x=N}30si7M_3Gm4s^b1MLsR8~Qr-*`RQPKEf7PWcsbhWJQZ2kgeVsLkGyzQm zM}VX1l%{KhgejsLF}In{0qp_y@)0JZ&|^c5wllgt`;>0yo<_D{4Z<#rnmqA literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv381.mid b/data/raw/bach/bwv381.mid new file mode 100644 index 0000000000000000000000000000000000000000..cd97fe6aca56890f4e953de1f4853deeb1ed8fd1 GIT binary patch literal 2632 zcmb7_Uuqg*6vaQS{j-EFK?p&k5*0=57*Qm7st>Jifffoav6wC(lv0HDAq(glx`r;L zJF)jS-{f$|u>*O^;e7Ypd+r}6SE~>2LI}@7CDdx+YPJ0sLUk7QPoBTteBNH)Y{H)q z{)P#E_HV0|O4z@t)v7OF?85zgy$g5q;J^ZA;Tgruc$%e8_ffTkSsEj733F+TfKERrJfTu8IaE8YQUOomC-J*if*{`xRX1B_1Q6(iu} z<|qEZtOUp5=6uNL=~1;VX!#=bll3mEqm(4xnS;93wCT7*1da7#bMy#4?BEiHrdl?YRgPEHFS$ zW&!u~JwEl>eDrKZ@vOdzCB!(Z<{4v7WtpRS%Zzzdm)zZg$+>8Kb@iKb3IE%>Vl;Wl z^~)$`mW>ji%rY-VpeWZW`>Zl|31SrEc45J+NijVRpcni}{^qlpT;JZ7Tx6Yn*DX

2a&7Lx?4^4Jt literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv382.mid b/data/raw/bach/bwv382.mid new file mode 100644 index 0000000000000000000000000000000000000000..161ed823b64a66293147ae91ca390c25b4622ef0 GIT binary patch literal 2290 zcma)-OKuZk5QP62^Ed)0$SRf}vgP<0KVmtG$O#MT0DxF{!NSWdISM)PHw%b#;4kwR-m^gzzLBg=#fitv2sNIQkX#kDk61by9HnogE^78BA0+mfeXNez!I>GlS`hK$?k9R zUE0Fs#VSXvXP$gZWlRB6HJ#9XA`ppJ3&dM;@(?}4So{=1m><&JEh2>~$Eeb# z%Au)yO&BL9Y(!+FoN@AlrEJ5#o~^Ue&^oKr51-0**<*~}p0VbW+})|2@hF=tO^9w1|IkfA4J3?L-(FG4-BILnxGzFeDE zX<;*-X1Tk0p}Tp!dV90plzap_^zVqW3+M{iGtc@E`OX<9UsH!BfSi1b9byAc+bWOf zD)S8CA$b5u%~N@L>{%~Aox*&2m_nDB`$4!@v~Zn2%$~HkgdVoQV}Cldz%d(Dd}>qG zR!)btkZj;8gD!+PA9<*9uFQ@_{^%+FbYwZj-%5$*HoXwms%yUIE4 zWv6O51!1)2|Bh3VW6kdFrhVq(>*VrCyvD)ICOJ(3D|E!R6rbF}-5v4lKFuc9(V_)N tHz<(avB160g!J4yAmtE=c$Aa7gcF!glvCqh53ZJI_9~D0r+Azm;vcm)Vc`G( literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv383.mid b/data/raw/bach/bwv383.mid new file mode 100644 index 0000000000000000000000000000000000000000..8a3eb609c44e52dd104c754a83a4fb939ac7c5d0 GIT binary patch literal 4947 zcmds(Uuu(45XG+=|17};^rf_=wIsweX-JxeN};}3MDr#n2#S^J0z^dmAmS3-h~R?@ zaVPbh@8148>Gu)pi>OZ>?sxCZnRCuedT{vsX-ervx{_M0bZ~h5BBg6T(&@FE4~||R zKY4YOzNhpvjr`~I@l{eVNQo(z{6t!PF;Ho$NW-Q*h70y%_AxzT{6+ z2hErF{c2yYNJy=*KaKTiH2a#~jTG>SfLDJGhUgd?*|0*Uz{tQlnSIJkjb|Uu(3d;B z8kmkjQlfzq4gP}81ZZSH@Cm~sL%h)9$FmmSpSAdV@0HPJ8kq;Du2?*LL0-)g>3pQQ;Ef^|lmj@VXC&N%4_r)Xt{&FrqBk^*etC=`Sr|V^wTi-Oxt?|pZ ziv}5D76xk3vh2*H?~a092fGT8g<#kA@F&ECV1gi&GMk~XrzDSdao5l#JW>M(9*MrE zzF%c7cm5g78l=8?G5UdBn)^|ZPxQ$rLw}lEBPh>e==+Xebv-Oy&uG`FyH#qj=tLu5 z$}Rc36*2tBJ4Q*NkyB50aJy~@%ln3IkYJ!hU{^;}f| z5ny*b5c-i$xmA>_Mm#LB>-V+9t{*;ob#%Po-w}q30E#&2nMT8=5!3`4_856Ma{FK` za?lxuArG1Bp4@UmOAmW}pJbORFtEE`aCa4encyF8CoZV4spKJ#c%Y*U35My~XI^XF z+2hiJ%b+DiiSwB za7pNG2D;}?!+(kRgYG*fEmNeRtwftX*^C*>FGpBI?UlGyANpUzohNVJELf^-ljj-~!%7=2zoAd- z4%QW{IapJ$>R`1xk;#3+WuEhj5^J6fUv6r?z~DJ}po4^=mR{NQZ75$2S%@wP%qRZ$MDAOxzxnjM2XUSqLc~J$X^}czna0l*@Wz`w87xdinhN?Po z)u5`XS}44LJMcFBgr1ehuQt6?E%+U`dM9S)^7*hW8`-ih(e#>63=u%|1L(kFWmhr8 zvvt4sBy2dyohdM)`uhzt>^sOoG3Z=?gI8hL3i<^wppy*@F_$SCny-sl+Mx@;Q?#j8 t;it}6`F(FPAmBrZVu6k=&}>qwpId;V(0l;|zbHpz!CmEYSuoXh{RM#eE^`0? literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv384.mid b/data/raw/bach/bwv384.mid new file mode 100644 index 0000000000000000000000000000000000000000..3f3cc3010650dc223ca70ca6c10326a1f70a27b5 GIT binary patch literal 1975 zcmd6m%Sr-q6vmG>T^^x#5KI&qZ#Yd?84(w`sM!exL6KoSfJB6g7Cus&mc2u-&;x{h z-;92Yj7huP=#O(h=lf5mcYSGQTb41$u}*JzW0u{r>Bjci;C|S@8`zuKr|t7^dXfFc z@44e-cX!4%X@_GQwaq3$_-vy9&?2+|UAnq}4lNx(n-B-X#b8+!a~e);bPAX1sIqz; zvGNgO4he?ZtOXOsFw5{4uvUPOh_Ji+~s7F#~4(c2&4|RrN{~ ze3=XP6bsj4!Iq6}x;J|bnGd`M$G?4C^%T-#c+}fNSD!$66qAq;u2@3F%#>5GKr+|3 zY7GSia(SGdP19NbJCDbiIha5*3(_Spii zZZKT&fj2mH1C{E8IzW~*)TwhE17KE@<2QfFQVf7GI*g#nrgYU0FxB>X~@%1PklgNV7T}mBO|~_5ht5xy!aWJ zr{qkPa|yTxCUIOktq?9P5884oBLjQxp@pMY`Rc#Y>`zJyYMjkkW-#;!i1PO z24JfVvWeDVa41>IqT>S5aScXfghBsuTuu@A7C>ty(@6kQ#5kQa6q>n;+b=fmdNmC{NXFcB2 zfEI%tkIuwzUV?#lXdM^SUu4SiWj-!X&c3aY$=b7Y*0u!9{e%sd88 zPMUh(D(~*yR7W@UZ2sYPxhnXsbZHy!L`<}8vzN9&i>Fo=5g^hg^57{??odT}1JKw{ zRs^0dUmAM#8IjeS@F`d70U=H8kQeS{HWAiTP7AO%mnUt))0B(Sn)_nL z1mx;_WOLm9kMhPnkKOc>lf6U_W@XmeKn8<3;v6fq_3qU|*xrQJQ?Q=ASNd6c!)IxD zb9Yy8L51q&H0tYEUKgk_Pc4f`VvOjCNR^ywmXk*+L@J8dg$fr$Bxx!_Ms30z*PBP2 zlQb0}P3?khwRe{4oC#017vbmB@;0t=3vLb}V0#1{bhh1V~7r7&$xuLI|axNXg^y zD6~9~SM(6UMnK{QkoxOh>LUwP#PR!u2$}3SXw-CU8dTOeuqDc1^L`M&w4yjR9i;M}|a( ztH}3F&DXqUNI$6oH3NZZw)rR^8k^4zyv)Mj{^^)|8CajeT8-Rr^(gz6OP&BGD}lMN zt)L0o^VG&oFQFi9-B$K@jEUo&B^2hDE&s8xT#T@Mko^Q)g=K4VD^GPR^%oyMR~?F1 zb~hl7%-C+)9Npi?i2jO^I6^JOwN${VgqmbkBaqX-3%Kv`eVD=36wRy>h)04A7F1TB zA`#IBeKy?Rac{tUn3;#WAPG6>LxK55Ga_`Q>HBr8QC1RKI<+voXUs z2d55+94gWVv;~d;M*>cDQPxFSm#1@&1$JC_zuOLY=s*uO0T62Q5Hn2Cz=Zx^u5HA_ z-coIq57jAaZXv#}cStpRTaMGhE~G_RPc9PU~qqT;7YT_u;rNj*ht4f;_AR e>lUo7s8GGOsLatdp5dn(jBl*YLI>Z>5B@KOwxFc| literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv387.mid b/data/raw/bach/bwv387.mid new file mode 100644 index 0000000000000000000000000000000000000000..5d14b2557f0ee18058d73015b12eaeb7abc858b4 GIT binary patch literal 1642 zcmaKrOKKZo5QN)~66Xjxfx+0aY#~|bi5?byfLGBXnXC*61QM(uQY_=&rxIs(W-d`TQ{=Ud3LNN^v)teTmrn5UUplZ>Qg8_Yc$f8}Sr< zepc`IMP0osmGrh4vYtb}rE)89gWyfR;+6&d+{SFak4|6DUFlNks^Zp&5u_LZ$mP~9K_x}7 z4>_m2j8$c`;<;8_8hrg;wBIH^ni6Uv1ZV@=0$#LD+fV`UF?Io&&JzCEBoxTG&t)EB zY$zKAd$B`<7Oz_Q6uDe#k;{>N0|#`=U|Z1SE{o!XYjS?|f3*6SlTQ!RS;4nm$822! z1`R5WRC0ZdIz!-e__q1%+lh9TYHR~wWea+`bqw5Up~JV(Onz-VD-M1xP`-%# z#s2YU8Q#z51qZ95SWTU+E!IiMd2G6hG@LWYX95*KMW9TpoRZhUT(RlxEm+6X3pj3> zT%hc~hCNqsh*b}DF7LNY98w$sjs#8trvh#rqjRjv3E(7c3Gm91J?k9Kxmxz@=>^Kx KIpq0acFX_09J4(D literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv388.mid b/data/raw/bach/bwv388.mid new file mode 100644 index 0000000000000000000000000000000000000000..bbb21460c68c13b535610c5e0442abebf977e54d GIT binary patch literal 2767 zcmdUvO^Opy6op^M@@EO|A%rwBBps3zl`2Bgp?lOBXw4cF1f?Ts7tn}E1|qJ)b+{A< z?jzo>UU_)c6-serCduKx`+M%Gd%1r7(mD6Yowz7+m+S2t=UUI){=ws`&AaXO&BlFq z?uSeG+rMa?*zfZwYCV0jb6>N3=k78WfEY_0T9#OrW?29h2Ihcy=%YOI{G)$b0B~*y zPso#)PYOs6CRFDCt+9r=R*bWoQD=YUGQ{aPfEDTKl|_{9R7j%`cnRdsGZw) ze@o}5Nhg}Uecz-T)esml#>mEyMJkac&Odo=P4W-!Zeq@3qQ(WVQ2|qCo)&owAjBD# znSli0BmzXDEEcMT5r7$A=&B6d5G&F^l;O60oEI7}F=G4>cvq zKN)~teR4sRh5zk`TF-o_G2_`crs`&)M1uMOF+H=Cx>}?J?Ohg)laZ%VqFi^V^>3#2 zhwE22n{C699K#S&8UYa35KRpY3;=_|V%5CGd=6WBIQOdIrSln?&+JK`Q4b5weL&wp zP^+vSIG34^s#WV5R<$}UQ{Uwj#{4lbfEF~MXb}klF`K_99Fvki21X{wpk8zW&;BME zsH{7Pg{>QVIFUA|FL5v#KBU6k7ZM<~a&d ztt>;t>cwH&^2fzM<&;SDfwn9m&f-V(YL((y>(;(hJ$SN&{>qfCs+KY?6ue4=iE%s-@i>MJxPyJtCgnb^A9Pl{!EM2r!TKQ%`Yym z(vOsWrM`a_uU8bhc-3mHym)q#ZpX8m^ktj^II-nKmXX0oU}!LmF{iei$}%ySRKd5x zayk>Jk0E{R7*{7axO8%b7*roH!{v6+hrX~hw1e`87xEGk+*uY7P6g%4ojS$LEb z&8d<;_1vcl1~jBo0>H@t&HSGFF9+B0kwE4{iGR9_zVA#SuYd(-Ya4p+&u)t>(gBA) z@KEOfIEPUlIp!$FPXI_EHV0O+ZW%mn?RX9)yvr^12YyvqJR; zc3s^ib_{j|0##W|l@j5=hs7E4d+uWIz8$IIcJ{2HEp!@yT<)E$T?g;V5@sPwMLL2h z3JCg;B|a{}DB(j^s8y;8LtOjrYd=!OMN!6-Uy%c+AH?*$L^x2vmDi4wsnxSkmSx{y zi5R^LROIDFr1$(lhygZTVpFxY4YmbBI#lH{XNUn%o(4I&p)ZILlRvRo>SA=`mcIFV zLi&{_*rH@qNu8|>evhiYB647LP17N{ezVXz?(Vq|g5j$OVO9cMWhfIz!; z`5J^}Ewi?qUO9*H1eek)CH{{t5DLK?dJh^(4L?B4V%_qt*UGzXSFz%y;4D40!ju*4 zDX%$eO@QGt3yL<3l5OE$b^O677D->yVvz(Y%f`tYuI`v{y-V`>>p(EI>UKlvl}9|Z zBbRA#4nv^}gknrAc92(`y`ls+sEWJ{uI*dUR(hU=EL6{nhTSMT%^xXRW~N+xEFq?B Mr{g~=o#K`G4cSzGZvX%Q literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv39.7.mid b/data/raw/bach/bwv39.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..28ef5b1d72017038234862a2590058f58c9897d0 GIT binary patch literal 2767 zcmd6nO^#Ag5QVS!{8@r~=mZHgA^e2D2ZTUK4`iT>>_ih2O=D;mV2lF>4%mrX=r!~T zT!~np_j+<4@AZolV^83u?y0)xRMmZ}^}9FDxySB-OA@zQ@7_CCdF_r5pS;+9++AL6 z-HmfU+>pQHtIALNeVHVcXHWO;Fx%|i=b3YdIbd#J0a(Nlai$zi?I;DL21bC90dewm zmT;EFDXM(%x0j@=pg8|dh7?Nk3h^rwuZTDjw%C{pIwrEf1?d;@QBfUB_nrUh>nt}0 z=$Pt6S%EW$Lzdc-*E2&H!(Bi|VQFQPnwfj#G$;%O_wM-o&z{}do+YCXpURd@TT%*4 zBAYZs>(GG6Lz+mW2k05d@1Mv6ID=8KO^0233hw&cMW%j4Lft`I1CSGp_QKBW$NlobKvux-*jLwqKZ63MvGy!sq5 z6fMA*QKC8JQnKW0!jZQe3PzXO(Os8n%HN7tBHrxpw%L!?Z?CpHclYNi9K+Aw;A@Pc|s0>F(U9vKk zOX?^~1;e=GwY}kkJiffXF4@|AAw`P(SQm;rUSnW2^HY>%#xlz)V@Q>){hhP!lyG>5tW-s4~LGVR>} literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv390.mid b/data/raw/bach/bwv390.mid new file mode 100644 index 0000000000000000000000000000000000000000..b2b76f41f284eaf0e886874d0088e629ebcb7e2e GIT binary patch literal 4072 zcmdUxJ8siK5Qmr8JWhbPLloJvVmnbB%a6Qd*-AkQa2E+ABv6bT4nRSXf+8iy;Raj* zi5qYMGe7U@)2x^L1yrQUXm+08%>13%#hX_lgh$~)sMo{nV)-_N+K;fRJ$}A;zr4I! zgs&ld4+H&Kz1%X>)r)#<>)Df=aC$%dy2xHnu+4b>umlh=9);5W-|Z0@kBlMszUgrPN!;FSRApWp|4Xxh`>z{@Nxvl zilZmT&@>tx#sqYOvsq|xZi1$X<4*1bq|}*m&CCl;X;V&TrcIF7pSVNAMc!PSGT^zE zP}+h zqC(IClL=z%W?^TQ9ok5TrlgcXWZcUqddE0%c3+3uH~Ts~ym)=JSXTTSK(PoeZDKam zQe;!@Nuw{vftYDu(7?kznN9YY!Pwbs2J9+D*CJCG!v9ubR}fU{zJ&c83%zeno-XK% zTVa&|1=W3FQ3{eGboA6&KP7YyFJ+hz7tjQKcwDYzA;9XeqEM zBbR--IH^?Ul`3>tjB2dV1nnWYh(iiE_jPlE(323|ty8&^3#!Dyy<*C^lhhff6g<&| z^V$TSuE3x5PyOhRF0ZdEu9_U+*wrw0t;4pqq-{b|nx+Zv$uxSR`KF9zL%=WI6jRInW2AeX)J*pXoPz4l21qb0Tl7iwJiqo(-I}&zGAaZF#uF|FiUJ}Ed$ix9% oSDygkZA-{@6=U241j5QL90`RUT;9V`okFbEkTer1es6$*#WQldmkWFnjgNTd`LDO~1p@+f%| zJl{Qdbnd-~&Pf`3v^%@AyJxspi;wR@2+zY&s8++(V*M$E%B!$Fe(`4YWqotI3co}6 z6Z-tyzO5YT?{)RK^7`c_+>e%<@NEG59kXF0YiZit74Y{ zV32WiGB^XChsXdjU_>P6tr4CmL`2R-tTm)Oik3N2&&}fp^Mpet%yIfe;yN0GRHC(8 zaLn*yr6#;CjvP}JBLYMciE@=9a6FG2`k2WWo={aB!BrDP_iNcV2Cj0%zzZgCs?PBU ze_cH_;s+V=+2Z}}YJK4Abk1v>>o5l1!=Q^zy5bl()hETSJ$)kT6aJgPYzTp#-swaTK7Bn{P>BeKv#paK?w?OrS|sj$DTf$9>vFkf`GcQjQ!{mlo AumAu6 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv392.mid b/data/raw/bach/bwv392.mid new file mode 100644 index 0000000000000000000000000000000000000000..99ab8cc7cea05c7871ec91b89bd05f8ec804db2d GIT binary patch literal 2123 zcmc(fPmU5{5XHa2_Rk5_E6fH7Ob=;>01X4_Kv>B_dpC(DCYr%89>5qEEL?CTk1}WQ z0E6}G@8hMJb~-UG+|0auRrTssy=s=L5AU3FPuz)%BDY*^K00@D=k|}DzFvRcTwSl- zPv>skh=2RHjXV4MCW;y_pKaZ4o^RdPxpTW2U}hi#WCrH>cOO~+7WT3vv^22Dcm74? zHOZ=~GG{Q;YX%|Rr?i+FNC9aPGVqYFZwFxpys#iudNP;RXPTNgivB3^(wW{s;n2QQm982!V-3$a3|`aB()ci zvH@iX>O#~lh=Ps_UM}pVw3pCcJnA)K3nNPwb7>34gXj^24kLUa_jIVBPYObS+pr#RZ038EusM`iwfR+K}w8`-y1B7B;;&P58HYtZ$ zJYwz;qL<3W+$DquF#zT>z*(6`Rmu^ecv=WM60ZSc{Ej)3bCS-Dy6U{f&O)LaOIQ%Pi??pVR0S50ko+>mjD0& literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv393.mid b/data/raw/bach/bwv393.mid new file mode 100644 index 0000000000000000000000000000000000000000..b6db41fabfc1cb4b5d89ec9f2b5810bf1d14ef11 GIT binary patch literal 1975 zcmd6nO>PrW5QIC)@N)z%VOe$@$Ii%(8I5JxN>+FgW)}%0Bv6bT4uB8~FIafVaX1BA zB96cXOn;ei=?xh@ShBH8{kpsARXzK1`R0|GJ+=c&61!Zk-zkE* zGrO}1U%QuwNB()0B!|zQZfrX*HuiCDww(f|4rYLvgL(0}JX!!2Ub*1t!oi~0mKBXh znl%+{7OC%nG-q?}U;>ypi0b*Y*W;knQz?{;S@Cs$3voI4&o5X>U0?!+%U)Sm*|M=+ zd!O`oPda)2?n5kQ`J1si3yqfJ0+Al2GUZK_$vGf79pxNR3HEq}P(^W$jPtNEVTztH zVC-N-zxmD=OTi5afE`0`g$>B)G$n4pS;Nk)bYdLq_okH*zJMNhLoGU{PZwI@vX zm#6z^`TAzHj{J&cl|YJlsmmV%hK*pr(I7n1Jt9C;eH`lh_yADbBX%`MgeioSFwq>H zaxSiuLQ3<9FnJ~-J>yPpFn@&i~4{v3BnO?_CK^pN%ZBva3#u)n+C*$=aymhYqL{9PynpTqa9XN1b`9cY?!k_JsMZoAD@K@;GnxBYa8bYjRzC zt_dTPx}I3BQxcab6mjghmnH8-Wle*{nP=2G1M8IZ(+VI$Fe$$VL1Th(6^RnZOlCyB zh+YS*h$Kq%f}~*?*g5qEEL^bkI3C4|7_6H2 ztUMhh>cWjy`t_%(tAT^j`Kg($Siz#m4n~s;v%;&*msStQ*OQa0u|1o;SeyUm$HgW5 zJ&K~@#@f_ogLG8&5(HdbG!_9>Cp%pDN=63w^RIRKvWN%IT($&hLb?IK53khYeK-n9_MHQt@imXnesXeiv%qF?4H{v_CoeIcd)elK zwgKuCU(dFQ2tBCtiIFWnZG|~yK9vzE5tINFsW4JOq()E!P^8R0tkSF!BP_2GxMTp9 zD_J?4%-PHu`kWdsfK_>hvPavHyD@*3csHUUAQgcw%p&J1r&j?)RUrRVVe)q>uokKa RMj*lwT9i5qc&}|r^)DXET1A@67jRRE~spA z<#~m@-I>hKlbO7ni_8bWKp_TVg;U_vg)=5+Ix(>82Kl4BPn^t&aN|vskGIYG#P>Dc zCMM3uJBIJ+d*b9Rg+cPcQ)jZMtlA2-EwA%1U00Q*M(h#k9uBBAlMWdjg&vxoyQ@v| zu-4hKw6loL;$-=t0bzVHruN*QA42))U%q`l|}(g6CZAwPm8}5&P^aSR6u-; z_?Y&bZ)VN@g^-29A0yo(lVPb19I*}o#O7>&f{ho`U zjjWoA13p4P<<2#|PkewVP%yQHITO`n-eb4ysrJHv%`h~d3KM#(EPeV#bJVW4jlr1&?031%s!h5h#3DnpN=R0sO#57egnN z9~mn$NtQ9`E}2AlAL05=uVm^$INp%B0z;0lL=Tm@qaV9$9rX%!&wCwMG%&VT#y`RE zdn1MG)be$DI)8VwTowGDN6Z*`r4FFuAlNXEFts8<|I~>xyTAnuU3iuroo&&iS95CL?0#29bt?Dxm5>zBwmy?h$Q>-lJ7%P>1xwSyL9;(9!nGEkMgb13-G4 zUL2`~o~jRxW)6-#9s4SxbQM&KI=$+Cxkj&=gF1jng`I(xM}CU=iTJzX!KyfiNYH{z zG?mIt2*+b*fHMby7Afu*j0n;ZyjN zFq7*{u6r$uO*^{xoS8X~>)fqAe>Aff_RONl?pB*GW}T58E?&M{f7{$YtnH84U(5LK z@S)Se-}h0}dGl&#`$f64?ZRw7C71$C2qpl!63ENFZF56f&Y&DY8A0X)MbCIO!eb;&U(^*`WKWw|iRY6byEE&v`P)w>JD450c8#3P<(<_OF z#)w+rmif0xE12(m0MN&hja{-b$to>8k^O>c#gnwk(t;u!?2N#T0e}-$_XH;8Z_a#Y zhu&#_a_mp^_Urey<GCgjDyHO0=WHfC$ah!#+^=MgcaR!qXI#MjWu zH5FYMn$VfEh;&+|K$0+7NV@yPo6_A=v zhMd}vwWUl;8`Bi+0ZffcGh}H)0I5ntU`S@hciXQebsxT7eg5d2d*v#wT6Nc}%@^m+Hg5Og^}F@A&F$UV{c-NE z8}euO;jB_|yZ6=V+1oc;_cY74?qTL4uq3jy$O5o1FwY*{!#vM1K=M5MxsUwbms=!x zQu%~F6RVm6rgp zoTT9u$yfHY$V_mmB(Fe3%*wf!o|aV6FxtWz`g?`rE|`8mKIEwL6dGJ`0^p_-I#1lz z?dp5yt<8DW(bw-~w$r`Gcw!uP9MjrI?1>psPCksO;YmDHHKcr)SJ^(kkAZ_ezkDQ0 z4m1XI9^`zA)5Ff1B^v*Q;Sj29D$Ws&KwkF_cZx2jEhNGK2e5k|(2qMy=Na<)PuD@F1{9xD!K7BFNM>ArJkv$EuQt}xoS)7Yb=uz(PZspy?i9h%O z9N*sGml&~$?V2{eL8FF&3s$`_PzTiGh;nLht=UtJ9Kbo?Jg>4ozREf$eUziB2LE>% zT4OqWPK{3+efW6ffF_%I#SB2c33(zd04`~x4^`T$#7RZBX+(#H{5mvf$Shf*#NwKD j3DrxhQo{z3e_h!|aIfgfmV9triyXH^RF!)p|4;l3QiHW< literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv4.8.mid b/data/raw/bach/bwv4.8.mid new file mode 100644 index 0000000000000000000000000000000000000000..2584165bf0737ca1d04a2db2d295bc2fad921f02 GIT binary patch literal 2834 zcmds%OO6s@6or4Vd@R8wkWOf5n(%HYAvB?16B#J8PBbymG=_Eo#yB8p2Q0y*IPO*S z4qO7>um1AnZ;F%-TSuIn`}*&>hdQ6Vd*hsY;tDQ`-1%(z-nrs;w|VsR<>KS=@@nCJ zICtk_em1X*g@W6>ilXB4XDhd!%vbL7#JTk`;Ml-q{?#*6z|@!%LMH~!0B0dHg&{|M z1V)5L78(P_Va}M&Fe3mtL%`5L42ToPsyt%=Mx7t}Q%%-jjdZcB9DkFeodtA*Q)E3g zUBq0V-9^F}_`{uaIbApB@H(Nk7&6_TXT5cvAlX9xx(0&emD^N)`}D?q8ol`NDbJ+Y zsT!XPQt2i1fJYB@nyXK!Z=pUS0tNt*<9WKF%DW_YE%ZPiW(L#~W8TW&C!T-vAXqF7 z1n--zgJ=@>%B_3X0U+1{Kj#70Suc>v+1ycjm3>*Ls z3{*(27}y8whs++#UdSB692yghFb3P|y1`HjF|^FAa?x4n=(?I! nqY4Men-yNj!}L_;s7igRSdw*Ap7lhP5#(r7m6s?lc}M>OxQF;; literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv40.3.mid b/data/raw/bach/bwv40.3.mid new file mode 100644 index 0000000000000000000000000000000000000000..7b1d40677a58b51fc8b57f3eef9d5fb0421271fb GIT binary patch literal 2038 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 L$=$%d4R7CHd4Jxd literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv402.mid b/data/raw/bach/bwv402.mid new file mode 100644 index 0000000000000000000000000000000000000000..0b5eeea5467e957c8b559d37435060f237d1b4d0 GIT binary patch literal 4324 zcmeH}OHNc#5QdN1K9=AP2=bO!(=^?-JVG#xWS~9Jm}oT7fB_dki~|M^j4N^}Zp2`H zeNVoe%WXQ24HNiN?^E?x-99|}@HVA%FWpM5RysU7{g~37pXu_>{pTm2Pv0D$q+coh zPEYuE`SSLk`1_*Oy8ZCMMf%YnUZnGWD!>5AASBzvZ|QtHzyN?m<85qE?E-cK>;d*l zu!CeLBpMsJPe76yS(|3Sed6p-j%=>M@W+)>tyy3h|HlKL(Vu70pC&j!bx^j>W(w?l z(_P8G#E}4Yb%!ZK097VcV)h*dH=ZqpO=gtt0tuk8Q`W}pKBxIWZ3McH<4@GX7L3bY z=ix=VT*#Z*dKH`58hrXPX)QZUt`niV!|&<58(?$zHJxvcBmt20Q1$APP$B7~V!?XM z07;L4fNfOOR)?gv)f#v4s#0WkA1^Rqv2u~UN@^M5j-*3Cp3~?9pD1uPfJF1NXrRdWE-e-x^IP0x}(KCd4tIpfHYr6}19XQN3 zSOFp+H)#uMarP`jvUyb8OI5zh6sjcuV`_dJkyijK0anQcMfDQsWgK5>VcJMhC4$1; zCghIEc{k4Xnqu67Tr=GA%)IBv%+oh#XA`c>GLL61&0!t(WdWOouvz4X;9`JBNFD{4 z0n7yO@r$$-8yjtkIaG6@S^(4nP7`N3RP%uO0QO}WV=6S@JQ8fi<+^IDjb5|3&xZRn zpq6xs>{Fq#=9{)eH*Cuk9iuB*u;EP`X){B1$X2i= zBv+Ua0a@=wBEv&zEVcX;EfKI*m>jd772?#+M6nJz#S(i_#mSQ5fsuj-+9-?nITF$e uJwRShPun`Dmc#0TSm7F_u7%2FEWXE4M$K!&TB#~3jL5vg3Ns}}=jJcX5rb6# literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv403.mid b/data/raw/bach/bwv403.mid new file mode 100644 index 0000000000000000000000000000000000000000..2b7559e2e0cca2d379f009374e373d2e4311eeec GIT binary patch literal 2353 zcma)+yKWOv6h*HeJU#)@&>1O~jbkUa{I+LgCyJB`7vL@uNJyXbmb$fTeaetiq z>t=lR@5}p=+rO(;$}gVp++)1nx$m(%Zak);DLGTinXJt-NeuH~EbuJMSdz00Jwl$7 zGq=!;oS7MUoS2+U8xfw!k|U}x@;PE(kV6}J&k`IO3p)IjCf^XcvCuW;*GY~~7NDk( z=ZfU3q{@=1Qb=6#sOMk`V~^d=?cexQm0#Pbs`D@3itaR7|427J!WbFrgg&^z5MyY@ z2!l}I@yUIv`bpJ)aRit@&lu!!QtnA->!0Z@#~`O6^U#kxefA4!pYoL5JQ)FrG!U7m zP)H*W;2Id9ChbDeHIMdtif(k&2tc$o!$6t=jt|9zkmh3Tb)#~1D37#$?C>@hICHka zd(g;JmdOK~!j-->Ex|}98M(YNxjb2Yyx(jK-nCYx%l9DZ8ObFimu7S@I-#dWYvgn> z*lUj*Ji-|e;s`QyXO+vN%gZ>{*dc|kTG)nNo;HHU3@4)wk!tn=_Ppv(^Cb5@QgP`zXKdrl0Oe7R zs)W-<3b3m&t+xvfuR8BhvL3vW<jb~40TZt`q_OGU|v)h-ceVKh*!e@E2?Xu-{6m1_K z%xy88%sfl3;<4n}m1ylaRBrUSqr1&a*y zCk_gxeY#)<0K}RsMw%Y&tf~!rbQR8#X>f9}Yi`TZZ;p?iW7K+n-xQ*bPcTc|KH)IH zIp92HR9Xd1x|*Rz1J};}>FfB}5=|De>H6#v7`G!rzxCgoTv? z0l}rK=X4p!&(Q{C`?x0CXVtX96%7j$fA_?9$M-MO*@pl2jJ`8Bsbf-iPy^H)oKiYX z83!;D=WZ}AF0@M{5QuZH23-vwsLb@vD*e~xnPpu*hoq&^vs9T}^^(rfhB2ksOF`uM ztIAz}kS43WP8#GRP=g_s7!Vh-zvOSfxP5!u5PjYjOgv`L@!v#SoWPtoQwEeBQ~;Gw zvpz?gt*4;F^tx3B5?Psl5{o04BL~{21XD^i4$uS^&X7w?JNasIpz-L@=y@tUMs`L1 ND!NqX$nRzn8^0GuJMw6az8sr0j) zt*Sp?r>!oa`zS}VM)R+>8aZdetciobk5}+BrG>*whF*r1F)cVFX7SDdFt9M8yvFEb zC&^h1n@WdP$3ejH3hpJ>%0`e=(+)DG<$eMuZTX0)8`@MJPW0VRRP28Iyz4$)^qKMU z(Pd|}V$!F1@|CSz?KQXqlAh?`}I9Gzk9EVQp20(o)+RU=V3Abk_FET%<^id6bMRC&ypt1xzs{M>;& z3uv!-j$Yng%_!(^l8l@{_kfM8_+@2GXi zoex7!jae-E1aRUYzaSk$oKwiBPS(aXLRO_Zz{Y`-OH42EUsb^>^eWyv1{^z(exJ(z hUs(_=Pu4JnSFi}Ld_e)nD=bJ+6+^}%yhiEI_YYiK?r#79 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv406.mid b/data/raw/bach/bwv406.mid new file mode 100644 index 0000000000000000000000000000000000000000..ae3f3dfd0feb08086763bdca97a8dd4f32f09b9f GIT binary patch literal 1984 zcmaKs&5jaL5QQ&H`?Ju!4=|a`gn$fzA@*<+Rc%C%31S6(?1vs?Mof&2shOopbK7tGOt0%hl$ibG5IoIC=7V{dse9yLP{w z`{NRRinsNm=888_RDbbw>vr>e>+a{y?J_`SU4h>LY^^CaKkwEC=Ebk0Lz+BNQSd&g~T9(kVQ*Q+Tv`f4koB z{r%@NjA;<>RU5#oeCX){j%~gOSyCXNz;Z-_Tuhx1?P5qZ=t17*B z2lMoiXBn&Rr46}lWbIBPG+pHq)<&wYveRUGlStD*3(ztkj(jQ7VyNdFrk@fywW_Q~U-b$Tc>n+a literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv407.mid b/data/raw/bach/bwv407.mid new file mode 100644 index 0000000000000000000000000000000000000000..982ee82d3b6be46f496fa03c9f26c983ee9040f0 GIT binary patch literal 3631 zcmb7_OKuZk5QKk%dE5X_V1W|L#7P`1$ByHN@=#cj1$c)95)z1@zyTt}A`2D>v0%wT zSa1|>66%{CO8+=!5Syg*_p7?Pd;I9+<@1!%&2%j_8tKu=*{hUR&eG-eTaQoQo;`bW zntrDAD~vL`?+7fU&>`Fv`Jj z{ym)!_3~dOCe$MHJ_#vmaKOt!{xYM)KghfK5t)yc@^J|RM;T101u?(Wf>Nk4MbT%O zVxK~>;rwF=l_^$+TloX3)BB8sv^)h&i9#GI75qK5N0e3z)*qL!Sg<%@O8JNWF#)Q1m>IlNW` zB^=B7YEe@)c_%d3WjYY^ymk>PsCuR%#+Xdi&NajJ?d_3puV`nn_dQz1WU9Vue~Gg2 za_K#m?%maw4dtq0dim!$h(<5J;l>@^ z@QsrfZ%)r@emi_UUL^yY%I||e6ty$#F(~e`4`2a%%!ik4z_vh_-Ru@XK7dV}HwBhC ztNZX#I6ltYNBh`ug;x&3k~^W-#HIl>Vsr{$*iF^?+f-%ZR-DIE_3>rWEoQb)A2k;A zQKzAg?kQRppye+5@UjhOd^QQkl&PwhiclSVI`Xjy88MkEU(Fp##FwK~HPcxpsG75j znubewxZVWs&$8Z?Id(&UzP6yTCE%6l@In_gc|1xBWnx`K2*PqkBx$l z^9-oYCb)NZ>ZmM_oFk7wT!AtpU3TdDa>TO9Cr02B0wTdY1I#J#Lo7(uaWim0FOv9!PoHz37*^7vAMQ+F84~TjolWV!eeN6XdY66-9 z_W<_YXW9Cy}lxU8{5jxXP2fEhm(`5b`e9 z2{ZE2H%Q+|+DYE#U_6yH);2j?Tzi`XCvCcpkdE@nyvv7eaqXmd`s;a*0&9EB4bzO+ z7PhQDU+Ga-Dn?(w?>kYC&Gck#CrI!3JDWem$WZKfx>*SxTX0&bq8uR|F@yL!fo6=rDhVjjXKzaMo^k>E%00ya}aG3!fsdTwjS0MMz=_xZLXIQ+% z;^m5y&In_@Ek+0&d74+1z&jj5-K(B+v%51zG@h9G+yrNnPFu zkh`ds#38!)=BbI3W}f3+uCv;opRJE{Uu|CTv=P!Aq7Q%*((ZM(vhUV9^k-q^It!}` zVcR@Wan80bC4=MX-K&ETLrZ&E+9uuO6I3t=yW?MeYQwvShdpO(Aw-TQIoQ6R zvBY9aQcMD}q)e$SQU!KJpa!T3)Oo54oB~eMiX2g?!vR!yqN_|L(+QQ;(tVHTkj}++ zM-BQLs`w1AREUqXJM(YGFXTF_WM?Rzsm+BvM~x?vIXGd)i7GDCz+z@dAPX&!Wfj0s g@TxUdQLLtlddrp;*dEBoA45JCxx`e?p#P!&0i)mNaR2}S literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv410.mid b/data/raw/bach/bwv410.mid new file mode 100644 index 0000000000000000000000000000000000000000..04854130121acff31140150a427b770818f8d993 GIT binary patch literal 2254 zcmb7^O^#Ag5QQ&@KTB{0oph4`f$&d2prHw!9?3x8tP@R4G>xHM05J|2IA96A6qn*6 z9E0a^Kz0Lp5x!s#WA^-Bl#%;&R#;wQBZ6|<P);Yi?Zv*F>(< z$Ty#wB?e%gCELFv3@}|?CkT~_rz<5OLdg(NN_yr9^WsepKnnlMv3R;>#o(A8Id6Kf zWr8r)G{G^zIC)@$8@DTGyU$l__l4o7FQ*pYXBmC#KLN%J<2XiuQ98`Jh{%NzJbS4j zk)hSZU;xh`O&Op@JVV~&y96HP(Y~h;?)eg=tlg&!c*`=Np~rv`^1va?=o#=FG+zQP zQ_XRWX{JWSfvZ-G&%xV`=iu#GBz8+j1I^^CTQ?0f0F5+aHAI?71GE7YcL202r65S+Cx?vYM=tBq!CLIsZs+Fp%&lafV^ea<&V{h86jpp z{v4ijOO-IXWI&b$gvN6~XpsZW7D00$)gmY?As*&&#&7NH0U0A2v3Y^bsWM=G-Y`H+;h4B;t#Z;<+y``xA#Ny6qKTCP+fQtTr{s7uN BVRHZg literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv411.mid b/data/raw/bach/bwv411.mid new file mode 100644 index 0000000000000000000000000000000000000000..41421d44be51175f8f472593a42a9608c1ed360f GIT binary patch literal 3244 zcmds&O^y;#6op^Y__GA}0E7$>Ozb&+e!Dy{lDj)SKKV$zje+%br-H!bT`Y*2j>b4ces4^a{Xy@d$)E!ocrkp z{5!lZT-e`N#bV*b^PSr#tDV~>?i7e{MWJhqWo(woYVWp_)b-V;k5>k~%K)xxEY}8R zWX%jL01E?i(&wqm0Iq*zj5!nf!HzReu}ssMf9nz(WA=gs5j7%x6j~-&;764OR7Y&6 z&e<##wC;>LTYdAaPB{Ss^akD=W~*ZD2;A< zfS!Rapc`7GErG%6i`xz?CI-X?#6nEEx1(oM(IiRk4O zWdKF#Iugl{m|@z~fZxK_@y9jbzi~(XC`)Py6lKBm$}^VmuDnRBMI81D>R5{?^Jd=I zn|ZQ)cemc0`3|3YB6fs7JR@awIA+Ht>T*M#n#LDZ5oe)bKC4Am%Um4*bs}~pxDT)W zG|K>$`@~@BP|!EE?hoGgqZz)(I$l!-GM5*1`ENi#cz$;y%GWV~5{Fy|ZK|M7pwC{Q zabuNvG?;E0SnN6w-r+i&pbcoJmg7;{?1e?Wdc^qeu>qfMF{HPc5CJGymAhm;IPOs! z+Dk89&qzYbOG_=psxzsirYi z2hwn#}$Jfd$+fLw> zZI+C(8^kn>77?z)RXJQWb=iA>=L#HFQeZBCj+;-HOLZy~B&!T4hjkRAER9j8Dc#jV zG5O(jQ(d`1FBVimy}c_cqs&v?ZDrI_BHe4%EPM;j2vURP3u^ZoA0S`Zx|jSz{RQMd BWAXq1 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv412.mid b/data/raw/bach/bwv412.mid new file mode 100644 index 0000000000000000000000000000000000000000..991972f4aad80605a65ad2070b8884fe9e89448a GIT binary patch literal 2500 zcma)+%T7~K7=<@jFOT38kZ`L|Xi1?dy`)eI9T-W}&PX&d(SQMFP8#EYfrAcwARomy zsp~uYxIBlAjia;jU)K6>XOGW6ybB>b2}_|;3FGtYk0C6-4D&}%UtN8^zPP*!KSTHx zI(+7Dm*-1i{-#n{e*Ww(%#J2^VR{t8Y&7{ErXzvj}&_>mT3{j26no&Wq zMgcU^^7~{#-A6vEs-Z!N+G#^%(MTIQn|uw^Gr7h9x<7*&i<>?n{iK|(80K+;e97fr z3-h?&PoZdu##RO5IK}+%@J#6Dd#E$l+;tb`Fa8|XYaLdl`{{PkRhhA{M2|Bs+A%5U zGMBF852@o&pbcne7P+EDYsoh5=q>{$txI$SIZ=KeK9s_K9qc*|k&hYzs5Y@QxdDrL z)M>sgY4>(@VC-bI{)n}9C^}lyS+^u+)dk>){L+tejK;Av{7?K3NJo`g(&p1mxx+NQ zJ;`?GZ4}SzM(6eT{Qc$Cb@=zI^$=ygD!caSeqY_U04)K#_OR^9QfFp$fgQk3W>IN% zhF{2+kNkatN{o)l4l~g@zeTWQ$w0D_y=NZ7o~ek6o_b+iMorD>ICtdQ~_0iEdY#mr46mp z&??jmOLO}IP;a8TSrn^cDY@2>UsucqU?a;CAj@rRB44u9;ED4Ph%--_Wr2B(;57kj f`Hd*>#NV#7nfJz zX9&MSo6q>|@^~qX-&9tXpFg_`_pQ;laN7#uzCHRHZrcJKKu4el=n3>k_u;lLFc{s1 z+d&RqVRV zoH>r2@ z%d2aCynp!r?(sV9DdYis90=4QFFqkUf+}ZoXYRvCJ>vXDwk;w@?$dl4+-gjcDmzIV zlz}CihMJDI1ejQpUICA~c(dVkv~082&b=qb?9*fmBO3`gjwg744>Qfk6uppn1kXnT z-b-8TT*qhXXVQRqrsG^CC@Zv2c9bUAL;!T*xjShoNYmoJY-!MGl#PipKZ{t*p`4@U zRUxb9$QFMa8FOUn%73gm^mPN*T!+khzOt(|e(~Llo0~ZsTcg#Q(ysy51Z=4>FpjnX z+moYY*~PLe%N}56;T4B5m$cSsbtcy$0p&x$4RUP=Yyvg~wg6iKF10MIicdAaXm=!B8Vg8Br|Fi;IcfKUNLIaSR08+n(qE^j?_r5Q%q1eTaau{MNi>!v<_a?r314HL!))j>{2Lzb$_q)x!jA<9#Zv~)HNe-+%e)TLVL zczi#d&2v6VS-m-g!0bwQcvuKFX#g}bK^>vG9r9weQerM`2zNBGYtznQLzcVv7P*>p zm`~l6jus$jLMVtpurC7DV2CGZK|_ei>yXKjmwnjT=xjUa4Iia&vRLF8sD#&->=Uvh zXH=0>)tnkY%}%a>sVKufE*RXqip5an0)VLiAejtv>IkLWRt8f}SDDTnQG&Pdcuwb= z4|)qOcmXjlbU~iL@`UPxpDs6L4$I3ZhlbQSS9#MgYlOKDM`T?`zYe&vIm*U}KWvDF AL;wH) literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv415.mid b/data/raw/bach/bwv415.mid new file mode 100644 index 0000000000000000000000000000000000000000..3e3da2a5a85c74c578e7a15137c0854ca7c5bea4 GIT binary patch literal 2704 zcmdUv%T7~K7=^c`ULL{t01bftFkvo_~BFLUE(-?aNC*QgzHWSw^=c7s)sk2Ouyf4kp-U+% z`&90$#Q-o6aOEURm2+7Rc6uMespIqk77E(c#nP36Ck)zpm0v zgF+1z@-2&CfLvnxY{M=a(%u7&u&`K>UoUUq#Z2NO8N-8F^j2F@Ktom@YUSeY2|pQQ zLwF`QVN4o@v80Z8j+QLA%Te#0SuWmrawfIFk~CEe0&*{_T>zuZjsbcOca+u zRHEv{r!N49Nw6%jspyRg%6cX5JBw*CPb(d)jfE@^pTtO;3~wd07(S*8b?C)q1=!*Tzfa7*VrtOK zbqw6=p))B9dfn7K+pi_@% literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv416.mid b/data/raw/bach/bwv416.mid new file mode 100644 index 0000000000000000000000000000000000000000..4511bf2f18760d412b21dd1ff9f409b99b81ddcd GIT binary patch literal 2155 zcmaKs&2Exm5QPVdKR00FMYQE7P@wz-q?DGxN*2nli6$nRVyG8jj0+ZBa7kW@7vUb~ zz~_^Jx3c2o%$b=pGcVtC_UVI}J-3_{3O1cBKbz(L*yiNL+r`)A-TlITnf0?sVYymi~})aG1A-$+(w4bM4>$~Ek+8dDN|gDxrz*R(kvL#0c?ZW z30*!xOA*Q_OCkKk?fa`d_{sJ3OTi3)#9OLmhA5l@DFFC!l+i zg{CQSGltTFFr)*h9C~>{^&*Q+rCSJ$JJhSCAnEi15aQl2q~oWp+1p+jCWteu*Z|Ng zWe8EHtsU-KIMBlRU!j3X!Qn09Qz-jWcsBcZzgQmm2vCw^0_w6>kB(AtO`2NNkbbGq zrH2?1z&blx@b0-~(=!laj?k1?&#fiUauCv;(ee<}y(JqGV+=ruf`l4s(TG_M)!Ac6 z$7;&3v8RstU(eV8)a6IFs0nD{Rr#q#hiJm0ve~Q3lDIbiu}iNDsNjX_Tv&WKuk;Oh zbNBFYf>*<+O4GxQPSll|y#tE}Kvv(&(4u0Imo`znusAy#Enb}zj8n%($ Z($`j=!(ULxunV literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv417.mid b/data/raw/bach/bwv417.mid new file mode 100644 index 0000000000000000000000000000000000000000..6e62f9e051c2bc311b31600af1774e04a67154a6 GIT binary patch literal 3001 zcmds&%}!HM6on6^Dv#hZ@MA+$T1o@`1DZC#LLT70sY(}7Z&eR z1q0GcO+AKPBMQ=D0EofbnF;@oEt0#D1f@&zaU?*ym)?2eQhIdh$N<*s2%fQ6uS4WU zN)ujH$Cfea@iYa{!pG_st~{jjg6>6@HT8|z;`GOQN%z>@m!N`NLiINKd<**Nd#L@@ zdw6#K{_^U2$>(>EsrOW}#|!NV?6Gvo(!+wwpo^s|%PwG7U?0H4@@*PavpU&*xa}yo zP4{*VG(O;|&2zwnyt&5|ldE(c$xD@D3t5GRV_tL2(#r9Dt4>r^pk(pAm~hXN(5r%| z)1@+^B!sIV76)4<$Jo+GK|WyK)ZJ}ymUT~>7Gos6)SZ)X9dFTvRR*)mW7tw9(=lyE zP0l9$7ue)qV03YFv*hTV-=a`Ub2J&KDX!mvMva3Td@8K2TRSFusYsPS}yFdMzO^b=zfWr-~(*eX!fB;&0FCWJiY`}aI5@5^+ zv?RSr_rcqyE`@uk~Nn;`D0%;av#fd3X}a<#07$eGH-04cn(LUN1kdu5Xs% zE`;AK?s`(U?MODOa*3unZO0$;{NJ;yqYY&#m6JA zM!GU^9|Jcu7%YB9(#Nrj3-%eL=$S75vy4kzT&lC3+Pi_p&k!GFsA_*uZfJ0U<_9ja z@}#p)b~-ylgF^4hhgqBx)VV-DUJq`{8^n+CJ{FkZYZBIBTm8F3zqCW;^G{!j7N|?3 zuIl@Me#&ZkgFa-uNgk_;{Tp&M{MYitYSzb{yZAv^ht8d}^AM?UjRDcT-mv`+XvEcn zG)yGU#9#gFQe`;0&i{0@l;#hrvpCkqq+DCF9PVW}lLDYkz2KpUvOjELR2Jy*7&4 zqP50EwR)qvjac3obQYU<<(+bsRlA|9PT@Me?_*L^XqZs6;A*8@o}r^^6IFbyK0A-C z#~^ReC)RU0=zMo7s$SR;>1kh ts>kG0Bf~f^0qhi%AM-elTYy+R+=6(M5oA@?Y&!>ZK2XC7iB;kr{{gtq%YXm? literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv419.mid b/data/raw/bach/bwv419.mid new file mode 100644 index 0000000000000000000000000000000000000000..d01ab839a51abb89af9f8cc9826c7308e9d871c0 GIT binary patch literal 2641 zcmd6pyKWO<5QPV`Tpodz2Z)^b8p|7JZO2;6N-A8yc9B3r0>#MT0W3se35t{yJPhwa z!<(2n-p!|f*=R)-rSj2S&zYHj<%{L}w`TU#9$6IG#d7_@tnt!zkDt9-eOg~$t?ZZC zA4~MJd(-f+-Rmf7ym-E~n_0HC&CCLj%96TeE--hn5Lh@!v+ucUmVM2$rgBZ)1*j=V z&=e?9pFzFPe7ocX~W04mK!TeAh;HHsRea##d@f5>BPVJi9cDsyIQSlzJx)yqAhpV7m@zHzXM$& z-RRHopbr=*ec)MDa4gsH-sP+n^FV0yHF8NF2#6SRkX&8MP{H}TbY1yNbzQRXKmi;V z=SD&5Ffn!kfDa5IMhh$>eK54R6M+*4Z1Aq8g=B`%ldhg;b+oUJgRVf=0k;8Fz`x54 zzq&v5)ty{kU)NkD!r(#IjtGfIOQ01p>xr4T!mKSzJB+EOA1db1W4bCRVL^<$N-YL@ zV);RPu)u?5h_0q|HJxhpwt_vmQpxE^pvKF-S!$rP7!)s-U{(;!(1SHYmU359@1Eb5 k|II3`pe^#+AS#YzIdTgwy0^4S^+NmqoXvqGALO6Szt>^KivR!s literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv42.7.mid b/data/raw/bach/bwv42.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..028907a3e0253869c501c2fc22b1d633dbb00138 GIT binary patch literal 4432 zcma);&1zd$6opS>rOgwBzJw6|6PAr+Sy%`edsGin%>pSDTI^!?0ZPcggA6jrAj3RL z^Co$cx@+kif9!kD&7~tP_SwH{|6E;N|MoVe^h0`<27`2UefN7xJO8G~ogaU`{qye4 z&29Q8rEh8OpT}RG?>tM7uLpzYKfQcN9~Ya4^!FllfipjyZJ*v}o%4;rxg<+JEd|aE zEWr;?D?hFD1X$aAy_E>~DJXx;lC`a@Q-lBK2hRfC87`cLORmca`IO|BR?dC|a-~YO z!B|MFB#)#g7SV%_%o}9FDqwDY=1uBKs=f3U9THn_RE2rIFt~_>uUxXbv);UW(h;!E zYV+Z#afO!U=5yvJ^h;0Q>oT5;&V|d#(Mvv;mR!bsf==6W2r8>w4h{(+;1HLt%bqU` zS|uxb9!LSVyY}2Q8;aGMF`0WdXj5pef;M)Co-WK`%SxUtVZVru1go&8TR#u!aa69r z;FYex;OvjT`cA;qj87G8W-yCjy7`o!CjK@S zQZs;{wP&IO=)tM$I#oWWPRt=%zRD(~eFo9QFXB z18QaJ3i)V8-JO*;-$Tz+m$EXn^4v3O5L&5nT9>h14s8mAmkohu&JBQ@3qZL?f_Ye7 zW!Qa*C>aoHr@5tHQxoL{K^cHm4bTD9Z9-D(%uKkaWxDzDw4NoOdVXqt@Ek@$4yP$z zhbvu&7uUbu+}`#4LzsAbCQ76RN1o^-J)IbwY;^>z%+uKBV@amgF^fUDcqYdaE87oz z%>Bjj+|B$k%6tf9Kee(Xd0GJqn#~1Tw@o_sQ%5I_8lVipfUW`y8^^Bwcw2kP88VMt zvN=QoKR65_$XT>>lZhVyA?O8?i4$w|3oAfS)*fVKfkw_K<8W-x?mLsf{hNBU8_X}< z<%N_P?Vv0_jY@Gi@m@L~+7!k{MCD14d1C-z6`si%&vo(?NGv1(h&pg$2eGH<0P3FN z`NZbl0vwVdIWvb?P0XsMAIC=xNEd3*_1bJS03pT}>v5h3GQR9|M7W zQ_B6?^;vK1GAlz_3f_ BrZ)fp literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv420.mid b/data/raw/bach/bwv420.mid new file mode 100644 index 0000000000000000000000000000000000000000..1bc7adf9b6c0a832845ed7acca3c58847bd5f88e GIT binary patch literal 1984 zcma)*&u$W76ve;NQM;&npMcP`1WKTVLdozi(1xyLq3oJyVxlRA`T(YJ!NNtCzKePwtO$>|yFjK(Pz$M@^GiO4%uS)u8 zM7mr|din(;F7juoe9BNS%)pkgA6|TVgccOgUII@Up&V7Ip{&c99^}}{Be!zv%EJ|Z z+7+YTr!RRYjBzS9r?S9zAL?UJ-*Sc|4-M!l0b@Blg(1lsIZ757%&qgll6xfg3}||f z5gUv`G08{`9+@#4k4#Pt=XN<{1m(%58akjMGE^0WESb;%JsTj{V!M3%7+H>KR@&7> zYH-5BOFQAS+54NtGUqq!ps{0OJ1hif1KI{!gjxogfM&?FVaQQcm#VHYfoH~Gxk5_T zh;#a!XXc#I@XSIj05YT}2Lw`+swU-Le8OnD^hjaM<N04fI5rw&81m==FAeNHJqHP8Sw45T|B6FRm~jXum$pCU{#WYXnT$`Pi}3CxKx zS$o+F*ph0=|B)*3a^op`$*~4ou)CyIQ0P50z%7nojtrCmFo%Fc0|$Tu10_HyWQs8O OQ<~rVP-5M`H}My@1QR#_ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv421.mid b/data/raw/bach/bwv421.mid new file mode 100644 index 0000000000000000000000000000000000000000..7350581b5ce92b604d8e1c60eb098c15b5c3a8aa GIT binary patch literal 1822 zcmaKrO>PrW5QJaC@N)z%VcBtPIsT1*V<$>hcmdu;0tpEeBZmVZ#KH>}EI9->V8aPG z12-}C@rKfiW;ClQbys&)zwWtNzkMA-coL36mW7-3?p+8+Kf>YB(-+$hyW6{M_!YvR zFy?c3bu8N9WtJU3f3^?b7Mp$ev0owU*1v{Ctm|i=91}fy)it*}!B+Om@l-RUw*iG~goa!=e6vXFs*GZ1VnN z)xyTS%UJI+-h7R~Vg_?|Fc)VAc_uIcOa!KYsX!ml7jQ#!TvY_-6ssIbfNWrOiXTMh zh+@n)G2duUF(M9!X!GWHt{HtEjB`Q53so5u$?j9JCwES)O6!4D_wf|@r0EKOYlV;3 zZ|=6cil1)490R!?0Y(CTvn~U574d$0M0$!iWpGC7tTZ(sg@m>Go6m9KT|ktOIwvs1 z#!z5H6@DyH1VvF>wN^5h)*G)?5&);{@EpDR0i@j@X79)@g`mi?;YNvFa!5)0uPW0yrRRwJArvM=BnxIk{Eu i+oG;=%5&LjlZL!c3xFS2HHh%M2}fFR@+toPn12C%itB>_ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv422.mid b/data/raw/bach/bwv422.mid new file mode 100644 index 0000000000000000000000000000000000000000..e34103f8ec6c3327c1a328fe8450441e44f7c47c GIT binary patch literal 2146 zcmcJPO>PrG5QRHt_&EYQ4iH(kEdOL|%ks=<YHvqwLQeFSox`bUcGu<!GiJx0hn zO8tkug1sd^V}gV|xZuWZJG&?UZBL$LA3hy>?>W?Sqs{=CfdYV2b5UKDrEmF>-OjP?!Z$%u6jYA~lM^kkrs3LsEcI_1)K` zD5OhLBkzO4l@%@i4UI0pEx2Um{H zKiE5khjuYbn4}8)d*%2{QvM(Eo4dOsSJGvC*T(k%Jp+9}-+)pBUS$xcdKk1#8_gEP9$EFw4iM3~i~y;FA?@OrGB5glqs^^rmGkYax>2AI`sZ&TB@l%$@b z=d|Xr6g=Qh=kvX8#w7~l^t4jbBg%XaqOGJv;Ik_im}EZ;+go&ou<%}d)}I!NC!&;@kk zoEAAPdr1K_Jlt@|hOo=x(ePH~3Sf|7YYfYw2BPfNMx#oj1w8`cM~s zl2xu8T|*%`x`}2@tBU+<;_ca_M`v$}Fou+l8d?>fh)CtlAcI?rw8ee+R*ogxJZ!4+ zKFR3X20)=c8ooiOVIj?<&e87H*?+rsIxkdsQRfC1qtCH&tD;=V9lobKUNow}u__H_ zfWaiMfXW4=PY%#OS)0B5A6Vd0)uE&G@1jkmM#BFD*NMz#ojZFT|Hhy8@cQ;P$Koxt z!vRe$x97hqj;va!1SlD(04fF)I_2ebn`7nVT+rvjKp9YuLls_pxdA%YD6bhf2b^z{ z4bZ2GQsjuMPI=v4az@q1b4kO?xLl)_2{D*FDt%S1>vl-STMYn?EHl_0<(gRyBk8oe z0d`mCGbqlsFBXEU#>(WVq5A04)h8!0>-0gW!_JcKP|PY^2(Fn$n!}|tsY>!{)SO$C J5VPc6`x_1K@>&1@ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv424.mid b/data/raw/bach/bwv424.mid new file mode 100644 index 0000000000000000000000000000000000000000..def36af0cc3e04c47fac1c7611006d73623474d8 GIT binary patch literal 1847 zcmd6mK~CFX5QPVD3rFY?*hGmCkqB`tr->CSN>*e6-XT#5iHcOA2Z*YwV$p^7JwxwM z^(5TH%;*1S_)|;S6d_i5ntA`cH*ezk;`&NN-ph_ek<1sX8@fL_CT|GD?aRRWLX=Ci8$tK3`!P=U-pz`PwQos-Gej-=n-lt_bdPa literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv425.mid b/data/raw/bach/bwv425.mid new file mode 100644 index 0000000000000000000000000000000000000000..690ad31657c675a5d9ee6ce9b04603af008d2da2 GIT binary patch literal 4879 zcmcJR&1zd$6opR{CGD&o_5m`83G$C3$(AJx$+qGU$S5APngv=Yw8X{f1DMi52pRZ+ zI_RVHP29D#k3XHOdwXLH8ELcs_uA|1tJmkh{FG99oW4q(PI`TQ`D;oK|4ug#zkYM^ z`{mnr7wMmr{!KIg-2C`JZZ|)4IuE}8=0mz(EI*{HMM~Gx<)?Htl`vcWm9AzI<~GeG zoLD%Ku&~L_XBN&RytL`%N+ZD<5+a=1=d{s8W&{!v{=&6htip5k6KmYh+(LAy<|~@{ z^4g~Agz6(ElyHv;RU;F*s zKJ%(7d!_v|*Kb}hvmy{h<}bQM%^EBK4~-F|z6EXO$tpXqYiOUY3p|uMcrKv=!z*Wg zr42FkU1n|B%gs)H!;c>84R_|h{n7S-M=n27d4#bkGnVGa!qJL55=mgsR~(Q3 z#;|5&ghocFKv=d&q^3U;zrIWpqc>5?iGj5+b+y=Z-cZ4ztih*1Sf(JQg!uBP55MSB zC-leU*uwEjqoUTpJjN)53|jj+>&s;dT<#VpbGc};be-(dV8~u z>>Vlzu>~}FuOJPV(I5aY%@zY`)>yQJSQH~>7*33I<@3*?j=g6u0S)ZL#DuUM&5<*I zhLr1T_?@odqw}BNU0k;OpBcELfjZi^urGnPy>B=x8un5^rKo^G&XpH{&)5&yOXU3* zc@!1A&v|I0?t_Lr9HzR7^%e;Qo@*T%#kgX(5BV-A;B)ACB3@1VE>Z&l5D#4JKt4kY z!Qt>vGr-BE^5AcAKg#G2mpxMAQsa&(6$vqUg*LU$-|4Tf6`~H2) zS?rm(JnufsPtO+?k&%idy(=+qAtZA;GoKJhSQ9s+Nkn)hz?P?mqA0i=eyZV0IEhY&U3EsKJRXz-zFOkHDU6nloM z7f^}!Cd{5~0gMD|>QFzm&r_M0XWNOkod|@1k^1%aF*RLf)u`~5@Fs+{yBH`p4RvrX zh$0^og~7lBpDmMNOFn42UUV=|g1JZu8Y3Z5_&hOWPZYIgXFhp;k(qgLu>n_9R0Cl4 u%E|}6VioXk26FNcMYBE68aF4iyCs~2+>;`++SoWO8r9di7$;LuXYoIZKNyq% literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv426.mid b/data/raw/bach/bwv426.mid new file mode 100644 index 0000000000000000000000000000000000000000..1a681966a560e226617a5406f4e72f30205e0018 GIT binary patch literal 2658 zcmaKsOKuub6hvPL`79x8u#G^NuZ$2MArP`hVURGhlt_^hnaIuptSAEyGGLOdCyU4e zvJ+CL`?>rYT8t>YTeoiAPjj{U^dW@sGCT{_YPee6eh#714!h^C-fq6$Uf*oOpAi0q z5kI^46;XHZs@2My*AHR4SU-gOMF`tDU@kBN%u0bdi}jDkEP+DSbiEDt(;(@DyMB3E^Xo;=G_}w!xv$f;2j_qCpusT1-M&)v`90SX@fkpsb&mZq5;KiQr`> zsBxm440zv0Sr>5$&RVjcJsp)OEXt#cgL(+N`s4BZ((zQsU%nl?oDnrf@;U~L1*Yqt z`Rc~&@A=CJkaJWXj>$8!Sg-p@(xc#*xsWvij5vXWttal}@MX;AlQi=6f{zF!6eYuU zf{}@0Uj398q$iXmWU_^ZaE1!)dkkBLhNQz8KpqI#tBc0Zg-{$`5{foFDzD5hhgL0k z*p9R2_{on!AYVeP<^8y2H)v%SO~^9Od=v9=Ju~_$?78eZR6Sox-Ht7$9am6Q*lly0jL4+S_jbK8Q?4n#WvhnBB&7ivEb3~QDm;v pR*ww2LG}D_1oFelW|w%j4I6V8?&}1dlgyz2ohCzwFFqXI_J4r)%ccMT literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv427.mid b/data/raw/bach/bwv427.mid new file mode 100644 index 0000000000000000000000000000000000000000..83dcf1785181d348b4698d331898e45e91bf6833 GIT binary patch literal 2027 zcmbW1!EO?95XS%DYJCLXfHZBOfo`B1y0}6}Q__h_t?YhpIYs$JmBGl#}FtdN_-y5=5Ij7@W^ zt#q*%i(vkUCypn@>XbseYAGGTS9Su89@T6DKY^bvz82X-Xu~||?`)@0>Sv43_Z=B1 zI+CgZA{udwd}R*zWXY8$HT^K6u2H}>REjB*Ayyo!N*k!Sr{obf(5oUcFX0?;NaxVl z+BrO)zr9(mYJT5+^!rwF02p{bheUAr9IMX_D54Dwcq&-;8%o#^+dG4QmRHQ*h*&m} zm_cIpsccp1lSD@`AU4pWP|rXYS{Is<1YEY!$kz3^Q?aMYVadOmoIPC+nXx#&vZ8C> znx%bprXPsxlbC>d)vPf?GrcyXC&#iJ=F#%{oI$^G2EX`McyWDuTXO{}?Nn{B${0?g zoX}Zrd+D*4HalxuM<;+2Z$pm=dl9Y8I@{2WcssJUW5BTiSIE>T)Wwjl0Tp`Scc69b zO|o4gm27Do@^t7mT0~kF(KWi;wI?i=>Ynzcs-5c`L{pCDIAx$yE3JykQLl=~k6nja J?7UU%{0~Z3Cb9qk literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv428.mid b/data/raw/bach/bwv428.mid new file mode 100644 index 0000000000000000000000000000000000000000..6e2e435874e92c3722e8391931dccf0f6b2c8bd6 GIT binary patch literal 2677 zcmcJQPi|6C6vl56txIqPO#`7&N}&Ww`4a+Z(vb}GjclTciKZCp0*rCMzyU*7;5uA` zD{v?De7xIV?(@A~(}5HCa{hhieCJ%aTD*VjoO|Z>T)FJ77OM}=mEO4Rll_;=Ppj*j zrTgXFA2-z3_H}8`K3|o~r5DfFZZk>N?#slv%|KvaU??y&FcugaAZ9Ad)GRZBS?HQ2 z-%`t5U~aBU#axCU5;IRWX%>|MbJbBnEVMBZmztjnWEz7D7gOMhw(19DivQ5z-x@L( zlLCsC;%6UgcCCpRRtaGCJO%m$vg8G~?MU89@*LGu0Kf)5IPA&QHTBHt>CvxAv#U5_X4A|?-l zHT#i^rm%i8Z+NKV$mlanzTR65q|ZA)psAs(fznkl;PRGpxz5eil?dHzjBkUi$T)!r zz72wdec9O!GH3VG&hF{r-OX|p`El#1$KI|-1M0D(W;-FE{hnM3<|HE)vH%@%sd869 zTs`eMW%mlfPG!=uJPJ@SAoU~n)rMYJutT$C9?hek2(qx%0Qky~MwF)xAQ;*1F0-#- zF1yxrI|ejYgrcogwk@VD5d?xde#=>~^ia%(ed3kL39J_BL{? zRrOl6UTXq119gp2H*h3yv~wAdt163vD*~0!(vYQL76wCwmMXW*)l^K=KubUtxJV}k zuArc0NmeW;s&ld{=qVsAdKeb0UBV7HRh?6Fu|g=$PrG5QUq>{2YNJB#|sDcI?ElY)_onR;*-27T{eZkdQzLayUSQSY*M%OD@0} z*m4v$oFlx?Jv{X=&WIfw`>DFB>(#5*bAIvmbqL`}cob^2aDK6P7sAFO+;2X8as6R& zd37Crgzz(D{N2CW*wpXKT5aR`v%9by&+o$RID};e$OJ}!k-!PyM8G*yB2z_9=byvv zslXIK#5q2iaWvD>8C7R1pa{T670I*tGM1lGPA`KQ5pH(G#Ktsb920Yn!M{<>IsadV zp3CG7)~zX@{R9zMoO8Tf1B*~@kw~X|P=1}@+D_d2R|LNc_l-Z!`zGhrj^2N)vYmNk z^DohMLr4$REICpnI#M7yQXmfIi1t(%H5p7fk)i;eNOZ}|lU}-~;QsQFBbLmO4Dyr@ z00V(OpfAt^^aQ$qu7EvyOypRR(fm^!@E8yy;={-u$K+jZ8c9SK#`h^z185;c@l5Oc(&+?;G#1|nz3h3vftK&YgJs^~S~ z2pT44;G4_(jOQzBCIeb2hNZec4OLF`BjJ$uE=@LREB9m+co z44BJeeL4sglOI&9hsSZ5dv$pkag_oE1NJzIZ#U0zF9S35fEiU$AA!F<2Kj}3a-y|0 zV8Pn{PWVErYR*Y{-oiUgzCbd2zhL(7e3?g=H#Zetx3`iBb6NLT#-6lm0-6H5D84Ju z05k-)0owvQfE|HkE2_eymTZq4E_BoKh0dvyTvxJzo9@B~8Ybo{_wsviFW=MTX2!Af ziO@P?PgcX_hg2Qv$WPaNJaU_ywsI|P$(Q+Q-| z_Xb-i#)S<4iz^?wMV%a!_kix@eVIlgl&0Wa?Nh!l;2if#W|vSnVGG5!1nPXN>(Rcy E0eJoGMF0Q* literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv43.11.mid b/data/raw/bach/bwv43.11.mid new file mode 100644 index 0000000000000000000000000000000000000000..ef5f091e32868d8d7e2239a8121bba28ae34b1a4 GIT binary patch literal 2551 zcmd6ny>1#&5QVQXN&E8N{+Qa zV7TDgZ5sc)n3)%=@4kLNWW)ip4y=9%7#hd``#qr?fyh8sg@J}><{iB}z+1FPcsVIU zmII@ZlB1XZ=NOttAVpVdGiyRAjTlpkb}{EjJ~u`{{?om+aDkj&EK@mS7`|$KmdX*M zash>MoWz3}PU5(lPyz?Eh>j9F>8CmA)%?@_VtL>y5rVP=LG=)v@271~CR8~Tv#khMg~ zrgV#uQr&q-x&JP$+~2}_af_6u`;U@f3jfJkj(3MK9t1|;L9|sR?}C&u=+(ywJIA%; zo#PtAe!?kZOa9=;ExUVoIN(V6M&@WCwPi1MnS*AULn~92R$r&8Zpkgy;mgCUO_-*I zYUI?)96JU%QPWUW!;$2uMU-*>quPdArW z*Wq^ve?sPetJjS!{e9JJHeNit3(IMK7rsnGSY`&9z}R3cFfo`2kTY{+rpTGWS^DWL z{}v;2gSkGPJLfzFH97Nq8LQ|Fn7fY~5`o6lvrK+wP$EV$)kU5#QszX8G3#=>&Y!O@iw>mUo)}u;6!L)qe2VFZrx_^6_(>$%dvl zRQD#Od@ADCL}*^J$s0BCdiw zLLnWWj$M9ypIlTWIYs2yB9wACclB^|9$AEVZh^Q(Avk={utu@WuFX={ZatT4A1~fr zUEkFFHtu_~eQky%d)}j`$brFu00#%KS>HJ}@}a@ueU%!zs@jm`YWcwBej>>TA_8j< zOOYs*W{p*az}2(xo_L@Dh9*?iFz&v-MUt%PUYQ8T#EC@U!>_`oD$R;cEC5v`!L%)n+`Z5}S{d+#XyuGb?7%e-prPghOwm`?Lb_Dhe_5`{HU4a7wn;to^ z)UH46>Jvgk5jBaBlc=e3>vH5iM*@i0cErS(p2(_CB_DUaMWiZVs=JPuSk0!}9 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv431.mid b/data/raw/bach/bwv431.mid new file mode 100644 index 0000000000000000000000000000000000000000..34717d6c75ff2d55c08b155f012380d2eba48bd4 GIT binary patch literal 1745 zcmb7@O==rK5QW>$B=He)g~8|tSwcu2%NhwAZ@h{Y&g={h1QMhm=KvvuphXBiN6wH% zZjdYZCUSi}tw)cf40t0ws$NySdNqAL`*7!+d*u#XlDO;H@}qMHbGLr+`t9QL@^-#( zf1P`DWB%6f4%ha3lO%_4j#lm=FIMhr?jkTHGPTGB;KIPP_`Zo4AaY6SvdZ~cazxIH z2RhpfHQHAehDpbm)?;g}hy-1cy86%fATdWP`|S1^Q9iO%2FMINOPI*g6BMr8y0vlr zx4E9=pT5*to)u;l<4@6g>IH?!hzJrR^dI{Q>3TKVJyb#eoT^8&5H4Lz`l${~y%ttK6S#>gj0p(jx zg`L$|!iJF9Co6t!Ow@)}MIYIrs;v02L-s@Cv;N^BPHyk-Yp$wmbXkm@I|%9+P^3+& zZ4nvNhC`%7szMg038!fskyBn|%EdJGg!+^EMlCok-zeyiL@8^+VORsuFpvULUlp`A n5Jc)2aBM*8)u%PrW5QLwDAsm4_SdkOQvSs;i7|V(kDXVw^vx@{05-3Iv2LObS7c5wF47dQN zV9iZTee>Rw#=%%@l2X6!s_JUnSIbu~LI{sSBQ%@gYPo(LLgQQ5J~+N!yI+vi6O{e9MK9zA)y314T$CcK}88kkd=t8xLj5SSOAs)_)W1(ikFlPaDvp~n~S z#AXvF2{-2u<|3Q{qMy$Z`Z*wx2rZEnV$L-6H**FdPZPjI;QzKr z61AW-9-|W=%(UqyY}?g^zUxBGr*GaJI*)y1#h1#N#BeqtDL@8@`$&usU6~ahs}Kct zo*aiId<@^fLA&Cq3}!^9fN3cz^_}d@Y>*RcwBhEo#TcHkcqV{*d#Mtq1olgeVUFVh zjPKJ*PtM2d)OJ@7A2N?8^YzR9(B&R3U*4|P2fkTD91X=}FyK%FReFG)K%btzzyQFL zdwkvz%_BVx2?oLefMzp0U~e{sFrG!@WHzD_c?2R)5;aec9*hkUjXeTr^{GUwsp2VT z?~2E3Q%TDb2DP61%w0sg^-Z0IS00hZPCo8Qe(Ixw|`XIUDkw?4yIBjtrdw zP6b?PkzK2-2+(sv&xt@A&=xo_wNF$$EZ>DW0{sX8ENVhaShR)cj-NI>*zh`Du+Ps6 z*LB4w^e55|J?>9!2WD122b}*yLQhDXVeG7I7T9U-aLX940P%V+Z)&X+czNAFLT=wM literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv433.mid b/data/raw/bach/bwv433.mid new file mode 100644 index 0000000000000000000000000000000000000000..0c4cf66a12a2a4025eaa0dbd1d9a093e88007b00 GIT binary patch literal 3873 zcmd^B%Z?I36s;NB$Hu+iFdYH`0wE0zHX+PrR+N0;o539?o zrTgyOPdDbj&CAmh{C$xmr%xZR-FmXPbvF|i8B=covG`R=jbHFHq z7M=j89Szxi3EC_ciW%5Z89W6MEtt&%1bfahc2nE3G2}$UJ94ai%yUR+)WSS!p`4st zho-nbIVV$BB}L=op#O7g?KmNPd+(7##p2VJGZ+El9iIR)@Ck#l5xE)#u6>qUXFNMY zOwd|VBm?CPm^?soMvhoz1~@7wRZ)wsfm+Wo%CyOp>f_6*x2VZAU^W?% z#|H4X25b>+ZL72U1iOz=kM%tmT~gci9vJk9&^|*U*+N}bFENO2TH55^=29o^^K7eX-DRVq9jD83Cxziy=qmh+|@sMl~%Hz9gt z>H&uhPp1v5tyNw&GIrm?Q`-xVXjh|3FHY?ne^L~e*VjiL91SgEI^?4RJX=tR%0XkAohhCm22W5M0k0#rUceZ!ylrKiQC#QS1 zBM2d&+ByP#OHrGwwPPMT^cw4 zsFe;mit3ScASfI}9j44SMsYI^K3qtmXD7cVC*c4Z>5QH;e-aFi)Z%PBTk@5n>I`vO PiC$X$V`bVNxT?PZUlbXp literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv434.mid b/data/raw/bach/bwv434.mid new file mode 100644 index 0000000000000000000000000000000000000000..cb7c46edb5266ecf8fbc242f1a785a4021a66b8e GIT binary patch literal 2569 zcmds1yG|QX6g-&C;}iG^%U~O9%MbioVOh9}3)l_`5KnG`9lD20m@F7r95`3nBT znb~WGvtHyHQSIow@0r;%nciKS*+<*6D6+|P{?)8dvGx9^FSGCStNWS#GkdZwKkLf^ z!qyj2R5sm=#(2&-!MO)xzCE~p1=l12m>@=3;zH?p zmzw66Ibw@I}aqG>ugZ~OEIYJKLg*ei2wiq literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv435.mid b/data/raw/bach/bwv435.mid new file mode 100644 index 0000000000000000000000000000000000000000..a765c2d7cda7f344f10fb3571daeb4b62cd4ffda GIT binary patch literal 2146 zcmb7EJ5D1}5Nvw~c8@?t2$BUx#`0kN8{0xAA;JMnh6EB42qVJ*5F&6uK+I`43O6xb zGrgsTHw+?jsb6(hz3MkUnqHoZ$f{H%isWcIzY?ju%JR?O}Do!BJYymXL(w! zRAhM)Mb))`3wfEO3wfA`0|%%aXl0zf$irB{2$fM*QGkl$ScM#d1YJpa`vekD=fFdB z9cqPu4#^=HgZ#-4k3v9WVOMCQl&qrPCHC|`F$G9$gbM;#8Vgz0Z9~-!-B2{VzAsx( zlIkFYH~<)AgRIg)rK6P|K(CPFx@;Lm1D^v4k_`+HG}Jo)5M_mH?!!i3kGcTejBE~h z#ORr?YuCwW??VE>9fgz42Fa9Q8m#cj6b-vV4y`(}8RHzTfbA4@A(+)9{e8~3v>81+ut=ff{bPHN7uf_Hl%Y+|J zW@auSZHEolWw#(XTtZ1Z{lxhCpx%NFIHVuPF|9T@NQ{7@tne0HkdX#CG1i-F{hUT0 zWW4bqq8lnGdO;@9gBHH;4!S-CwTGiU@y}$6f0fbM-CfBmX+pKB6I}{l-4}5zDIV1! zU)MQJfPA2WJm|0FZE&`g%&tvTHhraNj&cxd4W4TmSph^FXm2P8-wp58Ko>atFzTqF zeFtDi!4|-l0uHQUGPKyvD|0djvO-SS#R^438?4X|ugnTLoI}sM@Vu*@OER?Q;-2_E Qy7sk;FPq!3IoaF#0Mza}vj6}9 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv436.mid b/data/raw/bach/bwv436.mid new file mode 100644 index 0000000000000000000000000000000000000000..3a71ec08c28237ad38a138fa619ee46b93ebb54b GIT binary patch literal 3140 zcmd^AOHLb65bT&q!Vx$C*&vybWdpWHmM4Reg@6@aB(p;TDN-UFnH&H`S$L6!kC3Bq zl-$Ir^1PIu-6KcJA`7yCQh#1|S67d(CLeCi?3KN+B(bZ>?4w!Zhb?zrUr#^JZtkb{ zWcJf?{#(9pB>4L-Ng8{*b6e!)+#YkY#h73WFd`TMc-J{y=Wq!qOF*s*245iflHd|R z7R3lCUDdtojPIP`9mN#o!X67))T)4g(7RMZKv@EEsri354%Rc~gw<96xD{`y;{{BS z7cup>G2$11D%mo;D66ZbchFdFb6ciCr#nsPG%P2oc7$b>y2Bc|Khh zy(5c2kJWo|Kk8W`S8!H-ub7Uq!leJ*$hZ*+PhdzXR=NeCZtF+{W%Zxbi0I9j=n$|l zmWZSP3ok-38JEfu(Vox`)#hU)4y{mX^UX&VUt%SN_*nM&3sc-YJZ!m@4mHlpXcM#n zWNFdTf<>LlC6T6#N#m>@EgOnPuYb5XJ$S(M13c(oZqn6^T`dyL4%-B4&8L*YT4QSd znNNz#Xmj|A4ghXfbhPLqWnx_0jnoP@tM6ynoW7r)yOh+E=sMNw9c+#Y(884Em)c>6 h>{gEu^o03}H$}g-fO0)m~ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv437.mid b/data/raw/bach/bwv437.mid new file mode 100644 index 0000000000000000000000000000000000000000..3bc5de8ff9c5c41aeeccf4ba9f8c5de32f22a8c8 GIT binary patch literal 5613 zcmb7{&u)`f5XEmHKp&w`5P^c@B-k-d9Lr8(0uij5Me7|>D^+Sms?Y~OsH(E)!iz3g z_EA{(Df$F`h4h^7UVfR+*H~he(ahYLGiUyM&Z~=`en=_ZPhX{tjr8i`>gSa1{*!L* zKKSi(W4W3sJg(lFujPMI*OT*!5n|Mm{u&S6VSY_fZ?YG5zJY&#v<# zErxF9P&AB9gZUu+Wd8osNJ_|5{kfz$vQJ*s580;xYAyu~D@UGf33l^T#gG8iw@PgPb*T_9*b`)X#me zXbRUPtj{u;W6w<9`p#>TaYuH&BoBEaKkL;8K3`!0IAcQ89y{2&_9l1c0Nx*s^ zxDQkFlh;5(UJO0A283WHX_y2Rm{&!DpX1D0(ryNT)kQ;rm1>(?U_<^xtQe9K8H%?SYj#YpJI`5u@Opy9*f=JIRk_8sjgVt?hRiJe^*Bu|W z?)ZPYf=#z}$? z7T)xA=s-3NEaV&jLL;G-6&!1j^$psu=*!SM=3Gw=>}kY;3rk+qY|uK8w!ka||$1 z;jVf04d^<3S3<`^M*_}k;&glrI=+ovkC5MURe1l%rbjYuS=efFNN|pAYqr}a@nO@Z zLvKnT&KewD&!n^OIN;98SD2Vd0)`Zd<9mKvSnWh0OhlyknvRZN{4lJV(z#@$r*fb2xBO<~gu419RC=W?8seyz%`=gtlrkg#W9e*VOL ze-&d>DS<>x ZOdA7@24}E7cIO^9k)cEXL~Q2I$^Q{9)ad{K literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv438.mid b/data/raw/bach/bwv438.mid new file mode 100644 index 0000000000000000000000000000000000000000..9b901ad52a9ef318b2e07099706ed353103d6849 GIT binary patch literal 1633 zcmaKrK~5@R5QJMD^&P=0xKTnt!h|3&0SS@SWAPrYOf)gkh(Qlvj0+YfvhyCEz@vB* z?2j2MKMu}DDm~R*)z!bl(ba{S?bwDzkqt-FYqO0rTWszAo!m{&ZzuL)_GvAC7XLRF z{`X%LZSMV<*}OfT*<;&m-UsxT;5h}ov4fshx_s(7NB~J#IiYg0>{5FM)TPNi$P83P z98J#q8PGNGE&+9EjwTC;Go*d!?Wcg#a87^xl5RR+QzU|wy|S`$W^87Q!|#aSJmRQ* z^H7v;1J#C)Zlgia2_Oye7Y&=Y;IzUnRhkTJ`ll8EPQn@tTqoh2bd9HPj)T;Ox|~Br z5`pLJlddArK$N`{bTZB)I)F}Stiw7~MD9{ajXC(ue4ZmeuD;H5c%D~3&-Uo@b}}t^ z|8@f#pkpk^@zA41KD=sf3&gxlkzqXfFfG4r&0>%yT56$@@&+cd|Ym(0<^R o{A3L**z}0@qtHg-V|8^NYZ)7u56*?1%cxj@O_T=9CopbJ=$9(bOT?pZ6I0;D-=8N^m5KexE-RZN}tIzAJ>s9y> z!mlvk-|lVYkN&<%lFEy-P1sJCoA7lS!gdT83rqkLf$8#FmYM-(ip)vP1!l`_7V-0v zV!w)*Eh-*FFJZnENCBz9AwT&mYfUhQ)yeYvt!Fa}{7XAIkIftWuP$bE%2W@vqZEDR zL)e7ftJ}T))?SnJ)0eWPdWd~A`XVyuF|wW_T|if$O-=hwEZTv2M%0W{lk$r7^Z_tC zG9p5acWE%*6W4$NO1xN-iCQf zK*@xPgNbZN6dS%oA5II0nbo|e#h!`Sp+RKzXkYHM19L|_w$Y(?B5u&?O^UP8*^edk zD*IL(5g<}DW`|B0IA!%i+YvL{ams`8H$F-Ir~zsM zRZ>*}*H}IpkZK;>mLe?GXBQEQ8A3-a+CZzZPYIyj#^B(ATV&yU;MUp-$5pjIUolxS!``RF|VJfY_czNpt8Oq z0%Q*r8G0m`QRHNLD$SrF;9MUcKhSuF(R!qgqi{Tprh1zC(?pwz^jJXKGouE~R6g_M zYk}*1pNb3&1KcY6*0ZUfO1-J*GmY$O1lBW^%}Qlt54A`xv4i}KKDKm^Z1GoGZ)_JI zO!C%E621HOqs}3m2+-3;J>Lk2;2F*^6xm^ZB4;EbWcNf?^<9CkgP^0gmLE85b!w{d z>Aqo+Ob$+~(IXQx$#9%e9Y%zO`YO{Ja3zQF0r180HHziwa}*{Z>wD;URqtZZk)+CP z?L5XM7tjbhPJaICJ9|``KE9>#)z(e5ZhGtLQ(LU%A{qrb#b%dUG3Q!D*dB^R&gc=` z!|V0$#U3ckRJg`s7Hc7fpaT&aLBFZ8=7|oci!`;71c?PC`h_IA2z6-5JQCE+^B*H_ BfSLdR literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv47.5.mid b/data/raw/bach/bwv47.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..d676d0df75f9c33aea509a40c53d3111e71a7960 GIT binary patch literal 1880 zcmaKrO->t85QLw}B;*L(0fFtYY=bf5KWvaCR`G(cLkbd7A{?06W;c~J197649Sijl*u>88ZxnG7~A^Z+Q zKI@M=e`{fVl_WcR?;pd{0G z1Dk@*SWHP!b7j|dx{T8)Btw#xGi^Z;an9JnnRo9vo6b}~_w8`sicwD~JKgI32(L%Eq5*c-hTJwF)9$aZ6!R!D zgv=v3M(5aovtg-X<8ea0D3P_z6Le0>&v$(D@KAB^I%Re1+Ms>IgMCu_7D)lAcP5MF zb&9O=F3Rjhrh5qTPia%CYC&%0DFZA~hiXuTLq$@^7?b%!IENNF02~;Qjg&j5+*u(x oYa>Ln7G<=rxT@T%nX242qt_;aO%rqz#ujqlr28vQbeKQie}07ic>n+a literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv48.3.mid b/data/raw/bach/bwv48.3.mid new file mode 100644 index 0000000000000000000000000000000000000000..b6cd41e2101d50a06f44f198ec55c3dd9a3f3ad0 GIT binary patch literal 1606 zcmaKrO>PrG5QQsYARK`!L`wYs7t0xY?8LGxWrY_oyGTJoB#M#40T5#01ya1^C`fEL zN=_1|zKnV5@qjn>r|wr>uU_|D%syV3*(=+#D6)&$;@WKQ%GNIq-p)TSE^p`d$Lzrd z{H@>bKl<;xDB6GXdTFb1y0oujv(-6p?l1yI4hfKipe>12K0!Qju~wuBs=j9}#;F5M zN9k&-SFv0xY9W|%&eYGD0J-kcXo|qbW>VQu`IITL1GmSSU^Q#;3-e1`m;Yw{$+M1< zn=iY9mJh*zW&?NM19~AyGh}P{oRkB%QjAsN;yFD`=T43}F!po$K;J>-{{oMd7tkkP z#HUo9I;dB%N^`~OkF3{-@|^iG#&`i|z?s7kVA2F}u4$6~WF<`e-V=X0`*1s7@TmXu zwl%BF_Bfk7x>%=(56=64E(4Ktl(4Y~~oG-?Dp-0kW4^-J3LR`j)J!mo$P7 z;*N{kKs&Tr^sHwe81t$uUdmX?z^aE5l7ycrCyA5Qdj`cROySgz1tW zq?s$MRD9(SICQ83b%!cYb&y6gx7cd=mR4deHD@unX5ZqP+h~Za3FH!23mL1?q84^9 znwMBxGJiz*k(VC>#|~wn?4Y@7d?U1I;HTjb%(ZQ`K{*Dl_x{)@$j<@v?J zzMK8Dp?=n{D!=w@{W6Lw&z`RAI!RY{l~@MEip1H-Sdp0O`eKlb@2GXW2j)p=#>=l34^<{pYh??09qs4uQ!KM)u=AOh$q z)$>$W?ft;c777QOId0#mw??B3r zq(;tL2!)dXMG=NlUXJ7y%5#fT)tug4$APA!Ay+N}YBD-+$j5R*xQ>G@XL}@f+$43g zswP9;UE9yO_QqZNc>d;Mv9#ZR_i$N93w69Dpsh$dyBXV~2lJ7WhHTHPfmRIn@y@yr zW~ZjD8V#)r)brCfN;3kgfd7_rOY5|J9TtQ$>!26_zn~9_mAoR=(NNu#p)K81H2$Ur zF?mHFI(PL~(^rZJoS_Q&qU)(S(O35*=ieXt>c;1nmnHUvVoi(HoJUqQ50GP3AyhDob+(4UJ=mQ3r3yyHpVz@RJM&{ zWL*oY*ReW03ieDupAzOO`5c=@13v#5>J`GQfD`58PRckbZ?9Z*ENa^zxe65w8I)K3 zbvKTJy$#kdMNPc7kod;WLT9pA#5{#EWN6V#%9UrY?5u>&kW>Mxf`UBOoL7*;Nlrl) zAgdq)kWr8ZNc$YB^0~!b0)7Fqx){I! literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv55.5.mid b/data/raw/bach/bwv55.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..a1126c8b69903cbb7ded6de11e5087a8e438a417 GIT binary patch literal 2704 zcmd6nO>PrW5QH0NfE0EL^Ncea1YwhuURQTlSGQ-e{P51qp4cNx5?d@cAI)lSZGZCg)%x@1>UwRrW^$@dF2^^Uenc& zJbl8;#9t<>T@EVhL6-w#=qXwCH2f4jrz!8&?9SM^yYAT>m5yW@= z&F}c}^8NLC!)NlIuVoL_Jy#t87t6~9BVIT-HkoG~Tv<^F>CPctb-EPn9`*{|yO0U> zu^bm8J%Q6B{o#d4>N%RvvjH9ClNNzEZRTpnpMTICUt;z}eR*|rQ+bF*(QWL&vNOP$1HCkOX=EYKBGlwKnhsio zS}~~eQumiAO9efP7A?}rYC=A!Q^$JJb$=ROdj1oI(G}2W3 qEE75u?0BdRIPPHwGvVlfniRxdwW!c6PP91h^|#j@t|gpJcE@*arQR3- literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv56.5.mid b/data/raw/bach/bwv56.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..9ccc7a94a9b256a276e72463a6e266ff970c1f8b GIT binary patch literal 2770 zcmd6oyKWOv5QZnlTpodUa1t!9oOSHg+UvU#rNRZciv$u9C`Jx7azT-T!WA{|LBmVX z^CX!0yqlk6tz-!aBv<}4b7sz5{yn~$y?JG3kL<{*RlAxk-zjpr zH~VQlel{;Fzm9D4qFSvyeX_RobiTIL)NDPN-`Q&5Fa@v(##qK~8P7lEFakzy84(T) zfPvlFx(ju;rXpiTeCC!eVYpHt-CEq0TO6aoAL+?W%mmp(8 z`8POHg58)~Oq-ZID5;rCI07&uO*#v}$ABm`7#$WUPn&VJw=*l|Dwhrinf+2SXH5F9uTVmP zGRqQxUy;8j4rr;+K=8mxCqwGtTa`r>$`XKg$^-XD+}~W>4`;7$7Rx;kY|N-)zogCV z^O-py!SZuho?<%xeE%+bu|#!9*x3n|R)7z2o7vAUo_3iB*1=k6ydx@ur>eS%`IB_@w&Ky)?9SesWL^T|0Kn-Yo6z%(Yl%J)K+K6~}eh3>NaVrK{JtVRNTn}TL2^v&f*c~e?sz^&G%o;v*qR~rNUXzVgQTs-a*lzW8oLg~N_8&7;1evWQ#)|f$!1cGZ8W(X+yFevJ*2VC>OBf9t@ zkwcFtwMS$xuk!6NgCZI#@Rid=LsUgR;!x2Chl;rv`$Pcju6hCK64NoJqjE837W<0yNc9BF>5_sx02Id%heg|m$-aRbTEb&^)TBzCi^~c8 z^C|4rlg_Fty`+bhc%S2!)MsR7w?j{1i6gU{(_=sPR;TlHOXvBn^E_U>ys07=vUn;&8D<>r3%WdP@P; zkQm!bbkL%69Z*k!C2Z9W9Z9rQ&Xcrf14}sKJ}&pj-bNeGZ8huwaM)hzbnVjV{`^^k ztDBo6m&+L}SA7G}5U2vG0_Uv$Tp;nWKeK%_;1pE?MU~2_I_&KIdYgU$hYjm=X5%$L zE%j5wVG-GD9hyIbbEc|Oz^Q;ERyT0!0`i5(o-0S4{Um)9p>vf~X=GbHOy!&>FV6ED Danr_4 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv60.5.mid b/data/raw/bach/bwv60.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..a152a19a650e7963da4bcf3bdf19ce081ef698c0 GIT binary patch literal 2759 zcmcJQOKuZU5Jexh2`qt4SXSbH{A>SWId(>P0G>qx2?-Pq#_+vcCWTzy<$Uai~@=YG0~ z|F*AldHeTOp^$s={MK#8%Z6inCZe0ZdYiR3`A3 z9c68{-dk%zekW;L@;8+~vYRUOKYTiLP!W>8MySd&gZ)Dp(lg*`0Q-QM z8maZ8>@`e;l^%QDu^NKu|z2@!V4jh3}$#iO;&|jHIi!v8o1U-xfVF;vm2B(EZf_^S8SIrRs88Rz!?P}QybE;A<030 z=kq+cyuLngkA9<&G`7q?1)LgaL%R)az3CoX5Mk?00BXg*h7e>|02Ko#fD;49fMWwC zK*>Onn=KlsFqLFEBOW@n5;;^=U=}AEh^Kq@b#m&KQzNGa`=HGJrcfq|5~heqC#Nn( zby&x}4a5>X>qj}-e6`e&tXGOCS!dK@YHYQE{Z^}7TxF35#zSvX9hhZ05LCs!>ds=X ntW2c5i+IzMj%p;b+He`xlvM$AOcoN9S#K0+`$e`^jIa0?H*WHt literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv64.2.mid b/data/raw/bach/bwv64.2.mid new file mode 100644 index 0000000000000000000000000000000000000000..583503b7fa74314c7a1403890f23a5528ea96d0b GIT binary patch literal 1741 zcma)+F-{v{5QPV_Bsl_iK$b1bc(K;3);1Ovf+{YO?T~_m1j5KfsVP#pNWl@f2Ms64 z8Muj=k9D4AW#pvt)6ARyy_u)=+4S6hjbm#s z>mQp=FVk8>V8A{DmzRbt{+}TqC)6SD4C6bhyr=FvbIl>k*QR7c;{}}R^bR=vAzFtH zdVrn-NeJkyI(stY!XyK%WXv1|Sg`aSlep9xH3gS%;Cw46|tIimHgCDftnQA8`U$8PhwO z>LE&EDIj&wWx?(n@CraJk!4KD2Q443(pViq#sqSrgQEwP;kv^l>cm-E9apWkXi&06Gp@fR=-Oz@TW!clbO7wt1^gpIdDa&4(_kEl;KxPr6DrQBISih?Rr&EL O{K%m=DSx1872zuivD0Dz literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv64.8.mid b/data/raw/bach/bwv64.8.mid new file mode 100644 index 0000000000000000000000000000000000000000..a3d520e117d43d1a8b3de03aff3880ce0f691d87 GIT binary patch literal 2650 zcmd^=O>R1?|DbtJZ5(lO|M%nEa}RJaefP%9o>{?4CA*j|-kTM7Z1v>%%lXH}_08OV znEkSdkJam9p`&)_ za|aWWC+moVB;rp*uE@D^a5?*GcbDtrFUiwn_ALSGEbz|~J7t|y-y)#udnFqBUT8Q# z4S;f_*cs(#;nRc&Lg{HtIr5GGnR}^Wu0F16WJ_C>|M=s(`=iwV@F~w6a=>7gt`P$g zD>y~05WzJAdPI8u)P`%@LD0vaP+>@)j6g9}na+yHf1;ssEiVwL;5#SMr$bf#IJek7 zfk#ljhnNT+0f=b9ZRMqEm+N#rIVVTS%26cdtDD?QG`t}+y3nAr`1Cn$Ka2znJ()8p zS&j;fVzaZ{%*^I_BhbR4t+cr%DN5h5+URs-Ano$Q+~V_Gu?eVqFH*X zbHTb-H7Rd~Ko{(A!Hgw>!);ok$=_2md_vF{9?=>i`HfAcP8sL=GKP z0aXVzo=DyY>^mp}%IhcJho_u|!3b~22uUv$B#;zuFr8$Ti-u$kXt)Z0q46K?RpCq( z*RTrUlzaGZ&q0p7f#7}uR8@JZ)Bpeg literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv65.2.mid b/data/raw/bach/bwv65.2.mid new file mode 100644 index 0000000000000000000000000000000000000000..02b9539d943da14f68ca8f0758f031d2ac91433e GIT binary patch literal 1543 zcmaJKgnHDrOB;RDqdag zWFN&l*+!BJM)6*@Bh`!`1{ed3EyFuu{3hG*pwTU8CJ;|7WA3CH9vs69TV&`?3j*F5 z!eXdf5!R3DgkX@zY$@}nPHM`7ykjnFuSj;1T>n1tT%XwKzijf}H$bvL?X!S^7%_wx zS;_Rl^bhN5k2@ThWNGK@IvMsE;NZaCp@x7OlUXg`-otv&0&2`i#n71Wx`lNzY;nr# z(9}NkMj!fY_PAKCa=v6A(R?+@f^0N06tf2zA73&K2J!pvhi4yKr@FMCNE< z)X))`3YdyAb%45p8bD2f2jJO}hd^LBVhx67`K*_Rs#xb%R?Iw1$UJ4_DeF2lRWMa$ isBvL|?yN&VO*R;r77n&_ox$kEbsjwBuJ7ai{9)f93ZISu literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv65.7.mid b/data/raw/bach/bwv65.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..ee9faf08076c75fe4409109dd6f7a862ad8df238 GIT binary patch literal 3208 zcmds&O>PrG5QQ7ZK#ss2l94UP@sI2{Gj=RTk+Q-Im|Y~0kU%kVI6#D0c!7i$2yq;a z!c9!Q>ETn4+8QZ4!pcwG)m5)vy&7LH-@S3pJ#$Z7v+1sv>-Wwzez@Ji^OviS>zmt^ z`{mqkm+EKtx?y3vSIuVQ#o@+n(|qIZQ|Gobfti81z&t#;)XAlt02Vq~geUP8d9L!W z?*6I>{^Ik*&lmaDC!FU$ef58q7=6WHp-v^sJhx7zA)O*GU@8r#7Q+dE%sk&GuPIh3 zk*cUhITfg6CLtwA2#9ONSLAu%ObbVC+^$u+^Wf0j*~~tCspGb1j%^oomYHMXAC6QOIR(xskRU*!7B#!h{z-6NPNZ`moTR^V>#MI`ogkE}kF6p}}s#?5)PogW&*%nMOiT+k}@}ITCn6YM0^2)Wb zKE$9HCwQG#Eos==nP=d5QH0hlK2QdgC!eb8N`o(VFW@*urdpqoh4hc)1D?~+c9A5V6@oS(*d1BBfUX0X3P`69ryrBM=oDQ+ zS!4liT!I2oFjszSi9xx6S0i`#jbkeJ9#1{5q#T27s3J}WPG`T%P3a1=$9MYUcltEH zdt9#G`7~Ncwp<|64qNQ7D%@Itf}=|4N@*voK$JS@=q#Ee;&?l2kh{Fpr5F+Lt|C~7 z(IjEhb+q7*Sm?Yx+S#Ij+yx@RFqbmdxmZ1S_ouz{iqmFM?R-+_5MJZ7ac^6Ex?g-^ z+0A?@bk#h^1@;#XP64M5>VRS%=P*wda@9eNC%R4mCk`3_ zI8ltyrAqlvRu+tOT##`TUO?y3?xLt6Mx-1DJSX9~3)Z+3;m-hP4yruu%_Xv)La_Wi E&nJk#MgRZ+ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv67.4.mid b/data/raw/bach/bwv67.4.mid new file mode 100644 index 0000000000000000000000000000000000000000..d0fc2bfc143b8dc03c9a6c5803535eeff7dbb22e GIT binary patch literal 1759 zcmaKrNlrpx5QJNK4oC0|CWhb?0T~{F5W=vLg}O7*#6%+oJb()qEIop2PvK4UCfFZ5 zD!=)W4OFVDyL$Lve|UduX4|%5Nn-us_`z&rYO~zV#pro_^E9$AvmdMTH@n(Q{P!}+ zZSL((?Y(h5wbzCL-j^U_Ixrm%bn(>A;|ABW^no(}f|ckEZWn05b?Rz3aDS zK?jJHC3h9!jB`R7V47!60tKESh&_F;2#)VBr3*rb$8C z$d>6h$S?2l;rB?=$Cq`-sL)5n^J^5U&4Dw33JjrO9uF~wx>qQ^rI>gxVl?U+CZ&yZ zWgBspOto>{pvI)kRiUlmUO%8SgbXLMB$a zyn=Bu3(ZyJba++qsyc`*R7YS{V_t`ctdPX2ET)8M$-;|$^JO(|CX+P>(-`v5#x+mO zC`+1SMm_dk70T04K4fH}Z7MxxR7aYaDPU0uEhJVys(eI;M=s6-XiS;{40R3w2Y)qg m!CZ%g4jo9W)yH$m>x8Tm&x)IuyPivIp;l$O&&d0WGyei&h1&oC literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv67.7.mid b/data/raw/bach/bwv67.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..6e01d08a89f87d5468faa4b8d6008f8ed7bb47bf GIT binary patch literal 1912 zcmc&!J!%4B5FK^%bA((%L=jO$S;a*Zt+GX8CnOL^(4aX$iWHVx<~S(=>2ii#Atx~N zcJ=WsW4?A9eayU>dGp54dHirEBIi<)Adq>yc@!yq$-Z)Ny?)*-S8MqY`H>J```dCw zKW~Dde08~#WU|=F>qI1p03rorfUyFmW{Au*G6k5rz{6pR4GAWT_iQLRg-oX&3n+{! zt8fH2M(PHE=pi&%@-9 zKBV8xQ zXenTXoH|nVl%stzjsjGX(*UQTktRS>K^4Ers>^XqEK*Msw}iqLKyGD<=U$A^pBfgd VX*q2nAcs}#Lsu>5U+dDp=06S52W$WU literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv69.6-a.mid b/data/raw/bach/bwv69.6-a.mid new file mode 100644 index 0000000000000000000000000000000000000000..2e02e608e55b52340671df2c614f243d7ff55822 GIT binary patch literal 2326 zcmd6o&rVul5XA?)ZG8lvfG&vPPY8sdgg+q~qAOV_I}=Ts)QG`8fQv3zbitwz)JN%y zG&twpn_uQuy=yjb^39p~&YYPKE*IbK%FITIl_3h)z{+Ru> zk-l~})rx;!CrS0_aAVuya$_$;v+Y!1>R=`?b8seb=HOi5+`)YL%U|6PoCXiC@9VNN$Y$1QRHTV{Z$F zlcJd$+cokfsDAY&NX8F8$~IsiL4$ZbIsj+|&<327rSHUv*BJZvF+7H8}rwCrxEVTGUES$JM@{mwZSv^1L zsj@&{KpdQB7PuNf(eSt~zkOXkE$$yz>ylp#?hhJWk?tq-o;2qamLibzhPvvkTi#h$ zy=I&|i#nvYRi_>G?7vhLGCGFIqpFTS{-GWCt1wp-?%`q7GwXaDe|qaW|X#DVy9rKbNd#U4rVaekjW9k9{?fxI+jt#-f}}*A~Rb8+6f8< mvil=)Os@5QQ5v`8h)FfGmTtZ28}@u`Q7CCSD}oAth3zL^v`WfJGKwWWkYg6mH_w zo9TRNPs0dU!D^nWtE=k0s_HpkeE;g4d+YXGlDPB5`iFD-CAZyw_i6QOeQ~*Rf1SH? z1AVq%N~Jxw{hTDF5AQebcCh^IZU)ZX4h4n=M$3)685tN0j15c$rlI9bmNT=Q3YUqJ1`3lizEa@cFNI=p-2k8J45uBJ07QjqLGdlvz6>y$f4Cn~uXFAF( z2JY_#-QgA%lEPxDfLWIfWOS^a9Xd~J3ULf%6P33h6n%$#4Cc}&Q^O1OAg_(vR{n27 z&o&|X`187G4cZFbHhrms%HkQFF8^doO(dCmiE{w#C|f5_J{S&v#L6Knps&dNu%5mu zl!a0Oud`+&s6FqAX)k5!EnQi<>5);^QBT|jx&k@^APXX(A@bhWK}(UFb+cr%ZeZsn zB74wWDTtF^f@to*ybI4o3+vJN6w`gfw^k(txa5tAhUISxGz~xz6$21!W)|tnP{hS@oe>}fmSB4 zG(|_s#~@(po$GS0n=_z51mp#vJgT3x$?gOdr5S7cPZvy6L-g+qdYO z*!y#)hyOUkkX3P$9PXU^b?)(hxBU3t%%0nYRjYQl+tys^XOi`VNfoBM~g{WAMw z5&sVFDi{9uZS}J9>gCS%lhxj~6SMtvwX^Ni!Hmc(j7<0hCkDh0B0%I|xcXt+p@Wh- zbI5b&%m7JcZ$YmK=~OOB*I@r)4DGI&7pSrD2^Gn2F=Gq%5_!R55#^OM>e<0;AP8+m5`>0Kl0>+>1y=i{w#APpPaiobi$4;N+AZ$viHaPz%QN zV)zJYTBRdWFU?B<@6fP*}*a}Nw z1FXT^8*W*}kc`+xB%7RbD(_+a^xF+A22Nj08pw&XcvR&K*nyCZS~}%gil+sVvjbl0PEP zW%A8dmpf;#r9AoYX|hQZPLdyK^@raf1Lnb0tcstBz#f_KJQjyz_rU@nVG&Uo^Aj@XM^ejKQI^fwlD65^S_nFFE#@B`q8Jn#dDu{4_Qg6dyV%P4W6 zcc(9&`wj-GUc5?_&6WW~ad~*rh{8e?%>(cu3P4nTcEax!Ng(=znT!7E{N2rBS@JUX z#7EEh=m>Niv;%$oTs9_Ft}3Q#I1d<3OUXtLeIf zhCstX(FJp7U9cmCAMK(XD5@@t00iapw3S(d1$20nwn8nUiu&>QQ$1HTeANNeKbCPa zaqy7ASip}nrtOsaWE(uzQjXoZA)u)I;)1KL|l~uO%=StsP_t6T9eEew7r)ZT~ q8)QZ{RduMH62-{8_%-RLwyT~I6$mM_FzJaBp15;U%?GmC-I>3AAVSjs literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv73.5.mid b/data/raw/bach/bwv73.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..d8796bfd82a61875dbbfa89d8aba814275524227 GIT binary patch literal 2308 zcmc(gOKuZk5QIBs2wVV(J4A}DSkA+-{9tTn6l;_PMuOQz0)zyLk;4HHV&Me~FF6iJ z;UsaoJkFHMQvZP!+hp1hoWo?l+g?3dYZ z>+8?zP3>mKRmT9rDuc_HG6UZE#3!FQc2uvL00{J?%EK_4e#vTFC4uA)c z7C*~b4>I&ZnlHk2SP+2JiKJ@xAadUg2myKF{**>}u{@01iC`2UPGRp*;)hNcTSxnu zYRO|ng0mW#f_*gZ^UUMXH6oQU!N<%589YRuoe?Fa|_{s_3D=9vkM0$Ed{W8$p)^*4q zm;qg-N>?3dch(6A-6#=~>ZnV_v_lwo1u~pRGPd$Kb1DAYoiGQLSq$y#z512odZtg= zi_7clEw|Os!#7+9Pk5@xX&B*>(0ZtvL$Bd(nu;_%!b!ChX?dhBP!B;vS~c`xr?Yab znN9a4e&3}wrCAG-Vs|#h1omp_|C~&KCvK+;88LHg_<@8Stc5wKI8XbYYWBQlWBB_2 F+${uBbCLi6 literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv74.8.mid b/data/raw/bach/bwv74.8.mid new file mode 100644 index 0000000000000000000000000000000000000000..179ae0ed584003bfea1956dc74689672ec79008a GIT binary patch literal 2515 zcmbu9&5jaL5QVSU{yc*3Fc1i71_(dluLHrEl`OP(lV~*242JOmjB&xj#VmaapTS4* zO|TBP=Sw%Y?a{d6EpaomS^ECZ-cNFHbN&T5%4BW%8-cf2#YE*bqZ|zAv+Pt~m z?kc`cLtS-f*FXtopwPfVeI22H1jY!I1y`w(KB-y@N;EMSLMo~D(sGpvW;1}mYLi0AC<%Mu!=p0@wC9C>#zZ)^m#s&+Ui4V6&^6n~K-gkdKB*bGeR~jxjBPmVvfF+dy5Q zZh)#-Ongi>XG(6$VzV@dG1wG$VpG^anJQkuxmuiCi&#M2+X8af67V+6m~4!gILQuvf_7 VkV#>{+=z%|;UY^P$4Bu^ z#&hnyIo@Py=tgK)J)H0V+>`0~^zCaidty75Bz8WXzc*{Vvg*;(7qgG^tLvHlGW%^q z{;6IzsvWB?lccfxY+=iBxv(!|v*jtlDS(&}nGu*Xf-?ucc`zvfChJv8_Cd!9vo~U3 zI71!BtoKvD`l*u=;9pfg{T|xv0qh!`8jjDYOAZx=1Vey~DrAlUAfue9e5I?dSFA3B z808ckR-pB$3@R$5XH}J+P9ZVM32Q8@dcLySXIL%CKYZHeGaX&jhMvQ6WBun0n5L4e!B<8K2c#2f&*t zFvkoX;|%4bWKzdq`whcE#hfZivz#YVDv2kbMtUG;?GYtR%5py}EF@jEkboN2r>kMz z_n|zt;5%6G@$}90Y`*1NS64=h+zmjhj9T569hBAi1ByOyG6K+pSqTqQ{U`^HW6o_2 zrQTh@f7?uF^m$JoyG8&vlj-rvdjN+7hcTmM^-1}=O{t=6DKIF%dp%PAH`p*yU0^U2 zug_$^2LShorUrpEULi>yO~-|6FBW~Y5aP$???>-~AHCx0=4OlGG^|VUy4XxVrN{$e zYM{CLB}N_#9;@_IdBX@WTG6`$d)aB^jdLM zk5wFYe|Oc2``mRu-agU=A?hNg#bln^q>4?d*d)~i)ghpGO45_H8DgVIPB4^H;%TA! QlgR_JpbWS9J#zN?1I`4ge*gdg literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv78.7.mid b/data/raw/bach/bwv78.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..6211b5f4b7db7cf44003547d534f5237ca7fc6ef GIT binary patch literal 2731 zcmdUv%WhI(6oq&3czFchfq(=G1WLG_&=8uAWT4ENXrj>+LmfDD;DBKt$*E&sz$X#+ z>iPZhpZ??wy^L7d|Jt{;7w2;Q=9QT}vJ=ZPyIk+ynbqFf;lbnQ+Yh^|>#cn?`(ac4 z9A4Ibp4j0&K)cTmUodaMP#vYAP(eQoIK7VJ>|?r zo;#VW#pbps_^-{w@T`Lx=@YW#(no5r;7lveVtuHSu6!Z#g_BpRqw6dMbON%NCryXL z6XfX01uxwlG90ql6p-s)x$W)n?6=`Qx#6VxF&Ky^0CpKmm$9n=m?$#w z$V37Oj0Fl#03$_4{xlL2bb5=p@y7>pKacPy2HsWzR)E5pH>n3XeE0M106 zW59Km#iLu?zZYA~rF`iVz!SZQ08k?wF81Gd_us?y>+9{V;&V5Y7lwDj1XDy_xIZk$ z!Bg0c2%MoLSLMDyzYM&WB0Y8Q#ZLo~2Oc54Ct<|-k48;3HC^Ra`I(&pPyC_+t^z(ie!VGZj25eOkZi z(>lMpxv6k=G*B3k#dS0C}J47}~sr!FcRZnuc{`fwG@GLwD^?JBm?>>c4`w{Msp1;|C*E@Q2QRZ=oj7ahE1xWU<(RpF zv#3l~Iflygn!4ar=@WyAz}N-H0waS_TA3CA>QI^PD;NA{Gc!E=l-Zbh!I>7EZ|)+8 z2eOjAloj_9i0b@#vT(tII&=plgNdjZEMO_89xRF?U{N5PG5)TO3LX@9AMTsEgO6Ux z!S&alzaFwLLnC~Zfz-8NAS~6lC;A!VTFk4?d}0lVVX?8VTnB3=yy(ij5HoVH%{nv~ z3Jgr*AUhH8N#7@h?*H``n3a_w3NqoR>Pj9h$OMPy=I}h@P{15=l}I2mEy2XB76475 zml&=nICQ$zVP>ufCOrWftYCl(*SSdNDHp`6fXU|D?>Yj}Z23CG49rHAky+T+l7({#f^F zdDF<4fC+~&d<?4}b^MV+ILIU>QBc8AL4ksT$c-g12`#96=B8(9 pQ(6G3>S*^kYEA-+ZZ?iR#&O6V&jZRuWU2rF literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv81.7.mid b/data/raw/bach/bwv81.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..33b9131bd785c6eac6f5c7b60506fc1fb306dd47 GIT binary patch literal 2749 zcmds%J#HFN6onsz{461DIwWLcV+6+hO$H$h#&!{kWI9WU6e*F3a2DXg1w{%kAx-v? zJ!At}MOtz{-uURjB$GN+9NoWn?>UD#pS^$UoO|L5u2gd8v&9GJiZ9&i(bHG+Pm8PT zx%=+iPZ#mCdQ&VE-0F3yRDAwy>F!6#(%p_+0ER?{78w8r2IA!2-NptYKok~_sTo^j z0+@uUDaBKZoB_@ZOsOGq3Ai+H0k{akH2Lal{-ecCx#HBW(9YseU;qh_shV8sQlciw zoo96nfafuD03*PLaGD%EYIC*}G#?Plie?iDGA zJx=!28Tj+bJ+z=E%d;d9$TAiuUmk?BC%ge{;FbZDGT>8bBxXZYmJ=c(f3uAV*WNJe z4>RlI*}LocBIlbX1GcdezUu%wYhbSd+C00FQlv$yWi?HxY8udvBDhOUH=NVr3EyQY zx->^?Xfb_JvnkaC|DH7s!5>RqJ9k$qil}SC^FPRxC>@Huxas#sL48rGGwkF-#Gm$$Y|VjE(TrAX$e+^JGaKOz62C9In zfjz*UfeN6qj#x2~DqYl+xuZ%up{Z)rB~c`tA~p2FEy2Jvq8eGe$`hC*NTs?< YQ>A1-J&{fAbH%<54D4rem%aOc1M!LD=>Px# literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv83.5.mid b/data/raw/bach/bwv83.5.mid new file mode 100644 index 0000000000000000000000000000000000000000..ba38bab6af669269f3a04138e7288ab84d70e5fb GIT binary patch literal 2020 zcmaKsO>P=d5QHCi@^ggT!9p>J9|Hp#z!sJzufigkoux#Il*mLl2go7|7Fn>&adMMH zK0+=)`r|#9IxuEMsb6Qe}{hp;_)@n-pDb$hoAze4yE z3Vycl>Xx>Bn`QM^FV|r+F4y7PIE2k5;L?K`k(ouV0oMku09OX)fVofBlXw)Fm){?g z4Itslf9^$GRgzFd%rZ8?#>5B}DTovn8JC;KzJ5fB88&EV0-&k@#AK^t2su@`0clC1 z%EmsSY^Yoj@i zSrnKusi~D;z;oew4m%X{kgB02=K#j4Ya5leczRak(AXif%Q3>IR%i~<8nR2&i_$KD zHIJ|nMGeG#Cu0Np8dy%Bs_H>i`LXhNK#A~BLfaJ>W8*1xvw^xBOOntjh$rpTokH!e zox-!lhr8wK$S2>S*UqljeYGJ^%&d<`j8yF~+1GWrhOC^~=Zriq!IC3k(mIFv+^f5Y z9R;Ft*uziHBAQ1|BuXTp)#*u94%k-V(RbiL>a>S3a-`nj7XBNQs>CeO0p;<6M3~IC z@!YOdccNB>R#mbMld&kd3t>0-&Hv_4V0wFhe`N73%34O$1T+mOBGoQ!bnVG)#gdU% zPJ{A>k7#6V%4xL)K&#CVi8T1+sgmd!JZC;42@z`08oh2*qwgWX=9-)xeKk;zS{8{m zk})my$Pk>mRmHn8zz}q8@}p^}uT%OuwPY=ZgFI3FGiH*&2l(NjuqBiW$x=9x*^vG8Toxv1}!-q|>)9 zb^7-0>wD4YJ4oHpT0MZLz?T07s=??e?%-DuZj5*D0f}6g!G#&}i9CeiFvb&%M5@7I z3_qq?^H%0fAkgImZsj4LkgfIx3bfUPp13|COi)K#dfDyji$3Jv@s5;*|G8yQuD6^0Y&rGqPx|I89OaXx;$ mh_rhXKabnOzVh0zQ}hWF@`yUZlOd!{WFDif)MVSb_sI^Rj7y^c literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv85.6.mid b/data/raw/bach/bwv85.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..922cafc275c6d42f11999a24e9c0aed34e463896 GIT binary patch literal 2830 zcma)-Pi~S?6vbaF{#k;1XoC%eK%ps6T4*4o0~si@CYqRNT0>nxV;pp#NjKp>9J>k! zu0uSB_xa0%_qBG!$$R(SbMCqKdrW8V-h>dIgso7igz0SYK7{RWVfpCk%gc|8^NY*y zBZOa}=bz>4?LS*#`KnUce*Wwx+z#e9;d&6l?Ww`3z{p^fo{Z;T!u41u6N8DsaQ-!1 z4+V~Wax6d{K;L!xt6%{KbCqzZPUKP@vyYt>xdhAw`>DAcGc+h?M-MUm`E8WZb>*(o zCkC-{!If7YI>r=8W!O6UN?N|tA3UV5kmXQH_&+I+1L&_CgR8H!sL67obwkSA`TfmMT zo79gBfDt5p752hTUvxow0z?s?t%8d#prByVj%FG+Q=n`!(_R0mU4J}#dvUo4cR#;u zA^=~J-?R-)+0Za(2(Sw|Xn9*(ifJ0eEPHq)$ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv86.6.mid b/data/raw/bach/bwv86.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..060417ebd9a72481c076d3ebc0a48f1e47d8b40d GIT binary patch literal 2632 zcmdUw!A@FX5QV3B+xiH71UE_uNI(Nz2w+rP$)aUvQWKLl(qJFJG+mH%!vpjg`V2lw z--OQL($BfMde^$qlljlgKXc~%my7AmXES?eZ!AgdV!HTZRvFoP=l$jU+v4hWZVzUE zE!DsEr%K{~KPE}#!|u{nC$pv9pI9k46X(o1rvj&uJW^y7BSS@o9!Y0E?LKud5EwY% zXe`b+W)&;H{Kh7lV&YSr3!FP(3L+EDo^c%HIK=@e$PopHsv}iL0y)810rCO{YD~%( zIUIGw={Tn+&~uOqq_(tm^}m_^xS5jv*Y9Oc3b%TT*}iGoE2`Ff?bgndA3;%w5>zsmS$~vR#Tw40nQO%`Xgl>MGlvuE84%JDVQC_ z5P`V>K@As5YVe3r0}c@YS9GOwZcQAK4j>(XysWZ0TV?y&juS2UTOZQF)!ki*BO7X{ z;q%l5>JF*`RR?^YG5$ZHVR^^cH9HrMpuEitBb!DlInk+6( zRY3i)o??ewT09E3ztHAUgV|Aok?{m8C~}IkV{z8R%f~?Y?@&uQj5^a8>0D9MnzWtJ Vv!`p_a1K=PAV&5S*~@x0Ly7N3@vSBr2T z!uQbQ&-zVCZtK_Oa_Q-lRk$6_SK($D5-`9rkfjgk3-so<;if0h1$0wqhmUa{>**YD zE-=A)vatw6%eQE`mqJT2c$FilZ zqQyJyP!uIt8wpUJs1|{okDqi-Jhiy1mOvscEw`EK_~4mz{BZW}YO&n&ZA|Kmswi7m z%QwflrgeqMu@|JTbd` zoUlVbTaT-bHa=ezJ3MgLTwfSLPEyJUIbG;)FG-b2Ep4LxBnsjarrS N?-l<>NSpt+egLI1EBycf literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv88.7.mid b/data/raw/bach/bwv88.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..bc25222ea8c266b70b0fcb43b48d61d247339ff8 GIT binary patch literal 2407 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 YiX!PU4Wx%;Kxf0GY=h>r^=_~BKTeu#I{*Lx literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv92.9.mid b/data/raw/bach/bwv92.9.mid new file mode 100644 index 0000000000000000000000000000000000000000..dfc3482028f7ae1a4967930bc02df98be5e60459 GIT binary patch literal 3082 zcmdUwJ8oKG5QWE>JeH6}U?U^U!-xyHU?D7AnIgHJr9_I9$V4~`Kv4>c6qH#@D%V*> zc0%UkzdriG2&G7oTlwhB{PQ?xuDPCmcxPtM?a0byyPnQJnw5Uq`uN4o?DPEgZe|Z= zzpc-o_1jYE$kuPl<6W&x<`;Zi@e3}${`BS0`6h^%_^N$C-$9CY;h=L7#R&AtAz477eM)&{ zzJ~!V262l4bpqpx(^Pe$kiR0N2@?*QnF~F9kKKEly>`Xir>f@!5q6WMm|h7)`h0yf z*TI&UX_hksz?M6G7+g*O2;K#B9drO42kIX6D$F7EIHaCM-%RP3e>2af@9$>w1OM|o zSjYBV0D2^Vpis^zN1#nk+mi(pl4CtS5ssn@2uk}adMWvWIu{$pKN><}8Z6X^lmFWZ z8*IU-EjDdAXamrv17NQMA?+nu1Qe1f0t$8bB@NPfuOMdLR5z}xmpjt=K(DC9u5t2R zKy}pO-yA@6(cxDhy}iHxn}e1s=h$=Z9*EJbEkeOC2N+g^sX3?ust!&7Cl0h~6H}Yc zH2Bwn@pVAmfhsr12_XlBRJl$;7|m1V*69^J_Z*%VXm}}BXZNsRE`qLKA$=hV?NiL3 w2QM6;kED|+QniAr70)>ZoI21vXE0~Z)EJC{@=Fdj$qAl1K=}fDvH52H08_6$y8r+H literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv93.7.mid b/data/raw/bach/bwv93.7.mid new file mode 100644 index 0000000000000000000000000000000000000000..889cf9a2a98087e3e91858fe1da6b80ad759cf6d GIT binary patch literal 2194 zcmdT^y-pip5L`PK5-Qrf0|gc*|8TZ!Uu=wpWx0q8xXuztNJKa?c>okqxJYp&kCR8q zlf;?v9mASKZh`7XyR-Z4&hFlLdUauDJ65tFu<>+pZC2j3)rU{t=06s*o4Nfl`)gf( zR_En^C0m^ZLHWz)rKP=OX?H!dbVx7+I3+j*7!i!TrN}uU=LDQQ4>AsD8o(sbr=|Zy za*qv@`^Q%S_^L7vlZVXp4oWO)HfGOb^fMutcp#U+C`qX_#1q^35dUln&oz5#Qfu*+ zwmNuRh&?Ps5P$!9CVur+w9E6!<5AXY{VBi&Vq&* zrN^8rPv|VKTB55XuS};<1iGmK<>cM;39@s+TJ$KM!ldvqg*^t_-3u%{U}fwv(Z-~@ zys0iSKCQ(7Yw>Yu0~R^wpd*2nhc98ldf#6033pfu5+8}8{4$QpUl_U?d_Ijs&K3oB-%2LIyrT48Uzi1 zDnS)Mu6F&(hB=vK?;9!m8nBjrYmW1tW-#xDlKd^ nBw+JWQ7090bwY|4QmRa$T;UomHJ{PFfsC9>k&~;q{MNsO`?g3W-yEgAjSntmLA8WcoVGG z{rSt+G~#A>sjuq2s#i6AxBT?M%wF0vtJm#rx%q5Xdt-;^ukP1hHxG|%`(^gq68#+B z*J}RvUAb*1Va-=4k?R(t0Y{$=*G#24)r9SkqC>6cAy*Q+sIQGI=V!(;2}~4eQEV`EeF!V zP6h-}P9*&Ep8Ce39@*kkX!e2T66gy^y*dSMAR3)OaD%I-4I)%UZ3I_Q?@3)-?&@&5 zrNde36O=wYJ)OCmmb`0ueOsXIpd--9869Z5JoTg@F&wAGQw@1%D(|R85w-;+(Gn<$ zHYD1}b3z;37ADddqEVGMRxo>ci5ab?M4K)FbG5OKK1ym8X0$jLrl1_cs!`XP>)HvU zWN+iYwgjUXxgqD}4_eqlgybuUUU_m;RT??ka$v67(vUxrxK#P2159X(r(N9EAEJnM APXGV_ literal 0 HcmV?d00001 diff --git a/data/raw/bach/bwv96.6.mid b/data/raw/bach/bwv96.6.mid new file mode 100644 index 0000000000000000000000000000000000000000..1b90dc290476d36c6a86c0c2ab647251a5cd179c GIT binary patch literal 2173 zcmd6ny-osA5QPU^e_p`EN01PZ5SHHs76^ofN(!YT(Zoap27CYt3knNLAIC>AzQ{TU z){`NNn^>q+e3_Yh@0mHn4u*F(B61`NaU2;8XZIqB4+##AFQ<>Q@nkA*BJbkkC%8@q z2??$oCwX?VlvQiAltoJb&l~6fIvVLB)m7*K5Mi-DTFJuKNCT;cE$$)Gv!{05^ZNCu z7XRbx-?mK6Y=_WC?|s`~A1x!oQ-t3d-BN;!(COr{r04fS?KwE+9!Ugh?+I_P(QsW_GZ}o5*ra^57+fOeEEN08mR1?!^ z>TwP;3LGy}=JoL3_=EA<nI2_(irn8uj09~y@Y}NYXVNKvz6@XNF&0;XC} zZ~>TV38}3)^FqpC#K1Rmw)>L9$D}=;&tukw?q;DQyH=(EWjRE03VA?YAq_|?WB?hP zVh#6(hH(mvuz5b=;$wnG_fJpg6P;tH6rY8c7+nT{v6w-5Yg_c-MA0U)2Ty)_B^kMoa zc@ulj%;d*RK094+RqR6h++s|gTS9Umm_Ga^SdwsL9 z-)8qV(XYe1+L`}+8%4Dj&v&*TCp)_vo9$-;GY4~lxr2qk!ogBt>0p)ow7XS$@*_K; z=2A76X^n%dCV#a^yjVPQffDmP*=HwoKQ%oo&82Y|5P(qtiUG`pQ517El`T_mF%g(J zn5t=Z;{NCaTVQ4>Av1jLQ4q?QCj`t> zaW&D*rBN%2X?n84Lh+=3CJ*&V!B^CrI6N<98+vB1TNB@=Kes~ zS2iA{#f!Bjc-Seg04#-F^hDSz_sR(=CM|_={FMU06bv{}4zs=IfgGwu7EuSW6+R-h zU-}-NUfWgQ1CftG`&K(lz#QL$}}bS)i}`XT(Jv0WGOIH+z?MA?UnPu9M<4! iLkhE3`6`<_(Uxf%E)E%CHtLe0Xm#{ISz(oFM*jdGr^T)S literal 0 HcmV?d00001 From c108850129b7315c98d49fd59f1ca628c364268a Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Sun, 14 Jul 2019 14:53:12 +0200 Subject: [PATCH 18/21] Update readme file again --- README.md | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bc0d7091..7b9c1361 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Composer -Generates video game music using neural networks. +Generate tunable music using neural networks. -https://youtu.be/UWxfnNXlVy8 +Repository to ["Generating Songs With Neural Networks (Neural Composer)"](https://youtu.be/UWxfnNXlVy8). ## How to install @@ -9,27 +9,31 @@ https://youtu.be/UWxfnNXlVy8 ## How to run -* Find some dataset to train on. More info on where to find datasets are in data/raw/README.md. +* Find some dataset to train on. More info on where to find datasets can be found in data/raw/README.md. A default bach dataset is included in the repository. * Run preprocess_songs.py. This will load all midi files from your midi files folder data/raw/ into data/interim/samples.npy & lengths.npy. - You can point the script to a location using the --data_folder flag one or multiple times to append more folders. + You can point the script to a location using the --data_folder flag one or multiple times to make it include more paths to index midi files. * Run train.py. This will train your network and store the progress from time to time (EPOCHS_TO_SAVE to change storing frequency). Only stops if you interrupt it or after 2000 epochs. -* Run composer.py --model "e1/" where "e1/" indicates the folder the stored model is in. +* Run composer.py --model_path "e300" where "e300" indicates the folder the stored model is in. Look into the results/history folder to find your trained model folders. ## Composer -The Composer script will load your trained model with is -music generator trained on the midi files you provided. -Internally, the model tries to compress a song into only 120 numbers. -The sliders adjust those numbers and are ordered from most -important (left) to least important (right). Just the +The Composer script will load your model trained on the midi files you provided +into the music generator. +Internally, the model tries to compress a song into only 120 numbers called the latent space. +Seen from the other perspective, the latent space numbers encode each song that the model +is trained on. Changing the latent numbers allows us to sample new, unknown songs. +To make the sampling more efficient, we use PCA, a way to extract the dimensions in which there is +most variations across all songs, to make the influence on the new songs strong. +The sliders in the composer adjust those numbers and are ordered from most +important/influential (left) to least important/influential (right). Just the top 40 are shown on screen. For more details about how this works and other fun projects, please check out my YouTube channel 'CodeParade'. Have fun making music! ========================================================= ``` -Controls: +Composer Controls: Right Click - Reset all sliders 'R' - Random Song 'T' - Randomize off-screen sliders @@ -43,3 +47,12 @@ Controls: '3' - Triangle wave instrument '4' - Sine wave instrument ``` + +## Pretrained models + +Below are some pretrained models for different datasets. To use the model, download the zip from the +link below and extract it into the results/history folder of your project. The zip should contain a folder +named e and some number, indicating the number of epochs the model was trained and some model.h5. +Pay attention when extracting the model not to override one of your own trained, most beloved models! + +* Bach dataset: https://drive.google.com/open?id=1lED0aiHyG81NHhMUD56bUm0CwZIG4X74 From 9f3ca10f7b3a5e29b0e3c9086d5380968de65f18 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Sun, 14 Jul 2019 15:44:44 +0200 Subject: [PATCH 19/21] Update requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0db5d285..730f2daf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,8 +4,9 @@ pyaudio==0.2.11 pydot==1.4.1 keras==2.2.4 +tensorflow==1.14.0 pyaudio==0.2.11 -numpy==1.14.3 +numpy==1.16.4 mido==1.2.9 From 9e7b681ed3b5e23ba372180ffb41ce94fdd0f268 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Sun, 14 Jul 2019 15:45:53 +0200 Subject: [PATCH 20/21] Make composer more verbose and robust to missing /data/interim/samples&lengths --- composer.py | 71 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/composer.py b/composer.py index 77b03445..4cd9f685 100644 --- a/composer.py +++ b/composer.py @@ -85,6 +85,7 @@ current_params = np.zeros((num_params,), dtype=np.float32) current_notes = np.zeros((num_measures, note_h, note_w), dtype=np.uint8) cur_controls = np.array(control_inits, dtype=np.float32) +songs_loaded = False # setup audio stream audio = pyaudio.PyAudio() @@ -331,6 +332,7 @@ def play(): global prev_mouse_pos global audio_reset global instrument + global songs_loaded print("Keras version: " + keras.__version__) @@ -343,14 +345,10 @@ def play(): [model.layers[-1].output]) print("Loading gaussian/pca statistics...") - latent_means = np.load(dir_name + sub_dir_name + 'latent_means.npy') - latent_stds = np.load(dir_name + sub_dir_name + 'latent_stds.npy') - latent_pca_values = np.load(dir_name + sub_dir_name + 'latent_pca_values.npy') - latent_pca_vectors = np.load(dir_name + sub_dir_name + 'latent_pca_vectors.npy') - - print("Loading songs...") - y_samples = np.load('data/interim/samples.npy') - y_lengths = np.load('data/interim/lengths.npy') + latent_means = np.load(dir_name + sub_dir_name + '/latent_means.npy') + latent_stds = np.load(dir_name + sub_dir_name + '/latent_stds.npy') + latent_pca_values = np.load(dir_name + sub_dir_name + '/latent_pca_values.npy') + latent_pca_vectors = np.load(dir_name + sub_dir_name + '/latent_pca_vectors.npy') # open a window pygame.init() @@ -410,26 +408,41 @@ def play(): audio_reset = True if event.key == pygame.K_o: # KEYDOWN O - # check how well the autoencoder can reconstruct a random song - print("Random Song Index: " + str(random_song_ix)) - if is_ae: - example_song = y_samples[cur_len:cur_len + num_measures] - current_notes = example_song * 255 - latent_x = encoder.predict(np.expand_dims(example_song, 0), batch_size=1)[0] - cur_len += y_lengths[random_song_ix] - random_song_ix += 1 - else: - random_song_ix = np.array([random_song_ix], dtype=np.int64) - latent_x = encoder.predict(random_song_ix, batch_size=1)[0] - random_song_ix = (random_song_ix + 1) % model.layers[0].input_dim - if use_pca: - current_params = np.dot(latent_x - latent_means, latent_pca_vectors.T) / latent_pca_values - else: - current_params = (latent_x - latent_means) / latent_stds - - needs_update = True - audio_reset = True + if not songs_loaded: + print("Loading songs...") + try: + y_samples = np.load('data/interim/samples.npy') + y_lengths = np.load('data/interim/lengths.npy') + songs_loaded = True + except Exception as e: + print("This functionality is to check if the model training went well by reproducing an original song. " + "The composer could not load samples and lengths from model training. " + "If you have the midi files, the model was trained with, process them by using" + " the preprocess_songs.py to find the requested files in data/interim " + "(Load exception: {0}".format(e)) + + if songs_loaded: + # check how well the autoencoder can reconstruct a random song + print("Random Song Index: " + str(random_song_ix)) + if is_ae: + example_song = y_samples[cur_len:cur_len + num_measures] + current_notes = example_song * 255 + latent_x = encoder.predict(np.expand_dims(example_song, 0), batch_size=1)[0] + cur_len += y_lengths[random_song_ix] + random_song_ix += 1 + else: + random_song_ix = np.array([random_song_ix], dtype=np.int64) + latent_x = encoder.predict(random_song_ix, batch_size=1)[0] + random_song_ix = (random_song_ix + 1) % model.layers[0].input_dim + + if use_pca: + current_params = np.dot(latent_x - latent_means, latent_pca_vectors.T) / latent_pca_values + else: + current_params = (latent_x - latent_means) / latent_stds + + needs_update = True + audio_reset = True if event.key == pygame.K_m: # KEYDOWN M # save song as midi @@ -522,8 +535,8 @@ def play(): if __name__ == "__main__": # configure parser and parse arguments parser = argparse.ArgumentParser(description='Neural Composer: Play and edit music of a trained model.') - parser.add_argument('--model', default=sub_dir_name, type=str, help='The folder the model is stored in.') + parser.add_argument('--model_path', type=str, help='The folder the model is stored in (e.g. a folder named e and a number located in results/history/).', required=True) args = parser.parse_args() - sub_dir_name = args.model + sub_dir_name = args.model_path play() From 9885a53cf0f2c5a0abca4987aa1cc0718e41b362 Mon Sep 17 00:00:00 2001 From: Benjamin Ellenberger Date: Sun, 14 Jul 2019 15:49:19 +0200 Subject: [PATCH 21/21] Update pretrained bach model --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b9c1361..c027352c 100644 --- a/README.md +++ b/README.md @@ -55,4 +55,4 @@ link below and extract it into the results/history folder of your project. The z named e and some number, indicating the number of epochs the model was trained and some model.h5. Pay attention when extracting the model not to override one of your own trained, most beloved models! -* Bach dataset: https://drive.google.com/open?id=1lED0aiHyG81NHhMUD56bUm0CwZIG4X74 +* Bach dataset: https://drive.google.com/open?id=1P_hOF0v55m1Snzvri5OBVP5yy099Lzgx