musicality 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +27 -1
- data/README.md +153 -10
- data/bin/collidify +102 -0
- data/bin/lilify +57 -29
- data/bin/midify +64 -24
- data/bin/musicality +39 -0
- data/examples/composition/auto_counterpoint.rb +4 -5
- data/examples/composition/part_generator.rb +8 -2
- data/examples/composition/scale_exercise.rb +1 -1
- data/examples/notation/notes.rb +27 -0
- data/examples/notation/parts.rb +51 -0
- data/examples/notation/scores.rb +38 -0
- data/examples/notation/twinkle.rb +34 -0
- data/examples/notation/twinkle.score +33 -0
- data/lib/musicality.rb +46 -11
- data/lib/musicality/composition/dsl/score_dsl.rb +2 -2
- data/lib/musicality/composition/dsl/score_methods.rb +10 -7
- data/lib/musicality/notation/conversion/change_conversion.rb +1 -1
- data/lib/musicality/notation/conversion/note_time_converter.rb +6 -23
- data/lib/musicality/notation/conversion/score_conversion.rb +15 -15
- data/lib/musicality/notation/conversion/score_converter.rb +50 -67
- data/lib/musicality/notation/model/articulations.rb +3 -2
- data/lib/musicality/notation/model/change.rb +15 -6
- data/lib/musicality/notation/model/dynamics.rb +11 -8
- data/lib/musicality/notation/model/instrument.rb +61 -0
- data/lib/musicality/notation/model/instruments.rb +111 -0
- data/lib/musicality/notation/model/key.rb +137 -0
- data/lib/musicality/notation/model/keys.rb +37 -0
- data/lib/musicality/notation/model/link.rb +6 -19
- data/lib/musicality/notation/model/mark.rb +43 -0
- data/lib/musicality/notation/model/marks.rb +11 -0
- data/lib/musicality/notation/model/meter.rb +4 -0
- data/lib/musicality/notation/model/note.rb +42 -28
- data/lib/musicality/notation/model/part.rb +18 -5
- data/lib/musicality/notation/model/pitch.rb +13 -4
- data/lib/musicality/notation/model/score.rb +104 -66
- data/lib/musicality/notation/model/symbols.rb +16 -11
- data/lib/musicality/notation/parsing/articulation_parsing.rb +38 -38
- data/lib/musicality/notation/parsing/articulation_parsing.treetop +14 -14
- data/lib/musicality/notation/parsing/link_parsing.rb +6 -6
- data/lib/musicality/notation/parsing/link_parsing.treetop +3 -3
- data/lib/musicality/notation/parsing/mark_parsing.rb +138 -0
- data/lib/musicality/notation/parsing/mark_parsing.treetop +31 -0
- data/lib/musicality/notation/parsing/note_node.rb +19 -12
- data/lib/musicality/notation/parsing/note_parsing.rb +218 -87
- data/lib/musicality/notation/parsing/note_parsing.treetop +9 -5
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +7 -2
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.treetop +1 -1
- data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.rb +6 -4
- data/lib/musicality/notation/parsing/numbers/positive_integer_parsing.treetop +1 -1
- data/lib/musicality/notation/util/function.rb +41 -18
- data/lib/musicality/packable.rb +156 -0
- data/lib/musicality/performance/conversion/glissando_converter.rb +2 -2
- data/lib/musicality/performance/conversion/note_sequence_extractor.rb +223 -70
- data/lib/musicality/performance/conversion/portamento_converter.rb +5 -2
- data/lib/musicality/performance/conversion/score_collator.rb +70 -64
- data/lib/musicality/performance/midi/midi_events.rb +3 -3
- data/lib/musicality/performance/midi/midi_settings.rb +127 -0
- data/lib/musicality/performance/midi/midi_util.rb +8 -2
- data/lib/musicality/performance/midi/part_sequencer.rb +19 -18
- data/lib/musicality/performance/midi/score_sequencer.rb +13 -9
- data/lib/musicality/performance/midi/score_sequencing.rb +5 -5
- data/lib/musicality/performance/model/attack.rb +8 -0
- data/lib/musicality/performance/model/duration_functions.rb +23 -0
- data/lib/musicality/performance/model/note_sequence.rb +52 -95
- data/lib/musicality/performance/model/separation.rb +10 -0
- data/lib/musicality/performance/supercollider/add_actions.rb +13 -0
- data/lib/musicality/performance/supercollider/bundle.rb +18 -0
- data/lib/musicality/performance/supercollider/conductor.rb +125 -0
- data/lib/musicality/performance/supercollider/group.rb +71 -0
- data/lib/musicality/performance/supercollider/message.rb +26 -0
- data/lib/musicality/performance/supercollider/node.rb +122 -0
- data/lib/musicality/performance/supercollider/performer.rb +123 -0
- data/lib/musicality/performance/supercollider/score_conducting.rb +17 -0
- data/lib/musicality/performance/supercollider/server.rb +8 -0
- data/lib/musicality/performance/supercollider/synth.rb +43 -0
- data/lib/musicality/performance/supercollider/synthdef.rb +57 -0
- data/lib/musicality/performance/supercollider/synthdef_settings.rb +23 -0
- data/lib/musicality/performance/supercollider/synthdefs.rb +1654 -0
- data/lib/musicality/{composition/model/pitch_class.rb → pitch_class.rb} +1 -1
- data/lib/musicality/{composition/model/pitch_classes.rb → pitch_classes.rb} +9 -9
- data/lib/musicality/printing/lilypond/clef.rb +12 -0
- data/lib/musicality/printing/lilypond/key_engraving.rb +9 -0
- data/lib/musicality/printing/lilypond/lilypond_settings.rb +105 -0
- data/lib/musicality/printing/lilypond/meter_engraving.rb +1 -1
- data/lib/musicality/printing/lilypond/note_engraving.rb +112 -30
- data/lib/musicality/printing/lilypond/part_engraver.rb +114 -3
- data/lib/musicality/printing/lilypond/pitch_class_engraving.rb +22 -0
- data/lib/musicality/printing/lilypond/pitch_engraving.rb +2 -15
- data/lib/musicality/printing/lilypond/score_engraver.rb +44 -73
- data/lib/musicality/printing/lilypond/score_engraving.rb +3 -3
- data/lib/musicality/project/create_tasks.rb +31 -0
- data/lib/musicality/project/file_cleaner.rb +19 -0
- data/lib/musicality/project/file_raker.rb +107 -0
- data/lib/musicality/project/load_config.rb +43 -0
- data/lib/musicality/project/project.rb +64 -0
- data/lib/musicality/version.rb +1 -1
- data/musicality.gemspec +3 -0
- data/spec/composition/util/random_sampler_spec.rb +1 -1
- data/spec/notation/conversion/measure_note_map_spec.rb +1 -1
- data/spec/notation/conversion/note_time_converter_spec.rb +5 -85
- data/spec/notation/conversion/score_conversion_spec.rb +6 -41
- data/spec/notation/conversion/score_converter_spec.rb +19 -137
- data/spec/notation/model/change_spec.rb +55 -0
- data/spec/notation/model/key_spec.rb +171 -0
- data/spec/notation/model/link_spec.rb +34 -5
- data/spec/notation/model/meter_spec.rb +15 -0
- data/spec/notation/model/note_spec.rb +33 -27
- data/spec/notation/model/part_spec.rb +53 -4
- data/spec/notation/model/pitch_spec.rb +15 -0
- data/spec/notation/model/score_spec.rb +64 -72
- data/spec/notation/parsing/link_nodes_spec.rb +3 -3
- data/spec/notation/parsing/link_parsing_spec.rb +6 -6
- data/spec/notation/parsing/note_node_spec.rb +34 -9
- data/spec/notation/parsing/note_parsing_spec.rb +11 -9
- data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +4 -0
- data/spec/notation/parsing/pitch_node_spec.rb +0 -1
- data/spec/notation/util/value_computer_spec.rb +2 -2
- data/spec/performance/conversion/glissando_converter_spec.rb +9 -9
- data/spec/performance/conversion/note_sequence_extractor_spec.rb +48 -53
- data/spec/performance/conversion/portamento_converter_spec.rb +11 -9
- data/spec/performance/conversion/score_collator_spec.rb +59 -63
- data/spec/performance/midi/midi_util_spec.rb +22 -8
- data/spec/performance/midi/part_sequencer_spec.rb +2 -2
- data/spec/performance/midi/score_sequencer_spec.rb +12 -10
- data/spec/performance/midi/score_sequencing_spec.rb +2 -2
- data/spec/performance/model/note_sequence_spec.rb +41 -134
- data/spec/printing/note_engraving_spec.rb +204 -0
- data/spec/printing/score_engraver_spec.rb +40 -0
- data/spec/spec_helper.rb +1 -0
- metadata +69 -23
- data/examples/notation/hip.rb +0 -32
- data/examples/notation/missed_connection.rb +0 -26
- data/examples/notation/song1.rb +0 -33
- data/examples/notation/song2.rb +0 -32
- data/lib/musicality/notation/model/links.rb +0 -11
- data/lib/musicality/notation/packing/change_packing.rb +0 -56
- data/lib/musicality/notation/packing/part_packing.rb +0 -31
- data/lib/musicality/notation/packing/score_packing.rb +0 -123
- data/lib/musicality/performance/model/note_attacks.rb +0 -19
- data/lib/musicality/performance/util/note_linker.rb +0 -28
- data/spec/notation/packing/change_packing_spec.rb +0 -304
- data/spec/notation/packing/part_packing_spec.rb +0 -66
- data/spec/notation/packing/score_packing_spec.rb +0 -255
- data/spec/performance/util/note_linker_spec.rb +0 -68
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
describe Pitch do
|
4
5
|
|
@@ -158,6 +159,20 @@ describe Pitch do
|
|
158
159
|
YAML.load(p.to_yaml).should eq p
|
159
160
|
end
|
160
161
|
end
|
162
|
+
|
163
|
+
describe '#pack' do
|
164
|
+
it 'should produce a Hash' do
|
165
|
+
Bb3.pack.should be_a Hash
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe 'unpack' do
|
170
|
+
it 'should produce an object equal the original' do
|
171
|
+
p2 = Pitch.unpack Bb3.pack
|
172
|
+
p2.should be_a Pitch
|
173
|
+
p2.should eq Bb3
|
174
|
+
end
|
175
|
+
end
|
161
176
|
|
162
177
|
describe '#to_s' do
|
163
178
|
context 'on-letter semitones' do
|
@@ -117,17 +117,31 @@ describe Score do
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
describe Score::
|
120
|
+
describe Score::Tempo do
|
121
|
+
before :all do
|
122
|
+
@basic_score = Score::Tempo.new(TWO_FOUR, 120,
|
123
|
+
meter_changes: {
|
124
|
+
2 => Change::Immediate.new(FOUR_FOUR),
|
125
|
+
4 => Change::Immediate.new(SIX_EIGHT),
|
126
|
+
},
|
127
|
+
parts: {
|
128
|
+
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
129
|
+
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1 /2".to_notes)
|
130
|
+
},
|
131
|
+
program: [ (0.5)..Rational(1,2), 0..1, 1..2 ]
|
132
|
+
)
|
133
|
+
end
|
134
|
+
|
121
135
|
describe '#initialize' do
|
122
136
|
it 'should use empty containers for parameters not given' do
|
123
|
-
s = Score::
|
137
|
+
s = Score::Tempo.new(FOUR_FOUR,120)
|
124
138
|
s.parts.should be_empty
|
125
139
|
s.program.should be_empty
|
126
140
|
end
|
127
141
|
|
128
142
|
it 'should assign given parameters' do
|
129
143
|
m = FOUR_FOUR
|
130
|
-
s = Score::
|
144
|
+
s = Score::Tempo.new(m,120)
|
131
145
|
s.start_meter.should eq m
|
132
146
|
s.start_tempo.should eq 120
|
133
147
|
|
@@ -136,7 +150,7 @@ describe Score::Measured do
|
|
136
150
|
mcs = { 1 => Change::Immediate.new(THREE_FOUR) }
|
137
151
|
tcs = { 1 => Change::Immediate.new(100) }
|
138
152
|
|
139
|
-
s = Score::
|
153
|
+
s = Score::Tempo.new(m,120,
|
140
154
|
parts: parts,
|
141
155
|
program: program,
|
142
156
|
meter_changes: mcs,
|
@@ -153,13 +167,13 @@ describe Score::Measured do
|
|
153
167
|
context 'with no meter changes' do
|
154
168
|
context 'with no parts' do
|
155
169
|
it 'should return 0' do
|
156
|
-
Score::
|
170
|
+
Score::Tempo.new(TWO_FOUR, 120).measures_long.should eq(0)
|
157
171
|
end
|
158
172
|
end
|
159
173
|
|
160
174
|
context 'with one part' do
|
161
175
|
it 'should return the duration of the part, in measures' do
|
162
|
-
Score::
|
176
|
+
Score::Tempo.new(TWO_FOUR, 120, parts: {
|
163
177
|
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes)
|
164
178
|
}).measures_long.should eq(3.5)
|
165
179
|
end
|
@@ -167,7 +181,7 @@ describe Score::Measured do
|
|
167
181
|
|
168
182
|
context 'with two parts' do
|
169
183
|
it 'should return the duration of the longest part, in measures' do
|
170
|
-
Score::
|
184
|
+
Score::Tempo.new(TWO_FOUR, 120, parts: {
|
171
185
|
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
172
186
|
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
173
187
|
}).measures_long.should eq(4)
|
@@ -177,7 +191,7 @@ describe Score::Measured do
|
|
177
191
|
|
178
192
|
context 'with meter changes' do
|
179
193
|
it 'should return the duration of the longest part, in measures' do
|
180
|
-
Score::
|
194
|
+
Score::Tempo.new(TWO_FOUR, 120,
|
181
195
|
meter_changes: {
|
182
196
|
2 => Change::Immediate.new(FOUR_FOUR),
|
183
197
|
},
|
@@ -187,7 +201,7 @@ describe Score::Measured do
|
|
187
201
|
}
|
188
202
|
).measures_long.should eq(3)
|
189
203
|
|
190
|
-
Score::
|
204
|
+
Score::Tempo.new(TWO_FOUR, 120,
|
191
205
|
meter_changes: {
|
192
206
|
2 => Change::Immediate.new(FOUR_FOUR),
|
193
207
|
4 => Change::Immediate.new(SIX_EIGHT),
|
@@ -202,7 +216,7 @@ describe Score::Measured do
|
|
202
216
|
|
203
217
|
context 'given specific note duration' do
|
204
218
|
it 'should change the given note duration to measures' do
|
205
|
-
score = Score::
|
219
|
+
score = Score::Tempo.new(TWO_FOUR, 120,
|
206
220
|
meter_changes: {
|
207
221
|
2 => Change::Immediate.new(FOUR_FOUR),
|
208
222
|
4 => Change::Immediate.new(SIX_EIGHT)
|
@@ -228,7 +242,7 @@ describe Score::Measured do
|
|
228
242
|
}.each do |context_str,args|
|
229
243
|
context context_str do
|
230
244
|
it 'should return true' do
|
231
|
-
Score::
|
245
|
+
Score::Tempo.new(*args).should be_valid
|
232
246
|
end
|
233
247
|
end
|
234
248
|
end
|
@@ -251,77 +265,33 @@ describe Score::Measured do
|
|
251
265
|
}.each do |context_str,args|
|
252
266
|
context context_str do
|
253
267
|
it 'should return false' do
|
254
|
-
Score::
|
268
|
+
Score::Tempo.new(*args).should be_invalid
|
255
269
|
end
|
256
270
|
end
|
257
271
|
end
|
258
272
|
end
|
259
|
-
end
|
260
273
|
|
261
|
-
describe
|
262
|
-
|
263
|
-
|
264
|
-
s = Score::Unmeasured.new(30)
|
265
|
-
s.parts.should be_empty
|
266
|
-
s.program.should be_empty
|
274
|
+
describe '#pack' do
|
275
|
+
it 'should produce a Hash' do
|
276
|
+
@basic_score.pack.should be_a Hash
|
267
277
|
end
|
268
|
-
|
269
|
-
it 'should
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
parts = { "piano (LH)" => Samples::SAMPLE_PART }
|
274
|
-
program = [0...0.75, 0...0.75]
|
275
|
-
tcs = { 1 => Change::Immediate.new(40) }
|
276
|
-
|
277
|
-
s = Score::Unmeasured.new(30,
|
278
|
-
parts: parts,
|
279
|
-
program: program,
|
280
|
-
tempo_changes: tcs
|
281
|
-
)
|
282
|
-
s.parts.should eq parts
|
283
|
-
s.program.should eq program
|
284
|
-
s.tempo_changes.should eq tcs
|
278
|
+
|
279
|
+
it 'should pack program as an array of strings' do
|
280
|
+
program = @basic_score.pack[:program]
|
281
|
+
program.each {|entry| entry.should be_a String}
|
285
282
|
end
|
286
|
-
end
|
287
283
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
292
|
-
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
293
|
-
}).notes_long.should eq(2)
|
284
|
+
it 'should pack sections as a Hash of strings' do
|
285
|
+
program = @basic_score.pack[:sections]
|
286
|
+
program.each {|name,entry| entry.should be_a String}
|
294
287
|
end
|
295
288
|
end
|
296
|
-
|
297
|
-
describe '
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
'valid part' => [ 30, :parts => { "piano" => Samples::SAMPLE_PART }],
|
303
|
-
'valid program' => [ 30, :program => [0..2,0..2] ]
|
304
|
-
}.each do |context_str,args|
|
305
|
-
context context_str do
|
306
|
-
it 'should return true' do
|
307
|
-
Score::Unmeasured.new(*args).should be_valid
|
308
|
-
end
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
{
|
313
|
-
'start tempo valid is zero' => [ 0 ],
|
314
|
-
'start tempo valid is negative' => [ -1 ],
|
315
|
-
'tempo change value is not a valid value' => [ 30,
|
316
|
-
:tempo_changes => { 1 => Change::Gradual.linear(-1,1) } ],
|
317
|
-
'invalid part' => [ 30, :parts => { "piano" => Part.new(-0.1) }],
|
318
|
-
'invalid program' => [ 30, :program => [2..0] ],
|
319
|
-
}.each do |context_str,args|
|
320
|
-
context context_str do
|
321
|
-
it 'should return false' do
|
322
|
-
Score::Unmeasured.new(*args).should be_invalid
|
323
|
-
end
|
324
|
-
end
|
289
|
+
|
290
|
+
describe 'unpack' do
|
291
|
+
it 'should produce an object equal the original' do
|
292
|
+
score2 = Score::Tempo.unpack @basic_score.pack
|
293
|
+
score2.should be_a Score
|
294
|
+
score2.should eq @basic_score
|
325
295
|
end
|
326
296
|
end
|
327
297
|
end
|
@@ -376,4 +346,26 @@ describe Score::Timed do
|
|
376
346
|
end
|
377
347
|
end
|
378
348
|
end
|
349
|
+
|
350
|
+
describe '#pack' do
|
351
|
+
it 'should produce a Hash' do
|
352
|
+
score = Score::Timed.new(parts: {
|
353
|
+
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
354
|
+
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
355
|
+
})
|
356
|
+
score.pack.should be_a Hash
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
describe 'unpack' do
|
361
|
+
it 'should produce an object equal the original' do
|
362
|
+
score = Score::Timed.new(parts: {
|
363
|
+
"abc" => Part.new(Dynamics::MF, notes: "/4 /4 /2 3/4".to_notes),
|
364
|
+
"def" => Part.new(Dynamics::MF, notes: "/4 /4 /2 1".to_notes)
|
365
|
+
})
|
366
|
+
score2 = Score::Timed.unpack score.pack
|
367
|
+
score2.should be_a score.class
|
368
|
+
score2.should eq score
|
369
|
+
end
|
370
|
+
end
|
379
371
|
end
|
@@ -4,9 +4,9 @@ describe Parsing::LinkNode do
|
|
4
4
|
parser = Parsing::LinkParser.new
|
5
5
|
|
6
6
|
{
|
7
|
-
LINK_SYMBOLS[
|
8
|
-
(LINK_SYMBOLS[
|
9
|
-
(LINK_SYMBOLS[
|
7
|
+
LINK_SYMBOLS[Link::Tie] => Link::Tie.new,
|
8
|
+
(LINK_SYMBOLS[Link::Glissando] + Db2.to_s) => Link::Glissando.new(Db2),
|
9
|
+
(LINK_SYMBOLS[Link::Portamento] + Db2.to_s) => Link::Portamento.new(Db2),
|
10
10
|
}.each do |str,tgt|
|
11
11
|
res = parser.parse(str)
|
12
12
|
context str do
|
@@ -5,15 +5,15 @@ describe Parsing::LinkParser do
|
|
5
5
|
@parser = Parsing::LinkParser.new
|
6
6
|
end
|
7
7
|
|
8
|
-
it "should parse #{LINK_SYMBOLS[
|
9
|
-
@parser.should parse(LINK_SYMBOLS[
|
8
|
+
it "should parse #{LINK_SYMBOLS[Link::Tie]}" do
|
9
|
+
@parser.should parse(LINK_SYMBOLS[Link::Tie])
|
10
10
|
end
|
11
11
|
|
12
|
-
it "should parse #{LINK_SYMBOLS[
|
13
|
-
@parser.should parse(LINK_SYMBOLS[
|
12
|
+
it "should parse #{LINK_SYMBOLS[Link::Glissando]} with target pitch" do
|
13
|
+
@parser.should parse(LINK_SYMBOLS[Link::Glissando] + C3.to_s)
|
14
14
|
end
|
15
15
|
|
16
|
-
it "should parse #{LINK_SYMBOLS[
|
17
|
-
@parser.should parse(LINK_SYMBOLS[
|
16
|
+
it "should parse #{LINK_SYMBOLS[Link::Portamento]} with target pitch" do
|
17
|
+
@parser.should parse(LINK_SYMBOLS[Link::Portamento] + C3.to_s)
|
18
18
|
end
|
19
19
|
end
|
@@ -32,15 +32,15 @@ describe Parsing::NoteNode do
|
|
32
32
|
|
33
33
|
context 'monophonic note' do
|
34
34
|
{
|
35
|
-
'/2C2
|
35
|
+
'/2C2~' => Note.new(Rational(1,2),[C2], links: { C2 => Link::Tie.new}),
|
36
36
|
'4/2D#6.' => Note.new(Rational(4,2),[Eb6],articulation:STACCATO),
|
37
|
-
'
|
38
|
-
"56/33B1
|
37
|
+
'28Eb7_' => Note.new(Rational(28,1),[Eb7],articulation:PORTATO),
|
38
|
+
"56/33B1!" => Note.new(Rational(56,33),[B1],articulation:STACCATISSIMO),
|
39
39
|
}.each do |str,tgt|
|
40
40
|
res = NOTE_PARSER.parse(str)
|
41
41
|
|
42
42
|
context str do
|
43
|
-
it 'should parse as
|
43
|
+
it 'should parse as `Node' do
|
44
44
|
res.should be_a Parsing::NoteNode
|
45
45
|
end
|
46
46
|
|
@@ -60,20 +60,21 @@ describe Parsing::NoteNode do
|
|
60
60
|
|
61
61
|
context 'polyphonic note' do
|
62
62
|
{
|
63
|
-
'/2C2,D2,E2
|
64
|
-
'/2C2,D2,E2
|
63
|
+
'/2C2,D2,E2>' => Note.new(Rational(1,2),[C2,D2,E2],articulation: Articulations::ACCENT),
|
64
|
+
'/2C2,D2,E2^' => Note.new(Rational(1,2),[C2,D2,E2],articulation: Articulations::MARCATO),
|
65
65
|
'4/2D#6,G4.' => Note.new(Rational(4,2),[Eb6,G4], articulation: Articulations::STACCATO),
|
66
|
-
'28Eb7,D7,
|
67
|
-
'56/33B1,B2,B3,B4,
|
66
|
+
'28Eb7,D7,G7-' => Note.new(Rational(28,1),[Eb7,D7,G7], articulation: Articulations::TENUTO),
|
67
|
+
'56/33B1,B2,B3,B4,B5_' => Note.new(Rational(56,33),[B1,B2,B3,B4,B5], articulation: Articulations::PORTATO),
|
68
68
|
}.each do |str,tgt|
|
69
69
|
res = NOTE_PARSER.parse(str)
|
70
70
|
context str do
|
71
|
-
it 'should parse as
|
71
|
+
it 'should parse as NoteNode' do
|
72
72
|
res.should be_a Parsing::NoteNode
|
73
73
|
end
|
74
74
|
|
75
75
|
describe '#to_note' do
|
76
76
|
n = res.to_note
|
77
|
+
|
77
78
|
it 'should produce a Note' do
|
78
79
|
n.should be_a Note
|
79
80
|
end
|
@@ -85,4 +86,28 @@ describe Parsing::NoteNode do
|
|
85
86
|
end
|
86
87
|
end
|
87
88
|
end
|
89
|
+
|
90
|
+
context 'with marks' do
|
91
|
+
[[BEGIN_SLUR],[BEGIN_SLUR, BEGIN_TRIPLET],[BEGIN_TRIPLET]].each do |begin_marks|
|
92
|
+
begin_marks_str = begin_marks.map {|m| m.to_s}.join
|
93
|
+
[[END_SLUR],[END_SLUR, END_TRIPLET],[END_TRIPLET]].each do |end_marks|
|
94
|
+
end_marks_str = end_marks.map {|m| m.to_s}.join
|
95
|
+
describe '#to_note' do
|
96
|
+
it 'should produce a Note with marks set correctly' do
|
97
|
+
str = "#{begin_marks_str}/4Bb2#{end_marks_str}"
|
98
|
+
n = NOTE_PARSER.parse(str).to_note
|
99
|
+
n.marks.should eq(begin_marks+end_marks)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'without marks' do
|
107
|
+
it 'should produce a Note with marks set to []' do
|
108
|
+
str = "/4Bb2"
|
109
|
+
n = NOTE_PARSER.parse(str).to_note
|
110
|
+
n.marks.should eq([])
|
111
|
+
end
|
112
|
+
end
|
88
113
|
end
|
@@ -9,20 +9,22 @@ describe Parsing::NoteParser do
|
|
9
9
|
'duration only' => ['1/4','/2','1','55/33'],
|
10
10
|
'single pitch' => ['/4C2','5/3Db3','/33E#8'],
|
11
11
|
'multiple pitches' => ['/4C2,C3,c5','5/3Db3,Bb2,E5','/33E#8,F1,B9'],
|
12
|
-
'with articulation' => ['/4C2.',"5/3Db3,Bb2,E5
|
13
|
-
'with accent' => ['/4C2
|
14
|
-
'with links' => ['/2C2
|
12
|
+
'with articulation' => ['/4C2.',"5/3Db3,Bb2,E5.",'/2D3,F4_'],
|
13
|
+
'with accent' => ['/4C2','3/2Db3,Bb4'],
|
14
|
+
'with links' => ['/2C2~','/2C2:D2','/4D4:E4,G4;A5.'],
|
15
|
+
'with marks' => ['(3/4Bb3]', '[/2F3,G3)', '[(2/4C3', '([1B2', '/3B2,C2)]', '2/3D4])'],
|
15
16
|
'with single pitch + articulation + link + accent' => [
|
16
|
-
'3/4D2
|
17
|
+
'(3/4D2~','5/8F2;G2.','/8Db4:Db5','/3G4;B4_'],
|
17
18
|
'with multiple pitches + articulation + links + accent' => [
|
18
|
-
'5/4D2
|
19
|
+
'5/4D2~,G4:A4,C3;D3.','5/8F2~,B4:A4_'],
|
19
20
|
}
|
20
21
|
invalid_cases = {
|
21
|
-
'duration +
|
22
|
-
'duration +
|
23
|
-
'duration + accent + link' => ['1/4!~','/2!/','2/3=!'],
|
22
|
+
'duration + articulation' => ['1/4.','/2.','2/3!'],
|
23
|
+
'duration + accent + link' => ['1/4;','/2:','2/3~'],
|
24
24
|
'single pith with bad letter' => ['5/3Hb3'],
|
25
|
-
'single pitch without octave' => ['/33E
|
25
|
+
'single pitch without octave' => ['/33E)'],
|
26
|
+
'begins marks at the end' => ['1Bb3(', '2Bb3['],
|
27
|
+
'end marks at the beginning ' => [']1B5', ')3C3']
|
26
28
|
}
|
27
29
|
|
28
30
|
valid_cases.each do |descr, strs|
|
@@ -14,7 +14,7 @@ describe ValueComputer do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should always return default value if no changes are given" do
|
17
|
-
[ValueComputer::DOMAIN_MIN, -1000, 0, 1, 5, 100, 10000
|
17
|
+
[ValueComputer::DOMAIN_MIN, -1000, 0, 1, 5, 100, 10000].each do |offset|
|
18
18
|
@comp.at(offset).should eq(0.5)
|
19
19
|
end
|
20
20
|
end
|
@@ -38,7 +38,7 @@ describe ValueComputer do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should be at the second value for all time after" do
|
41
|
-
@comp.at(
|
41
|
+
@comp.at(100_000).should eq(0.6)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -70,12 +70,12 @@ describe GlissandoConverter do
|
|
70
70
|
describe '.glissando_elements' do
|
71
71
|
before :all do
|
72
72
|
@dur = Rational(3,2)
|
73
|
-
@
|
74
|
-
@els = GlissandoConverter.glissando_elements(C4,A4,@dur,@
|
73
|
+
@att = Attack::TENUTO
|
74
|
+
@els = GlissandoConverter.glissando_elements(C4,A4,@dur,@att)
|
75
75
|
end
|
76
76
|
|
77
|
-
it 'should return an array of
|
78
|
-
@els.each {|el| el.should be_a
|
77
|
+
it 'should return an array of NoteSequence::Element objects' do
|
78
|
+
@els.each {|el| el.should be_a NoteSequence::Element }
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'should split up duration among elements' do
|
@@ -83,11 +83,11 @@ describe GlissandoConverter do
|
|
83
83
|
sum.should eq(@dur)
|
84
84
|
end
|
85
85
|
|
86
|
-
it 'should set
|
87
|
-
els = GlissandoConverter.glissando_elements(C4,A4,1,
|
88
|
-
els.each {|el| el.
|
89
|
-
els = GlissandoConverter.glissando_elements(C4,A4,1,
|
90
|
-
els.each {|el| el.
|
86
|
+
it 'should set attack as given for each element' do
|
87
|
+
els = GlissandoConverter.glissando_elements(C4,A4,1,Attack::TENUTO)
|
88
|
+
els.each {|el| el.attack.should eq(Attack::TENUTO) }
|
89
|
+
els = GlissandoConverter.glissando_elements(C4,A4,1,Attack::ACCENT)
|
90
|
+
els.each {|el| el.attack.should eq(Attack::ACCENT) }
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|