-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse_midi.py
98 lines (69 loc) · 2.8 KB
/
parse_midi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# -*- coding: utf-8 -*-
"""parse_midi.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1J4qWqXuOMS-e650qjnbSAk2C8B7CRpkW
"""
# !pip install tensorflow-gpu==2.0.0-alpha0
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Dense, GRU, Dropout, Embedding
from music21 import converter, instrument, note, chord, pitch
from google.colab import drive
import numpy as np
import time
import glob
import pickle
drive.mount('/content/gdrive')
data_path = "/content/gdrive/My Drive/Applied Deep Learning/Data/"
def get_notes(filename):
notes = []
midi = converter.parse(filename)
notes_to_parse = None
try: # file has instrument parts
s2 = instrument.partitionByInstrument(midi)
notes_to_parse = s2.parts[0].recurse()
except: # file has notes in a flat structure
notes_to_parse = midi.flat.notes
for element in notes_to_parse:
new_chord = [-1] * 6 # 5 pitches + 1 duration
if isinstance(element, note.Note):
new_chord[0] = element.pitch.ps
new_chord[5] = float(element.duration.quarterLength)
# new_chord[5] = round(float(element.duration.quarterLength), 3)
notes.append(new_chord)
elif isinstance(element, chord.Chord):
new_chord[5] = float(element.duration.quarterLength)
# new_chord[5] = round(float(element.duration.quarterLength), 3)
for k in range(len(element.pitches)):
new_chord[k] = element.pitches[k].ps
if k >= len(new_chord) - 1:
break
notes.append(new_chord)
return notes
from magenta.music import abc_parser as abc_parser
import numpy as np
MAX_NOTES = 2500
NUM_PARAM = 5 + 1 # 5 pitches + 1 duration
# 3D numpy array: num songs x MAX_NOTES x NUM_PARAM
all_songs_data = np.empty((1, MAX_NOTES, NUM_PARAM), np.float64)
for f in glob.glob(data_path + '*.mid'):
song_notes = get_notes(f)
temp_data = np.empty((1, 1, NUM_PARAM), np.float64)
notes_data = np.zeros((1, MAX_NOTES, NUM_PARAM)) - 1
for elem in song_notes:
# Convert notes into a 2D numpy array
# The 1st dimension is 5 pitches and 1 duration
# The 2nd dimension is the number of notes
raw_notes = np.array([[elem]])
temp_data = np.append(temp_data, raw_notes, axis=1)
temp_data = temp_data[:, 1:, :]
notes_data[0, :temp_data.shape[1],:temp_data.shape[2]] = temp_data
# print('notes_data = ', notes_data)
all_songs_data = np.append(all_songs_data, notes_data, axis=0)
all_songs_data = all_songs_data[1:,:,:]
all_songs_data.shape
preprocessed_path = "/content/gdrive/My Drive/Applied Deep Learning/Outputs/"
import pickle
pickle.dump( all_songs_data, open( preprocessed_path + "all_songs_data.p", "wb" ) )
all_songs_data = pickle.load( open( preprocessed_path + "all_songs_data.p", "rb" ) )