musicality 0.2.0 → 0.3.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 +30 -0
- data/lib/musicality/errors.rb +1 -0
- data/lib/musicality/notation/conversion/change_conversion.rb +63 -3
- data/lib/musicality/notation/conversion/note_time_converter.rb +23 -5
- data/lib/musicality/notation/conversion/score_conversion.rb +60 -0
- data/lib/musicality/notation/conversion/score_converter.rb +105 -0
- data/lib/musicality/notation/model/change.rb +98 -28
- data/lib/musicality/notation/model/part.rb +1 -1
- data/lib/musicality/notation/model/score.rb +4 -4
- data/lib/musicality/notation/packing/change_packing.rb +35 -25
- data/lib/musicality/notation/packing/score_packing.rb +2 -2
- data/lib/musicality/notation/util/function.rb +99 -0
- data/lib/musicality/notation/util/piecewise_function.rb +79 -99
- data/lib/musicality/notation/util/transition.rb +12 -0
- data/lib/musicality/notation/util/value_computer.rb +12 -152
- data/lib/musicality/performance/conversion/score_collator.rb +35 -20
- data/lib/musicality/performance/midi/part_sequencer.rb +2 -5
- data/lib/musicality/validatable.rb +6 -1
- data/lib/musicality/version.rb +1 -1
- data/lib/musicality.rb +4 -4
- data/musicality.gemspec +1 -0
- data/spec/notation/conversion/change_conversion_spec.rb +216 -9
- data/spec/notation/conversion/measure_note_map_spec.rb +2 -2
- data/spec/notation/conversion/note_time_converter_spec.rb +91 -9
- data/spec/notation/conversion/{measured_score_conversion_spec.rb → score_conversion_spec.rb} +44 -9
- data/spec/notation/conversion/score_converter_spec.rb +246 -0
- data/spec/notation/model/change_spec.rb +139 -36
- data/spec/notation/model/part_spec.rb +3 -3
- data/spec/notation/model/score_spec.rb +4 -4
- data/spec/notation/packing/change_packing_spec.rb +222 -71
- data/spec/notation/packing/part_packing_spec.rb +1 -1
- data/spec/notation/packing/score_packing_spec.rb +3 -2
- data/spec/notation/util/function_spec.rb +43 -0
- data/spec/notation/util/transition_spec.rb +51 -0
- data/spec/notation/util/value_computer_spec.rb +43 -87
- data/spec/performance/conversion/score_collator_spec.rb +46 -7
- data/spec/performance/midi/part_sequencer_spec.rb +2 -1
- metadata +29 -14
- data/lib/musicality/notation/conversion/measured_score_conversion.rb +0 -70
- data/lib/musicality/notation/conversion/measured_score_converter.rb +0 -95
- data/lib/musicality/notation/conversion/unmeasured_score_conversion.rb +0 -47
- data/lib/musicality/notation/conversion/unmeasured_score_converter.rb +0 -64
- data/spec/notation/conversion/measured_score_converter_spec.rb +0 -329
- data/spec/notation/conversion/unmeasured_score_conversion_spec.rb +0 -71
- data/spec/notation/conversion/unmeasured_score_converter_spec.rb +0 -116
@@ -7,17 +7,156 @@ describe Change::Immediate do
|
|
7
7
|
c.offsets(44).should eq([44])
|
8
8
|
end
|
9
9
|
end
|
10
|
+
|
11
|
+
describe '#remap' do
|
12
|
+
it 'should return a clone of the change' do
|
13
|
+
c = Change::Immediate.new(12)
|
14
|
+
c2 = c.remap(1,{})
|
15
|
+
c2.should eq(c)
|
16
|
+
c2.should_not be c
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#to_transition' do
|
21
|
+
before :all do
|
22
|
+
@ch = Change::Immediate.new(20)
|
23
|
+
@off = 0
|
24
|
+
@f = @ch.to_transition(@off,0)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should return a peicewise function' do
|
28
|
+
@f.should be_a Function::Piecewise
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should return a function defined from base offset to DOMAIN_MAX' do
|
32
|
+
@f.domain_include?(@off).should be true
|
33
|
+
@f.domain_include?(Function::DOMAIN_MAX).should be true
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should return change value from base offset onward' do
|
37
|
+
@f.at(@off).should eq(@ch.end_value)
|
38
|
+
@f.at(@off+1).should eq(@ch.end_value)
|
39
|
+
@f.at(@off+1000).should eq(@ch.end_value)
|
40
|
+
end
|
41
|
+
end
|
10
42
|
end
|
11
43
|
|
12
44
|
describe Change::Gradual do
|
45
|
+
before :all do
|
46
|
+
@change = Change::Gradual.linear(100,1.5)
|
47
|
+
@base = 25.5
|
48
|
+
end
|
49
|
+
|
13
50
|
describe '#offsets' do
|
14
51
|
before :all do
|
15
|
-
@change = Change::Gradual.new(100,1.5,0.5,0.25)
|
16
|
-
@base = 25.5
|
17
52
|
@offsets = @change.offsets(@base)
|
18
53
|
end
|
19
54
|
|
20
|
-
it 'should return array with
|
55
|
+
it 'should return array with 2 elements' do
|
56
|
+
@offsets.size.should eq(2)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should include the given base offset' do
|
60
|
+
@offsets.should include(@base)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should include the base offset + duration' do
|
64
|
+
@offsets.should include(@base + @change.duration)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#remap' do
|
69
|
+
before :all do
|
70
|
+
@c2 = @change.remap(@base, @base => 3, (@base + @change.duration) => 5)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should return a new Gradual' do
|
74
|
+
@c2.should be_a(Change::Gradual)
|
75
|
+
@c2.should_not be(@change)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should keep end value, and change duration based on given offset map' do
|
79
|
+
@c2.end_value.should eq(@change.end_value)
|
80
|
+
@c2.duration.should eq(2)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#to_transition' do
|
85
|
+
{ 'linear transition' => Change::Gradual.linear(130,20),
|
86
|
+
'sigmoid transition' => Change::Gradual.sigmoid(130,20)
|
87
|
+
}.each do |descr, change|
|
88
|
+
context descr do
|
89
|
+
before :all do
|
90
|
+
@offset = 3
|
91
|
+
@start_value = 50
|
92
|
+
@func = @change.to_transition(@offset, @start_value)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should return a piecewise function' do
|
96
|
+
@func.should be_a Function::Piecewise
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should return a function that is undefined before base offset' do
|
100
|
+
@func.domain_include?(@offset-1e-5).should be false
|
101
|
+
@func.domain_include?(@offset-1e5).should be false
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should return a function defined from base offset to DOMAIN_MAX' do
|
105
|
+
@func.domain_include?(@offset).should be true
|
106
|
+
@func.domain_include?(@offset + @change.duration/2.0).should be true
|
107
|
+
@func.domain_include?(@offset + @change.duration).should be true
|
108
|
+
@func.domain_include?(@offset + @change.duration + 1).should be true
|
109
|
+
@func.domain_include?(Function::DOMAIN_MAX).should be true
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should make function that evaluates to start_value at start offset' do
|
113
|
+
@func.at(@offset).should eq(@start_value)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should make function that evaluates to end_value at start offset + duration' do
|
117
|
+
@func.at(@offset + @change.duration).should eq(@change.end_value)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should make function that evaluates to 1/2 between start/end value at 1/2 between start/end offset' do
|
121
|
+
tgt = (@change.end_value + @start_value) / 2.0
|
122
|
+
@func.at(@offset + @change.duration/2.0).should be_within(1e-5).of(tgt)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should make function that evaluates to end value after change has elapsed' do
|
126
|
+
@func.at(@offset + @change.duration + 1).should eq(@change.end_value)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'start value already defined in change' do
|
132
|
+
{ 'linear transition' => Change::Gradual.linear(130,20,start_value:80),
|
133
|
+
'sigmoid transition' => Change::Gradual.sigmoid(130,20,start_value:80)
|
134
|
+
}.each do |descr, change|
|
135
|
+
context descr do
|
136
|
+
it 'should produce a function that begins at already-defined start value' do
|
137
|
+
offset = 3
|
138
|
+
start_value = 50
|
139
|
+
func = change.to_transition(offset, start_value)
|
140
|
+
func.at(offset).should eq(change.start_value)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe Change::Gradual::Trimmed do
|
149
|
+
before :all do
|
150
|
+
@change = Change::Gradual.linear(100,1.5.to_r).to_trimmed(0.5.to_r,0.5.to_r)
|
151
|
+
@base = 25.5.to_r
|
152
|
+
end
|
153
|
+
|
154
|
+
describe '#offsets' do
|
155
|
+
before :all do
|
156
|
+
@offsets = @change.offsets(@base)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should return array with 2 elements' do
|
21
160
|
@offsets.size.should eq(4)
|
22
161
|
end
|
23
162
|
|
@@ -25,16 +164,84 @@ describe Change::Gradual do
|
|
25
164
|
@offsets.should include(@base)
|
26
165
|
end
|
27
166
|
|
28
|
-
it 'should include the base offset -
|
29
|
-
@offsets.should include(@base - @change.
|
167
|
+
it 'should include the base offset - preceding' do
|
168
|
+
@offsets.should include(@base - @change.preceding)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should include the base offset + remaining' do
|
172
|
+
@offsets.should include(@base + @change.remaining)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'should include the base offset - preceding + duration' do
|
176
|
+
@offsets.should include(@base - @change.preceding + @change.duration)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe '#remap' do
|
181
|
+
before :all do
|
182
|
+
@offsets = { @base => 3, (@base - @change.preceding) => 0,
|
183
|
+
(@base + @change.remaining) => 5, (@base - @change.preceding + @change.duration) => 7 }
|
184
|
+
@c2 = @change.remap(@base, @offsets)
|
30
185
|
end
|
31
186
|
|
32
|
-
it 'should
|
33
|
-
@
|
187
|
+
it 'should return a new Gradual::Trimmed' do
|
188
|
+
@c2.should be_a(Change::Gradual::Trimmed)
|
189
|
+
@c2.should_not be(@change)
|
34
190
|
end
|
35
191
|
|
36
|
-
it 'should
|
37
|
-
@
|
192
|
+
it 'should keep end value, and change duration based on given offset map' do
|
193
|
+
@c2.end_value.should eq(@change.end_value)
|
194
|
+
@c2.duration.should eq(7)
|
195
|
+
@c2.preceding.should eq(3)
|
196
|
+
@c2.remaining.should eq(2)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe '#to_transition' do
|
201
|
+
Change::Gradual::TRANSITIONS.each do |transition|
|
202
|
+
context "#{transition} transition" do
|
203
|
+
[nil,35].each do |start_val|
|
204
|
+
context "change start_value = #{start_val}" do
|
205
|
+
before :all do
|
206
|
+
untrimmed = Change::Gradual.new(130,20, transition, start_value: start_val)
|
207
|
+
untrimmed_offset = 0
|
208
|
+
untrimmed_start_val = 50
|
209
|
+
@untrimmed_trans = untrimmed.to_transition(untrimmed_offset, untrimmed_start_val)
|
210
|
+
|
211
|
+
trimmed = untrimmed.trim(5,3)
|
212
|
+
trimmed_offset = untrimmed_offset + trimmed.preceding
|
213
|
+
trimmed_start_val = @untrimmed_trans.at(trimmed_offset)
|
214
|
+
@trimmed_trans = trimmed.to_transition(trimmed_offset, trimmed_start_val)
|
215
|
+
|
216
|
+
@xrange = trimmed_offset..(trimmed_offset + trimmed.remaining)
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should produce function that is undefined before trimmed domain' do
|
220
|
+
@trimmed_trans.domain_include?(@xrange.first-1).should be false
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should produce function that is defined for trimmed domain' do
|
224
|
+
@trimmed_trans.domain_include?(@xrange.first).should be true
|
225
|
+
@trimmed_trans.domain_include?((@xrange.first + @xrange.last)/2.0).should be true
|
226
|
+
@trimmed_trans.domain_include?(@xrange.last).should be true
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should produce function that is defined after trimmed domain' do
|
230
|
+
@trimmed_trans.domain_include?(@xrange.last+1).should be true
|
231
|
+
@trimmed_trans.domain_include?(Function::DOMAIN_MAX).should be true
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should produce function that stays at end value after transition' do
|
235
|
+
@trimmed_trans.at(@xrange.last + 1).should eq(@trimmed_trans.at(@xrange.last))
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should produce function that samples same as equivalent untrimmed' do
|
239
|
+
srate = 50
|
240
|
+
@trimmed_trans.sample(@xrange, srate).should eq(@untrimmed_trans.sample(@xrange, srate))
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
38
245
|
end
|
39
246
|
end
|
40
247
|
end
|
@@ -38,10 +38,10 @@ describe 'Conversion.measure_note_map' do
|
|
38
38
|
@score = Score::Measured.new(@start_meter, 120,
|
39
39
|
meter_changes: { @first_mc_off => Change::Immediate.new(@new_meter) },
|
40
40
|
tempo_changes: {
|
41
|
-
"1/2".to_r => Change::Gradual.
|
41
|
+
"1/2".to_r => Change::Gradual.linear(100,1),
|
42
42
|
2 => Change::Immediate.new(120),
|
43
43
|
3 => Change::Immediate.new(100),
|
44
|
-
3.1 => Change::Gradual.
|
44
|
+
3.1 => Change::Gradual.linear(100,1),
|
45
45
|
5 => Change::Immediate.new(120),
|
46
46
|
6 => Change::Immediate.new(100),
|
47
47
|
}
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
|
-
describe NoteTimeConverter do
|
3
|
+
describe NoteTimeConverter::Unmeasured do
|
4
4
|
describe '#notes_per_second_at' do
|
5
5
|
it 'should convert tempo using Tempo::QNPM.to_nps' do
|
6
6
|
tc = ValueComputer.new(
|
7
|
-
120, 1 => Change::Gradual.
|
8
|
-
converter = NoteTimeConverter.new(tc,200)
|
7
|
+
120, 1 => Change::Gradual.linear(100,1), 2 => Change::Gradual.linear(150,1))
|
8
|
+
converter = NoteTimeConverter::Unmeasured.new(tc,200)
|
9
9
|
(0..2).step(0.2).each do |offset|
|
10
|
-
nps = Tempo::QNPM.to_nps(tc.
|
10
|
+
nps = Tempo::QNPM.to_nps(tc.at(offset))
|
11
11
|
converter.notes_per_second_at(offset).should eq(nps)
|
12
12
|
end
|
13
13
|
end
|
@@ -18,7 +18,7 @@ describe NoteTimeConverter do
|
|
18
18
|
before :each do
|
19
19
|
@tempo_computer = ValueComputer.new 120
|
20
20
|
sample_rate = 48
|
21
|
-
@converter = NoteTimeConverter.new(@tempo_computer, sample_rate)
|
21
|
+
@converter = NoteTimeConverter::Unmeasured.new(@tempo_computer, sample_rate)
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should return a time of zero when note end is zero." do
|
@@ -34,9 +34,9 @@ describe NoteTimeConverter do
|
|
34
34
|
context "linear tempo-change" do
|
35
35
|
before :each do
|
36
36
|
@tempo_computer = ValueComputer.new(
|
37
|
-
120, 1 => Change::Gradual.
|
37
|
+
120, 1 => Change::Gradual.linear(60, 1))
|
38
38
|
sample_rate = 200
|
39
|
-
@converter = NoteTimeConverter.new(@tempo_computer, sample_rate)
|
39
|
+
@converter = NoteTimeConverter::Unmeasured.new(@tempo_computer, sample_rate)
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should return a time of zero when note end is zero." do
|
@@ -53,12 +53,12 @@ describe NoteTimeConverter do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
describe "#
|
56
|
+
describe "#note_time_map" do
|
57
57
|
context "constant tempo" do
|
58
58
|
before :each do
|
59
59
|
@tempo_computer = ValueComputer.new 120
|
60
60
|
sample_rate = 4800
|
61
|
-
@converter = NoteTimeConverter.new(
|
61
|
+
@converter = NoteTimeConverter::Unmeasured.new(
|
62
62
|
@tempo_computer, sample_rate)
|
63
63
|
end
|
64
64
|
|
@@ -79,3 +79,85 @@ describe NoteTimeConverter do
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
+
|
83
|
+
describe NoteTimeConverter::Measured do
|
84
|
+
describe '#notes_per_second_at' do
|
85
|
+
it 'should convert tempo using Tempo::BPM.to_nps' do
|
86
|
+
tc = ValueComputer.new(120, 1 => Change::Gradual.linear(100,1),
|
87
|
+
2 => Change::Gradual.linear(150,1))
|
88
|
+
bdc = ValueComputer.new(0.25.to_r, 2.5 => Change::Immediate.new(0.375.to_r))
|
89
|
+
converter = NoteTimeConverter::Measured.new(tc,bdc,200)
|
90
|
+
(0..3.2).step(0.2).each do |offset|
|
91
|
+
nps = Tempo::BPM.to_nps(tc.at(offset), bdc.at(offset))
|
92
|
+
converter.notes_per_second_at(offset).should eq(nps)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#time_elapsed" do
|
98
|
+
context "constant tempo, beat duration" do
|
99
|
+
before :each do
|
100
|
+
@tempo_computer = ValueComputer.new 120
|
101
|
+
@bdur_computer = ValueComputer.new Rational(1,4)
|
102
|
+
sample_rate = 48
|
103
|
+
@converter = NoteTimeConverter::Measured.new(@tempo_computer, @bdur_computer, sample_rate)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should return a time of zero when note end is zero." do
|
107
|
+
@converter.time_elapsed(0, 0).should eq(0)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should return a time of 1 second when note end is equal to the initial notes-per-second" do
|
111
|
+
note_end = @converter.notes_per_second_at(0)
|
112
|
+
@converter.time_elapsed(0, note_end).should eq(1)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "linear tempo-change, constant beat duration" do
|
117
|
+
before :each do
|
118
|
+
@tempo_computer = ValueComputer.new(120, 1 => Change::Gradual.linear(60, 1))
|
119
|
+
@bdur_computer = ValueComputer.new Rational(1,4)
|
120
|
+
sample_rate = 200
|
121
|
+
@converter = NoteTimeConverter::Measured.new(@tempo_computer, @bdur_computer, sample_rate)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should return a time of zero when note end is zero." do
|
125
|
+
@converter.time_elapsed(0.0, 0.0).should eq(0.0)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return a time of 3 sec during a 1-note long transition from 120bpm to 60bpm" do
|
129
|
+
@converter.notes_per_second_at(1.0).should eq(0.5)
|
130
|
+
@converter.notes_per_second_at(2.0).should eq(0.25)
|
131
|
+
|
132
|
+
@converter.time_elapsed(1.0, 2.0).should be_within(0.05).of(2.77)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "#note_time_map" do
|
139
|
+
context "constant tempo, beat duration" do
|
140
|
+
before :each do
|
141
|
+
@tempo_computer = ValueComputer.new 120
|
142
|
+
@bdur_computer = ValueComputer.new Rational(1,4)
|
143
|
+
sample_rate = 4800
|
144
|
+
@converter = NoteTimeConverter::Measured.new(@tempo_computer, @bdur_computer, sample_rate)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should map offset 0.0 to time 0.0" do
|
148
|
+
map = @converter.note_time_map [0.0]
|
149
|
+
map[0.0].should eq(0.0)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should map offset 0.25 to time 0.5" do
|
153
|
+
map = @converter.note_time_map [0.0, 0.25]
|
154
|
+
map[0.25].should be_within(0.01).of(0.5)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should map offset 1.0 to time 2.0" do
|
158
|
+
map = @converter.note_time_map [0.0, 1.0]
|
159
|
+
map[1.0].should be_within(0.01).of(2.0)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
data/spec/notation/conversion/{measured_score_conversion_spec.rb → score_conversion_spec.rb}
RENAMED
@@ -8,7 +8,7 @@ describe Score::Measured do
|
|
8
8
|
dynamic_changes: {
|
9
9
|
1 => Change::Immediate.new(Dynamics::MF),
|
10
10
|
5 => Change::Immediate.new(Dynamics::FF),
|
11
|
-
6 => Change::Gradual.
|
11
|
+
6 => Change::Gradual.linear(Dynamics::MF,2),
|
12
12
|
14 => Change::Immediate.new(Dynamics::PP),
|
13
13
|
}
|
14
14
|
)
|
@@ -16,7 +16,7 @@ describe Score::Measured do
|
|
16
16
|
@prog = Program.new([0...3,4...7,1...20,17..."45/2".to_r])
|
17
17
|
tcs = {
|
18
18
|
0 => Change::Immediate.new(120),
|
19
|
-
4 => Change::Gradual.
|
19
|
+
4 => Change::Gradual.linear(60,2),
|
20
20
|
11 => Change::Immediate.new(110)
|
21
21
|
}
|
22
22
|
mcs = {
|
@@ -87,7 +87,7 @@ describe Score::Measured do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'should map start meter to offset 0' do
|
90
|
-
@mdurs[0].should eq(@score.start_meter.measure_duration)
|
90
|
+
@mdurs[0.to_r].should eq(@score.start_meter.measure_duration)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -107,7 +107,7 @@ describe Score::Measured do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
it 'should begin with meter change at offset 0, instead of start meter' do
|
110
|
-
@mdurs2[0].should eq(@change.
|
110
|
+
@mdurs2[0].should eq(@change.end_value.measure_duration)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
@@ -126,16 +126,51 @@ describe Score::Measured do
|
|
126
126
|
end
|
127
127
|
|
128
128
|
it 'should begin with start meter' do
|
129
|
-
@mdurs3[0].should eq(@score3.start_meter.measure_duration)
|
129
|
+
@mdurs3[0.to_r].should eq(@score3.start_meter.measure_duration)
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
describe '#
|
135
|
-
it 'should use
|
136
|
-
nscore1 = @score.
|
137
|
-
nscore2 =
|
134
|
+
describe '#to_timed' do
|
135
|
+
it 'should use ScoreConverter::Measured#convert_score' do
|
136
|
+
nscore1 = @score.to_timed(200)
|
137
|
+
nscore2 = ScoreConverter::Measured.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 = Program.new([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
|