musicality 0.2.0 → 0.3.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 +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
|