musicality 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +7 -1
  3. data/lib/musicality.rb +0 -1
  4. data/lib/musicality/composition/dsl/score_methods.rb +5 -6
  5. data/lib/musicality/notation/conversion/score_conversion.rb +3 -34
  6. data/lib/musicality/notation/conversion/score_converter.rb +6 -17
  7. data/lib/musicality/notation/model/mark.rb +0 -12
  8. data/lib/musicality/notation/model/marks.rb +0 -3
  9. data/lib/musicality/notation/model/note.rb +0 -8
  10. data/lib/musicality/notation/model/score.rb +14 -35
  11. data/lib/musicality/notation/model/symbols.rb +0 -2
  12. data/lib/musicality/notation/parsing/mark_parsing.rb +0 -58
  13. data/lib/musicality/notation/parsing/mark_parsing.treetop +0 -12
  14. data/lib/musicality/notation/parsing/note_node.rb +22 -27
  15. data/lib/musicality/notation/parsing/note_parsing.rb +59 -189
  16. data/lib/musicality/notation/parsing/note_parsing.treetop +2 -9
  17. data/lib/musicality/performance/conversion/note_sequence_extractor.rb +1 -20
  18. data/lib/musicality/performance/model/note_sequence.rb +1 -1
  19. data/lib/musicality/printing/lilypond/note_engraving.rb +3 -3
  20. data/lib/musicality/printing/lilypond/part_engraver.rb +16 -12
  21. data/lib/musicality/project/create_tasks.rb +1 -1
  22. data/lib/musicality/project/load_config.rb +16 -1
  23. data/lib/musicality/project/project.rb +2 -2
  24. data/lib/musicality/version.rb +1 -1
  25. data/musicality.gemspec +0 -1
  26. data/spec/composition/dsl/score_methods_spec.rb +73 -0
  27. data/spec/notation/conversion/score_conversion_spec.rb +0 -100
  28. data/spec/notation/conversion/score_converter_spec.rb +33 -33
  29. data/spec/notation/model/note_spec.rb +2 -2
  30. data/spec/notation/model/score_spec.rb +17 -87
  31. data/spec/notation/parsing/note_node_spec.rb +2 -2
  32. data/spec/notation/parsing/note_parsing_spec.rb +3 -3
  33. data/spec/performance/conversion/note_sequence_extractor_spec.rb +23 -0
  34. data/spec/performance/model/note_sequence_spec.rb +50 -6
  35. metadata +4 -19
  36. data/lib/musicality/notation/conversion/measure_note_map.rb +0 -40
  37. data/spec/notation/conversion/measure_note_map_spec.rb +0 -73
@@ -19,35 +19,13 @@ module Note
19
19
 
20
20
  include Duration
21
21
 
22
- include Mark
23
-
24
22
  module Note0
25
- def first
26
- elements[0]
27
- end
28
-
29
- def second
30
- elements[1]
31
- end
32
- end
33
-
34
- module Note1
35
- def first
36
- elements[0]
37
- end
38
-
39
- def second
40
- elements[1]
41
- end
42
- end
43
-
44
- module Note2
45
23
  def pl
46
24
  elements[1]
47
25
  end
48
26
  end
49
27
 
50
- module Note3
28
+ module Note1
51
29
  def first_pl
52
30
  elements[0]
53
31
  end
@@ -61,28 +39,8 @@ module Note
61
39
  end
62
40
  end
63
41
 
64
- module Note4
65
- def first
66
- elements[0]
67
- end
68
-
69
- def second
70
- elements[1]
71
- end
72
- end
73
-
74
- module Note5
75
- def first
76
- elements[0]
77
- end
78
-
79
- def second
80
- elements[1]
81
- end
82
- end
83
-
84
- module Note6
85
- def begin_marks
42
+ module Note2
43
+ def begin_slur
86
44
  elements[0]
87
45
  end
88
46
 
@@ -94,7 +52,7 @@ module Note
94
52
  elements[2]
95
53
  end
96
54
 
97
- def end_marks
55
+ def end_slur
98
56
  elements[3]
99
57
  end
100
58
  end
@@ -111,56 +69,12 @@ module Note
111
69
  end
112
70
 
113
71
  i0, s0 = index, []
114
- i2 = index
115
- i3, s3 = index, []
116
- r4 = _nt_begin_triplet
117
- s3 << r4
118
- if r4
119
- r6 = _nt_begin_slur
120
- if r6
121
- r5 = r6
122
- else
123
- r5 = instantiate_node(SyntaxNode,input, index...index)
124
- end
125
- s3 << r5
126
- end
127
- if s3.last
128
- r3 = instantiate_node(SyntaxNode,input, i3...index, s3)
129
- r3.extend(Note0)
130
- else
131
- @index = i3
132
- r3 = nil
133
- end
134
- if r3
135
- r3 = SyntaxNode.new(input, (index-1)...index) if r3 == true
136
- r2 = r3
72
+ if (match_len = has_terminal?("(", false, index))
73
+ r2 = true
74
+ @index += match_len
137
75
  else
138
- i7, s7 = index, []
139
- r8 = _nt_begin_slur
140
- s7 << r8
141
- if r8
142
- r10 = _nt_begin_triplet
143
- if r10
144
- r9 = r10
145
- else
146
- r9 = instantiate_node(SyntaxNode,input, index...index)
147
- end
148
- s7 << r9
149
- end
150
- if s7.last
151
- r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
152
- r7.extend(Note1)
153
- else
154
- @index = i7
155
- r7 = nil
156
- end
157
- if r7
158
- r7 = SyntaxNode.new(input, (index-1)...index) if r7 == true
159
- r2 = r7
160
- else
161
- @index = i2
162
- r2 = nil
163
- end
76
+ terminal_parse_failure('"("')
77
+ r2 = nil
164
78
  end
165
79
  if r2
166
80
  r1 = r2
@@ -169,130 +83,86 @@ module Note
169
83
  end
170
84
  s0 << r1
171
85
  if r1
172
- r11 = _nt_duration
173
- s0 << r11
174
- if r11
175
- i13, s13 = index, []
176
- r14 = _nt_pitch_link
177
- s13 << r14
178
- if r14
179
- s15, i15 = [], index
86
+ r3 = _nt_duration
87
+ s0 << r3
88
+ if r3
89
+ i5, s5 = index, []
90
+ r6 = _nt_pitch_link
91
+ s5 << r6
92
+ if r6
93
+ s7, i7 = [], index
180
94
  loop do
181
- i16, s16 = index, []
95
+ i8, s8 = index, []
182
96
  if (match_len = has_terminal?(",", false, index))
183
- r17 = true
97
+ r9 = true
184
98
  @index += match_len
185
99
  else
186
100
  terminal_parse_failure('","')
187
- r17 = nil
101
+ r9 = nil
188
102
  end
189
- s16 << r17
190
- if r17
191
- r18 = _nt_pitch_link
192
- s16 << r18
103
+ s8 << r9
104
+ if r9
105
+ r10 = _nt_pitch_link
106
+ s8 << r10
193
107
  end
194
- if s16.last
195
- r16 = instantiate_node(SyntaxNode,input, i16...index, s16)
196
- r16.extend(Note2)
108
+ if s8.last
109
+ r8 = instantiate_node(SyntaxNode,input, i8...index, s8)
110
+ r8.extend(Note0)
197
111
  else
198
- @index = i16
199
- r16 = nil
112
+ @index = i8
113
+ r8 = nil
200
114
  end
201
- if r16
202
- s15 << r16
115
+ if r8
116
+ s7 << r8
203
117
  else
204
118
  break
205
119
  end
206
120
  end
207
- r15 = instantiate_node(SyntaxNode,input, i15...index, s15)
208
- s13 << r15
209
- if r15
210
- r20 = _nt_articulation
211
- if r20
212
- r19 = r20
121
+ r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
122
+ s5 << r7
123
+ if r7
124
+ r12 = _nt_articulation
125
+ if r12
126
+ r11 = r12
213
127
  else
214
- r19 = instantiate_node(SyntaxNode,input, index...index)
128
+ r11 = instantiate_node(SyntaxNode,input, index...index)
215
129
  end
216
- s13 << r19
130
+ s5 << r11
217
131
  end
218
132
  end
219
- if s13.last
220
- r13 = instantiate_node(SyntaxNode,input, i13...index, s13)
221
- r13.extend(Note3)
133
+ if s5.last
134
+ r5 = instantiate_node(SyntaxNode,input, i5...index, s5)
135
+ r5.extend(Note1)
222
136
  else
223
- @index = i13
224
- r13 = nil
137
+ @index = i5
138
+ r5 = nil
225
139
  end
226
- if r13
227
- r12 = r13
140
+ if r5
141
+ r4 = r5
228
142
  else
229
- r12 = instantiate_node(SyntaxNode,input, index...index)
143
+ r4 = instantiate_node(SyntaxNode,input, index...index)
230
144
  end
231
- s0 << r12
232
- if r12
233
- i22 = index
234
- i23, s23 = index, []
235
- r24 = _nt_end_triplet
236
- s23 << r24
237
- if r24
238
- r26 = _nt_end_slur
239
- if r26
240
- r25 = r26
241
- else
242
- r25 = instantiate_node(SyntaxNode,input, index...index)
243
- end
244
- s23 << r25
245
- end
246
- if s23.last
247
- r23 = instantiate_node(SyntaxNode,input, i23...index, s23)
248
- r23.extend(Note4)
145
+ s0 << r4
146
+ if r4
147
+ if (match_len = has_terminal?(")", false, index))
148
+ r14 = true
149
+ @index += match_len
249
150
  else
250
- @index = i23
251
- r23 = nil
252
- end
253
- if r23
254
- r23 = SyntaxNode.new(input, (index-1)...index) if r23 == true
255
- r22 = r23
256
- else
257
- i27, s27 = index, []
258
- r28 = _nt_end_slur
259
- s27 << r28
260
- if r28
261
- r30 = _nt_end_triplet
262
- if r30
263
- r29 = r30
264
- else
265
- r29 = instantiate_node(SyntaxNode,input, index...index)
266
- end
267
- s27 << r29
268
- end
269
- if s27.last
270
- r27 = instantiate_node(SyntaxNode,input, i27...index, s27)
271
- r27.extend(Note5)
272
- else
273
- @index = i27
274
- r27 = nil
275
- end
276
- if r27
277
- r27 = SyntaxNode.new(input, (index-1)...index) if r27 == true
278
- r22 = r27
279
- else
280
- @index = i22
281
- r22 = nil
282
- end
151
+ terminal_parse_failure('")"')
152
+ r14 = nil
283
153
  end
284
- if r22
285
- r21 = r22
154
+ if r14
155
+ r13 = r14
286
156
  else
287
- r21 = instantiate_node(SyntaxNode,input, index...index)
157
+ r13 = instantiate_node(SyntaxNode,input, index...index)
288
158
  end
289
- s0 << r21
159
+ s0 << r13
290
160
  end
291
161
  end
292
162
  end
293
163
  if s0.last
294
164
  r0 = instantiate_node(NoteNode,input, i0...index, s0)
295
- r0.extend(Note6)
165
+ r0.extend(Note2)
296
166
  else
297
167
  @index = i0
298
168
  r0 = nil
@@ -6,23 +6,16 @@ grammar Note
6
6
  include Articulation
7
7
  include Link
8
8
  include Duration
9
- include Mark
10
9
 
11
10
  rule note
12
- begin_marks:(
13
- (first:begin_triplet second:begin_slur?) /
14
- (first:begin_slur second:begin_triplet?)
15
- )?
11
+ begin_slur:"("?
16
12
  duration
17
13
  more:(
18
14
  first_pl:pitch_link
19
15
  more_pl:("," pl:pitch_link)*
20
16
  art:articulation?
21
17
  )?
22
- end_marks:(
23
- (first:end_triplet second:end_slur?) /
24
- (first:end_slur second:end_triplet?)
25
- )?
18
+ end_slur:")"?
26
19
  <NoteNode>
27
20
  end
28
21
 
@@ -3,7 +3,7 @@ module Musicality
3
3
  class NoteSequenceExtractor
4
4
  attr_reader :notes
5
5
  def initialize notes
6
- prepare_notes(notes)
6
+ @notes = notes.map {|n| n.clone }
7
7
  mark_slurring
8
8
  remove_bad_links
9
9
  calculate_offsets
@@ -134,25 +134,6 @@ class NoteSequenceExtractor
134
134
  end
135
135
  end
136
136
 
137
- def prepare_notes notes
138
- in_triplet = false
139
- @notes = Array.new(notes.size) do |i|
140
- note = notes[i]
141
-
142
- if note.begins_triplet?
143
- in_triplet = true
144
- end
145
-
146
- new_note = in_triplet ? note.resize(note.duration * Rational(2,3)) : note.clone
147
-
148
- if note.ends_triplet?
149
- in_triplet = false
150
- end
151
-
152
- new_note
153
- end
154
- end
155
-
156
137
  def mark_slurring
157
138
  @slurring_flags = []
158
139
  under_slur = false
@@ -49,7 +49,7 @@ class NoteSequence
49
49
  end
50
50
 
51
51
  def full_duration
52
- offsets.last + elements.last.duration
52
+ @elements.map {|el| el.duration }.inject(0,:+)
53
53
  end
54
54
 
55
55
  def first_pitch
@@ -3,7 +3,7 @@ module Musicality
3
3
  class Note
4
4
  SMALLEST_PIECE = Rational(1,256)
5
5
 
6
- def to_lilypond sharpit = false
6
+ def to_lilypond sharpit = false, begins_triplet: false, ends_triplet: false
7
7
  subdurs = [1]*@duration.to_i + fractional_subdurs(SMALLEST_PIECE)
8
8
 
9
9
  piece_strs = []
@@ -63,11 +63,11 @@ class Note
63
63
  end
64
64
  end
65
65
 
66
- if begins_triplet?
66
+ if begins_triplet
67
67
  piece_strs[0].prepend("\\tuplet 3/2 {")
68
68
  end
69
69
 
70
- if ends_triplet?
70
+ if ends_triplet
71
71
  piece_strs[-1].concat("}")
72
72
  end
73
73
 
@@ -14,6 +14,10 @@ class PartEngraver
14
14
  @part = (@transpose_interval == 0) ? part : part.transpose(@transpose_interval)
15
15
  @title = title
16
16
  @indent = INDENT
17
+
18
+ @triplet_flags = @part.notes.map do |note|
19
+ note.duration.to_r.denominator % 3 == 0
20
+ end
17
21
  end
18
22
 
19
23
  def increase_indent
@@ -50,7 +54,17 @@ class PartEngraver
50
54
  end
51
55
 
52
56
  def make_body sharpit
53
- pieces = @part.notes.map {|n| n.to_lilypond(sharpit)}
57
+ i = 0
58
+ pieces = @part.notes.map do |n|
59
+ if @triplet_flags[i]
60
+ n.resize(n.duration * Rational(3,2)).to_lilypond(sharpit,
61
+ begins_triplet: i == 0 || !@triplet_flags[i-1],
62
+ ends_triplet: i == (@triplet_flags.size-1) || !@triplet_flags[i+1])
63
+ else
64
+ n.to_lilypond(sharpit)
65
+ end
66
+ i += 1
67
+ end
54
68
 
55
69
  output = ""
56
70
  while pieces.any?
@@ -82,24 +96,14 @@ class PartEngraver
82
96
  ranges = CLEF_RANGES.select {|clef,range| allowed_clefs.include?(clef) }
83
97
  range_scores = Hash.new(0)
84
98
 
85
- in_triplet = false
86
99
  notes.each do |note|
87
- if note.begins_triplet?
88
- in_triplet = true
89
- end
90
-
91
- dur = note.duration * (in_triplet ? Rational(2,3) : 1)
92
100
  note.pitches.each do |p|
93
101
  ranges.each do |name,range|
94
102
  if p >= range.min && p <= range.max
95
- range_scores[name] += dur
103
+ range_scores[name] += note.duration
96
104
  end
97
105
  end
98
106
  end
99
-
100
- if note.ends_triplet?
101
- in_triplet = false
102
- end
103
107
  end
104
108
  range_score = range_scores.max_by {|range,score| score}
105
109
  range_score.nil? ? allowed_clefs.first : range_score[0]