musicality 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/lib/musicality/version.rb
CHANGED
data/musicality.gemspec
CHANGED
@@ -28,7 +28,7 @@ describe RandomSampler do
|
|
28
28
|
sampler.values.each_with_index do |val,i|
|
29
29
|
count = counts[val]
|
30
30
|
tgt_prob = sampler.probabilities[i]
|
31
|
-
(count / 1000.to_f).should be_within(0.
|
31
|
+
(count / 1000.to_f).should be_within(0.1).of(tgt_prob)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -35,7 +35,7 @@ describe 'Conversion.measure_note_map' do
|
|
35
35
|
@first_mc_off = 3
|
36
36
|
@start_meter = THREE_FOUR
|
37
37
|
@new_meter = TWO_FOUR
|
38
|
-
@score = Score::
|
38
|
+
@score = Score::Tempo.new(@start_meter, 120,
|
39
39
|
meter_changes: { @first_mc_off => Change::Immediate.new(@new_meter) },
|
40
40
|
tempo_changes: {
|
41
41
|
"1/2".to_r => Change::Gradual.linear(100,1),
|
@@ -1,92 +1,12 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
|
-
describe NoteTimeConverter::
|
4
|
-
describe '#notes_per_second_at' do
|
5
|
-
it 'should convert tempo using Tempo::QNPM.to_nps' do
|
6
|
-
tc = ValueComputer.new(
|
7
|
-
120, 1 => Change::Gradual.linear(100,1), 2 => Change::Gradual.linear(150,1))
|
8
|
-
converter = NoteTimeConverter::Unmeasured.new(tc,200)
|
9
|
-
(0..2).step(0.2).each do |offset|
|
10
|
-
nps = Tempo::QNPM.to_nps(tc.at(offset))
|
11
|
-
converter.notes_per_second_at(offset).should eq(nps)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "#time_elapsed" do
|
17
|
-
context "constant tempo" do
|
18
|
-
before :each do
|
19
|
-
@tempo_computer = ValueComputer.new 120
|
20
|
-
sample_rate = 48
|
21
|
-
@converter = NoteTimeConverter::Unmeasured.new(@tempo_computer, sample_rate)
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should return a time of zero when note end is zero." do
|
25
|
-
@converter.time_elapsed(0, 0).should eq(0)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should return a time of 1 second when note end is equal to the initial notes-per-second" do
|
29
|
-
note_end = @converter.notes_per_second_at(0)
|
30
|
-
@converter.time_elapsed(0, note_end).should eq(1)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context "linear tempo-change" do
|
35
|
-
before :each do
|
36
|
-
@tempo_computer = ValueComputer.new(
|
37
|
-
120, 1 => Change::Gradual.linear(60, 1))
|
38
|
-
sample_rate = 200
|
39
|
-
@converter = NoteTimeConverter::Unmeasured.new(@tempo_computer, sample_rate)
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should return a time of zero when note end is zero." do
|
43
|
-
@converter.time_elapsed(0.0, 0.0).should eq(0.0)
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should return a time of 3 sec during a 1-note long transition from 120bpm to 60bpm" do
|
47
|
-
@converter.notes_per_second_at(1.0).should eq(0.5)
|
48
|
-
@converter.notes_per_second_at(2.0).should eq(0.25)
|
49
|
-
|
50
|
-
@converter.time_elapsed(1.0, 2.0).should be_within(0.05).of(2.77)
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "#note_time_map" do
|
57
|
-
context "constant tempo" do
|
58
|
-
before :each do
|
59
|
-
@tempo_computer = ValueComputer.new 120
|
60
|
-
sample_rate = 4800
|
61
|
-
@converter = NoteTimeConverter::Unmeasured.new(
|
62
|
-
@tempo_computer, sample_rate)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should map offset 0.0 to time 0.0" do
|
66
|
-
map = @converter.note_time_map [0.0]
|
67
|
-
map[0.0].should eq(0.0)
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should map offset 0.25 to time 0.5" do
|
71
|
-
map = @converter.note_time_map [0.0, 0.25]
|
72
|
-
map[0.25].should be_within(0.01).of(0.5)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should map offset 1.0 to time 2.0" do
|
76
|
-
map = @converter.note_time_map [0.0, 1.0]
|
77
|
-
map[1.0].should be_within(0.01).of(2.0)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe NoteTimeConverter::Measured do
|
3
|
+
describe NoteTimeConverter::Tempo do
|
84
4
|
describe '#notes_per_second_at' do
|
85
5
|
it 'should convert tempo using Tempo::BPM.to_nps' do
|
86
6
|
tc = ValueComputer.new(120, 1 => Change::Gradual.linear(100,1),
|
87
7
|
2 => Change::Gradual.linear(150,1))
|
88
8
|
bdc = ValueComputer.new(0.25.to_r, 2.5 => Change::Immediate.new(0.375.to_r))
|
89
|
-
converter = NoteTimeConverter
|
9
|
+
converter = NoteTimeConverter.new(tc,bdc,200)
|
90
10
|
(0..3.2).step(0.2).each do |offset|
|
91
11
|
nps = Tempo::BPM.to_nps(tc.at(offset), bdc.at(offset))
|
92
12
|
converter.notes_per_second_at(offset).should eq(nps)
|
@@ -100,7 +20,7 @@ describe NoteTimeConverter::Measured do
|
|
100
20
|
@tempo_computer = ValueComputer.new 120
|
101
21
|
@bdur_computer = ValueComputer.new Rational(1,4)
|
102
22
|
sample_rate = 48
|
103
|
-
@converter = NoteTimeConverter
|
23
|
+
@converter = NoteTimeConverter.new(@tempo_computer, @bdur_computer, sample_rate)
|
104
24
|
end
|
105
25
|
|
106
26
|
it "should return a time of zero when note end is zero." do
|
@@ -118,7 +38,7 @@ describe NoteTimeConverter::Measured do
|
|
118
38
|
@tempo_computer = ValueComputer.new(120, 1 => Change::Gradual.linear(60, 1))
|
119
39
|
@bdur_computer = ValueComputer.new Rational(1,4)
|
120
40
|
sample_rate = 200
|
121
|
-
@converter = NoteTimeConverter
|
41
|
+
@converter = NoteTimeConverter.new(@tempo_computer, @bdur_computer, sample_rate)
|
122
42
|
end
|
123
43
|
|
124
44
|
it "should return a time of zero when note end is zero." do
|
@@ -141,7 +61,7 @@ describe NoteTimeConverter::Measured do
|
|
141
61
|
@tempo_computer = ValueComputer.new 120
|
142
62
|
@bdur_computer = ValueComputer.new Rational(1,4)
|
143
63
|
sample_rate = 4800
|
144
|
-
@converter = NoteTimeConverter
|
64
|
+
@converter = NoteTimeConverter.new(@tempo_computer, @bdur_computer, sample_rate)
|
145
65
|
end
|
146
66
|
|
147
67
|
it "should map offset 0.0 to time 0.0" do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
|
-
describe Score::
|
3
|
+
describe Score::Tempo do
|
4
4
|
before :all do
|
5
5
|
@parts = {
|
6
6
|
"piano" => Part.new(Dynamics::MP,
|
@@ -23,7 +23,7 @@ describe Score::Measured do
|
|
23
23
|
1 => Change::Immediate.new(TWO_FOUR),
|
24
24
|
3 => Change::Immediate.new(SIX_EIGHT)
|
25
25
|
}
|
26
|
-
@score = Score::
|
26
|
+
@score = Score::Tempo.new(THREE_FOUR, 120,
|
27
27
|
parts: @parts,
|
28
28
|
program: @prog,
|
29
29
|
tempo_changes: tcs,
|
@@ -94,7 +94,7 @@ describe Score::Measured do
|
|
94
94
|
context 'meter change at offset 0' do
|
95
95
|
before :all do
|
96
96
|
@change = Change::Immediate.new(THREE_FOUR)
|
97
|
-
@score2 = Score::
|
97
|
+
@score2 = Score::Tempo.new(FOUR_FOUR, 120, meter_changes: { 0 => @change })
|
98
98
|
@mdurs2 = @score2.measure_durations
|
99
99
|
end
|
100
100
|
|
@@ -113,7 +113,7 @@ describe Score::Measured do
|
|
113
113
|
|
114
114
|
context 'no meter changes' do
|
115
115
|
before :all do
|
116
|
-
@score3 = Score::
|
116
|
+
@score3 = Score::Tempo.new(FOUR_FOUR, 120)
|
117
117
|
@mdurs3 = @score3.measure_durations
|
118
118
|
end
|
119
119
|
|
@@ -132,45 +132,10 @@ describe Score::Measured do
|
|
132
132
|
end
|
133
133
|
|
134
134
|
describe '#to_timed' do
|
135
|
-
it 'should use ScoreConverter
|
135
|
+
it 'should use ScoreConverter#convert_score' do
|
136
136
|
nscore1 = @score.to_timed(200)
|
137
|
-
nscore2 = ScoreConverter
|
137
|
+
nscore2 = ScoreConverter.new(@score,200).convert_score
|
138
138
|
nscore1.should eq(nscore2)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
end
|
142
|
-
|
143
|
-
describe Score::Unmeasured do
|
144
|
-
before :all do
|
145
|
-
@parts = {
|
146
|
-
"piano" => Part.new(Dynamics::MP,
|
147
|
-
notes: [Note.quarter(C4), Note.eighth(F3), Note.whole(C4), Note.half(D4)]*12,
|
148
|
-
dynamic_changes: {
|
149
|
-
1 => Change::Immediate.new(Dynamics::MF),
|
150
|
-
5 => Change::Immediate.new(Dynamics::FF),
|
151
|
-
6 => Change::Gradual.linear(Dynamics::MF,2),
|
152
|
-
14 => Change::Immediate.new(Dynamics::PP),
|
153
|
-
}
|
154
|
-
)
|
155
|
-
}
|
156
|
-
@prog = [0...3,4...7,1...20,17..."45/2".to_r]
|
157
|
-
tcs = {
|
158
|
-
0 => Change::Immediate.new(120),
|
159
|
-
4 => Change::Gradual.linear(60,2),
|
160
|
-
11 => Change::Immediate.new(110)
|
161
|
-
}
|
162
|
-
@score = Score::Unmeasured.new(120,
|
163
|
-
parts: @parts,
|
164
|
-
program: @prog,
|
165
|
-
tempo_changes: tcs,
|
166
|
-
)
|
167
|
-
end
|
168
|
-
|
169
|
-
describe '#to_timed' do
|
170
|
-
it 'should use ScoreConverter::Unmeasured#convert_score' do
|
171
|
-
nscore1 = @score.to_timed(200)
|
172
|
-
nscore2 = ScoreConverter::Unmeasured.new(@score,200).convert_score
|
173
|
-
nscore1.should eq(nscore2)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
|
-
describe ScoreConverter
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
describe ScoreConverter::Measured do
|
3
|
+
describe ScoreConverter do
|
8
4
|
describe '#initialize' do
|
9
5
|
context 'current score is invalid' do
|
10
6
|
it 'should raise NotValidError' do
|
11
|
-
score = Score::
|
12
|
-
expect { ScoreConverter
|
7
|
+
score = Score::Tempo.new(1, 120)
|
8
|
+
expect { ScoreConverter.new(score,200) }.to raise_error(NotValidError)
|
13
9
|
end
|
14
10
|
end
|
15
11
|
end
|
@@ -18,19 +14,19 @@ describe ScoreConverter::Measured do
|
|
18
14
|
before :each do
|
19
15
|
@changeA = Change::Immediate.new(Dynamics::PP)
|
20
16
|
@changeB = Change::Gradual.linear(Dynamics::F, 2)
|
21
|
-
@score = Score::
|
17
|
+
@score = Score::Tempo.new(FOUR_FOUR, 120,
|
22
18
|
parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => @changeA, 3 => @changeB })}
|
23
19
|
)
|
24
20
|
end
|
25
21
|
|
26
22
|
it 'should return Hash with original part names' do
|
27
|
-
parts = ScoreConverter
|
23
|
+
parts = ScoreConverter.new(@score,200).convert_parts
|
28
24
|
parts.should be_a Hash
|
29
25
|
parts.keys.sort.should eq(@score.parts.keys.sort)
|
30
26
|
end
|
31
27
|
|
32
28
|
it 'should convert part dynamic change offsets from measure-based to note-based' do
|
33
|
-
parts = ScoreConverter
|
29
|
+
parts = ScoreConverter.new(@score,200).convert_parts
|
34
30
|
parts.should have_key("simple")
|
35
31
|
part = parts["simple"]
|
36
32
|
part.dynamic_changes.keys.sort.should eq([2,6])
|
@@ -41,7 +37,7 @@ describe ScoreConverter::Measured do
|
|
41
37
|
change.duration.should eq(4)
|
42
38
|
|
43
39
|
#@score.start_meter = THREE_FOUR
|
44
|
-
#parts = ScoreConverter
|
40
|
+
#parts = ScoreConverter.new(@score,200).convert_parts
|
45
41
|
#parts.should have_key("simple")
|
46
42
|
#part = parts["simple"]
|
47
43
|
#part.dynamic_changes.keys.sort.should eq([Rational(3,4),Rational(9,4)])
|
@@ -55,13 +51,13 @@ describe ScoreConverter::Measured do
|
|
55
51
|
|
56
52
|
#context 'gradual changes with positive elapsed and/or remaining' do
|
57
53
|
# it 'should change elapsed and remaining so they reflect note-based offsets' do
|
58
|
-
# score = Score::
|
54
|
+
# score = Score::Tempo.new(THREE_FOUR,120, parts: {
|
59
55
|
# "abc" => Part.new(Dynamics::P, dynamic_changes: {
|
60
56
|
# 2 => Change::Gradual.linear(Dynamics::F,2,1,3),
|
61
57
|
# 7 => Change::Gradual.linear(Dynamics::F,1,4,5)
|
62
58
|
# })
|
63
59
|
# })
|
64
|
-
# converter = ScoreConverter
|
60
|
+
# converter = ScoreConverter.new(score)
|
65
61
|
# parts = converter.convert_parts
|
66
62
|
# dcs = parts["abc"].dynamic_changes
|
67
63
|
#
|
@@ -75,8 +71,8 @@ describe ScoreConverter::Measured do
|
|
75
71
|
describe '#convert_program' do
|
76
72
|
before :each do
|
77
73
|
@prog = [0...4,2...5]
|
78
|
-
@score = Score::
|
79
|
-
@converter = ScoreConverter
|
74
|
+
@score = Score::Tempo.new(FOUR_FOUR, 120, program: @prog)
|
75
|
+
@converter = ScoreConverter.new(@score,200)
|
80
76
|
end
|
81
77
|
|
82
78
|
it 'shuld return array with same size' do
|
@@ -86,7 +82,7 @@ describe ScoreConverter::Measured do
|
|
86
82
|
end
|
87
83
|
|
88
84
|
it 'should convert program segments offsets from measure-based to note-based' do
|
89
|
-
prog = ScoreConverter
|
85
|
+
prog = ScoreConverter.new(@score,200).convert_program
|
90
86
|
prog.size.should eq(2)
|
91
87
|
prog[0].first.should eq(0)
|
92
88
|
prog[0].last.should eq(8)
|
@@ -94,7 +90,7 @@ describe ScoreConverter::Measured do
|
|
94
90
|
prog[1].last.should eq(10)
|
95
91
|
|
96
92
|
@score.start_meter = THREE_FOUR
|
97
|
-
prog = ScoreConverter
|
93
|
+
prog = ScoreConverter.new(@score,200).convert_program
|
98
94
|
prog.size.should eq(2)
|
99
95
|
prog[0].first.should eq(0)
|
100
96
|
prog[0].last.should eq(6)
|
@@ -105,15 +101,15 @@ describe ScoreConverter::Measured do
|
|
105
101
|
|
106
102
|
describe '#convert_score' do
|
107
103
|
it 'should return a timed score' do
|
108
|
-
score = Score::
|
109
|
-
converter = ScoreConverter
|
104
|
+
score = Score::Tempo.new(FOUR_FOUR, 120)
|
105
|
+
converter = ScoreConverter.new(score,200)
|
110
106
|
converter.convert_score.should be_a Score::Timed
|
111
107
|
end
|
112
108
|
|
113
109
|
it 'should use output from convert_program' do
|
114
110
|
prog =[0...4,2...5]
|
115
|
-
score = Score::
|
116
|
-
converter = ScoreConverter
|
111
|
+
score = Score::Tempo.new(FOUR_FOUR, 120, program: prog)
|
112
|
+
converter = ScoreConverter.new(score,200)
|
117
113
|
nscore = converter.convert_score
|
118
114
|
nscore.program.should eq(converter.convert_program)
|
119
115
|
end
|
@@ -121,126 +117,12 @@ describe ScoreConverter::Measured do
|
|
121
117
|
it 'should use output from convert_parts' do
|
122
118
|
changeA = Change::Immediate.new(Dynamics::PP)
|
123
119
|
changeB = Change::Gradual.linear(Dynamics::F, 2)
|
124
|
-
score = Score::
|
120
|
+
score = Score::Tempo.new(FOUR_FOUR, 120,
|
125
121
|
parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => changeA, 3 => changeB })}
|
126
122
|
)
|
127
|
-
converter = ScoreConverter
|
123
|
+
converter = ScoreConverter.new(score,200)
|
128
124
|
nscore = converter.convert_score
|
129
125
|
nscore.parts.should eq(converter.convert_parts)
|
130
126
|
end
|
131
127
|
end
|
132
128
|
end
|
133
|
-
|
134
|
-
describe ScoreConverter::Unmeasured do
|
135
|
-
describe '#initialize' do
|
136
|
-
context 'current score is invalid' do
|
137
|
-
it 'should raise NotValidError' do
|
138
|
-
score = Score::Unmeasured.new(-1)
|
139
|
-
expect { ScoreConverter::Unmeasured.new(score,200) }.to raise_error(NotValidError)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
describe '#convert_parts' do
|
145
|
-
before :each do
|
146
|
-
@changeA = Change::Immediate.new(Dynamics::PP)
|
147
|
-
@changeB = Change::Gradual.linear(Dynamics::F, 2)
|
148
|
-
@score = Score::Unmeasured.new(120,
|
149
|
-
parts: {
|
150
|
-
"normal" => Part.new(Dynamics::MP,
|
151
|
-
dynamic_changes: { 1 => @changeA, 3 => @changeB },
|
152
|
-
notes: "/4C2 /8D2 /8E2 /2C2".to_notes * 4),
|
153
|
-
"empty" => Part.new(Dynamics::PP)
|
154
|
-
}
|
155
|
-
)
|
156
|
-
@parts = ScoreConverter::Unmeasured.new(@score,200).convert_parts
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'should return Hash with original part names' do
|
160
|
-
@parts.should be_a Hash
|
161
|
-
@parts.keys.sort.should eq(@score.parts.keys.sort)
|
162
|
-
end
|
163
|
-
|
164
|
-
it 'should convert part dynamic change offsets from note-based to time-based' do
|
165
|
-
part = @parts["normal"]
|
166
|
-
part.dynamic_changes.keys.sort.should eq([2,6])
|
167
|
-
change = part.dynamic_changes[2.0]
|
168
|
-
change.end_value.should eq(@changeA.end_value)
|
169
|
-
change = part.dynamic_changes[6.0]
|
170
|
-
change.end_value.should eq(@changeB.end_value)
|
171
|
-
change.duration.should eq(4.0)
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'should convert note durations to time durations' do
|
175
|
-
part = @parts["normal"]
|
176
|
-
part.notes.map {|x| x.duration }.should eq([0.5,0.25,0.25,1]*4)
|
177
|
-
end
|
178
|
-
|
179
|
-
context 'trimmed, gradual changes' do
|
180
|
-
it 'should change preceding and remaining so they reflect time-based duration' do
|
181
|
-
score = Score::Unmeasured.new(120, parts: {
|
182
|
-
"abc" => Part.new(Dynamics::P, dynamic_changes: {
|
183
|
-
2 => Change::Gradual.linear(Dynamics::F,4).to_trimmed(2,1),
|
184
|
-
7 => Change::Gradual.linear(Dynamics::F,5).to_trimmed(1,3)
|
185
|
-
})
|
186
|
-
})
|
187
|
-
converter = ScoreConverter::Unmeasured.new(score,200)
|
188
|
-
parts = converter.convert_parts
|
189
|
-
dcs = parts["abc"].dynamic_changes
|
190
|
-
|
191
|
-
dcs.keys.should eq([4,14])
|
192
|
-
dcs[4.0].should eq(Change::Gradual.linear(Dynamics::F,8).to_trimmed(4,2))
|
193
|
-
dcs[14.0].should eq(Change::Gradual.linear(Dynamics::F,10).to_trimmed(2,6))
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
describe '#convert_program' do
|
199
|
-
before :each do
|
200
|
-
@prog = [0...4,2...5]
|
201
|
-
@score = Score::Unmeasured.new(120, program: @prog)
|
202
|
-
@converter = ScoreConverter::Unmeasured.new(@score,200)
|
203
|
-
@prog2 = @converter.convert_program
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'should return array with same size' do
|
207
|
-
@prog2.should be_a Array
|
208
|
-
@prog2.size.should eq(@prog.size)
|
209
|
-
end
|
210
|
-
|
211
|
-
it 'should convert program segments offsets from note-based to time-based' do
|
212
|
-
prog = @prog2
|
213
|
-
prog[0].first.should eq(0)
|
214
|
-
prog[0].last.should eq(8)
|
215
|
-
prog[1].first.should eq(4)
|
216
|
-
prog[1].last.should eq(10)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
describe '#convert_score' do
|
221
|
-
it 'should return an timed score' do
|
222
|
-
score = Score::Unmeasured.new(120)
|
223
|
-
converter = ScoreConverter::Unmeasured.new(score,200)
|
224
|
-
converter.convert_score.should be_a Score::Timed
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'should use output from convert_program' do
|
228
|
-
prog = [0...4,2...5]
|
229
|
-
score = Score::Unmeasured.new(120, program: prog)
|
230
|
-
converter = ScoreConverter::Unmeasured.new(score,200)
|
231
|
-
nscore = converter.convert_score
|
232
|
-
nscore.program.should eq(converter.convert_program)
|
233
|
-
end
|
234
|
-
|
235
|
-
it 'should use output from convert_parts' do
|
236
|
-
changeA = Change::Immediate.new(Dynamics::PP)
|
237
|
-
changeB = Change::Gradual.linear(Dynamics::F, 2)
|
238
|
-
score = Score::Unmeasured.new(120,
|
239
|
-
parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => changeA, 3 => changeB })}
|
240
|
-
)
|
241
|
-
converter = ScoreConverter::Unmeasured.new(score,200)
|
242
|
-
nscore = converter.convert_score
|
243
|
-
nscore.parts.should eq(converter.convert_parts)
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|