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
@@ -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
|