musicality 0.11.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -3,31 +3,31 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
|
3
3
|
describe Change::Immediate do
|
4
4
|
context '#initialize' do
|
5
5
|
it 'should set end value to given' do
|
6
|
-
Change::Immediate.new(5).end_value.
|
6
|
+
expect(Change::Immediate.new(5).end_value).to eq 5
|
7
7
|
end
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
describe '==' do
|
11
11
|
it 'should return true if two immediate changes have the same end value' do
|
12
|
-
Change::Immediate.new(5).
|
12
|
+
expect(Change::Immediate.new(5)).to eq(Change::Immediate.new(5))
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it 'should return false if two immediate changes do not have the same end value' do
|
16
|
-
Change::Immediate.new(5).
|
16
|
+
expect(Change::Immediate.new(5)).to_not eq(Change::Immediate.new(4))
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
describe '#to_yaml' do
|
21
21
|
it 'should produce YAML that can be loaded' do
|
22
22
|
c = Change::Immediate.new(4)
|
23
|
-
YAML.load(c.to_yaml).
|
23
|
+
expect(YAML.load(c.to_yaml)).to eq c
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
describe '#pack' do
|
28
28
|
it 'should produce a Hash' do
|
29
29
|
h = Change::Immediate.new(2).pack
|
30
|
-
h.
|
30
|
+
expect(h).to be_a Hash
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -35,8 +35,8 @@ describe Change::Immediate do
|
|
35
35
|
it 'should return a Change::Immediate equal to the original' do
|
36
36
|
c1 = Change::Immediate.new(2)
|
37
37
|
c2 = Change::Immediate.unpack(c1.pack)
|
38
|
-
c2.
|
39
|
-
c2.
|
38
|
+
expect(c2).to be_a Change::Immediate
|
39
|
+
expect(c2).to eq c1
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -45,104 +45,104 @@ describe Change::Gradual do
|
|
45
45
|
context '#initialize' do
|
46
46
|
it 'should set end value and duration to given values' do
|
47
47
|
ch = Change::Gradual.new(5,2,Change::Gradual::LINEAR)
|
48
|
-
ch.end_value.
|
49
|
-
ch.duration.
|
48
|
+
expect(ch.end_value).to eq(5)
|
49
|
+
expect(ch.duration).to eq(2)
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it 'should set start_value to nil if not given' do
|
53
|
-
Change::Gradual.linear(5,2).start_value.
|
53
|
+
expect(Change::Gradual.linear(5,2).start_value).to be nil
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
it 'should set start_value if given' do
|
57
|
-
Change::Gradual.linear(5,2, start_value: 3).start_value.
|
57
|
+
expect(Change::Gradual.linear(5,2, start_value: 3).start_value).to eq(3)
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
it 'should raise NonPositiveError if duration is <= 0' do
|
61
61
|
expect { Change::Gradual.new(11,0,Change::Gradual::LINEAR) }.to raise_error(NonPositiveError)
|
62
62
|
expect { Change::Gradual.new(11,-1,Change::Gradual::LINEAR) }.to raise_error(NonPositiveError)
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
describe '#relative?' do
|
67
67
|
context 'start_value is nil' do
|
68
68
|
it 'should return true' do
|
69
|
-
Change::Gradual.linear(25,3).relative
|
69
|
+
expect(Change::Gradual.linear(25,3).relative?).to be true
|
70
70
|
end
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
context 'start_value is not nil' do
|
74
74
|
it 'should return false' do
|
75
|
-
Change::Gradual.linear(25,3, start_value: 10).relative
|
75
|
+
expect(Change::Gradual.linear(25,3, start_value: 10).relative?).to be false
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
context '.linear' do
|
81
81
|
before(:all){ @change = Change::Gradual.linear(55,20, start_value: 25) }
|
82
|
-
|
82
|
+
|
83
83
|
it 'should assign end_value, duration, and start_value as normal' do
|
84
|
-
@change.end_value.
|
85
|
-
@change.duration.
|
86
|
-
@change.start_value.
|
84
|
+
expect(@change.end_value).to eq(55)
|
85
|
+
expect(@change.duration).to eq(20)
|
86
|
+
expect(@change.start_value).to eq(25)
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
it 'should set transition to linear' do
|
90
|
-
@change.transition.
|
90
|
+
expect(@change.transition).to eq(Change::Gradual::LINEAR)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
94
|
context '.sigmoid' do
|
95
95
|
before(:all){ @change = Change::Gradual.sigmoid(55,20, start_value: 25) }
|
96
|
-
|
96
|
+
|
97
97
|
it 'should assign end_value, duration, and start_value as normal' do
|
98
|
-
@change.end_value.
|
99
|
-
@change.duration.
|
100
|
-
@change.start_value.
|
98
|
+
expect(@change.end_value).to eq(55)
|
99
|
+
expect(@change.duration).to eq(20)
|
100
|
+
expect(@change.start_value).to eq(25)
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
it 'should set transition to SIGMOID' do
|
104
|
-
@change.transition.
|
104
|
+
expect(@change.transition).to eq(Change::Gradual::SIGMOID)
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
describe '==' do
|
109
109
|
context 'two gradual changes have the same end value, duration, and start value' do
|
110
110
|
it 'should return true' do
|
111
|
-
Change::Gradual.linear(5,2).
|
112
|
-
Change::Gradual.linear(5,2,start_value:0).
|
111
|
+
expect(Change::Gradual.linear(5,2)).to eq(Change::Gradual.linear(5,2))
|
112
|
+
expect(Change::Gradual.linear(5,2,start_value:0)).to eq(Change::Gradual.linear(5,2,start_value:0))
|
113
113
|
end
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
context 'two gradual changes do not have the same end value' do
|
117
117
|
it 'should return false' do
|
118
|
-
Change::Gradual.linear(5,2).
|
118
|
+
expect(Change::Gradual.linear(5,2)).to_not eq(Change::Gradual.linear(4,2))
|
119
119
|
end
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
context 'two gradual changes do not have the same duration' do
|
123
123
|
it 'should return false' do
|
124
|
-
Change::Gradual.linear(5,2).
|
124
|
+
expect(Change::Gradual.linear(5,2)).to_not eq(Change::Gradual.linear(5,1))
|
125
125
|
end
|
126
126
|
end
|
127
|
-
|
127
|
+
|
128
128
|
context 'two gradual changes do not have the start value' do
|
129
129
|
it 'should return false' do
|
130
|
-
Change::Gradual.linear(5,2, start_value: 3).
|
130
|
+
expect(Change::Gradual.linear(5,2, start_value: 3)).to_not eq(Change::Gradual.linear(5,1))
|
131
131
|
end
|
132
132
|
end
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
describe '#to_yaml' do
|
136
136
|
it 'should produce YAML that can be loaded' do
|
137
137
|
c = Change::Gradual.linear(4,2)
|
138
|
-
YAML.load(c.to_yaml).
|
138
|
+
expect(YAML.load(c.to_yaml)).to eq c
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
142
|
describe '#pack' do
|
143
143
|
it 'should produce a Hash' do
|
144
144
|
h = Change::Gradual.linear(4,2).pack
|
145
|
-
h.
|
145
|
+
expect(h).to be_a Hash
|
146
146
|
end
|
147
147
|
end
|
148
148
|
|
@@ -150,47 +150,47 @@ describe Change::Gradual do
|
|
150
150
|
it 'should return a Change::Gradual equal to the original' do
|
151
151
|
c1 = Change::Gradual.linear(4,2)
|
152
152
|
c2 = Change::Gradual.unpack(c1.pack)
|
153
|
-
c2.
|
154
|
-
c2.
|
153
|
+
expect(c2).to be_a Change::Gradual
|
154
|
+
expect(c2).to eq c1
|
155
155
|
end
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
159
|
describe Change::Gradual::Trimmed do
|
160
160
|
it 'should be a Change::Gradual' do
|
161
|
-
Change::Gradual::Trimmed.new(35,1,Change::Gradual::LINEAR,preceding: 0, remaining: 0.5).
|
161
|
+
expect(Change::Gradual::Trimmed.new(35,1,Change::Gradual::LINEAR,preceding: 0, remaining: 0.5)).to be_a Change::Gradual
|
162
162
|
end
|
163
|
-
|
163
|
+
|
164
164
|
describe '.linear' do
|
165
165
|
before(:all){ @change = Change::Gradual::Trimmed.linear(55,20,preceding:5,remaining:6) }
|
166
|
-
|
166
|
+
|
167
167
|
it 'should assign end_value, duration, preceding, and remaining as normal' do
|
168
|
-
@change.end_value.
|
169
|
-
@change.duration.
|
170
|
-
@change.preceding.
|
171
|
-
@change.remaining.
|
168
|
+
expect(@change.end_value).to eq(55)
|
169
|
+
expect(@change.duration).to eq(20)
|
170
|
+
expect(@change.preceding).to eq(5)
|
171
|
+
expect(@change.remaining).to eq(6)
|
172
172
|
end
|
173
|
-
|
173
|
+
|
174
174
|
it 'should set transition to linear' do
|
175
|
-
@change.transition.
|
175
|
+
expect(@change.transition).to eq(Change::Gradual::LINEAR)
|
176
176
|
end
|
177
177
|
end
|
178
|
-
|
178
|
+
|
179
179
|
describe '.sigmoid' do
|
180
180
|
before(:all){ @change = Change::Gradual::Trimmed.sigmoid(55,20,preceding:5,remaining:6) }
|
181
|
-
|
181
|
+
|
182
182
|
it 'should assign end_value, duration, preceding, and remaining as normal' do
|
183
|
-
@change.end_value.
|
184
|
-
@change.duration.
|
185
|
-
@change.preceding.
|
186
|
-
@change.remaining.
|
183
|
+
expect(@change.end_value).to eq(55)
|
184
|
+
expect(@change.duration).to eq(20)
|
185
|
+
expect(@change.preceding).to eq(5)
|
186
|
+
expect(@change.remaining).to eq(6)
|
187
187
|
end
|
188
|
-
|
188
|
+
|
189
189
|
it 'should set transition to SIGMOID' do
|
190
|
-
@change.transition.
|
190
|
+
expect(@change.transition).to eq(Change::Gradual::SIGMOID)
|
191
191
|
end
|
192
192
|
end
|
193
|
-
|
193
|
+
|
194
194
|
it 'should raise NegativeError if preceding is < 0' do
|
195
195
|
expect { Change::Gradual::Trimmed.linear(11,1,preceding: -1,remaining: 0.5) }.to raise_error(NegativeError)
|
196
196
|
end
|
@@ -199,41 +199,41 @@ describe Change::Gradual::Trimmed do
|
|
199
199
|
expect { Change::Gradual::Trimmed.linear(11,3,preceding: 1,remaining: 0) }.to raise_error(NonPositiveError)
|
200
200
|
expect { Change::Gradual::Trimmed.linear(11,3,preceding: 1,remaining: -1) }.to raise_error(NonPositiveError)
|
201
201
|
end
|
202
|
-
|
202
|
+
|
203
203
|
describe '#untrim' do
|
204
204
|
before :all do
|
205
205
|
@trimmed = Change::Gradual.linear(51,12).trim(2,2)
|
206
206
|
@untrimmed = @trimmed.untrim
|
207
207
|
end
|
208
|
-
|
208
|
+
|
209
209
|
it 'should return a Change::Gradual' do
|
210
|
-
@untrimmed.
|
210
|
+
expect(@untrimmed).to be_a Change::Gradual
|
211
211
|
end
|
212
|
-
|
212
|
+
|
213
213
|
it 'should keep end_value, duration, and transition' do
|
214
|
-
@untrimmed.end_value.
|
215
|
-
@untrimmed.duration.
|
216
|
-
@untrimmed.transition.
|
214
|
+
expect(@untrimmed.end_value).to eq(@trimmed.end_value)
|
215
|
+
expect(@untrimmed.duration).to eq(@trimmed.duration)
|
216
|
+
expect(@untrimmed.transition).to eq(@trimmed.transition)
|
217
217
|
end
|
218
218
|
end
|
219
|
-
|
219
|
+
|
220
220
|
describe '#trailing' do
|
221
221
|
it 'should return the amount of transition unused at the end' do
|
222
|
-
Change::Gradual.linear(41,19).trim(4,9).trailing.
|
222
|
+
expect(Change::Gradual.linear(41,19).trim(4,9).trailing).to eq(9)
|
223
223
|
end
|
224
224
|
end
|
225
225
|
|
226
226
|
describe '#to_yaml' do
|
227
227
|
it 'should produce YAML that can be loaded' do
|
228
228
|
c = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5)
|
229
|
-
YAML.load(c.to_yaml).
|
229
|
+
expect(YAML.load(c.to_yaml)).to eq c
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
233
233
|
describe '#pack' do
|
234
234
|
it 'should produce a Hash' do
|
235
235
|
h = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5).pack
|
236
|
-
h.
|
236
|
+
expect(h).to be_a Hash
|
237
237
|
end
|
238
238
|
end
|
239
239
|
|
@@ -241,8 +241,8 @@ describe Change::Gradual::Trimmed do
|
|
241
241
|
it 'should return a Change::Gradual::Trimmed equal to the original' do
|
242
242
|
c1 = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5)
|
243
243
|
c2 = Change::Gradual::Trimmed.unpack(c1.pack)
|
244
|
-
c2.
|
245
|
-
c2.
|
244
|
+
expect(c2).to be_a Change::Gradual::Trimmed
|
245
|
+
expect(c2).to eq c1
|
246
246
|
end
|
247
247
|
end
|
248
|
-
end
|
248
|
+
end
|
@@ -1,44 +1,28 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
2
|
|
3
3
|
describe Key do
|
4
|
-
describe '.
|
5
|
-
it 'should set triad to MAJOR
|
6
|
-
k = Key.
|
7
|
-
k.
|
8
|
-
k.
|
4
|
+
describe '.major' do
|
5
|
+
it 'should set triad to MAJOR' do
|
6
|
+
k = Key.major(PitchClasses::C)
|
7
|
+
expect(k.triad_type).to eq(Key::MAJOR)
|
8
|
+
expect(k.accidental_type).to eq(Key::NONE)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
describe '.
|
13
|
-
it 'should set triad to
|
14
|
-
k = Key.
|
15
|
-
k.
|
16
|
-
k.
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '.major_sharp' do
|
21
|
-
it 'should set triad to MINOR and accidental_pref to FLAT' do
|
22
|
-
k = Key.minor_flat(0)
|
23
|
-
k.triad.should eq(Key::MINOR)
|
24
|
-
k.accidental_pref.should eq(Key::FLAT)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '.minor_sharp' do
|
29
|
-
it 'should set triad to MINOR and accidental_pref to SHARP' do
|
30
|
-
k = Key.minor_sharp(0)
|
31
|
-
k.triad.should eq(Key::MINOR)
|
32
|
-
k.accidental_pref.should eq(Key::SHARP)
|
12
|
+
describe '.minor' do
|
13
|
+
it 'should set triad to MINOR' do
|
14
|
+
k = Key.minor(PitchClasses::A)
|
15
|
+
expect(k.triad_type).to eq(Key::MINOR)
|
16
|
+
expect(k.accidental_type).to eq(Key::NONE)
|
33
17
|
end
|
34
18
|
end
|
35
19
|
|
36
20
|
describe '.new' do
|
37
21
|
context 'given tonic_pc that is not in 0..11' do
|
38
22
|
it 'should apply mod 12 to bring it in range' do
|
39
|
-
{ 12 => 0, 13 => 1, -1 => 11, 24 => 0, 18 => 6
|
23
|
+
{ 12 => 0, 13 => 1, -1 => 11, 24 => 0, 18 => 6
|
40
24
|
}.each do |t1,t2|
|
41
|
-
Key.
|
25
|
+
expect(Key.major(t1).tonic_pc).to eq(t2)
|
42
26
|
end
|
43
27
|
end
|
44
28
|
end
|
@@ -46,33 +30,33 @@ describe Key do
|
|
46
30
|
context 'given tonic_pc in 0..11' do
|
47
31
|
it 'should not change' do
|
48
32
|
(0..11).each do |pc|
|
49
|
-
Key.
|
33
|
+
expect(Key.major(pc).tonic_pc).to eq(pc)
|
50
34
|
end
|
51
35
|
end
|
52
36
|
end
|
53
|
-
|
37
|
+
|
54
38
|
context 'given triad that is not MAJOR or MINOR' do
|
55
39
|
it 'should raise ArgumentError' do
|
56
40
|
expect { Key.new(0, triad: :flipping) }.to raise_error(ArgumentError)
|
57
41
|
end
|
58
42
|
end
|
59
|
-
|
60
|
-
context 'given accidental_pref that is not FLAT or SHARP' do
|
61
|
-
it 'should raise ArgumentError' do
|
62
|
-
expect { Key.new(0, accidental_pref: :squiggle) }.to raise_error(ArgumentError)
|
63
|
-
end
|
64
|
-
end
|
65
43
|
end
|
66
|
-
|
44
|
+
|
67
45
|
describe '#flat?' do
|
68
|
-
|
46
|
+
|
47
|
+
context 'given accidental type is FLAT' do
|
69
48
|
it 'should return true' do
|
70
|
-
Key.
|
49
|
+
expect(Key.major(PitchClasses::F).flat?).to be true
|
71
50
|
end
|
72
51
|
end
|
73
|
-
context 'given
|
52
|
+
context 'given accidental type is SHARP' do
|
53
|
+
it 'should return false' do
|
54
|
+
expect(Key.major(PitchClasses::D).flat?).to be false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context 'given accidental type is NONE' do
|
74
58
|
it 'should return false' do
|
75
|
-
Key.
|
59
|
+
expect(Key.major(PitchClasses::C).flat?).to be false
|
76
60
|
end
|
77
61
|
end
|
78
62
|
end
|
@@ -80,12 +64,17 @@ describe Key do
|
|
80
64
|
describe '#sharp?' do
|
81
65
|
context 'given accidental_pref is FLAT' do
|
82
66
|
it 'should return false' do
|
83
|
-
Key.
|
67
|
+
expect(Key.major(PitchClasses::F).sharp?).to be false
|
84
68
|
end
|
85
69
|
end
|
86
70
|
context 'given accidental_pref is SHARP' do
|
87
71
|
it 'should return true' do
|
88
|
-
Key.
|
72
|
+
expect(Key.major(PitchClasses::D).sharp?).to be true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
context 'given accidental type is NONE' do
|
76
|
+
it 'should return false' do
|
77
|
+
expect(Key.major(PitchClasses::C).sharp?).to be false
|
89
78
|
end
|
90
79
|
end
|
91
80
|
end
|
@@ -93,12 +82,12 @@ describe Key do
|
|
93
82
|
describe '#major?' do
|
94
83
|
context 'given triad is MAJOR' do
|
95
84
|
it 'should return true' do
|
96
|
-
Key.
|
85
|
+
expect(Key.major(0).major?).to be true
|
97
86
|
end
|
98
87
|
end
|
99
88
|
context 'given triad is MINOR' do
|
100
89
|
it 'should return false' do
|
101
|
-
Key.
|
90
|
+
expect(Key.minor(0).major?).to be false
|
102
91
|
end
|
103
92
|
end
|
104
93
|
end
|
@@ -106,66 +95,143 @@ describe Key do
|
|
106
95
|
describe '#minor?' do
|
107
96
|
context 'given triad is MAJOR' do
|
108
97
|
it 'should return false' do
|
109
|
-
Key.
|
98
|
+
expect(Key.major(0).minor?).to be false
|
110
99
|
end
|
111
100
|
end
|
112
101
|
context 'given triad is MINOR' do
|
113
102
|
it 'should return true' do
|
114
|
-
Key.
|
103
|
+
expect(Key.minor(0).minor?).to be true
|
115
104
|
end
|
116
105
|
end
|
117
106
|
end
|
118
|
-
|
107
|
+
|
119
108
|
describe '#==' do
|
120
109
|
context 'objects with different tonic_pc' do
|
121
110
|
it 'should return false' do
|
122
|
-
Key.
|
111
|
+
expect(Key.major(0)).to_not eq(Key.major(1))
|
123
112
|
end
|
124
113
|
end
|
125
|
-
|
114
|
+
|
126
115
|
context 'objects with different triad' do
|
127
116
|
it 'should return false' do
|
128
|
-
Key.
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
context 'objects with different accidental_type' do
|
133
|
-
it 'should return false' do
|
134
|
-
Key.major_flat(0).should_not eq(Key.major_sharp(0))
|
117
|
+
expect(Key.major(0)).to_not eq(Key.minor(0))
|
135
118
|
end
|
136
119
|
end
|
137
|
-
|
138
|
-
context 'objects with same tonic_pc
|
120
|
+
|
121
|
+
context 'objects with same tonic_pc and triad type' do
|
139
122
|
it 'should return true' do
|
140
|
-
Key.
|
123
|
+
expect(Key.major(0)).to eq(Key.major(0))
|
141
124
|
end
|
142
125
|
end
|
143
126
|
end
|
144
|
-
|
127
|
+
|
145
128
|
describe '#clone' do
|
146
129
|
it 'should return a different, equal object' do
|
147
|
-
k1 = Key.
|
130
|
+
k1 = Key.major(0)
|
148
131
|
k2 = k1.clone
|
149
|
-
k1.
|
150
|
-
k1.
|
132
|
+
expect(k1).to_not be k2
|
133
|
+
expect(k1).to eq k2
|
151
134
|
end
|
152
135
|
end
|
153
|
-
|
136
|
+
|
154
137
|
describe '#accidentals' do
|
138
|
+
context 'C major or A minor' do
|
139
|
+
it 'should have no accidentals' do
|
140
|
+
expect(Keys::C_MAJOR.accidentals).to be_empty
|
141
|
+
expect(Keys::A_MINOR.accidentals).to be_empty
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'F major or D minor' do
|
146
|
+
it 'should have one flat' do
|
147
|
+
expect(Keys::F_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(1))
|
148
|
+
expect(Keys::D_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(1))
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'Bb major or G minor' do
|
153
|
+
it 'should have two flats' do
|
154
|
+
expect(Keys::Bb_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(2))
|
155
|
+
expect(Keys::G_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(2))
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'Eb major or C minor' do
|
160
|
+
it 'should have three flats' do
|
161
|
+
expect(Keys::Eb_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(3))
|
162
|
+
expect(Keys::C_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(3))
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'Ab major or F minor' do
|
167
|
+
it 'should have four flats' do
|
168
|
+
expect(Keys::Ab_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(4))
|
169
|
+
expect(Keys::F_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(4))
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'Db major or Bb minor' do
|
174
|
+
it 'should have five flats' do
|
175
|
+
expect(Keys::Db_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(5))
|
176
|
+
expect(Keys::Bb_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(5))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'Gb major or Eb minor' do
|
181
|
+
it 'should have six flats' do
|
182
|
+
expect(Keys::Gb_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(6))
|
183
|
+
expect(Keys::Eb_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(6))
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context 'G major or E minor' do
|
188
|
+
it 'should have one sharp' do
|
189
|
+
expect(Keys::G_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(1))
|
190
|
+
expect(Keys::E_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(1))
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'D major or B minor' do
|
195
|
+
it 'should have two sharps' do
|
196
|
+
expect(Keys::D_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(2))
|
197
|
+
expect(Keys::B_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(2))
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'A major or F# minor' do
|
202
|
+
it 'should have three sharps' do
|
203
|
+
expect(Keys::A_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(3))
|
204
|
+
expect(Keys::Fs_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(3))
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'E major or C# minor' do
|
209
|
+
it 'should have four sharps' do
|
210
|
+
expect(Keys::E_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(4))
|
211
|
+
expect(Keys::Cs_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(4))
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'B major or G# minor' do
|
216
|
+
it 'should have five sharps' do
|
217
|
+
expect(Keys::B_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(5))
|
218
|
+
expect(Keys::Gs_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(5))
|
219
|
+
end
|
220
|
+
end
|
155
221
|
end
|
156
222
|
|
157
223
|
describe '#pack' do
|
158
224
|
it 'should return a Hash' do
|
159
|
-
Key.
|
225
|
+
expect(Key.major(1).pack).to be_a Hash
|
160
226
|
end
|
161
227
|
end
|
162
228
|
|
163
229
|
describe '.unpack' do
|
164
230
|
it 'should return a Key object equal to the original' do
|
165
|
-
k1 = Key.
|
231
|
+
k1 = Key.major(1)
|
166
232
|
k2 = Key.unpack k1.pack
|
167
|
-
k2.
|
168
|
-
k2.
|
233
|
+
expect(k2).to be_a Key
|
234
|
+
expect(k2).to eq(k1)
|
169
235
|
end
|
170
236
|
end
|
171
237
|
end
|