musicality 0.11.1 → 0.12.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 +5 -5
- data/.coveralls.yml +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +4 -0
- data/ChangeLog.md +11 -0
- data/README.md +3 -0
- data/Rakefile +11 -3
- data/lib/musicality/composition/model/rhythm.rb +33 -0
- data/lib/musicality/composition/model/rhythm_class.rb +30 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_kit.rb +18 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_machine.rb +59 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_parts.rb +21 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_pattern.rb +66 -0
- data/lib/musicality/composition/sequencing/drum_machine/drum_patterns/pop_drum_patterns.rb +146 -0
- data/lib/musicality/composition/sequencing/note_array.rb +33 -0
- data/lib/musicality/composition/sequencing/note_fifo.rb +73 -0
- data/lib/musicality/composition/sequencing/sequenceable.rb +9 -0
- data/lib/musicality/composition/sequencing/sequencer.rb +35 -0
- data/lib/musicality/errors.rb +2 -2
- data/lib/musicality/notation/model/dynamics.rb +2 -2
- data/lib/musicality/notation/model/key.rb +42 -91
- data/lib/musicality/notation/model/keys.rb +35 -34
- data/lib/musicality/notation/model/note.rb +31 -9
- data/lib/musicality/notation/model/pitch.rb +2 -2
- data/lib/musicality/notation/parsing/convenience_methods.rb +23 -12
- data/lib/musicality/notation/parsing/duration_parsing.rb +3 -3
- data/lib/musicality/notation/parsing/key_parsing.rb +150 -0
- data/lib/musicality/notation/parsing/key_parsing.treetop +37 -0
- data/lib/musicality/notation/parsing/meter_parsing.rb +3 -3
- data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.rb +3 -1
- data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +1 -0
- data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.rb +1 -1
- data/lib/musicality/notation/parsing/numbers/positive_float_parsing.rb +4 -1
- data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.rb +1 -1
- data/lib/musicality/notation/parsing/parseable.rb +13 -17
- data/lib/musicality/notation/parsing/pitch_parsing.rb +7 -0
- data/lib/musicality/notation/parsing/segment_parsing.rb +3 -0
- data/lib/musicality/performance/conversion/note_sequence_extractor.rb +82 -134
- data/lib/musicality/performance/model/note_sequence.rb +22 -3
- data/lib/musicality/performance/supercollider/performer.rb +2 -2
- data/lib/musicality/performance/supercollider/sc_drum_kits.rb +29 -0
- data/lib/musicality/performance/supercollider/synthdefs/bass.rb +211 -0
- data/lib/musicality/performance/supercollider/synthdefs/claps.rb +80 -0
- data/lib/musicality/performance/supercollider/synthdefs/cymbals.rb +57 -0
- data/lib/musicality/performance/supercollider/synthdefs/hihats.rb +67 -0
- data/lib/musicality/performance/supercollider/synthdefs/kicks.rb +158 -0
- data/lib/musicality/performance/supercollider/synthdefs/mario.rb +49 -0
- data/lib/musicality/performance/supercollider/{synthdefs.rb → synthdefs/other.rb} +0 -767
- data/lib/musicality/performance/supercollider/synthdefs/pianos.rb +46 -0
- data/lib/musicality/performance/supercollider/synthdefs/snares.rb +169 -0
- data/lib/musicality/performance/supercollider/synthdefs/toms.rb +25 -0
- data/lib/musicality/performance/supercollider/synthdefs/volume.rb +20 -0
- data/lib/musicality/pitch_class.rb +1 -1
- data/lib/musicality/pitch_classes.rb +3 -5
- data/lib/musicality/version.rb +1 -1
- data/lib/musicality.rb +25 -1
- data/musicality.gemspec +3 -2
- data/spec/composition/convenience_methods_spec.rb +8 -8
- data/spec/composition/generation/random_rhythm_generator_spec.rb +5 -5
- data/spec/composition/model/pitch_class_spec.rb +22 -16
- data/spec/composition/model/pitch_classes_spec.rb +5 -5
- data/spec/composition/model/rhythm_class_spec.rb +42 -0
- data/spec/composition/model/rhythm_spec.rb +43 -0
- data/spec/composition/model/scale_class_spec.rb +26 -26
- data/spec/composition/model/scale_spec.rb +38 -38
- data/spec/composition/sequencing/drum_machine/drum_machine_spec.rb +67 -0
- data/spec/composition/sequencing/drum_machine/drum_pattern_spec.rb +58 -0
- data/spec/composition/sequencing/note_array_spec.rb +94 -0
- data/spec/composition/sequencing/note_fifo_spec.rb +183 -0
- data/spec/composition/sequencing/sequencer_spec.rb +76 -0
- data/spec/composition/util/adding_sequence_spec.rb +33 -33
- data/spec/composition/util/compound_sequence_spec.rb +6 -6
- data/spec/composition/util/note_generation_spec.rb +34 -34
- data/spec/composition/util/probabilities_spec.rb +7 -7
- data/spec/composition/util/random_sampler_spec.rb +3 -3
- data/spec/composition/util/repeating_sequence_spec.rb +28 -28
- data/spec/musicality_spec.rb +1 -1
- data/spec/notation/conversion/change_conversion_spec.rb +87 -87
- data/spec/notation/conversion/note_time_converter_spec.rb +22 -22
- data/spec/notation/conversion/score_conversion_spec.rb +1 -1
- data/spec/notation/conversion/score_converter_spec.rb +31 -31
- data/spec/notation/conversion/tempo_conversion_spec.rb +11 -11
- data/spec/notation/model/change_spec.rb +80 -80
- data/spec/notation/model/key_spec.rb +135 -69
- data/spec/notation/model/link_spec.rb +27 -27
- data/spec/notation/model/meter_spec.rb +28 -28
- data/spec/notation/model/note_spec.rb +68 -47
- data/spec/notation/model/part_spec.rb +19 -19
- data/spec/notation/model/pitch_spec.rb +69 -68
- data/spec/notation/model/score_spec.rb +50 -47
- data/spec/notation/parsing/articulation_parsing_spec.rb +4 -4
- data/spec/notation/parsing/convenience_methods_spec.rb +49 -10
- data/spec/notation/parsing/duration_nodes_spec.rb +13 -13
- data/spec/notation/parsing/duration_parsing_spec.rb +10 -10
- data/spec/notation/parsing/key_parsing_spec.rb +19 -0
- data/spec/notation/parsing/link_nodes_spec.rb +7 -7
- data/spec/notation/parsing/link_parsing_spec.rb +4 -4
- data/spec/notation/parsing/meter_parsing_spec.rb +5 -5
- data/spec/notation/parsing/note_node_spec.rb +19 -19
- data/spec/notation/parsing/note_parsing_spec.rb +4 -4
- data/spec/notation/parsing/numbers/nonnegative_float_spec.rb +8 -8
- data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +2 -2
- data/spec/notation/parsing/numbers/nonnegative_rational_spec.rb +1 -1
- data/spec/notation/parsing/numbers/positive_float_spec.rb +8 -8
- data/spec/notation/parsing/numbers/positive_integer_spec.rb +6 -6
- data/spec/notation/parsing/numbers/positive_rational_spec.rb +6 -6
- data/spec/notation/parsing/pitch_node_spec.rb +7 -7
- data/spec/notation/parsing/pitch_parsing_spec.rb +2 -2
- data/spec/notation/parsing/segment_parsing_spec.rb +3 -3
- data/spec/notation/util/function_spec.rb +15 -15
- data/spec/notation/util/transition_spec.rb +12 -12
- data/spec/notation/util/value_computer_spec.rb +35 -36
- data/spec/performance/conversion/glissando_converter_spec.rb +24 -24
- data/spec/performance/conversion/note_sequence_extractor_spec.rb +39 -39
- data/spec/performance/conversion/portamento_converter_spec.rb +23 -23
- data/spec/performance/midi/midi_util_spec.rb +41 -41
- data/spec/performance/midi/part_sequencer_spec.rb +10 -10
- data/spec/performance/midi/score_sequencer_spec.rb +15 -15
- data/spec/performance/midi/score_sequencing_spec.rb +2 -2
- data/spec/performance/util/optimization_spec.rb +9 -9
- data/spec/printing/note_engraving_spec.rb +16 -16
- data/spec/printing/score_engraver_spec.rb +5 -5
- data/spec/spec_helper.rb +5 -0
- metadata +85 -30
@@ -4,39 +4,39 @@ describe Change::Immediate do
|
|
4
4
|
describe '#offsets' do
|
5
5
|
it 'should return array with just the given base offset' do
|
6
6
|
c = Change::Immediate.new(12)
|
7
|
-
c.offsets(44).
|
7
|
+
expect(c.offsets(44)).to eq([44])
|
8
8
|
end
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
describe '#remap' do
|
12
12
|
it 'should return a clone of the change' do
|
13
13
|
c = Change::Immediate.new(12)
|
14
14
|
c2 = c.remap(1,{})
|
15
|
-
c2.
|
16
|
-
c2.
|
15
|
+
expect(c2).to eq(c)
|
16
|
+
expect(c2).to_not be c
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
describe '#to_transition' do
|
21
21
|
before :all do
|
22
22
|
@ch = Change::Immediate.new(20)
|
23
23
|
@off = 0
|
24
24
|
@f = @ch.to_transition(@off,0)
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it 'should return a peicewise function' do
|
28
|
-
@f.
|
28
|
+
expect(@f).to be_a Function::Piecewise
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
it 'should return a function defined from base offset to DOMAIN_MAX' do
|
32
|
-
@f.domain_include?(@off).
|
33
|
-
@f.domain_include?(Function::DOMAIN_MAX).
|
32
|
+
expect(@f.domain_include?(@off)).to be true
|
33
|
+
expect(@f.domain_include?(Function::DOMAIN_MAX)).to be true
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
it 'should return change value from base offset onward' do
|
37
|
-
@f.at(@off).
|
38
|
-
@f.at(@off+1).
|
39
|
-
@f.at(@off+1000).
|
37
|
+
expect(@f.at(@off)).to eq(@ch.end_value)
|
38
|
+
expect(@f.at(@off+1)).to eq(@ch.end_value)
|
39
|
+
expect(@f.at(@off+1000)).to eq(@ch.end_value)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -46,41 +46,41 @@ describe Change::Gradual do
|
|
46
46
|
@change = Change::Gradual.linear(100,1.5)
|
47
47
|
@base = 25.5
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
describe '#offsets' do
|
51
51
|
before :all do
|
52
52
|
@offsets = @change.offsets(@base)
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
it 'should return array with 2 elements' do
|
56
|
-
@offsets.size.
|
56
|
+
expect(@offsets.size).to eq(2)
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
it 'should include the given base offset' do
|
60
|
-
@offsets.
|
60
|
+
expect(@offsets).to include(@base)
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
it 'should include the base offset + duration' do
|
64
|
-
@offsets.
|
64
|
+
expect(@offsets).to include(@base + @change.duration)
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
describe '#remap' do
|
69
69
|
before :all do
|
70
70
|
@c2 = @change.remap(@base, @base => 3, (@base + @change.duration) => 5)
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it 'should return a new Gradual' do
|
74
|
-
@c2.
|
75
|
-
@c2.
|
74
|
+
expect(@c2).to be_a(Change::Gradual)
|
75
|
+
expect(@c2).to_not be(@change)
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
it 'should keep end value, and change duration based on given offset map' do
|
79
|
-
@c2.end_value.
|
80
|
-
@c2.duration.
|
79
|
+
expect(@c2.end_value).to eq(@change.end_value)
|
80
|
+
expect(@c2.duration).to eq(2)
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
describe '#to_transition' do
|
85
85
|
{ 'linear transition' => Change::Gradual.linear(130,20),
|
86
86
|
'sigmoid transition' => Change::Gradual.sigmoid(130,20)
|
@@ -91,43 +91,43 @@ describe Change::Gradual do
|
|
91
91
|
@start_value = 50
|
92
92
|
@func = @change.to_transition(@offset, @start_value)
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
it 'should return a piecewise function' do
|
96
|
-
@func.
|
96
|
+
expect(@func).to be_a Function::Piecewise
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
it 'should return a function that is undefined before base offset' do
|
100
|
-
@func.domain_include?(@offset-1e-5).
|
101
|
-
@func.domain_include?(@offset-1e5).
|
100
|
+
expect(@func.domain_include?(@offset-1e-5)).to be false
|
101
|
+
expect(@func.domain_include?(@offset-1e5)).to be false
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
it 'should return a function defined from base offset to DOMAIN_MAX' do
|
105
|
-
@func.domain_include?(@offset).
|
106
|
-
@func.domain_include?(@offset + @change.duration/2.0).
|
107
|
-
@func.domain_include?(@offset + @change.duration).
|
108
|
-
@func.domain_include?(@offset + @change.duration + 1).
|
109
|
-
@func.domain_include?(Function::DOMAIN_MAX).
|
105
|
+
expect(@func.domain_include?(@offset)).to be true
|
106
|
+
expect(@func.domain_include?(@offset + @change.duration/2.0)).to be true
|
107
|
+
expect(@func.domain_include?(@offset + @change.duration)).to be true
|
108
|
+
expect(@func.domain_include?(@offset + @change.duration + 1)).to be true
|
109
|
+
expect(@func.domain_include?(Function::DOMAIN_MAX)).to be true
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
it 'should make function that evaluates to start_value at start offset' do
|
113
|
-
@func.at(@offset).
|
113
|
+
expect(@func.at(@offset)).to eq(@start_value)
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
it 'should make function that evaluates to end_value at start offset + duration' do
|
117
|
-
@func.at(@offset + @change.duration).
|
117
|
+
expect(@func.at(@offset + @change.duration)).to eq(@change.end_value)
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
it 'should make function that evaluates to 1/2 between start/end value at 1/2 between start/end offset' do
|
121
121
|
tgt = (@change.end_value + @start_value) / 2.0
|
122
|
-
@func.at(@offset + @change.duration/2.0).
|
122
|
+
expect(@func.at(@offset + @change.duration/2.0)).to be_within(1e-5).of(tgt)
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
it 'should make function that evaluates to end value after change has elapsed' do
|
126
|
-
@func.at(@offset + @change.duration + 1).
|
126
|
+
expect(@func.at(@offset + @change.duration + 1)).to eq(@change.end_value)
|
127
127
|
end
|
128
128
|
end
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
context 'start value already defined in change' do
|
132
132
|
{ 'linear transition' => Change::Gradual.linear(130,20,start_value:80),
|
133
133
|
'sigmoid transition' => Change::Gradual.sigmoid(130,20,start_value:80)
|
@@ -137,7 +137,7 @@ describe Change::Gradual do
|
|
137
137
|
offset = 3
|
138
138
|
start_value = 50
|
139
139
|
func = change.to_transition(offset, start_value)
|
140
|
-
func.at(offset).
|
140
|
+
expect(func.at(offset)).to eq(change.start_value)
|
141
141
|
end
|
142
142
|
end
|
143
143
|
end
|
@@ -150,53 +150,53 @@ describe Change::Gradual::Trimmed do
|
|
150
150
|
@change = Change::Gradual.linear(100,1.5.to_r).to_trimmed(0.5.to_r,0.5.to_r)
|
151
151
|
@base = 25.5.to_r
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
describe '#offsets' do
|
155
155
|
before :all do
|
156
156
|
@offsets = @change.offsets(@base)
|
157
157
|
end
|
158
|
-
|
158
|
+
|
159
159
|
it 'should return array with 2 elements' do
|
160
|
-
@offsets.size.
|
160
|
+
expect(@offsets.size).to eq(4)
|
161
161
|
end
|
162
|
-
|
162
|
+
|
163
163
|
it 'should include the given base offset' do
|
164
|
-
@offsets.
|
164
|
+
expect(@offsets).to include(@base)
|
165
165
|
end
|
166
|
-
|
166
|
+
|
167
167
|
it 'should include the base offset - preceding' do
|
168
|
-
@offsets.
|
168
|
+
expect(@offsets).to include(@base - @change.preceding)
|
169
169
|
end
|
170
|
-
|
170
|
+
|
171
171
|
it 'should include the base offset + remaining' do
|
172
|
-
@offsets.
|
172
|
+
expect(@offsets).to include(@base + @change.remaining)
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
it 'should include the base offset - preceding + duration' do
|
176
|
-
@offsets.
|
176
|
+
expect(@offsets).to include(@base - @change.preceding + @change.duration)
|
177
177
|
end
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
describe '#remap' do
|
181
181
|
before :all do
|
182
182
|
@offsets = { @base => 3, (@base - @change.preceding) => 0,
|
183
183
|
(@base + @change.remaining) => 5, (@base - @change.preceding + @change.duration) => 7 }
|
184
184
|
@c2 = @change.remap(@base, @offsets)
|
185
185
|
end
|
186
|
-
|
186
|
+
|
187
187
|
it 'should return a new Gradual::Trimmed' do
|
188
|
-
@c2.
|
189
|
-
@c2.
|
188
|
+
expect(@c2).to be_a(Change::Gradual::Trimmed)
|
189
|
+
expect(@c2).to_not be(@change)
|
190
190
|
end
|
191
|
-
|
191
|
+
|
192
192
|
it 'should keep end value, and change duration based on given offset map' do
|
193
|
-
@c2.end_value.
|
194
|
-
@c2.duration.
|
195
|
-
@c2.preceding.
|
196
|
-
@c2.remaining.
|
193
|
+
expect(@c2.end_value).to eq(@change.end_value)
|
194
|
+
expect(@c2.duration).to eq(7)
|
195
|
+
expect(@c2.preceding).to eq(3)
|
196
|
+
expect(@c2.remaining).to eq(2)
|
197
197
|
end
|
198
198
|
end
|
199
|
-
|
199
|
+
|
200
200
|
describe '#to_transition' do
|
201
201
|
Change::Gradual::TRANSITIONS.each do |transition|
|
202
202
|
context "#{transition} transition" do
|
@@ -207,38 +207,38 @@ describe Change::Gradual::Trimmed do
|
|
207
207
|
untrimmed_offset = 0
|
208
208
|
untrimmed_start_val = 50
|
209
209
|
@untrimmed_trans = untrimmed.to_transition(untrimmed_offset, untrimmed_start_val)
|
210
|
-
|
210
|
+
|
211
211
|
trimmed = untrimmed.trim(5,3)
|
212
212
|
trimmed_offset = untrimmed_offset + trimmed.preceding
|
213
213
|
trimmed_start_val = @untrimmed_trans.at(trimmed_offset)
|
214
214
|
@trimmed_trans = trimmed.to_transition(trimmed_offset, trimmed_start_val)
|
215
|
-
|
215
|
+
|
216
216
|
@xrange = trimmed_offset..(trimmed_offset + trimmed.remaining)
|
217
217
|
end
|
218
|
-
|
218
|
+
|
219
219
|
it 'should produce function that is undefined before trimmed domain' do
|
220
|
-
@trimmed_trans.domain_include?(@xrange.first-1).
|
220
|
+
expect(@trimmed_trans.domain_include?(@xrange.first-1)).to be false
|
221
221
|
end
|
222
|
-
|
222
|
+
|
223
223
|
it 'should produce function that is defined for trimmed domain' do
|
224
|
-
@trimmed_trans.domain_include?(@xrange.first).
|
225
|
-
@trimmed_trans.domain_include?((@xrange.first + @xrange.last)/2.0).
|
226
|
-
@trimmed_trans.domain_include?(@xrange.last).
|
224
|
+
expect(@trimmed_trans.domain_include?(@xrange.first)).to be true
|
225
|
+
expect(@trimmed_trans.domain_include?((@xrange.first + @xrange.last)/2.0)).to be true
|
226
|
+
expect(@trimmed_trans.domain_include?(@xrange.last)).to be true
|
227
227
|
end
|
228
|
-
|
228
|
+
|
229
229
|
it 'should produce function that is defined after trimmed domain' do
|
230
|
-
@trimmed_trans.domain_include?(@xrange.last+1).
|
231
|
-
@trimmed_trans.domain_include?(Function::DOMAIN_MAX).
|
230
|
+
expect(@trimmed_trans.domain_include?(@xrange.last+1)).to be true
|
231
|
+
expect(@trimmed_trans.domain_include?(Function::DOMAIN_MAX)).to be true
|
232
232
|
end
|
233
|
-
|
233
|
+
|
234
234
|
it 'should produce function that stays at end value after transition' do
|
235
|
-
@trimmed_trans.at(@xrange.last + 1).
|
235
|
+
expect(@trimmed_trans.at(@xrange.last + 1)).to eq(@trimmed_trans.at(@xrange.last))
|
236
236
|
end
|
237
|
-
|
237
|
+
|
238
238
|
it 'should produce function that samples same as equivalent untrimmed' do
|
239
239
|
srate = 50
|
240
|
-
@trimmed_trans.sample(@xrange, srate).
|
241
|
-
end
|
240
|
+
expect(@trimmed_trans.sample(@xrange, srate)).to eq(@untrimmed_trans.sample(@xrange, srate))
|
241
|
+
end
|
242
242
|
end
|
243
243
|
end
|
244
244
|
end
|
@@ -9,11 +9,11 @@ describe NoteTimeConverter::Tempo do
|
|
9
9
|
converter = NoteTimeConverter.new(tc,bdc,200)
|
10
10
|
(0..3.2).step(0.2).each do |offset|
|
11
11
|
nps = Tempo::BPM.to_nps(tc.at(offset), bdc.at(offset))
|
12
|
-
converter.notes_per_second_at(offset).
|
12
|
+
expect(converter.notes_per_second_at(offset)).to eq(nps)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
describe "#time_elapsed" do
|
18
18
|
context "constant tempo, beat duration" do
|
19
19
|
before :each do
|
@@ -22,17 +22,17 @@ describe NoteTimeConverter::Tempo do
|
|
22
22
|
sample_rate = 48
|
23
23
|
@converter = NoteTimeConverter.new(@tempo_computer, @bdur_computer, sample_rate)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it "should return a time of zero when note end is zero." do
|
27
|
-
@converter.time_elapsed(0, 0).
|
27
|
+
expect(@converter.time_elapsed(0, 0)).to eq(0)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "should return a time of 1 second when note end is equal to the initial notes-per-second" do
|
31
31
|
note_end = @converter.notes_per_second_at(0)
|
32
|
-
@converter.time_elapsed(0, note_end).
|
32
|
+
expect(@converter.time_elapsed(0, note_end)).to eq(1)
|
33
33
|
end
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
context "linear tempo-change, constant beat duration" do
|
37
37
|
before :each do
|
38
38
|
@tempo_computer = ValueComputer.new(120, 1 => Change::Gradual.linear(60, 1))
|
@@ -40,43 +40,43 @@ describe NoteTimeConverter::Tempo do
|
|
40
40
|
sample_rate = 200
|
41
41
|
@converter = NoteTimeConverter.new(@tempo_computer, @bdur_computer, sample_rate)
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
it "should return a time of zero when note end is zero." do
|
45
|
-
@converter.time_elapsed(0.0, 0.0).
|
45
|
+
expect(@converter.time_elapsed(0.0, 0.0)).to eq(0.0)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it "should return a time of 3 sec during a 1-note long transition from 120bpm to 60bpm" do
|
49
|
-
@converter.notes_per_second_at(1.0).
|
50
|
-
@converter.notes_per_second_at(2.0).
|
51
|
-
|
52
|
-
@converter.time_elapsed(1.0, 2.0).
|
49
|
+
expect(@converter.notes_per_second_at(1.0)).to eq(0.5)
|
50
|
+
expect(@converter.notes_per_second_at(2.0)).to eq(0.25)
|
51
|
+
|
52
|
+
expect(@converter.time_elapsed(1.0, 2.0)).to be_within(0.05).of(2.77)
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
end
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
describe "#note_time_map" do
|
59
59
|
context "constant tempo, beat duration" do
|
60
|
-
before :each do
|
60
|
+
before :each do
|
61
61
|
@tempo_computer = ValueComputer.new 120
|
62
62
|
@bdur_computer = ValueComputer.new Rational(1,4)
|
63
63
|
sample_rate = 4800
|
64
64
|
@converter = NoteTimeConverter.new(@tempo_computer, @bdur_computer, sample_rate)
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
it "should map offset 0.0 to time 0.0" do
|
68
68
|
map = @converter.note_time_map [0.0]
|
69
|
-
map[0.0].
|
69
|
+
expect(map[0.0]).to eq(0.0)
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should map offset 0.25 to time 0.5" do
|
73
73
|
map = @converter.note_time_map [0.0, 0.25]
|
74
|
-
map[0.25].
|
74
|
+
expect(map[0.25]).to be_within(0.01).of(0.5)
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
it "should map offset 1.0 to time 2.0" do
|
78
78
|
map = @converter.note_time_map [0.0, 1.0]
|
79
|
-
map[1.0].
|
79
|
+
expect(map[1.0]).to be_within(0.01).of(2.0)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -21,32 +21,32 @@ describe ScoreConverter do
|
|
21
21
|
|
22
22
|
it 'should return Hash with original part names' do
|
23
23
|
parts = ScoreConverter.new(@score,200).convert_parts
|
24
|
-
parts.
|
25
|
-
parts.keys.sort.
|
24
|
+
expect(parts).to be_a Hash
|
25
|
+
expect(parts.keys.sort).to eq(@score.parts.keys.sort)
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'should convert part dynamic change offsets from note-based to time-based' do
|
29
29
|
parts = ScoreConverter.new(@score,200).convert_parts
|
30
|
-
parts.
|
30
|
+
expect(parts).to have_key("simple")
|
31
31
|
part = parts["simple"]
|
32
|
-
part.dynamic_changes.keys.sort.
|
32
|
+
expect(part.dynamic_changes.keys.sort).to eq([2,6])
|
33
33
|
change = part.dynamic_changes[2.0]
|
34
|
-
change.end_value.
|
34
|
+
expect(change.end_value).to eq(@changeA.end_value)
|
35
35
|
change = part.dynamic_changes[6.0]
|
36
|
-
change.end_value.
|
37
|
-
change.duration.
|
36
|
+
expect(change.end_value).to eq(@changeB.end_value)
|
37
|
+
expect(change.duration).to eq(4)
|
38
38
|
|
39
39
|
@score.start_meter = THREE_FOUR
|
40
40
|
parts = ScoreConverter.new(@score,200).convert_parts
|
41
|
-
parts.
|
41
|
+
expect(parts).to have_key("simple")
|
42
42
|
part = parts["simple"]
|
43
|
-
part.dynamic_changes.keys.sort.
|
43
|
+
expect(part.dynamic_changes.keys.sort).to eq([2,6])
|
44
44
|
change = part.dynamic_changes[2.0]
|
45
|
-
change.end_value.
|
46
|
-
change.duration.
|
45
|
+
expect(change.end_value).to eq(@changeA.end_value)
|
46
|
+
expect(change.duration).to eq(0)
|
47
47
|
change = part.dynamic_changes[6.0]
|
48
|
-
change.end_value.
|
49
|
-
change.duration.
|
48
|
+
expect(change.end_value).to eq(@changeB.end_value)
|
49
|
+
expect(change.duration).to eq(4)
|
50
50
|
end
|
51
51
|
|
52
52
|
context 'gradual changes with positive elapsed and/or remaining' do
|
@@ -61,9 +61,9 @@ describe ScoreConverter do
|
|
61
61
|
parts = converter.convert_parts
|
62
62
|
dcs = parts["abc"].dynamic_changes
|
63
63
|
|
64
|
-
dcs.keys.
|
65
|
-
dcs[4.0].
|
66
|
-
dcs[14.0].
|
64
|
+
expect(dcs.keys).to eq([4, 14])
|
65
|
+
expect(dcs[4.0]).to eq(Change::Gradual.linear(Dynamics::F,4).to_trimmed(2,6))
|
66
|
+
expect(dcs[14.0]).to eq(Change::Gradual.linear(Dynamics::F,2).to_trimmed(8,10))
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
@@ -77,25 +77,25 @@ describe ScoreConverter do
|
|
77
77
|
|
78
78
|
it 'shuld return array with same size' do
|
79
79
|
prog = @converter.convert_program
|
80
|
-
prog.
|
81
|
-
prog.size.
|
80
|
+
expect(prog).to be_a Array
|
81
|
+
expect(prog.size).to eq(@score.program.size)
|
82
82
|
end
|
83
83
|
|
84
84
|
it 'should convert program segments offsets from note-based to time-based' do
|
85
85
|
prog = ScoreConverter.new(@score,200).convert_program
|
86
|
-
prog.size.
|
87
|
-
prog[0].first.
|
88
|
-
prog[0].last.
|
89
|
-
prog[1].first.
|
90
|
-
prog[1].last.
|
86
|
+
expect(prog.size).to eq(2)
|
87
|
+
expect(prog[0].first).to eq(0)
|
88
|
+
expect(prog[0].last).to eq(8)
|
89
|
+
expect(prog[1].first).to eq(4)
|
90
|
+
expect(prog[1].last).to eq(10)
|
91
91
|
|
92
92
|
@score.start_meter = THREE_FOUR
|
93
93
|
prog = ScoreConverter.new(@score,200).convert_program
|
94
|
-
prog.size.
|
95
|
-
prog[0].first.
|
96
|
-
prog[0].last.
|
97
|
-
prog[1].first.
|
98
|
-
prog[1].last.
|
94
|
+
expect(prog.size).to eq(2)
|
95
|
+
expect(prog[0].first).to eq(0)
|
96
|
+
expect(prog[0].last).to eq(8)
|
97
|
+
expect(prog[1].first).to eq(4)
|
98
|
+
expect(prog[1].last).to eq(10)
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
@@ -103,7 +103,7 @@ describe ScoreConverter do
|
|
103
103
|
it 'should return a timed score' do
|
104
104
|
score = Score::Tempo.new(120, start_meter: FOUR_FOUR)
|
105
105
|
converter = ScoreConverter.new(score,200)
|
106
|
-
converter.convert_score.
|
106
|
+
expect(converter.convert_score).to be_a Score::Timed
|
107
107
|
end
|
108
108
|
|
109
109
|
it 'should use output from convert_program' do
|
@@ -111,7 +111,7 @@ describe ScoreConverter do
|
|
111
111
|
score = Score::Tempo.new(120, start_meter: FOUR_FOUR, program: prog)
|
112
112
|
converter = ScoreConverter.new(score,200)
|
113
113
|
nscore = converter.convert_score
|
114
|
-
nscore.program.
|
114
|
+
expect(nscore.program).to eq(converter.convert_program)
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'should use output from convert_parts' do
|
@@ -122,7 +122,7 @@ describe ScoreConverter do
|
|
122
122
|
)
|
123
123
|
converter = ScoreConverter.new(score,200)
|
124
124
|
nscore = converter.convert_score
|
125
|
-
nscore.parts.
|
125
|
+
expect(nscore.parts).to eq(converter.convert_parts)
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
@@ -4,17 +4,17 @@ describe Tempo::QNPM do
|
|
4
4
|
before :all do
|
5
5
|
@tempo = 60
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
describe '#to_nps' do
|
9
9
|
it 'should change tempo value to be 1/240th' do
|
10
|
-
Tempo::QNPM.to_nps(@tempo).
|
10
|
+
expect(Tempo::QNPM.to_nps(@tempo)).to eq(Rational(1,4))
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
describe '#to_bpm' do
|
15
15
|
it 'should divide tempo value by (4*beatdur)' do
|
16
|
-
Tempo::QNPM.to_bpm(@tempo, Rational(1,4)).
|
17
|
-
Tempo::QNPM.to_bpm(@tempo, Rational(1,2)).
|
16
|
+
expect(Tempo::QNPM.to_bpm(@tempo, Rational(1,4))).to eq(60)
|
17
|
+
expect(Tempo::QNPM.to_bpm(@tempo, Rational(1,2))).to eq(30)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -23,18 +23,18 @@ describe Tempo::BPM do
|
|
23
23
|
before :all do
|
24
24
|
@tempo = 60
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
describe '#to_nps' do
|
28
28
|
it 'should multiply tempo value by beatdur/60' do
|
29
|
-
Tempo::BPM.to_nps(@tempo,Rational(1,4)).
|
29
|
+
expect(Tempo::BPM.to_nps(@tempo,Rational(1,4))).to eq(Rational(1,4))
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
describe '#to_qnpm' do
|
34
34
|
it 'should multiply tempo value by (4*beatdur)' do
|
35
|
-
Tempo::BPM.to_qnpm(@tempo,Rational(1,8)).
|
36
|
-
Tempo::BPM.to_qnpm(@tempo,Rational(1,4)).
|
37
|
-
Tempo::BPM.to_qnpm(@tempo,Rational(1,2)).
|
35
|
+
expect(Tempo::BPM.to_qnpm(@tempo,Rational(1,8))).to eq(30)
|
36
|
+
expect(Tempo::BPM.to_qnpm(@tempo,Rational(1,4))).to eq(60)
|
37
|
+
expect(Tempo::BPM.to_qnpm(@tempo,Rational(1,2))).to eq(120)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|