music-transcription 0.17.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/examples/hip.rb +4 -4
  3. data/examples/missed_connection.rb +3 -3
  4. data/examples/song1.rb +6 -6
  5. data/examples/song2.rb +3 -3
  6. data/lib/music-transcription.rb +8 -2
  7. data/lib/music-transcription/model/change.rb +9 -3
  8. data/lib/music-transcription/model/measure_score.rb +62 -0
  9. data/lib/music-transcription/model/meter.rb +5 -1
  10. data/lib/music-transcription/model/note.rb +4 -1
  11. data/lib/music-transcription/model/note_score.rb +60 -0
  12. data/lib/music-transcription/model/part.rb +4 -1
  13. data/lib/music-transcription/model/program.rb +5 -2
  14. data/lib/music-transcription/model/tempo.rb +13 -23
  15. data/lib/music-transcription/packing/measure_score_packing.rb +34 -0
  16. data/lib/music-transcription/packing/{score_packing.rb → note_score_packing.rb} +12 -21
  17. data/lib/music-transcription/packing/part_packing.rb +1 -1
  18. data/lib/music-transcription/packing/program_packing.rb +1 -1
  19. data/lib/music-transcription/parsing/convenience_methods.rb +37 -58
  20. data/lib/music-transcription/parsing/numbers/nonnegative_float_parsing.rb +172 -59
  21. data/lib/music-transcription/parsing/numbers/nonnegative_float_parsing.treetop +13 -1
  22. data/lib/music-transcription/parsing/numbers/positive_float_parsing.rb +505 -0
  23. data/lib/music-transcription/parsing/numbers/positive_float_parsing.treetop +35 -0
  24. data/lib/music-transcription/parsing/numbers/positive_integer_parsing.rb +2 -0
  25. data/lib/music-transcription/parsing/numbers/positive_integer_parsing.treetop +2 -0
  26. data/lib/music-transcription/parsing/numbers/positive_rational_parsing.rb +86 -0
  27. data/lib/music-transcription/parsing/numbers/positive_rational_parsing.treetop +21 -0
  28. data/lib/music-transcription/parsing/parseable.rb +32 -0
  29. data/lib/music-transcription/parsing/tempo_parsing.rb +396 -0
  30. data/lib/music-transcription/parsing/tempo_parsing.treetop +49 -0
  31. data/lib/music-transcription/validatable.rb +5 -18
  32. data/lib/music-transcription/version.rb +1 -1
  33. data/spec/model/measure_score_spec.rb +85 -0
  34. data/spec/model/note_score_spec.rb +68 -0
  35. data/spec/model/tempo_spec.rb +15 -15
  36. data/spec/packing/{score_packing_spec.rb → measure_score_packing_spec.rb} +13 -7
  37. data/spec/packing/note_score_packing_spec.rb +100 -0
  38. data/spec/packing/part_packing_spec.rb +1 -1
  39. data/spec/parsing/convenience_methods_spec.rb +80 -81
  40. data/spec/parsing/numbers/nonnegative_float_spec.rb +19 -2
  41. data/spec/parsing/numbers/positive_float_spec.rb +28 -0
  42. data/spec/parsing/numbers/positive_integer_spec.rb +13 -2
  43. data/spec/parsing/numbers/positive_rational_spec.rb +28 -0
  44. data/spec/parsing/tempo_parsing_spec.rb +21 -0
  45. metadata +27 -8
  46. data/lib/music-transcription/model/score.rb +0 -68
  47. data/spec/model/score_spec.rb +0 -69
@@ -0,0 +1,35 @@
1
+ module Music
2
+ module Transcription
3
+ module Parsing
4
+
5
+ grammar PositiveFloat
6
+ rule positive_float
7
+ (float1 / float2 / float3) {
8
+ def to_f
9
+ text_value.to_f
10
+ end
11
+
12
+ alias :to_num :to_f
13
+ }
14
+ end
15
+
16
+ rule float1
17
+ [0]* [1-9]+ [0-9]* exponent
18
+ end
19
+
20
+ rule float2
21
+ [0]* [1-9]+ [0-9]* [.] [0-9]+ exponent?
22
+ end
23
+
24
+ rule float3
25
+ [0]+ [.] [0]* [1-9]+ [0-9]* exponent?
26
+ end
27
+
28
+ rule exponent
29
+ "e" [+-]? [0-9]+
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -24,6 +24,8 @@ module PositiveInteger
24
24
  def to_i
25
25
  text_value.to_i
26
26
  end
27
+
28
+ alias :to_num :to_i
27
29
  end
28
30
 
29
31
  def _nt_positive_integer
@@ -10,6 +10,8 @@ grammar PositiveInteger
10
10
  def to_i
11
11
  text_value.to_i
12
12
  end
13
+
14
+ alias :to_num :to_i
13
15
  }
14
16
  end
15
17
  end
@@ -0,0 +1,86 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Music
5
+ module Transcription
6
+ module Parsing
7
+
8
+ module PositiveRational
9
+ include Treetop::Runtime
10
+
11
+ def root
12
+ @root ||= :positive_rational
13
+ end
14
+
15
+ include PositiveInteger
16
+
17
+ module PositiveRational0
18
+ def positive_integer1
19
+ elements[0]
20
+ end
21
+
22
+ def positive_integer2
23
+ elements[2]
24
+ end
25
+ end
26
+
27
+ module PositiveRational1
28
+ def to_r
29
+ text_value.to_r
30
+ end
31
+
32
+ alias :to_num :to_r
33
+ end
34
+
35
+ def _nt_positive_rational
36
+ start_index = index
37
+ if node_cache[:positive_rational].has_key?(index)
38
+ cached = node_cache[:positive_rational][index]
39
+ if cached
40
+ node_cache[:positive_rational][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
41
+ @index = cached.interval.end
42
+ end
43
+ return cached
44
+ end
45
+
46
+ i0, s0 = index, []
47
+ r1 = _nt_positive_integer
48
+ s0 << r1
49
+ if r1
50
+ if (match_len = has_terminal?("/", false, index))
51
+ r2 = true
52
+ @index += match_len
53
+ else
54
+ terminal_parse_failure("/")
55
+ r2 = nil
56
+ end
57
+ s0 << r2
58
+ if r2
59
+ r3 = _nt_positive_integer
60
+ s0 << r3
61
+ end
62
+ end
63
+ if s0.last
64
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
65
+ r0.extend(PositiveRational0)
66
+ r0.extend(PositiveRational1)
67
+ else
68
+ @index = i0
69
+ r0 = nil
70
+ end
71
+
72
+ node_cache[:positive_rational][start_index] = r0
73
+
74
+ r0
75
+ end
76
+
77
+ end
78
+
79
+ class PositiveRationalParser < Treetop::Runtime::CompiledParser
80
+ include PositiveRational
81
+ end
82
+
83
+
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,21 @@
1
+ module Music
2
+ module Transcription
3
+ module Parsing
4
+
5
+ grammar PositiveRational
6
+ include PositiveInteger
7
+
8
+ rule positive_rational
9
+ positive_integer "/" positive_integer {
10
+ def to_r
11
+ text_value.to_r
12
+ end
13
+
14
+ alias :to_num :to_r
15
+ }
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ module Music
2
+ module Transcription
3
+
4
+ # to use, include Parseable and define PARSER constant that has #parse method.
5
+ module Parseable
6
+ DEFAULT_SPLIT_PATTERN = " "
7
+
8
+ def self.included(base)
9
+ base.extend(ClassMethods)
10
+ end
11
+
12
+ module ClassMethods
13
+ def parser
14
+ self.const_get(:PARSER)
15
+ end
16
+
17
+ def convert node
18
+ node.send(self.const_get(:CONVERSION_METHOD))
19
+ end
20
+
21
+ def parse str
22
+ convert(parser.parse(str))
23
+ end
24
+
25
+ def split_parse str, pattern=" "
26
+ str.split(pattern).map {|x| convert(parser.parse(x)) }
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,396 @@
1
+ # Autogenerated from a Treetop grammar. Edits may be lost.
2
+
3
+
4
+ module Music
5
+ module Transcription
6
+ module Parsing
7
+
8
+ module Tempo
9
+ include Treetop::Runtime
10
+
11
+ def root
12
+ @root ||= :tempo
13
+ end
14
+
15
+ include PositiveInteger
16
+
17
+ include PositiveFloat
18
+
19
+ include PositiveRational
20
+
21
+ def _nt_tempo
22
+ start_index = index
23
+ if node_cache[:tempo].has_key?(index)
24
+ cached = node_cache[:tempo][index]
25
+ if cached
26
+ node_cache[:tempo][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
27
+ @index = cached.interval.end
28
+ end
29
+ return cached
30
+ end
31
+
32
+ i0 = index
33
+ r1 = _nt_tempo_bpm
34
+ if r1
35
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
36
+ r0 = r1
37
+ else
38
+ r2 = _nt_tempo_qnpm
39
+ if r2
40
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
41
+ r0 = r2
42
+ else
43
+ r3 = _nt_tempo_npm
44
+ if r3
45
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
46
+ r0 = r3
47
+ else
48
+ r4 = _nt_tempo_nps
49
+ if r4
50
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
51
+ r0 = r4
52
+ else
53
+ @index = i0
54
+ r0 = nil
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ node_cache[:tempo][start_index] = r0
61
+
62
+ r0
63
+ end
64
+
65
+ module TempoBpm0
66
+ def val
67
+ elements[0]
68
+ end
69
+
70
+ end
71
+
72
+ module TempoBpm1
73
+ def to_tempo
74
+ Music::Transcription::Tempo::BPM.new(val.to_num)
75
+ end
76
+ end
77
+
78
+ def _nt_tempo_bpm
79
+ start_index = index
80
+ if node_cache[:tempo_bpm].has_key?(index)
81
+ cached = node_cache[:tempo_bpm][index]
82
+ if cached
83
+ node_cache[:tempo_bpm][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
84
+ @index = cached.interval.end
85
+ end
86
+ return cached
87
+ end
88
+
89
+ i0, s0 = index, []
90
+ r1 = _nt_positive_number
91
+ s0 << r1
92
+ if r1
93
+ i2 = index
94
+ if (match_len = has_terminal?("bpm", false, index))
95
+ r3 = instantiate_node(SyntaxNode,input, index...(index + match_len))
96
+ @index += match_len
97
+ else
98
+ terminal_parse_failure("bpm")
99
+ r3 = nil
100
+ end
101
+ if r3
102
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
103
+ r2 = r3
104
+ else
105
+ if (match_len = has_terminal?("BPM", false, index))
106
+ r4 = instantiate_node(SyntaxNode,input, index...(index + match_len))
107
+ @index += match_len
108
+ else
109
+ terminal_parse_failure("BPM")
110
+ r4 = nil
111
+ end
112
+ if r4
113
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
114
+ r2 = r4
115
+ else
116
+ @index = i2
117
+ r2 = nil
118
+ end
119
+ end
120
+ s0 << r2
121
+ end
122
+ if s0.last
123
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
124
+ r0.extend(TempoBpm0)
125
+ r0.extend(TempoBpm1)
126
+ else
127
+ @index = i0
128
+ r0 = nil
129
+ end
130
+
131
+ node_cache[:tempo_bpm][start_index] = r0
132
+
133
+ r0
134
+ end
135
+
136
+ module TempoQnpm0
137
+ def val
138
+ elements[0]
139
+ end
140
+
141
+ end
142
+
143
+ module TempoQnpm1
144
+ def to_tempo
145
+ Music::Transcription::Tempo::QNPM.new(val.to_num)
146
+ end
147
+ end
148
+
149
+ def _nt_tempo_qnpm
150
+ start_index = index
151
+ if node_cache[:tempo_qnpm].has_key?(index)
152
+ cached = node_cache[:tempo_qnpm][index]
153
+ if cached
154
+ node_cache[:tempo_qnpm][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
155
+ @index = cached.interval.end
156
+ end
157
+ return cached
158
+ end
159
+
160
+ i0, s0 = index, []
161
+ r1 = _nt_positive_number
162
+ s0 << r1
163
+ if r1
164
+ i2 = index
165
+ if (match_len = has_terminal?("qnpm", false, index))
166
+ r3 = instantiate_node(SyntaxNode,input, index...(index + match_len))
167
+ @index += match_len
168
+ else
169
+ terminal_parse_failure("qnpm")
170
+ r3 = nil
171
+ end
172
+ if r3
173
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
174
+ r2 = r3
175
+ else
176
+ if (match_len = has_terminal?("QNPM", false, index))
177
+ r4 = instantiate_node(SyntaxNode,input, index...(index + match_len))
178
+ @index += match_len
179
+ else
180
+ terminal_parse_failure("QNPM")
181
+ r4 = nil
182
+ end
183
+ if r4
184
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
185
+ r2 = r4
186
+ else
187
+ @index = i2
188
+ r2 = nil
189
+ end
190
+ end
191
+ s0 << r2
192
+ end
193
+ if s0.last
194
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
195
+ r0.extend(TempoQnpm0)
196
+ r0.extend(TempoQnpm1)
197
+ else
198
+ @index = i0
199
+ r0 = nil
200
+ end
201
+
202
+ node_cache[:tempo_qnpm][start_index] = r0
203
+
204
+ r0
205
+ end
206
+
207
+ module TempoNpm0
208
+ def val
209
+ elements[0]
210
+ end
211
+
212
+ end
213
+
214
+ module TempoNpm1
215
+ def to_tempo
216
+ Music::Transcription::Tempo::NPM.new(val.to_num)
217
+ end
218
+ end
219
+
220
+ def _nt_tempo_npm
221
+ start_index = index
222
+ if node_cache[:tempo_npm].has_key?(index)
223
+ cached = node_cache[:tempo_npm][index]
224
+ if cached
225
+ node_cache[:tempo_npm][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
226
+ @index = cached.interval.end
227
+ end
228
+ return cached
229
+ end
230
+
231
+ i0, s0 = index, []
232
+ r1 = _nt_positive_number
233
+ s0 << r1
234
+ if r1
235
+ i2 = index
236
+ if (match_len = has_terminal?("npm", false, index))
237
+ r3 = instantiate_node(SyntaxNode,input, index...(index + match_len))
238
+ @index += match_len
239
+ else
240
+ terminal_parse_failure("npm")
241
+ r3 = nil
242
+ end
243
+ if r3
244
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
245
+ r2 = r3
246
+ else
247
+ if (match_len = has_terminal?("NPM", false, index))
248
+ r4 = instantiate_node(SyntaxNode,input, index...(index + match_len))
249
+ @index += match_len
250
+ else
251
+ terminal_parse_failure("NPM")
252
+ r4 = nil
253
+ end
254
+ if r4
255
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
256
+ r2 = r4
257
+ else
258
+ @index = i2
259
+ r2 = nil
260
+ end
261
+ end
262
+ s0 << r2
263
+ end
264
+ if s0.last
265
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
266
+ r0.extend(TempoNpm0)
267
+ r0.extend(TempoNpm1)
268
+ else
269
+ @index = i0
270
+ r0 = nil
271
+ end
272
+
273
+ node_cache[:tempo_npm][start_index] = r0
274
+
275
+ r0
276
+ end
277
+
278
+ module TempoNps0
279
+ def val
280
+ elements[0]
281
+ end
282
+
283
+ end
284
+
285
+ module TempoNps1
286
+ def to_tempo
287
+ Music::Transcription::Tempo::NPS.new(val.to_num)
288
+ end
289
+ end
290
+
291
+ def _nt_tempo_nps
292
+ start_index = index
293
+ if node_cache[:tempo_nps].has_key?(index)
294
+ cached = node_cache[:tempo_nps][index]
295
+ if cached
296
+ node_cache[:tempo_nps][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
297
+ @index = cached.interval.end
298
+ end
299
+ return cached
300
+ end
301
+
302
+ i0, s0 = index, []
303
+ r1 = _nt_positive_number
304
+ s0 << r1
305
+ if r1
306
+ i2 = index
307
+ if (match_len = has_terminal?("nps", false, index))
308
+ r3 = instantiate_node(SyntaxNode,input, index...(index + match_len))
309
+ @index += match_len
310
+ else
311
+ terminal_parse_failure("nps")
312
+ r3 = nil
313
+ end
314
+ if r3
315
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
316
+ r2 = r3
317
+ else
318
+ if (match_len = has_terminal?("NPS", false, index))
319
+ r4 = instantiate_node(SyntaxNode,input, index...(index + match_len))
320
+ @index += match_len
321
+ else
322
+ terminal_parse_failure("NPS")
323
+ r4 = nil
324
+ end
325
+ if r4
326
+ r4 = SyntaxNode.new(input, (index-1)...index) if r4 == true
327
+ r2 = r4
328
+ else
329
+ @index = i2
330
+ r2 = nil
331
+ end
332
+ end
333
+ s0 << r2
334
+ end
335
+ if s0.last
336
+ r0 = instantiate_node(SyntaxNode,input, i0...index, s0)
337
+ r0.extend(TempoNps0)
338
+ r0.extend(TempoNps1)
339
+ else
340
+ @index = i0
341
+ r0 = nil
342
+ end
343
+
344
+ node_cache[:tempo_nps][start_index] = r0
345
+
346
+ r0
347
+ end
348
+
349
+ def _nt_positive_number
350
+ start_index = index
351
+ if node_cache[:positive_number].has_key?(index)
352
+ cached = node_cache[:positive_number][index]
353
+ if cached
354
+ node_cache[:positive_number][index] = cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
355
+ @index = cached.interval.end
356
+ end
357
+ return cached
358
+ end
359
+
360
+ i0 = index
361
+ r1 = _nt_positive_float
362
+ if r1
363
+ r1 = SyntaxNode.new(input, (index-1)...index) if r1 == true
364
+ r0 = r1
365
+ else
366
+ r2 = _nt_positive_rational
367
+ if r2
368
+ r2 = SyntaxNode.new(input, (index-1)...index) if r2 == true
369
+ r0 = r2
370
+ else
371
+ r3 = _nt_positive_integer
372
+ if r3
373
+ r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
374
+ r0 = r3
375
+ else
376
+ @index = i0
377
+ r0 = nil
378
+ end
379
+ end
380
+ end
381
+
382
+ node_cache[:positive_number][start_index] = r0
383
+
384
+ r0
385
+ end
386
+
387
+ end
388
+
389
+ class TempoParser < Treetop::Runtime::CompiledParser
390
+ include Tempo
391
+ end
392
+
393
+
394
+ end
395
+ end
396
+ end