forked from Agerrr/Automated_Music_Transcription
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plotNotes.py
194 lines (177 loc) · 5.86 KB
/
plotNotes.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
from first_peaks_method import MIDI_Detector
#from least_squares_method import Highest_Peaks_MIDI_Detector
import sys
import os
#from least_squares_first_peaks_2 import MIDI_Detector_Least_Squares_2
#from least_squares_highest_peaks_2 import Highest_Peaks_Least_Squares
class NotePlotter(object):
"""
Class used for plotting sheet notes given MIDI note numbers.
"""
def __init__(self, wav_file):
print 'Inside Note Plotter constructor'
self.wav_file = wav_file
self.output_file = wav_file[:-3] + 'ly'
self.number2note = {
21: 'a,,,',
22: 'ais,,,',
23: 'b,,,',
24: 'c,,',
25: 'cis,,',
26: 'd,,',
27: 'dis,,',
28: 'e,,',
29: 'f,,',
30: 'fis,,',
31: 'g,,',
32: 'gis,,',
33: 'a,,',
34: 'ais,,',
35: 'b,,',
36: 'c,',
37: 'cis,',
38: 'd,',
39: 'dis,',
40: 'e,',
41: 'f,',
42: 'fis,',
43: 'g,',
44: 'gis,',
45: 'a,',
46: 'ais,',
47: 'b,',
48: 'c',
49: 'cis',
50: 'd',
51: 'dis',
52: 'e',
53: 'f',
54: 'fis',
55: 'g',
56: 'gis',
57: 'a',
58: 'ais',
59: 'b',
60: 'c\'',
61: 'cis\'',
62: 'd\'',
63: 'dis\'',
64: 'e\'',
65: 'f\'',
66: 'fis\'',
67: 'g\'',
68: 'gis\'',
69: 'a\'',
70: 'ais\'',
71: 'b\'',
72: 'c\'\'',
73: 'cis\'\'',
74: 'd\'\'',
75: 'dis\'\'',
76: 'e\'\'',
77: 'f\'\'',
78: 'fis\'\'',
79: 'g\'\'',
80: 'gis\'\'',
81: 'a\'\'',
82: 'ais\'\'',
83: 'b\'\'',
84: 'c\'\'\'',
85: 'cis\'\'\'',
86: 'd\'\'\'',
87: 'dis\'\'\'',
88: 'e\'\'\'',
89: 'f\'\'\'',
90: 'fis\'\'\'',
91: 'g\'\'\'',
92: 'gis\'\'\'',
93: 'a\'\'\'',
94: 'ais\'\'\'',
95: 'b\'\'\'',
96: 'c\'\'\'\'',
97: 'cis\'\'\'',
98: 'd\'\'\'',
99: 'dis\'\'\'',
100: 'e\'\'\'',
101: 'f\'\'\'',
102: 'fis\'\'\'',
103: 'g\'\'\'',
104: 'gis\'\'\'',
105: 'a\'\'\'',
106: 'ais\'\'\'',
107: 'b\'\'\'',
108: 'c\'\'\'\'',
}
def plot_notes_violin_stuff(self):
"""
Given .wav file detect MIDI notes, convert them into corresponding
character names. Afterwards plot and save into an output file.
The class uses lilypond library for drawing sheet notes.
"""
#detector = MIDI_Detector(self.wav_file)
detector = MIDI_Detector(self.wav_file)
midi_numbers = detector.detect_MIDI_notes()
lilypond_text = '\\version \"2.14.2\" \n{ \n \\clef treble \n'
for n in midi_numbers:
if n in self.number2note.keys():
lilypond_text += self.number2note[n] + ' '
lilypond_text += '\n}'
with open(self.output_file, 'w') as f:
f.write(lilypond_text)
command = "lilypond "
command += self.output_file
print command
os.system(command)
def plot_notes(self):
detector = MIDI_Detector(self.wav_file)
#detector = Highest_Peaks_MIDI_Detector(self.wav_file)
midi_numbers = detector.detect_MIDI_notes()
lilypond_text = '\\version \"2.14.2\" \n'
lilypond_text += ' \\new PianoStaff { \n'
lilypond_text += ' \\autochange { \n <'
for n in midi_numbers:
if n in self.number2note.keys():
lilypond_text += self.number2note[n] + ' '
lilypond_text += '> \n} \n}'
with open(self.output_file, 'w') as f:
f.write(lilypond_text)
command = "lilypond "
command += self.output_file
print command
os.system(command)
def plot_multiple_notes(self, directory):
"""
Plots notes using LilyPond library. The notes are on a left and righ
hand staff (piano) and may be plotted as chords (multiple notes
played simultaneously). The generated sheet notes are named after
the music file.
"""
lilypond_text = '\\version \"2.14.2\" \n'
lilypond_text += '\\score { \n'
lilypond_text += ' \\new PianoStaff { \n'
lilypond_text += ' \\autochange { \n'
numOfFiles = len(os.listdir(directory))
#for file_path in sorted(os.listdir(directory)):
for i in range(numOfFiles):
file_path = 'note' + str(i) + '.wav'
detector = MIDI_Detector(directory + '/' + file_path)
midi_numbers = detector.detect_MIDI_notes()
print 'File: ' + str(file_path) + ' MIDI: ' + str(midi_numbers)
if len(midi_numbers) > 0:
lilypond_text += ' < '
for n in midi_numbers:
if n in self.number2note.keys():
lilypond_text += self.number2note[n] + ' '
lilypond_text += ' >'
lilypond_text += ' \n} \n}'
lilypond_text += '\\layout { } \n \\midi { } \n}'
with open(self.output_file, 'w') as f:
f.write(lilypond_text)
command = "lilypond "
command += self.output_file
print command
os.system(command)
if __name__ == '__main__':
wav_file = sys.argv[1]
note_plotter = NotePlotter(wav_file)
note_plotter.plot_multiple_notes()