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
|
#!/usr/bin/env python
import tree
from ply import lex, yacc
class Note():
def __init__(self, value, duration=1, octave=8):
self.value = value
self.duration = duration
self.octave = octave
def __repr__(self):
return "Note %s %s %s" % (self.value, self.duration, self.octave)
class Chord():
def __init__(self, value, duration=1, chord_type="major", octave=5):
self.value = value
self.duration = duration
self.chord_type = chord_type
self.octave = octave
def __repr__(self):
return "Chord %s %s %s" % (self.value, self.duration, self.chord_type, self.octave)
class Rest():
def __init__(self, duration=1):
self.duration = duration
def __repr__(self):
return "Rest node %s" % self.duration
def parse(score, default_octave=8):
# Tokenize (lex)
tokens = (
"NOTE_LENGTH",
"BASENOTE",
"ACCIDENTAL",
"REST",
"OCTAVE",
"CHORD_TYPE",
"PAREN",
"SYNCOPATE",
"NODE",
)
t_ignore = " |"
t_BASENOTE = r"[A-Ga-g]"
# t_BASENOTE = r"I+V?|VI*|i+v?|vi*"
t_ACCIDENTAL = r"\^{1}|_{1}|="
t_REST = r"z"
t_OCTAVE = r"'+|,+"
t_CHORD_TYPE = r"m|7|m7|0|o|\+|mb5|sus|sus4|maj7|mmaj7|7sus4|dim|dim7|7b5|m7b5|6|b6|m6|mb6|46|maj9|9|add9|7b9|m9"
t_PAREN = "\[|\]"
t_SYNCOPATE = "\+|-"
t_NODE = r"\([a-zA-Z0-9_-]+\)"
def t_NOTE_LENGTH(t):
r"/?\d+"
multiplier = float(t.value.strip("/"))
if t.value.startswith("/"):
|
>
|
|
>
>
|
|
<
<
|
|
|
|
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
|
#!/usr/bin/env python
import tree
from ply import lex, yacc
class Note():
def __init__(self, value, duration=1, octave=8):
self.duration = duration
if value > 12:
self.duration += 1
value = value % 12
self.value = value
self.octave = octave
def __repr__(self):
return "Note %s %s %s" % (self.value, self.duration, self.octave)
class Chord():
def __init__(self, notes, duration=1):
self.notes = notes
self.duration = duration
def __repr__(self):
return "Chord %s" % (self.notes)
class Rest():
def __init__(self, duration=1):
self.duration = duration
def __repr__(self):
return "Rest node %s" % self.duration
def parse(score, default_octave=8):
# Tokenize (lex)
tokens = (
"NOTE_LENGTH",
"BASENOTE",
"ACCIDENTAL",
"REST",
"OCTAVE",
"CHORD_TYPE",
"BRACKET",
"SYNCOPATE",
"NODE",
)
t_ignore = " |"
t_BASENOTE = r"[A-Ga-g]"
# t_BASENOTE = r"I+V?|VI*|i+v?|vi*"
t_ACCIDENTAL = r"\^{1}|_{1}|="
t_REST = r"z"
t_OCTAVE = r"'+|,+"
t_CHORD_TYPE = r"m|7|m7|0|o|\+|mb5|sus|sus4|maj7|mmaj7|7sus4|dim|dim7|7b5|m7b5|6|b6|m6|mb6|46|maj9|9|add9|7b9|m9"
t_BRACKET = r"\[|\]"
t_SYNCOPATE = "\+|-"
t_NODE = r"\([a-zA-Z0-9_-]+\)"
def t_NOTE_LENGTH(t):
r"/?\d+"
multiplier = float(t.value.strip("/"))
if t.value.startswith("/"):
|
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
'''
new_note = p[1]
new_note.duration = p[2]
p[0] = new_note
def p_chord(p):
'''chord : PAREN note PAREN
| PAREN note CHORD_TYPE PAREN
'''
pitch = p[2].value
pitch = pitch.upper()
p[0] = Chord(value=pitch, octave=default_octave)
if len(p) > 3:
p[0].chord_type = p[3]
def p_note_syncopate(p):
''' note : note SYNCOPATE
'''
note.syncopate = p[2]
|
|
|
|
>
|
>
|
|
|
|
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
'''
new_note = p[1]
new_note.duration = p[2]
p[0] = new_note
def p_chord(p):
'''chord : BRACKET note BRACKET
| BRACKET note CHORD_TYPE BRACKET
'''
root_note = p[2].value
chorded_notes = []
for offset in [0, 4, 7]:
chorded_notes.append(Note(root_note+offset, octave=p[2].octave))
p[0] = Chord(notes=chorded_notes)
def p_note_syncopate(p):
''' note : note SYNCOPATE
'''
note.syncopate = p[2]
|