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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +30 -0
  3. data/lib/musicality/errors.rb +1 -0
  4. data/lib/musicality/notation/conversion/change_conversion.rb +63 -3
  5. data/lib/musicality/notation/conversion/note_time_converter.rb +23 -5
  6. data/lib/musicality/notation/conversion/score_conversion.rb +60 -0
  7. data/lib/musicality/notation/conversion/score_converter.rb +105 -0
  8. data/lib/musicality/notation/model/change.rb +98 -28
  9. data/lib/musicality/notation/model/part.rb +1 -1
  10. data/lib/musicality/notation/model/score.rb +4 -4
  11. data/lib/musicality/notation/packing/change_packing.rb +35 -25
  12. data/lib/musicality/notation/packing/score_packing.rb +2 -2
  13. data/lib/musicality/notation/util/function.rb +99 -0
  14. data/lib/musicality/notation/util/piecewise_function.rb +79 -99
  15. data/lib/musicality/notation/util/transition.rb +12 -0
  16. data/lib/musicality/notation/util/value_computer.rb +12 -152
  17. data/lib/musicality/performance/conversion/score_collator.rb +35 -20
  18. data/lib/musicality/performance/midi/part_sequencer.rb +2 -5
  19. data/lib/musicality/validatable.rb +6 -1
  20. data/lib/musicality/version.rb +1 -1
  21. data/lib/musicality.rb +4 -4
  22. data/musicality.gemspec +1 -0
  23. data/spec/notation/conversion/change_conversion_spec.rb +216 -9
  24. data/spec/notation/conversion/measure_note_map_spec.rb +2 -2
  25. data/spec/notation/conversion/note_time_converter_spec.rb +91 -9
  26. data/spec/notation/conversion/{measured_score_conversion_spec.rb → score_conversion_spec.rb} +44 -9
  27. data/spec/notation/conversion/score_converter_spec.rb +246 -0
  28. data/spec/notation/model/change_spec.rb +139 -36
  29. data/spec/notation/model/part_spec.rb +3 -3
  30. data/spec/notation/model/score_spec.rb +4 -4
  31. data/spec/notation/packing/change_packing_spec.rb +222 -71
  32. data/spec/notation/packing/part_packing_spec.rb +1 -1
  33. data/spec/notation/packing/score_packing_spec.rb +3 -2
  34. data/spec/notation/util/function_spec.rb +43 -0
  35. data/spec/notation/util/transition_spec.rb +51 -0
  36. data/spec/notation/util/value_computer_spec.rb +43 -87
  37. data/spec/performance/conversion/score_collator_spec.rb +46 -7
  38. data/spec/performance/midi/part_sequencer_spec.rb +2 -1
  39. metadata +29 -14
  40. data/lib/musicality/notation/conversion/measured_score_conversion.rb +0 -70
  41. data/lib/musicality/notation/conversion/measured_score_converter.rb +0 -95
  42. data/lib/musicality/notation/conversion/unmeasured_score_conversion.rb +0 -47
  43. data/lib/musicality/notation/conversion/unmeasured_score_converter.rb +0 -64
  44. data/spec/notation/conversion/measured_score_converter_spec.rb +0 -329
  45. data/spec/notation/conversion/unmeasured_score_conversion_spec.rb +0 -71
  46. data/spec/notation/conversion/unmeasured_score_converter_spec.rb +0 -116
@@ -0,0 +1,246 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe ScoreConverter::TempoBased do
4
+
5
+ end
6
+
7
+ describe ScoreConverter::Measured do
8
+ describe '#initialize' do
9
+ context 'current score is invalid' do
10
+ it 'should raise NotValidError' do
11
+ score = Score::Measured.new(1, 120)
12
+ expect { ScoreConverter::Measured.new(score,200) }.to raise_error(NotValidError)
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '#convert_parts' do
18
+ before :each do
19
+ @changeA = Change::Immediate.new(Dynamics::PP)
20
+ @changeB = Change::Gradual.linear(Dynamics::F, 2)
21
+ @score = Score::Measured.new(FOUR_FOUR, 120,
22
+ parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => @changeA, 3 => @changeB })}
23
+ )
24
+ end
25
+
26
+ it 'should return Hash with original part names' do
27
+ parts = ScoreConverter::Measured.new(@score,200).convert_parts
28
+ parts.should be_a Hash
29
+ parts.keys.sort.should eq(@score.parts.keys.sort)
30
+ end
31
+
32
+ it 'should convert part dynamic change offsets from measure-based to note-based' do
33
+ parts = ScoreConverter::Measured.new(@score,200).convert_parts
34
+ parts.should have_key("simple")
35
+ part = parts["simple"]
36
+ part.dynamic_changes.keys.sort.should eq([2,6])
37
+ change = part.dynamic_changes[2.0]
38
+ change.end_value.should eq(@changeA.end_value)
39
+ change = part.dynamic_changes[6.0]
40
+ change.end_value.should eq(@changeB.end_value)
41
+ change.duration.should eq(4)
42
+
43
+ #@score.start_meter = THREE_FOUR
44
+ #parts = ScoreConverter::Measured.new(@score,200).convert_parts
45
+ #parts.should have_key("simple")
46
+ #part = parts["simple"]
47
+ #part.dynamic_changes.keys.sort.should eq([Rational(3,4),Rational(9,4)])
48
+ #change = part.dynamic_changes[Rational(3,4)]
49
+ #change.end_value.should eq(@changeA.end_value)
50
+ #change.duration.should eq(0)
51
+ #change = part.dynamic_changes[Rational(9,4)]
52
+ #change.end_value.should eq(@changeB.end_value)
53
+ #change.duration.should eq(1.5)
54
+ end
55
+
56
+ #context 'gradual changes with positive elapsed and/or remaining' do
57
+ # it 'should change elapsed and remaining so they reflect note-based offsets' do
58
+ # score = Score::Measured.new(THREE_FOUR,120, parts: {
59
+ # "abc" => Part.new(Dynamics::P, dynamic_changes: {
60
+ # 2 => Change::Gradual.linear(Dynamics::F,2,1,3),
61
+ # 7 => Change::Gradual.linear(Dynamics::F,1,4,5)
62
+ # })
63
+ # })
64
+ # converter = ScoreConverter::Measured.new(score)
65
+ # parts = converter.convert_parts
66
+ # dcs = parts["abc"].dynamic_changes
67
+ #
68
+ # dcs.keys.should eq([Rational(6,4), Rational(21,4)])
69
+ # dcs[Rational(3,2)].should eq(Change::Gradual.linear(Dynamics::F,Rational(6,4),Rational(3,4),Rational(9,4)))
70
+ # dcs[Rational(21,4)].should eq(Change::Gradual.linear(Dynamics::F,Rational(3,4),Rational(12,4),Rational(15,4)))
71
+ # end
72
+ #end
73
+ end
74
+
75
+ describe '#convert_program' do
76
+ before :each do
77
+ @prog = Program.new([0...4,2...5])
78
+ @score = Score::Measured.new(FOUR_FOUR, 120, program: @prog)
79
+ @converter = ScoreConverter::Measured.new(@score,200)
80
+ end
81
+
82
+ it 'shuld return Program with same number of segments' do
83
+ prog = @converter.convert_program
84
+ prog.should be_a Program
85
+ prog.segments.size.should eq(@score.program.segments.size)
86
+ end
87
+
88
+ it 'should convert program segments offsets from measure-based to note-based' do
89
+ prog = ScoreConverter::Measured.new(@score,200).convert_program
90
+ prog.segments.size.should eq(2)
91
+ prog.segments[0].first.should eq(0)
92
+ prog.segments[0].last.should eq(8)
93
+ prog.segments[1].first.should eq(4)
94
+ prog.segments[1].last.should eq(10)
95
+
96
+ @score.start_meter = THREE_FOUR
97
+ prog = ScoreConverter::Measured.new(@score,200).convert_program
98
+ prog.segments.size.should eq(2)
99
+ prog.segments[0].first.should eq(0)
100
+ prog.segments[0].last.should eq(6)
101
+ prog.segments[1].first.should eq(3)
102
+ prog.segments[1].last.should eq(7.5)
103
+ end
104
+ end
105
+
106
+ describe '#convert_score' do
107
+ it 'should return a timed score' do
108
+ score = Score::Measured.new(FOUR_FOUR, 120)
109
+ converter = ScoreConverter::Measured.new(score,200)
110
+ converter.convert_score.should be_a Score::Timed
111
+ end
112
+
113
+ it 'should use output from convert_program' do
114
+ prog = Program.new([0...4,2...5])
115
+ score = Score::Measured.new(FOUR_FOUR, 120, program: prog)
116
+ converter = ScoreConverter::Measured.new(score,200)
117
+ nscore = converter.convert_score
118
+ nscore.program.should eq(converter.convert_program)
119
+ end
120
+
121
+ it 'should use output from convert_parts' do
122
+ changeA = Change::Immediate.new(Dynamics::PP)
123
+ changeB = Change::Gradual.linear(Dynamics::F, 2)
124
+ score = Score::Measured.new(FOUR_FOUR, 120,
125
+ parts: {"simple" => Part.new(Dynamics::MP, dynamic_changes: { 1 => changeA, 3 => changeB })}
126
+ )
127
+ converter = ScoreConverter::Measured.new(score,200)
128
+ nscore = converter.convert_score
129
+ nscore.parts.should eq(converter.convert_parts)
130
+ end
131
+ end
132
+ 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 = Program.new([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 Program with same number of segments' do
207
+ @prog2.should be_a Program
208
+ @prog2.segments.size.should eq(@prog.segments.size)
209
+ end
210
+
211
+ it 'should convert program segments offsets from note-based to time-based' do
212
+ prog = @prog2
213
+ prog.segments[0].first.should eq(0)
214
+ prog.segments[0].last.should eq(8)
215
+ prog.segments[1].first.should eq(4)
216
+ prog.segments[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 = Program.new([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
@@ -2,21 +2,17 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Change::Immediate do
4
4
  context '#initialize' do
5
- it 'should set value to given' do
6
- Change::Immediate.new(5).value.should eq 5
7
- end
8
-
9
- it 'should set duration to 0' do
10
- Change::Immediate.new(5).duration.should eq 0
5
+ it 'should set end value to given' do
6
+ Change::Immediate.new(5).end_value.should eq 5
11
7
  end
12
8
  end
13
9
 
14
10
  describe '==' do
15
- it 'should return true if two immediate changes have the same value' do
11
+ it 'should return true if two immediate changes have the same end value' do
16
12
  Change::Immediate.new(5).should eq(Change::Immediate.new(5))
17
13
  end
18
14
 
19
- it 'should return false if two immediate changes do not have the same value' do
15
+ it 'should return false if two immediate changes do not have the same end value' do
20
16
  Change::Immediate.new(5).should_not eq(Change::Immediate.new(4))
21
17
  end
22
18
  end
@@ -30,61 +26,168 @@ describe Change::Immediate do
30
26
  end
31
27
 
32
28
  describe Change::Gradual do
33
- context '.new' do
34
- it 'should set value to given value' do
35
- Change::Gradual.new(5,2).value.should eq 5
29
+ context '#initialize' do
30
+ it 'should set end value and duration to given values' do
31
+ ch = Change::Gradual.new(5,2,Change::Gradual::LINEAR)
32
+ ch.end_value.should eq(5)
33
+ ch.duration.should eq(2)
36
34
  end
37
35
 
38
- it 'should set duration to given impending duration' do
39
- c = Change::Gradual.new(5,2)
40
- c.duration.should eq 2
41
- c.impending.should eq 2
36
+ it 'should set start_value to nil if not given' do
37
+ Change::Gradual.linear(5,2).start_value.should be nil
42
38
  end
43
39
 
44
- it 'should set elapsed to 0 by default' do
45
- Change::Gradual.new(5,2).elapsed.should eq 0
40
+ it 'should set start_value if given' do
41
+ Change::Gradual.linear(5,2, start_value: 3).start_value.should eq(3)
46
42
  end
47
43
 
48
- it 'should set remaining to 0 by default' do
49
- Change::Gradual.new(5,2).remaining.should eq 0
44
+ it 'should raise NonPositiveError if duration is <= 0' do
45
+ expect { Change::Gradual.new(11,0,Change::Gradual::LINEAR) }.to raise_error(NonPositiveError)
46
+ expect { Change::Gradual.new(11,-1,Change::Gradual::LINEAR) }.to raise_error(NonPositiveError)
47
+ end
48
+ end
49
+
50
+ describe '#relative?' do
51
+ context 'start_value is nil' do
52
+ it 'should return true' do
53
+ Change::Gradual.linear(25,3).relative?.should be true
54
+ end
50
55
  end
51
56
 
52
- it 'should compute total_duration to be elapsed + impending + remaining' do
53
- Change::Gradual.new(100,7,2,3).total_duration.should eq(12)
57
+ context 'start_value is not nil' do
58
+ it 'should return false' do
59
+ Change::Gradual.linear(25,3, start_value: 10).relative?.should be false
60
+ end
54
61
  end
62
+ end
63
+
64
+ context '.linear' do
65
+ before(:all){ @change = Change::Gradual.linear(55,20, start_value: 25) }
55
66
 
56
- it 'should raise NonPositiveError if impending is <= 0' do
57
- expect { Change::Gradual.new(11,0) }.to raise_error(NonPositiveError)
58
- expect { Change::Gradual.new(11,-1) }.to raise_error(NonPositiveError)
67
+ it 'should assign end_value, duration, and start_value as normal' do
68
+ @change.end_value.should eq(55)
69
+ @change.duration.should eq(20)
70
+ @change.start_value.should eq(25)
59
71
  end
72
+
73
+ it 'should set transition to linear' do
74
+ @change.transition.should eq(Change::Gradual::LINEAR)
75
+ end
76
+ end
60
77
 
61
- it 'should raise NegativeError if elapsed is < 0' do
62
- expect { Change::Gradual.new(11,1,-1) }.to raise_error(NegativeError)
78
+ context '.sigmoid' do
79
+ before(:all){ @change = Change::Gradual.sigmoid(55,20, start_value: 25) }
80
+
81
+ it 'should assign end_value, duration, and start_value as normal' do
82
+ @change.end_value.should eq(55)
83
+ @change.duration.should eq(20)
84
+ @change.start_value.should eq(25)
63
85
  end
64
86
 
65
- it 'should raise NegativeError if remaining is < 0' do
66
- expect { Change::Gradual.new(11,1,0,-1) }.to raise_error(NegativeError)
87
+ it 'should set transition to SIGMOID' do
88
+ @change.transition.should eq(Change::Gradual::SIGMOID)
67
89
  end
68
90
  end
69
-
91
+
70
92
  describe '==' do
71
- it 'should return true if two gradual changes have the same value and duration' do
72
- Change::Gradual.new(5,2).should eq(Change::Gradual.new(5,2))
93
+ context 'two gradual changes have the same end value, duration, and start value' do
94
+ it 'should return true' do
95
+ Change::Gradual.linear(5,2).should eq(Change::Gradual.linear(5,2))
96
+ Change::Gradual.linear(5,2,start_value:0).should eq(Change::Gradual.linear(5,2,start_value:0))
97
+ end
73
98
  end
74
99
 
75
- it 'should return false if two gradual changes do not have the same value' do
76
- Change::Gradual.new(5,2).should_not eq(Change::Gradual.new(4,2))
100
+ context 'two gradual changes do not have the same end value' do
101
+ it 'should return false' do
102
+ Change::Gradual.linear(5,2).should_not eq(Change::Gradual.linear(4,2))
103
+ end
77
104
  end
78
105
 
79
- it 'should return false if two gradual changes do not have the same duration' do
80
- Change::Gradual.new(5,2).should_not eq(Change::Gradual.new(5,1))
106
+ context 'two gradual changes do not have the same duration' do
107
+ it 'should return false' do
108
+ Change::Gradual.linear(5,2).should_not eq(Change::Gradual.linear(5,1))
109
+ end
110
+ end
111
+
112
+ context 'two gradual changes do not have the start value' do
113
+ it 'should return false' do
114
+ Change::Gradual.linear(5,2, start_value: 3).should_not eq(Change::Gradual.linear(5,1))
115
+ end
81
116
  end
82
117
  end
83
118
 
84
119
  describe '#to_yaml' do
85
120
  it 'should produce YAML that can be loaded' do
86
- c = Change::Gradual.new(4,2)
121
+ c = Change::Gradual.linear(4,2)
87
122
  YAML.load(c.to_yaml).should eq c
88
123
  end
89
124
  end
90
125
  end
126
+
127
+ describe Change::Gradual::Trimmed do
128
+ it 'should be a Change::Gradual' do
129
+ Change::Gradual::Trimmed.new(35,1,Change::Gradual::LINEAR,preceding: 0, remaining: 0.5).should be_a Change::Gradual
130
+ end
131
+
132
+ describe '.linear' do
133
+ before(:all){ @change = Change::Gradual::Trimmed.linear(55,20,preceding:5,remaining:6) }
134
+
135
+ it 'should assign end_value, duration, preceding, and remaining as normal' do
136
+ @change.end_value.should eq(55)
137
+ @change.duration.should eq(20)
138
+ @change.preceding.should eq(5)
139
+ @change.remaining.should eq(6)
140
+ end
141
+
142
+ it 'should set transition to linear' do
143
+ @change.transition.should eq(Change::Gradual::LINEAR)
144
+ end
145
+ end
146
+
147
+ describe '.sigmoid' do
148
+ before(:all){ @change = Change::Gradual::Trimmed.sigmoid(55,20,preceding:5,remaining:6) }
149
+
150
+ it 'should assign end_value, duration, preceding, and remaining as normal' do
151
+ @change.end_value.should eq(55)
152
+ @change.duration.should eq(20)
153
+ @change.preceding.should eq(5)
154
+ @change.remaining.should eq(6)
155
+ end
156
+
157
+ it 'should set transition to SIGMOID' do
158
+ @change.transition.should eq(Change::Gradual::SIGMOID)
159
+ end
160
+ end
161
+
162
+ it 'should raise NegativeError if preceding is < 0' do
163
+ expect { Change::Gradual::Trimmed.linear(11,1,preceding: -1,remaining: 0.5) }.to raise_error(NegativeError)
164
+ end
165
+
166
+ it 'should raise NonPositiveError if remaining is <= 0' do
167
+ expect { Change::Gradual::Trimmed.linear(11,3,preceding: 1,remaining: 0) }.to raise_error(NonPositiveError)
168
+ expect { Change::Gradual::Trimmed.linear(11,3,preceding: 1,remaining: -1) }.to raise_error(NonPositiveError)
169
+ end
170
+
171
+ describe '#untrim' do
172
+ before :all do
173
+ @trimmed = Change::Gradual.linear(51,12).trim(2,2)
174
+ @untrimmed = @trimmed.untrim
175
+ end
176
+
177
+ it 'should return a Change::Gradual' do
178
+ @untrimmed.should be_a Change::Gradual
179
+ end
180
+
181
+ it 'should keep end_value, duration, and transition' do
182
+ @untrimmed.end_value.should eq(@trimmed.end_value)
183
+ @untrimmed.duration.should eq(@trimmed.duration)
184
+ @untrimmed.transition.should eq(@trimmed.transition)
185
+ end
186
+ end
187
+
188
+ describe '#trailing' do
189
+ it 'should return the amount of transition unused at the end' do
190
+ Change::Gradual.linear(41,19).trim(4,9).trailing.should eq(9)
191
+ end
192
+ end
193
+ end
@@ -13,7 +13,7 @@ describe Part do
13
13
  p.start_dynamic.should eq Dynamics::PPP
14
14
 
15
15
  notes = [Note::whole([A2]), Note::half]
16
- dcs = { "1/2".to_r => Change::Immediate.new(Dynamics::P), 1 => Change::Gradual.new(Dynamics::MF,1) }
16
+ dcs = { "1/2".to_r => Change::Immediate.new(Dynamics::P), 1 => Change::Gradual.sigmoid(Dynamics::MF,1) }
17
17
  p = Part.new(Dynamics::FF, notes: notes, dynamic_changes: dcs)
18
18
  p.notes.should eq notes
19
19
  p.dynamic_changes.should eq dcs
@@ -38,7 +38,7 @@ describe Part do
38
38
  # :dynamic_changes => { -0.2 => Change::Immediate.new(0.5) }],
39
39
  'dynamic change values outside 0..1' => [
40
40
  0.5, :notes => [ Note::whole ],
41
- :dynamic_changes => { 0.2 => Change::Immediate.new(-0.01), 0.3 => Change::Gradual.new(1.01,0.2) }],
41
+ :dynamic_changes => { 0.2 => Change::Immediate.new(-0.01), 0.3 => Change::Gradual.linear(1.01,0.2) }],
42
42
  'notes with 0 duration' => [ 0.5, :notes => [ Note.new(0) ]],
43
43
  'notes with negative duration' => [ 0.5, :notes => [ Note.new(-1) ]],
44
44
  }.each do |context_str, args|
@@ -56,7 +56,7 @@ describe Part do
56
56
  :notes => [ Note::whole([C4]), Note::quarter ],
57
57
  :dynamic_changes => {
58
58
  0.5 => Change::Immediate.new(Dynamics::MP),
59
- 1.2 => Change::Gradual.new(Dynamics::FF, 0.05) } ],
59
+ 1.2 => Change::Gradual.linear(Dynamics::FF, 0.05) } ],
60
60
  }.each do |context_str, args|
61
61
  context context_str do
62
62
  it 'should return true' do
@@ -138,7 +138,7 @@ describe Score::Measured do
138
138
  {
139
139
  'valid start tempo' => [ FOUR_FOUR, 40 ],
140
140
  'valid tempo changes' => [ FOUR_FOUR, 30,
141
- :tempo_changes => { 1 => Change::Gradual.new(40, 2), 2 => Change::Immediate.new(50) } ],
141
+ :tempo_changes => { 1 => Change::Gradual.linear(40, 2), 2 => Change::Immediate.new(50) } ],
142
142
  'valid meter changes' => [ FOUR_FOUR, 120,
143
143
  :meter_changes => { 1 => Change::Immediate.new(TWO_FOUR) } ],
144
144
  'valid part' => [ FOUR_FOUR, 120, :parts => { "piano" => Samples::SAMPLE_PART }],
@@ -161,7 +161,7 @@ describe Score::Measured do
161
161
  'non-meter values in meter changes' => [ FOUR_FOUR, 120,
162
162
  :meter_changes => { 1 => Change::Immediate.new(5) } ],
163
163
  'non-immediate meter change' => [ FOUR_FOUR, 120,
164
- :meter_changes => { 1 => Change::Gradual.new(TWO_FOUR,1) } ],
164
+ :meter_changes => { 1 => Change::Gradual.linear(TWO_FOUR,1) } ],
165
165
  'non-integer meter change offset' => [ FOUR_FOUR, 120,
166
166
  :meter_changes => { 1.1 => Change::Immediate.new(TWO_FOUR) } ],
167
167
  'invalid part' => [ FOUR_FOUR, 120, :parts => { "piano" => Part.new(-0.1) }],
@@ -216,7 +216,7 @@ describe Score::Unmeasured do
216
216
  {
217
217
  'valid start tempo' => [ 40 ],
218
218
  'valid tempo changes' => [ 30,
219
- :tempo_changes => { 1 => Change::Gradual.new(40, 2), 2 => Change::Immediate.new(50) } ],
219
+ :tempo_changes => { 1 => Change::Gradual.linear(40, 2), 2 => Change::Immediate.new(50) } ],
220
220
  'valid part' => [ 30, :parts => { "piano" => Samples::SAMPLE_PART }],
221
221
  'valid program' => [ 30, :program => Program.new([0..2,0..2]) ]
222
222
  }.each do |context_str,args|
@@ -231,7 +231,7 @@ describe Score::Unmeasured do
231
231
  'start tempo valid is zero' => [ 0 ],
232
232
  'start tempo valid is negative' => [ -1 ],
233
233
  'tempo change value is not a valid value' => [ 30,
234
- :tempo_changes => { 1 => Change::Gradual.new(-1,1) } ],
234
+ :tempo_changes => { 1 => Change::Gradual.linear(-1,1) } ],
235
235
  'invalid part' => [ 30, :parts => { "piano" => Part.new(-0.1) }],
236
236
  'invalid program' => [ 30, :program => Program.new([2..0]) ],
237
237
  }.each do |context_str,args|