music-transcription 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +34 -0
  3. data/lib/music-transcription/change.rb +2 -2
  4. data/lib/music-transcription/meter.rb +3 -4
  5. data/lib/music-transcription/note.rb +1 -2
  6. data/lib/music-transcription/parsing/articulation_parsing.rb +266 -0
  7. data/lib/music-transcription/parsing/articulation_parsing.treetop +61 -0
  8. data/lib/music-transcription/parsing/convenience_methods.rb +83 -0
  9. data/lib/music-transcription/parsing/duration_nodes.rb +23 -0
  10. data/lib/music-transcription/parsing/duration_parsing.rb +207 -0
  11. data/lib/music-transcription/parsing/duration_parsing.treetop +27 -0
  12. data/lib/music-transcription/parsing/link_nodes.rb +37 -0
  13. data/lib/music-transcription/parsing/link_parsing.rb +272 -0
  14. data/lib/music-transcription/parsing/link_parsing.treetop +35 -0
  15. data/lib/music-transcription/parsing/nonnegative_integer_parsing.rb +57 -0
  16. data/lib/music-transcription/parsing/nonnegative_integer_parsing.treetop +13 -0
  17. data/lib/music-transcription/parsing/note_nodes.rb +64 -0
  18. data/lib/music-transcription/parsing/note_parsing.rb +354 -0
  19. data/lib/music-transcription/parsing/note_parsing.treetop +47 -0
  20. data/lib/music-transcription/parsing/pitch_node.rb +20 -0
  21. data/lib/music-transcription/parsing/pitch_parsing.rb +355 -0
  22. data/lib/music-transcription/parsing/pitch_parsing.treetop +45 -0
  23. data/lib/music-transcription/parsing/positive_integer_parsing.rb +95 -0
  24. data/lib/music-transcription/parsing/positive_integer_parsing.treetop +19 -0
  25. data/lib/music-transcription/part.rb +1 -1
  26. data/lib/music-transcription/program.rb +1 -4
  27. data/lib/music-transcription/score.rb +1 -1
  28. data/lib/music-transcription/validatable.rb +16 -1
  29. data/lib/music-transcription/version.rb +1 -1
  30. data/lib/music-transcription.rb +14 -0
  31. data/music-transcription.gemspec +2 -0
  32. data/spec/parsing/articulation_parsing_spec.rb +23 -0
  33. data/spec/parsing/convenience_methods_spec.rb +89 -0
  34. data/spec/parsing/duration_nodes_spec.rb +83 -0
  35. data/spec/parsing/duration_parsing_spec.rb +70 -0
  36. data/spec/parsing/link_nodes_spec.rb +30 -0
  37. data/spec/parsing/link_parsing_spec.rb +23 -0
  38. data/spec/parsing/nonnegative_integer_spec.rb +11 -0
  39. data/spec/parsing/note_nodes_spec.rb +84 -0
  40. data/spec/parsing/note_parsing_spec.rb +43 -0
  41. data/spec/parsing/pitch_node_spec.rb +32 -0
  42. data/spec/parsing/pitch_parsing_spec.rb +23 -0
  43. data/spec/parsing/positive_integer_spec.rb +17 -0
  44. data/spec/spec_helper.rb +12 -0
  45. metadata +59 -2
@@ -0,0 +1,35 @@
1
+ module Music
2
+ module Transcription
3
+ module Parsing
4
+
5
+ grammar Link
6
+ include Pitch
7
+
8
+ rule link
9
+ slur_link / tie / legato_link / glissando / portamento
10
+ end
11
+
12
+ rule slur_link
13
+ "=" target:pitch <SlurNode>
14
+ end
15
+
16
+ rule tie
17
+ "=" <TieNode>
18
+ end
19
+
20
+ rule legato_link
21
+ "-" target:pitch <LegatoNode>
22
+ end
23
+
24
+ rule glissando
25
+ "~" target:pitch <GlissandoNode>
26
+ end
27
+
28
+ rule portamento
29
+ "/" target:pitch <PortamentoNode>
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,57 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Music
5
+ module Transcription
6
+ module Parsing
7
+
8
+ module NonnegativeInteger
9
+ include Treetop::Runtime
10
+
11
+ def root
12
+ @root ||= :nonnegative_integer
13
+ end
14
+
15
+ def _nt_nonnegative_integer
16
+ start_index = index
17
+ if node_cache[:nonnegative_integer].has_key?(index)
18
+ cached = node_cache[:nonnegative_integer][index]
19
+ if cached
20
+ node_cache[:nonnegative_integer][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
21
+ @index = cached.interval.end
22
+ end
23
+ return cached
24
+ end
25
+
26
+ s0, i0 = [], index
27
+ loop do
28
+ if has_terminal?(@regexps[gr = '\A[0-9]'] ||= Regexp.new(gr), :regexp, index)
29
+ r1 = true
30
+ @index += 1
31
+ else
32
+ terminal_parse_failure('[0-9]')
33
+ r1 = nil
34
+ end
35
+ if r1
36
+ s0 << r1
37
+ else
38
+ break
39
+ end
40
+ end
41
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
42
+
43
+ node_cache[:nonnegative_integer][start_index] = r0
44
+
45
+ r0
46
+ end
47
+
48
+ end
49
+
50
+ class NonnegativeIntegerParser < Treetop::Runtime::CompiledParser
51
+ include NonnegativeInteger
52
+ end
53
+
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,13 @@
1
+ module Music
2
+ module Transcription
3
+ module Parsing
4
+
5
+ grammar NonnegativeInteger
6
+ rule nonnegative_integer
7
+ [0-9]*
8
+ end
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,64 @@
1
+ module Music
2
+ module Transcription
3
+ module Parsing
4
+ class NoteNode < Treetop::Runtime::SyntaxNode
5
+ def primitives env
6
+ [ self.to_note ]
7
+ end
8
+ end
9
+
10
+ class RestNoteNode < NoteNode
11
+ def to_note
12
+ Music::Transcription::Note.new(duration.to_r)
13
+ end
14
+ end
15
+
16
+ class MonophonicNoteNode < NoteNode
17
+ def to_note
18
+ pitches = [ pl.pitch.to_pitch ]
19
+
20
+ links = {}
21
+ unless pl.the_link.empty?
22
+ links[pitches[0]] = pl.the_link.to_link
23
+ end
24
+
25
+ artic = Music::Transcription::Articulations::NORMAL
26
+ unless art.empty?
27
+ artic = art.to_articulation
28
+ end
29
+
30
+ accent_flag = acc.empty? ? false : true
31
+ Music::Transcription::Note.new(duration.to_r,
32
+ pitches, links: links, articulation: artic, accented: accent_flag)
33
+ end
34
+ end
35
+
36
+ class PolyphonicNoteNode < NoteNode
37
+ def to_note
38
+ pitches = [ pl.pitch.to_pitch ]
39
+
40
+ links = {}
41
+ unless pl.the_link.empty?
42
+ links[pitches[0]] = pl.the_link.to_link
43
+ end
44
+
45
+ more_pitches.elements.each do |mp|
46
+ pitches.push mp.pl.pitch.to_pitch
47
+ unless mp.pl.the_link.empty?
48
+ links[pitches[-1]] = mp.pl.the_link.to_link
49
+ end
50
+ end
51
+
52
+ artic = Music::Transcription::Articulations::NORMAL
53
+ unless art.empty?
54
+ artic = art.to_articulation
55
+ end
56
+
57
+ accent_flag = acc.empty? ? false : true
58
+ Music::Transcription::Note.new(duration.to_r,
59
+ pitches, links: links, articulation: artic, accented: accent_flag)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,354 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Music
5
+ module Transcription
6
+ module Parsing
7
+
8
+ module Note
9
+ include Treetop::Runtime
10
+
11
+ def root
12
+ @root ||= :note
13
+ end
14
+
15
+ include Pitch
16
+
17
+ include Articulation
18
+
19
+ include Link
20
+
21
+ include Duration
22
+
23
+ def _nt_note
24
+ start_index = index
25
+ if node_cache[:note].has_key?(index)
26
+ cached = node_cache[:note][index]
27
+ if cached
28
+ node_cache[:note][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
29
+ @index = cached.interval.end
30
+ end
31
+ return cached
32
+ end
33
+
34
+ i0 = index
35
+ r1 = _nt_polyphonic_note
36
+ if r1
37
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
38
+ r0 = r1
39
+ else
40
+ r2 = _nt_monophonic_note
41
+ if r2
42
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
43
+ r0 = r2
44
+ else
45
+ r3 = _nt_rest_note
46
+ if r3
47
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
48
+ r0 = r3
49
+ else
50
+ @index = i0
51
+ r0 = nil
52
+ end
53
+ end
54
+ end
55
+
56
+ node_cache[:note][start_index] = r0
57
+
58
+ r0
59
+ end
60
+
61
+ module RestNote0
62
+ def duration
63
+ elements[0]
64
+ end
65
+ end
66
+
67
+ def _nt_rest_note
68
+ start_index = index
69
+ if node_cache[:rest_note].has_key?(index)
70
+ cached = node_cache[:rest_note][index]
71
+ if cached
72
+ node_cache[:rest_note][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
73
+ @index = cached.interval.end
74
+ end
75
+ return cached
76
+ end
77
+
78
+ i0, s0 = index, []
79
+ r1 = _nt_duration
80
+ s0 << r1
81
+ if s0.last
82
+ r0 = instantiate_node(RestNoteNode,input, i0...index, s0)
83
+ r0.extend(RestNote0)
84
+ else
85
+ @index = i0
86
+ r0 = nil
87
+ end
88
+
89
+ node_cache[:rest_note][start_index] = r0
90
+
91
+ r0
92
+ end
93
+
94
+ module MonophonicNote0
95
+ def duration
96
+ elements[0]
97
+ end
98
+
99
+ def art
100
+ elements[1]
101
+ end
102
+
103
+ def pl
104
+ elements[2]
105
+ end
106
+
107
+ def acc
108
+ elements[3]
109
+ end
110
+ end
111
+
112
+ def _nt_monophonic_note
113
+ start_index = index
114
+ if node_cache[:monophonic_note].has_key?(index)
115
+ cached = node_cache[:monophonic_note][index]
116
+ if cached
117
+ node_cache[:monophonic_note][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
118
+ @index = cached.interval.end
119
+ end
120
+ return cached
121
+ end
122
+
123
+ i0, s0 = index, []
124
+ r1 = _nt_duration
125
+ s0 << r1
126
+ if r1
127
+ r3 = _nt_articulation
128
+ if r3
129
+ r2 = r3
130
+ else
131
+ r2 = instantiate_node(SyntaxNode,input, index...index)
132
+ end
133
+ s0 << r2
134
+ if r2
135
+ r4 = _nt_pitch_link
136
+ s0 << r4
137
+ if r4
138
+ r6 = _nt_accent
139
+ if r6
140
+ r5 = r6
141
+ else
142
+ r5 = instantiate_node(SyntaxNode,input, index...index)
143
+ end
144
+ s0 << r5
145
+ end
146
+ end
147
+ end
148
+ if s0.last
149
+ r0 = instantiate_node(MonophonicNoteNode,input, i0...index, s0)
150
+ r0.extend(MonophonicNote0)
151
+ else
152
+ @index = i0
153
+ r0 = nil
154
+ end
155
+
156
+ node_cache[:monophonic_note][start_index] = r0
157
+
158
+ r0
159
+ end
160
+
161
+ module PolyphonicNote0
162
+ def pl
163
+ elements[1]
164
+ end
165
+ end
166
+
167
+ module PolyphonicNote1
168
+ def duration
169
+ elements[0]
170
+ end
171
+
172
+ def art
173
+ elements[1]
174
+ end
175
+
176
+ def pl
177
+ elements[2]
178
+ end
179
+
180
+ def more_pitches
181
+ elements[3]
182
+ end
183
+
184
+ def acc
185
+ elements[4]
186
+ end
187
+ end
188
+
189
+ def _nt_polyphonic_note
190
+ start_index = index
191
+ if node_cache[:polyphonic_note].has_key?(index)
192
+ cached = node_cache[:polyphonic_note][index]
193
+ if cached
194
+ node_cache[:polyphonic_note][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
195
+ @index = cached.interval.end
196
+ end
197
+ return cached
198
+ end
199
+
200
+ i0, s0 = index, []
201
+ r1 = _nt_duration
202
+ s0 << r1
203
+ if r1
204
+ r3 = _nt_articulation
205
+ if r3
206
+ r2 = r3
207
+ else
208
+ r2 = instantiate_node(SyntaxNode,input, index...index)
209
+ end
210
+ s0 << r2
211
+ if r2
212
+ r4 = _nt_pitch_link
213
+ s0 << r4
214
+ if r4
215
+ s5, i5 = [], index
216
+ loop do
217
+ i6, s6 = index, []
218
+ if (match_len = has_terminal?(",", false, index))
219
+ r7 = true
220
+ @index += match_len
221
+ else
222
+ terminal_parse_failure(",")
223
+ r7 = nil
224
+ end
225
+ s6 << r7
226
+ if r7
227
+ r8 = _nt_pitch_link
228
+ s6 << r8
229
+ end
230
+ if s6.last
231
+ r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
232
+ r6.extend(PolyphonicNote0)
233
+ else
234
+ @index = i6
235
+ r6 = nil
236
+ end
237
+ if r6
238
+ s5 << r6
239
+ else
240
+ break
241
+ end
242
+ end
243
+ if s5.empty?
244
+ @index = i5
245
+ r5 = nil
246
+ else
247
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
248
+ end
249
+ s0 << r5
250
+ if r5
251
+ r10 = _nt_accent
252
+ if r10
253
+ r9 = r10
254
+ else
255
+ r9 = instantiate_node(SyntaxNode,input, index...index)
256
+ end
257
+ s0 << r9
258
+ end
259
+ end
260
+ end
261
+ end
262
+ if s0.last
263
+ r0 = instantiate_node(PolyphonicNoteNode,input, i0...index, s0)
264
+ r0.extend(PolyphonicNote1)
265
+ else
266
+ @index = i0
267
+ r0 = nil
268
+ end
269
+
270
+ node_cache[:polyphonic_note][start_index] = r0
271
+
272
+ r0
273
+ end
274
+
275
+ module PitchLink0
276
+ def pitch
277
+ elements[0]
278
+ end
279
+
280
+ def the_link
281
+ elements[1]
282
+ end
283
+ end
284
+
285
+ def _nt_pitch_link
286
+ start_index = index
287
+ if node_cache[:pitch_link].has_key?(index)
288
+ cached = node_cache[:pitch_link][index]
289
+ if cached
290
+ node_cache[:pitch_link][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
291
+ @index = cached.interval.end
292
+ end
293
+ return cached
294
+ end
295
+
296
+ i0, s0 = index, []
297
+ r1 = _nt_pitch
298
+ s0 << r1
299
+ if r1
300
+ r3 = _nt_link
301
+ if r3
302
+ r2 = r3
303
+ else
304
+ r2 = instantiate_node(SyntaxNode,input, index...index)
305
+ end
306
+ s0 << r2
307
+ end
308
+ if s0.last
309
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
310
+ r0.extend(PitchLink0)
311
+ else
312
+ @index = i0
313
+ r0 = nil
314
+ end
315
+
316
+ node_cache[:pitch_link][start_index] = r0
317
+
318
+ r0
319
+ end
320
+
321
+ def _nt_accent
322
+ start_index = index
323
+ if node_cache[:accent].has_key?(index)
324
+ cached = node_cache[:accent][index]
325
+ if cached
326
+ node_cache[:accent][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
327
+ @index = cached.interval.end
328
+ end
329
+ return cached
330
+ end
331
+
332
+ if (match_len = has_terminal?("!", false, index))
333
+ r0 = instantiate_node(SyntaxNode,input, index...(index + match_len))
334
+ @index += match_len
335
+ else
336
+ terminal_parse_failure("!")
337
+ r0 = nil
338
+ end
339
+
340
+ node_cache[:accent][start_index] = r0
341
+
342
+ r0
343
+ end
344
+
345
+ end
346
+
347
+ class NoteParser < Treetop::Runtime::CompiledParser
348
+ include Note
349
+ end
350
+
351
+
352
+ end
353
+ end
354
+ end