music 0.6.2 → 0.8.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 +7 -0
- data/.rubocop.yml +72 -0
- data/.rubocop_todo.yml +47 -0
- data/.travis.yml +5 -5
- data/CHANGELOG.md +15 -0
- data/Gemfile +8 -1
- data/Gemfile.lock +283 -44
- data/Guardfile +8 -21
- data/README.md +4 -0
- data/Rakefile +7 -8
- data/lib/music/chord.rb +34 -31
- data/lib/music/note.rb +62 -80
- data/lib/music/version.rb +1 -1
- data/lib/music.rb +0 -1
- data/music.gemspec +14 -17
- data/spec/classes/chord_spec.rb +59 -59
- data/spec/classes/note_spec.rb +295 -286
- data/spec/spec_helper.rb +1 -1
- data/spec/support/matchers/have_an_interval.rb +2 -2
- metadata +20 -75
- data/lib/music/patches/hash.rb +0 -5
- data/spec/classes/hash_spec.rb +0 -17
data/spec/classes/note_spec.rb
CHANGED
@@ -2,143 +2,149 @@ require 'spec_helper'
|
|
2
2
|
include Music
|
3
3
|
|
4
4
|
describe Music::Note do
|
5
|
+
describe '#new' do
|
6
|
+
it 'should allow note strings to initalize notes' do
|
7
|
+
Note.new('E0').frequency.should eq(20.60)
|
8
|
+
Note.new('Bb3').frequency.should eq(233.08)
|
9
|
+
end
|
5
10
|
|
6
|
-
|
7
|
-
|
8
|
-
Note.new(
|
9
|
-
Note.new('Bb3').frequency.should == 233.08
|
11
|
+
it 'should allow frequencies to initalize notes' do
|
12
|
+
Note.new(698.46).note_string.should eq('F5')
|
13
|
+
Note.new(1975.53).note_string.should eq('B6')
|
10
14
|
end
|
11
15
|
|
12
|
-
it
|
13
|
-
Note.new(
|
14
|
-
Note.new(
|
16
|
+
it 'should allow enharmonic note strings to initialize notes' do
|
17
|
+
Note.new('E#5').frequency.should eq(Note.new('F5').frequency)
|
18
|
+
Note.new('Fb5').frequency.should eq(Note.new('E5').frequency)
|
19
|
+
Note.new('B#5').frequency.should eq(Note.new('C5').frequency)
|
20
|
+
Note.new('Cb5').frequency.should eq(Note.new('B5').frequency)
|
15
21
|
end
|
16
22
|
end
|
17
23
|
|
18
|
-
describe
|
19
|
-
it
|
20
|
-
Note.new(698.46).should < Note.new(1975.53)
|
21
|
-
Note.new('B5').should > Note.new('B2')
|
22
|
-
Note.new(698.46).should
|
24
|
+
describe 'Comparing notes' do
|
25
|
+
it 'should compare notes by their frequencies' do
|
26
|
+
Note.new(698.46).should be < Note.new(1975.53)
|
27
|
+
Note.new('B5').should be > Note.new('B2')
|
28
|
+
Note.new(698.46).should eq(Note.new('F5'))
|
23
29
|
end
|
24
30
|
end
|
25
31
|
|
26
32
|
describe '#note_string' do
|
27
33
|
it 'Should return the letter, accidental, and octave as a string' do
|
28
|
-
Note.new(698.46).note_string.should
|
29
|
-
Note.new('C#6').note_string.should
|
34
|
+
Note.new(698.46).note_string.should eq('F5')
|
35
|
+
Note.new('C#6').note_string.should eq('C#6')
|
30
36
|
end
|
31
37
|
|
32
38
|
it 'Should return the flat version if asked' do
|
33
|
-
Note.new('C#6').note_string(true).should
|
39
|
+
Note.new('C#6').note_string(true).should eq('Db6')
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
37
43
|
describe '#letter' do
|
38
44
|
it 'Should return just the letter' do
|
39
|
-
Note.new('E0').letter.should
|
40
|
-
Note.new(698.46).letter.should
|
41
|
-
Note.new(1975.53).letter.should
|
45
|
+
Note.new('E0').letter.should eq('E')
|
46
|
+
Note.new(698.46).letter.should eq('F')
|
47
|
+
Note.new(1975.53).letter.should eq('B')
|
42
48
|
end
|
43
49
|
|
44
50
|
it 'Should return the letter based on if asked for the flat' do
|
45
|
-
Note.new('Bb3').letter.should
|
46
|
-
Note.new('Bb3').letter(true).should
|
51
|
+
Note.new('Bb3').letter.should eq('A')
|
52
|
+
Note.new('Bb3').letter(true).should eq('B')
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
50
56
|
describe '#accidental' do
|
51
57
|
it 'Should return just the accidental' do
|
52
|
-
Note.new('A#4').accidental.should
|
58
|
+
Note.new('A#4').accidental.should eq('#')
|
53
59
|
end
|
54
60
|
|
55
61
|
it 'Should return the flat if asked for' do
|
56
|
-
Note.new('Bb3').accidental.should
|
57
|
-
Note.new('Bb3').accidental(true).should
|
62
|
+
Note.new('Bb3').accidental.should eq('#')
|
63
|
+
Note.new('Bb3').accidental(true).should eq('b')
|
58
64
|
end
|
59
65
|
|
60
66
|
it 'Should return nil for no accidental' do
|
61
|
-
Note.new('B2').accidental.should
|
62
|
-
Note.new('G2').accidental.should
|
67
|
+
Note.new('B2').accidental.should.nil?
|
68
|
+
Note.new('G2').accidental.should.nil?
|
63
69
|
end
|
64
70
|
end
|
65
71
|
|
66
72
|
describe '#octave' do
|
67
73
|
it 'Should return the octave' do
|
68
|
-
Note.new('A#4').octave.should
|
69
|
-
Note.new('B7').octave.should
|
70
|
-
Note.new('Gb1').octave.should
|
71
|
-
Note.new('E0').octave.should
|
74
|
+
Note.new('A#4').octave.should eq(4)
|
75
|
+
Note.new('B7').octave.should eq(7)
|
76
|
+
Note.new('Gb1').octave.should eq(1)
|
77
|
+
Note.new('E0').octave.should eq(0)
|
72
78
|
end
|
73
79
|
end
|
74
80
|
|
75
|
-
describe
|
76
|
-
it
|
77
|
-
Note.parse_note_string('A#1').should
|
78
|
-
Note.parse_note_string('Cb4').should
|
81
|
+
describe '.parse_note_string(note_string)' do
|
82
|
+
it 'Should split note letter, accidental, and octave' do
|
83
|
+
Note.parse_note_string('A#1').should eq(['A', '#', 1])
|
84
|
+
Note.parse_note_string('Cb4').should eq(['C', 'b', 4])
|
79
85
|
end
|
80
86
|
|
81
|
-
it
|
82
|
-
Note.parse_note_string('g#1').should
|
87
|
+
it 'Should allow for lower case notes' do
|
88
|
+
Note.parse_note_string('g#1').should eq(['G', '#', 1])
|
83
89
|
end
|
84
90
|
|
85
|
-
it
|
86
|
-
Note.parse_note_string('A', 4).should
|
87
|
-
Note.parse_note_string('C#', 6).should
|
91
|
+
it 'Should allow for an assumed octave' do
|
92
|
+
Note.parse_note_string('A', 4).should eq(['A', nil, 4])
|
93
|
+
Note.parse_note_string('C#', 6).should eq(['C', '#', 6])
|
88
94
|
end
|
89
95
|
|
90
|
-
it
|
91
|
-
Note.parse_note_string('B3', 4).should
|
92
|
-
Note.parse_note_string('Gb6', 2).should
|
96
|
+
it 'Should ignore the assumed octave if there is a octave' do
|
97
|
+
Note.parse_note_string('B3', 4).should eq(['B', nil, 3])
|
98
|
+
Note.parse_note_string('Gb6', 2).should eq(['G', 'b', 6])
|
93
99
|
end
|
94
100
|
|
95
|
-
it
|
101
|
+
it 'Should not allow notes above G' do
|
96
102
|
expect { Note.parse_note_string('HB1') }.to raise_error ArgumentError
|
97
103
|
end
|
98
104
|
|
99
|
-
it
|
105
|
+
it 'Should not allow extraneous characters' do
|
100
106
|
expect { Note.parse_note_string(' Ab1') }.to raise_error ArgumentError
|
101
107
|
expect { Note.parse_note_string('%Hb1') }.to raise_error ArgumentError
|
102
108
|
expect { Note.parse_note_string('Hb1-') }.to raise_error ArgumentError
|
103
109
|
end
|
104
110
|
|
105
|
-
it
|
111
|
+
it 'Should not allow for upper case flats' do
|
106
112
|
expect { Note.parse_note_string('AB1') }.to raise_error ArgumentError
|
107
113
|
expect { Note.parse_note_string('aB1') }.to raise_error ArgumentError
|
108
114
|
end
|
109
115
|
|
110
|
-
it
|
111
|
-
Note.parse_note_string('C4').should
|
116
|
+
it 'Should return nil when there is no accidental' do
|
117
|
+
Note.parse_note_string('C4').should eq(['C', nil, 4])
|
112
118
|
end
|
113
119
|
|
114
|
-
it
|
115
|
-
Note.parse_note_string('G#8').should
|
120
|
+
it 'Should not allow note above octave 8' do
|
121
|
+
Note.parse_note_string('G#8').should eq(['G', '#', 8])
|
116
122
|
expect { Note.parse_note_string('Ab9') }.to raise_error ArgumentError
|
117
123
|
expect { Note.parse_note_string('Ab', 9) }.to raise_error ArgumentError
|
118
124
|
end
|
119
125
|
end
|
120
126
|
|
121
|
-
describe
|
127
|
+
describe '.note_distance(note_string1, note_string2)' do
|
122
128
|
{
|
123
129
|
['A4', 'A#4'] => 1,
|
124
|
-
|
125
|
-
|
130
|
+
%w(A4 Ab4) => -1,
|
131
|
+
%w(B0 B0) => 0,
|
126
132
|
['G#1', 'Ab1'] => 0,
|
127
133
|
['Bb1', 'A#1'] => 0,
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
134
|
+
%w(A3 A4) => 12,
|
135
|
+
%w(a3 A4) => 12,
|
136
|
+
%w(B1 F1) => -6,
|
137
|
+
%w(B1 f1) => -6,
|
138
|
+
%w(A4 Eb0) => -54,
|
139
|
+
%w(a4 eb0) => -54,
|
140
|
+
%w(A2 C4) => 15
|
135
141
|
}.each do |notes, distance|
|
136
142
|
it "Should return #{distance} between #{notes[0]} and #{notes[1]}" do
|
137
|
-
Note.note_distance(*notes).should
|
143
|
+
Note.note_distance(*notes).should eq(distance)
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
141
|
-
it
|
147
|
+
it 'Should not allow invalid note strings' do
|
142
148
|
expect { Note.note_distance('H0', 'A0') }.to raise_error ArgumentError
|
143
149
|
expect { Note.note_distance('A0', 'I#0') }.to raise_error ArgumentError
|
144
150
|
expect { Note.note_distance('A%0', 'A0') }.to raise_error ArgumentError
|
@@ -147,14 +153,14 @@ describe Music::Note do
|
|
147
153
|
|
148
154
|
describe '#distance_to(note)' do
|
149
155
|
it 'Should find the distance between the subject note object and the note passed in' do
|
150
|
-
Note.new('A2').distance_to(Note.new('C4')).should
|
156
|
+
Note.new('A2').distance_to(Note.new('C4')).should eq(15)
|
151
157
|
end
|
152
158
|
end
|
153
159
|
|
154
160
|
describe 'interval calculations' do
|
155
161
|
let(:c4) { Note.new('C4') }
|
156
162
|
let(:b4) { Note.new('B4') }
|
157
|
-
|
163
|
+
|
158
164
|
it { c4.should have_an_interval :minor_second, 'C#4' }
|
159
165
|
it { b4.should have_an_interval :minor_second, 'C5' }
|
160
166
|
|
@@ -206,276 +212,279 @@ describe Music::Note do
|
|
206
212
|
|
207
213
|
describe 'scales from notes (as scale key)' do
|
208
214
|
describe '#major_scale' do
|
209
|
-
|
210
|
-
Note.new('C4')
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
Note.new('G4')
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
215
|
+
it 'should return major scales' do
|
216
|
+
Note.new('C4').major_scale.should eq([
|
217
|
+
Note.new('C4'),
|
218
|
+
Note.new('D4'),
|
219
|
+
Note.new('E4'),
|
220
|
+
Note.new('F4'),
|
221
|
+
Note.new('G4'),
|
222
|
+
Note.new('A4'),
|
223
|
+
Note.new('B4')
|
224
|
+
])
|
225
|
+
|
226
|
+
Note.new('G4').major_scale.should eq([
|
227
|
+
Note.new('G4'),
|
228
|
+
Note.new('A4'),
|
229
|
+
Note.new('B4'),
|
230
|
+
Note.new('C5'),
|
231
|
+
Note.new('D5'),
|
232
|
+
Note.new('E5'),
|
233
|
+
Note.new('F#5')
|
234
|
+
])
|
235
|
+
end
|
228
236
|
end
|
229
237
|
|
230
238
|
describe '#minor_scale' do
|
231
|
-
|
232
|
-
Note.new('C4')
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
Note.new('G4')
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
239
|
+
it 'should return minor scales' do
|
240
|
+
Note.new('C4').minor_scale.should eq([
|
241
|
+
Note.new('C4'),
|
242
|
+
Note.new('D4'),
|
243
|
+
Note.new('D#4'),
|
244
|
+
Note.new('F4'),
|
245
|
+
Note.new('G4'),
|
246
|
+
Note.new('G#4'),
|
247
|
+
Note.new('A#4')
|
248
|
+
])
|
249
|
+
|
250
|
+
Note.new('G4').minor_scale.should eq([
|
251
|
+
Note.new('G4'),
|
252
|
+
Note.new('A4'),
|
253
|
+
Note.new('A#4'),
|
254
|
+
Note.new('C5'),
|
255
|
+
Note.new('D5'),
|
256
|
+
Note.new('D#5'),
|
257
|
+
Note.new('F5')
|
258
|
+
])
|
259
|
+
end
|
250
260
|
end
|
251
261
|
end
|
252
262
|
|
253
263
|
describe '#to_s' do
|
254
264
|
it 'should output the note_string' do
|
255
|
-
Note.new('E4').to_s.should
|
265
|
+
Note.new('E4').to_s.should eq('E4')
|
256
266
|
end
|
257
267
|
|
258
268
|
it 'should use the sharp version' do
|
259
|
-
Note.new('D#5').to_s.should
|
260
|
-
Note.new('Eb5').to_s.should
|
269
|
+
Note.new('D#5').to_s.should eq('D#5')
|
270
|
+
Note.new('Eb5').to_s.should eq('D#5')
|
261
271
|
end
|
262
272
|
end
|
263
273
|
|
264
274
|
describe 'chords from notes' do
|
265
275
|
c4 = Note.new('C4')
|
266
|
-
|
267
|
-
c_minor = Chord.new(
|
268
|
-
c_major = Chord.new(
|
269
|
-
c_fifth = Chord.new(
|
270
|
-
c_diminished = Chord.new(
|
276
|
+
|
277
|
+
c_minor = Chord.new(%w(C4 Eb4 G4))
|
278
|
+
c_major = Chord.new(%w(C4 E4 G4))
|
279
|
+
c_fifth = Chord.new(%w(C4 G4))
|
280
|
+
c_diminished = Chord.new(%w(C4 Eb4 Gb4))
|
271
281
|
c_augmented = Chord.new(['C4', 'E4', 'G#4'])
|
272
|
-
c_major_seventh = Chord.new(
|
273
|
-
c_minor_seventh = Chord.new(
|
274
|
-
c_diminished_seventh = Chord.new(
|
282
|
+
c_major_seventh = Chord.new(%w(C4 E4 G4 B4))
|
283
|
+
c_minor_seventh = Chord.new(%w(C4 Eb4 G4 Bb4))
|
284
|
+
c_diminished_seventh = Chord.new(%w(C4 Eb4 Gb4 A4))
|
275
285
|
c_augmented_seventh = Chord.new(['C4', 'E4', 'G#4', 'Bb4'])
|
276
|
-
c_half_diminished_seventh = Chord.new(
|
286
|
+
c_half_diminished_seventh = Chord.new(%w(C4 Eb4 Gb4 Bb4))
|
277
287
|
|
278
288
|
describe 'chords from notes' do
|
279
289
|
describe '#chord' do
|
280
290
|
it 'should recognize minor chords' do
|
281
|
-
c4.chord(:minor).should
|
282
|
-
c4.chord('Minor').should
|
283
|
-
c4.chord('minor').should
|
284
|
-
c4.chord('min').should
|
285
|
-
c4.chord('MIN').should
|
286
|
-
c4.chord('m').should
|
291
|
+
c4.chord(:minor).should eq(c_minor)
|
292
|
+
c4.chord('Minor').should eq(c_minor)
|
293
|
+
c4.chord('minor').should eq(c_minor)
|
294
|
+
c4.chord('min').should eq(c_minor)
|
295
|
+
c4.chord('MIN').should eq(c_minor)
|
296
|
+
c4.chord('m').should eq(c_minor)
|
287
297
|
end
|
288
298
|
|
289
299
|
it 'should recognize major chords' do
|
290
|
-
c4.chord(:major).should
|
291
|
-
c4.chord('Major').should
|
292
|
-
c4.chord('major').should
|
293
|
-
c4.chord('maj').should
|
294
|
-
c4.chord('MAJ').should
|
295
|
-
c4.chord('M').should
|
296
|
-
c4.chord('').should
|
300
|
+
c4.chord(:major).should eq(c_major)
|
301
|
+
c4.chord('Major').should eq(c_major)
|
302
|
+
c4.chord('major').should eq(c_major)
|
303
|
+
c4.chord('maj').should eq(c_major)
|
304
|
+
c4.chord('MAJ').should eq(c_major)
|
305
|
+
c4.chord('M').should eq(c_major)
|
306
|
+
c4.chord('').should eq(c_major)
|
297
307
|
end
|
298
308
|
|
299
309
|
it 'should recognize power chords' do
|
300
|
-
c4.chord(:power).should
|
301
|
-
c4.chord(:fifth).should
|
302
|
-
c4.chord('Power').should
|
303
|
-
c4.chord('power').should
|
304
|
-
c4.chord('Fifth').should
|
305
|
-
c4.chord('fifth').should
|
306
|
-
c4.chord('pow').should
|
307
|
-
c4.chord('POW').should
|
308
|
-
c4.chord('5').should
|
310
|
+
c4.chord(:power).should eq(c_fifth)
|
311
|
+
c4.chord(:fifth).should eq(c_fifth)
|
312
|
+
c4.chord('Power').should eq(c_fifth)
|
313
|
+
c4.chord('power').should eq(c_fifth)
|
314
|
+
c4.chord('Fifth').should eq(c_fifth)
|
315
|
+
c4.chord('fifth').should eq(c_fifth)
|
316
|
+
c4.chord('pow').should eq(c_fifth)
|
317
|
+
c4.chord('POW').should eq(c_fifth)
|
318
|
+
c4.chord('5').should eq(c_fifth)
|
309
319
|
end
|
310
320
|
|
311
321
|
it 'should recognize diminished chords' do
|
312
|
-
c4.chord(:diminished).should
|
313
|
-
c4.chord('Diminished').should
|
314
|
-
c4.chord('diminished').should
|
315
|
-
c4.chord('dim').should
|
316
|
-
c4.chord('DIM').should
|
322
|
+
c4.chord(:diminished).should eq(c_diminished)
|
323
|
+
c4.chord('Diminished').should eq(c_diminished)
|
324
|
+
c4.chord('diminished').should eq(c_diminished)
|
325
|
+
c4.chord('dim').should eq(c_diminished)
|
326
|
+
c4.chord('DIM').should eq(c_diminished)
|
317
327
|
end
|
318
328
|
|
319
329
|
it 'should recognize augmented chords' do
|
320
|
-
c4.chord(:augmented).should
|
321
|
-
c4.chord('Augmented').should
|
322
|
-
c4.chord('augmented').should
|
323
|
-
c4.chord('aug').should
|
324
|
-
c4.chord('AUG').should
|
325
|
-
c4.chord('+').should
|
330
|
+
c4.chord(:augmented).should eq(c_augmented)
|
331
|
+
c4.chord('Augmented').should eq(c_augmented)
|
332
|
+
c4.chord('augmented').should eq(c_augmented)
|
333
|
+
c4.chord('aug').should eq(c_augmented)
|
334
|
+
c4.chord('AUG').should eq(c_augmented)
|
335
|
+
c4.chord('+').should eq(c_augmented)
|
326
336
|
end
|
327
337
|
|
328
338
|
it 'should recognize major seventh chords' do
|
329
|
-
c4.chord(:major_seventh).should
|
330
|
-
c4.chord('major_seventh').should
|
331
|
-
c4.chord('major seventh').should
|
332
|
-
c4.chord('Major seventh').should
|
333
|
-
c4.chord('maj seventh').should
|
334
|
-
c4.chord('maj 7').should
|
335
|
-
c4.chord('maj 7th').should
|
336
|
-
c4.chord('maj7').should
|
337
|
-
c4.chord('maj7th').should
|
338
|
-
c4.chord('MAJ7').should
|
339
|
-
c4.chord('M7').should
|
339
|
+
c4.chord(:major_seventh).should eq(c_major_seventh)
|
340
|
+
c4.chord('major_seventh').should eq(c_major_seventh)
|
341
|
+
c4.chord('major seventh').should eq(c_major_seventh)
|
342
|
+
c4.chord('Major seventh').should eq(c_major_seventh)
|
343
|
+
c4.chord('maj seventh').should eq(c_major_seventh)
|
344
|
+
c4.chord('maj 7').should eq(c_major_seventh)
|
345
|
+
c4.chord('maj 7th').should eq(c_major_seventh)
|
346
|
+
c4.chord('maj7').should eq(c_major_seventh)
|
347
|
+
c4.chord('maj7th').should eq(c_major_seventh)
|
348
|
+
c4.chord('MAJ7').should eq(c_major_seventh)
|
349
|
+
c4.chord('M7').should eq(c_major_seventh)
|
340
350
|
end
|
341
351
|
|
342
352
|
it 'should recognize minor seventh chords' do
|
343
|
-
c4.chord(:minor_seventh).should
|
344
|
-
c4.chord('minor_seventh').should
|
345
|
-
c4.chord('minor seventh').should
|
346
|
-
c4.chord('minor seventh').should
|
347
|
-
c4.chord('min seventh').should
|
348
|
-
c4.chord('min 7').should
|
349
|
-
c4.chord('min 7th').should
|
350
|
-
c4.chord('min7').should
|
351
|
-
c4.chord('min7th').should
|
352
|
-
c4.chord('min7').should
|
353
|
-
c4.chord('m7').should
|
353
|
+
c4.chord(:minor_seventh).should eq(c_minor_seventh)
|
354
|
+
c4.chord('minor_seventh').should eq(c_minor_seventh)
|
355
|
+
c4.chord('minor seventh').should eq(c_minor_seventh)
|
356
|
+
c4.chord('minor seventh').should eq(c_minor_seventh)
|
357
|
+
c4.chord('min seventh').should eq(c_minor_seventh)
|
358
|
+
c4.chord('min 7').should eq(c_minor_seventh)
|
359
|
+
c4.chord('min 7th').should eq(c_minor_seventh)
|
360
|
+
c4.chord('min7').should eq(c_minor_seventh)
|
361
|
+
c4.chord('min7th').should eq(c_minor_seventh)
|
362
|
+
c4.chord('min7').should eq(c_minor_seventh)
|
363
|
+
c4.chord('m7').should eq(c_minor_seventh)
|
354
364
|
end
|
355
365
|
|
356
366
|
it 'should recognize diminished seventh chords' do
|
357
|
-
c4.chord(:diminished_seventh).should
|
358
|
-
c4.chord('diminished_seventh').should
|
359
|
-
c4.chord('diminished seventh').should
|
360
|
-
c4.chord('diminished seventh').should
|
361
|
-
c4.chord('dim seventh').should
|
362
|
-
c4.chord('dim 7').should
|
363
|
-
c4.chord('dim 7th').should
|
364
|
-
c4.chord('dim7').should
|
365
|
-
c4.chord('dim7th').should
|
366
|
-
c4.chord('dim7').should
|
367
|
-
c4.chord('d7').should
|
367
|
+
c4.chord(:diminished_seventh).should eq(c_diminished_seventh)
|
368
|
+
c4.chord('diminished_seventh').should eq(c_diminished_seventh)
|
369
|
+
c4.chord('diminished seventh').should eq(c_diminished_seventh)
|
370
|
+
c4.chord('diminished seventh').should eq(c_diminished_seventh)
|
371
|
+
c4.chord('dim seventh').should eq(c_diminished_seventh)
|
372
|
+
c4.chord('dim 7').should eq(c_diminished_seventh)
|
373
|
+
c4.chord('dim 7th').should eq(c_diminished_seventh)
|
374
|
+
c4.chord('dim7').should eq(c_diminished_seventh)
|
375
|
+
c4.chord('dim7th').should eq(c_diminished_seventh)
|
376
|
+
c4.chord('dim7').should eq(c_diminished_seventh)
|
377
|
+
c4.chord('d7').should eq(c_diminished_seventh)
|
368
378
|
end
|
369
379
|
|
370
380
|
it 'should recognize augmented seventh chords' do
|
371
|
-
c4.chord(:augmented_seventh).should
|
372
|
-
c4.chord('augmented_seventh').should
|
373
|
-
c4.chord('augmented seventh').should
|
374
|
-
c4.chord('augmented seventh').should
|
375
|
-
c4.chord('aug seventh').should
|
376
|
-
c4.chord('aug 7').should
|
377
|
-
c4.chord('aug 7th').should
|
378
|
-
c4.chord('aug7').should
|
379
|
-
c4.chord('aug7th').should
|
380
|
-
c4.chord('aug7').should
|
381
|
-
c4.chord('+7').should
|
381
|
+
c4.chord(:augmented_seventh).should eq(c_augmented_seventh)
|
382
|
+
c4.chord('augmented_seventh').should eq(c_augmented_seventh)
|
383
|
+
c4.chord('augmented seventh').should eq(c_augmented_seventh)
|
384
|
+
c4.chord('augmented seventh').should eq(c_augmented_seventh)
|
385
|
+
c4.chord('aug seventh').should eq(c_augmented_seventh)
|
386
|
+
c4.chord('aug 7').should eq(c_augmented_seventh)
|
387
|
+
c4.chord('aug 7th').should eq(c_augmented_seventh)
|
388
|
+
c4.chord('aug7').should eq(c_augmented_seventh)
|
389
|
+
c4.chord('aug7th').should eq(c_augmented_seventh)
|
390
|
+
c4.chord('aug7').should eq(c_augmented_seventh)
|
391
|
+
c4.chord('+7').should eq(c_augmented_seventh)
|
382
392
|
end
|
383
393
|
|
384
394
|
it 'should recognize half diminished seventh chords' do
|
385
|
-
c4.chord(:half_diminished_seventh).should
|
386
|
-
c4.chord('half_diminished_7').should
|
387
|
-
c4.chord('half_diminished_7th').should
|
388
|
-
c4.chord('half-diminished seventh').should
|
389
|
-
c4.chord('half-diminished 7').should
|
390
|
-
c4.chord('half-diminished 7th').should
|
391
|
-
c4.chord('half_dim seventh').should
|
392
|
-
c4.chord('half_dim 7').should
|
393
|
-
c4.chord('half_dim 7th').should
|
394
|
-
c4.chord('half_dim7').should
|
395
|
-
c4.chord('half_dim7th').should
|
396
|
-
c4.chord('half_dim7').should
|
395
|
+
c4.chord(:half_diminished_seventh).should eq(c_half_diminished_seventh)
|
396
|
+
c4.chord('half_diminished_7').should eq(c_half_diminished_seventh)
|
397
|
+
c4.chord('half_diminished_7th').should eq(c_half_diminished_seventh)
|
398
|
+
c4.chord('half-diminished seventh').should eq(c_half_diminished_seventh)
|
399
|
+
c4.chord('half-diminished 7').should eq(c_half_diminished_seventh)
|
400
|
+
c4.chord('half-diminished 7th').should eq(c_half_diminished_seventh)
|
401
|
+
c4.chord('half_dim seventh').should eq(c_half_diminished_seventh)
|
402
|
+
c4.chord('half_dim 7').should eq(c_half_diminished_seventh)
|
403
|
+
c4.chord('half_dim 7th').should eq(c_half_diminished_seventh)
|
404
|
+
c4.chord('half_dim7').should eq(c_half_diminished_seventh)
|
405
|
+
c4.chord('half_dim7th').should eq(c_half_diminished_seventh)
|
406
|
+
c4.chord('half_dim7').should eq(c_half_diminished_seventh)
|
397
407
|
end
|
398
408
|
end
|
399
409
|
|
400
410
|
describe 'chord methods' do
|
401
411
|
it 'should have minor methods' do
|
402
|
-
c4.minor_chord.should
|
403
|
-
c4.min_chord.should
|
404
|
-
c4.m_chord.should
|
412
|
+
c4.minor_chord.should eq(c_minor)
|
413
|
+
c4.min_chord.should eq(c_minor)
|
414
|
+
c4.m_chord.should eq(c_minor)
|
405
415
|
end
|
406
416
|
|
407
417
|
it 'should have major methods' do
|
408
|
-
c4.major_chord.should
|
409
|
-
c4.maj_chord.should
|
410
|
-
c4.M_chord.should
|
418
|
+
c4.major_chord.should eq(c_major)
|
419
|
+
c4.maj_chord.should eq(c_major)
|
420
|
+
c4.M_chord.should eq(c_major)
|
411
421
|
end
|
412
422
|
|
413
423
|
it 'should have diminished methods' do
|
414
|
-
c4.diminished_chord.should
|
415
|
-
c4.dim_chord.should
|
424
|
+
c4.diminished_chord.should eq(c_diminished)
|
425
|
+
c4.dim_chord.should eq(c_diminished)
|
416
426
|
end
|
417
427
|
|
418
428
|
it 'should have augmented methods' do
|
419
|
-
c4.augmented_chord.should
|
420
|
-
c4.aug_chord.should
|
429
|
+
c4.augmented_chord.should eq(c_augmented)
|
430
|
+
c4.aug_chord.should eq(c_augmented)
|
421
431
|
end
|
422
432
|
|
423
433
|
it 'should have major seventh methods' do
|
424
|
-
c4.major_seventh_chord.should
|
425
|
-
c4.maj_seventh_chord.should
|
426
|
-
c4.maj_7_chord.should
|
427
|
-
c4.maj_7th_chord.should
|
428
|
-
c4.maj7_chord.should
|
429
|
-
c4.maj7th_chord.should
|
430
|
-
c4.M7_chord.should
|
434
|
+
c4.major_seventh_chord.should eq(c_major_seventh)
|
435
|
+
c4.maj_seventh_chord.should eq(c_major_seventh)
|
436
|
+
c4.maj_7_chord.should eq(c_major_seventh)
|
437
|
+
c4.maj_7th_chord.should eq(c_major_seventh)
|
438
|
+
c4.maj7_chord.should eq(c_major_seventh)
|
439
|
+
c4.maj7th_chord.should eq(c_major_seventh)
|
440
|
+
c4.M7_chord.should eq(c_major_seventh)
|
431
441
|
end
|
432
442
|
|
433
443
|
it 'should have minor seventh methods' do
|
434
|
-
c4.minor_seventh_chord.should
|
435
|
-
c4.min_seventh_chord.should
|
436
|
-
c4.min_7_chord.should
|
437
|
-
c4.min_7th_chord.should
|
438
|
-
c4.min7_chord.should
|
439
|
-
c4.min7th_chord.should
|
440
|
-
c4.m7_chord.should
|
444
|
+
c4.minor_seventh_chord.should eq(c_minor_seventh)
|
445
|
+
c4.min_seventh_chord.should eq(c_minor_seventh)
|
446
|
+
c4.min_7_chord.should eq(c_minor_seventh)
|
447
|
+
c4.min_7th_chord.should eq(c_minor_seventh)
|
448
|
+
c4.min7_chord.should eq(c_minor_seventh)
|
449
|
+
c4.min7th_chord.should eq(c_minor_seventh)
|
450
|
+
c4.m7_chord.should eq(c_minor_seventh)
|
441
451
|
end
|
442
452
|
|
443
453
|
it 'should have diminished seventh methods' do
|
444
|
-
c4.diminished_seventh_chord.should
|
445
|
-
c4.dim_seventh_chord.should
|
446
|
-
c4.dim_7_chord.should
|
447
|
-
c4.dim_7th_chord.should
|
448
|
-
c4.dim7_chord.should
|
449
|
-
c4.dim7th_chord.should
|
450
|
-
c4.d7_chord.should
|
454
|
+
c4.diminished_seventh_chord.should eq(c_diminished_seventh)
|
455
|
+
c4.dim_seventh_chord.should eq(c_diminished_seventh)
|
456
|
+
c4.dim_7_chord.should eq(c_diminished_seventh)
|
457
|
+
c4.dim_7th_chord.should eq(c_diminished_seventh)
|
458
|
+
c4.dim7_chord.should eq(c_diminished_seventh)
|
459
|
+
c4.dim7th_chord.should eq(c_diminished_seventh)
|
460
|
+
c4.d7_chord.should eq(c_diminished_seventh)
|
451
461
|
end
|
452
462
|
|
453
463
|
it 'should have augmented seventh methods' do
|
454
|
-
c4.augmented_seventh_chord.should
|
455
|
-
c4.aug_seventh_chord.should
|
456
|
-
c4.aug_7_chord.should
|
457
|
-
c4.aug_7th_chord.should
|
458
|
-
c4.aug7_chord.should
|
459
|
-
c4.aug7th_chord.should
|
460
|
-
c4.send('+7_chord').should
|
464
|
+
c4.augmented_seventh_chord.should eq(c_augmented_seventh)
|
465
|
+
c4.aug_seventh_chord.should eq(c_augmented_seventh)
|
466
|
+
c4.aug_7_chord.should eq(c_augmented_seventh)
|
467
|
+
c4.aug_7th_chord.should eq(c_augmented_seventh)
|
468
|
+
c4.aug7_chord.should eq(c_augmented_seventh)
|
469
|
+
c4.aug7th_chord.should eq(c_augmented_seventh)
|
470
|
+
c4.send('+7_chord').should eq(c_augmented_seventh)
|
461
471
|
end
|
462
472
|
|
463
473
|
it 'should have half diminished seventh methods' do
|
464
|
-
c4.half_diminished_seventh_chord.should
|
465
|
-
c4.half_diminished_7_chord.should
|
466
|
-
c4.half_diminished_7th_chord.should
|
467
|
-
c4.half_dim_seventh_chord.should
|
468
|
-
c4.half_dim_7_chord.should
|
469
|
-
c4.half_dim_7th_chord.should
|
470
|
-
c4.half_dim7_chord.should
|
471
|
-
c4.half_dim7th_chord.should
|
474
|
+
c4.half_diminished_seventh_chord.should eq(c_half_diminished_seventh)
|
475
|
+
c4.half_diminished_7_chord.should eq(c_half_diminished_seventh)
|
476
|
+
c4.half_diminished_7th_chord.should eq(c_half_diminished_seventh)
|
477
|
+
c4.half_dim_seventh_chord.should eq(c_half_diminished_seventh)
|
478
|
+
c4.half_dim_7_chord.should eq(c_half_diminished_seventh)
|
479
|
+
c4.half_dim_7th_chord.should eq(c_half_diminished_seventh)
|
480
|
+
c4.half_dim7_chord.should eq(c_half_diminished_seventh)
|
481
|
+
c4.half_dim7th_chord.should eq(c_half_diminished_seventh)
|
472
482
|
end
|
473
483
|
end
|
474
484
|
end
|
475
|
-
|
476
485
|
end
|
477
486
|
|
478
|
-
describe
|
487
|
+
describe '.calculate_frequency(letter, accidental, octave)' do
|
479
488
|
{
|
480
489
|
['C', nil, 0] => 16.35,
|
481
490
|
['E', 'b', 0] => 19.45,
|
@@ -489,37 +498,37 @@ describe Music::Note do
|
|
489
498
|
['E', 'b', 8] => 4978.03
|
490
499
|
}.each do |note_array, frequency|
|
491
500
|
it "Should return #{frequency} for #{note_array.join}" do
|
492
|
-
Note.calculate_frequency(*note_array).should
|
501
|
+
Note.calculate_frequency(*note_array).should eq(frequency)
|
493
502
|
end
|
494
503
|
end
|
495
504
|
|
496
|
-
it
|
497
|
-
Note.calculate_frequency('A#1').should
|
498
|
-
Note.calculate_frequency('A4').should
|
499
|
-
Note.calculate_frequency('C7').should
|
505
|
+
it 'Should take note strings as an argument' do
|
506
|
+
Note.calculate_frequency('A#1').should eq(58.27)
|
507
|
+
Note.calculate_frequency('A4').should eq(440.00)
|
508
|
+
Note.calculate_frequency('C7').should eq(2093.00)
|
500
509
|
end
|
501
510
|
|
502
|
-
it
|
503
|
-
Note.calculate_frequency('a#1').should
|
504
|
-
Note.calculate_frequency('db2').should
|
505
|
-
Note.calculate_frequency('e', nil, 3).should
|
511
|
+
it 'Should allow lower case notes' do
|
512
|
+
Note.calculate_frequency('a#1').should eq(58.27)
|
513
|
+
Note.calculate_frequency('db2').should eq(69.3)
|
514
|
+
Note.calculate_frequency('e', nil, 3).should eq(164.81)
|
506
515
|
end
|
507
516
|
|
508
|
-
it
|
517
|
+
it 'Should not take argument lengths above 3' do
|
509
518
|
expect { Note.calculate_frequency('A', nil, 0, 0) }.to raise_error ArgumentError
|
510
519
|
end
|
511
520
|
|
512
|
-
it
|
521
|
+
it 'Should not allow invalid notes' do
|
513
522
|
expect { Note.calculate_frequency('H', nil, 0) }.to raise_error ArgumentError
|
514
523
|
expect { Note.calculate_frequency('I', nil, 0) }.to raise_error ArgumentError
|
515
524
|
end
|
516
525
|
|
517
|
-
it
|
526
|
+
it 'Should not allow invalid accidentals' do
|
518
527
|
expect { Note.calculate_frequency('A', 5, 0) }.to raise_error ArgumentError
|
519
528
|
expect { Note.calculate_frequency('A', '&', 0) }.to raise_error ArgumentError
|
520
529
|
end
|
521
530
|
|
522
|
-
it
|
531
|
+
it 'Should not allow invalid octaves' do
|
523
532
|
expect { Note.calculate_frequency('A', nil, -1) }.to raise_error ArgumentError
|
524
533
|
expect { Note.calculate_frequency('A', nil, 9) }.to raise_error ArgumentError
|
525
534
|
end
|
@@ -527,7 +536,7 @@ describe Music::Note do
|
|
527
536
|
|
528
537
|
# TODO: Should return accurracy
|
529
538
|
# Thought: ((frequency off) / (distance to next note's frequency)) * 2.0?
|
530
|
-
describe
|
539
|
+
describe '.calculate_note(frequency)' do
|
531
540
|
test_frequencies = {
|
532
541
|
[16.35] => ['C', nil, 0],
|
533
542
|
[19.45, true] => ['E', 'b', 0],
|
@@ -543,48 +552,48 @@ describe Music::Note do
|
|
543
552
|
|
544
553
|
test_frequencies.each do |args, note_string|
|
545
554
|
it "Should return #{note_string} for #{args[0]}#{args[1] && ' (giving flat)'}" do
|
546
|
-
Note.calculate_note(*args).should
|
555
|
+
Note.calculate_note(*args).should eq(note_string)
|
547
556
|
end
|
548
557
|
end
|
549
558
|
|
550
|
-
it
|
551
|
-
Note.calculate_note(420, true).should
|
552
|
-
Note.calculate_note(430).should
|
559
|
+
it 'Should calculate the closest note near to a frequency' do
|
560
|
+
Note.calculate_note(420, true).should eq(['A', 'b', 4])
|
561
|
+
Note.calculate_note(430).should eq(['A', nil, 4])
|
553
562
|
end
|
554
563
|
end
|
555
564
|
|
556
|
-
describe
|
565
|
+
describe '.nearest_note_frequency(frequency)' do
|
557
566
|
it 'should return the frequency if it is the frequency of a note' do
|
558
|
-
Note.nearest_note_frequency(2093.00).should
|
567
|
+
Note.nearest_note_frequency(2093.00).should eq(2093.00)
|
559
568
|
end
|
560
569
|
|
561
570
|
it 'should return the nearest frequency which matches a note' do
|
562
|
-
Note.nearest_note_frequency(41.00).should
|
563
|
-
Note.nearest_note_frequency(40.50).should
|
564
|
-
Note.nearest_note_frequency(40.00).should
|
565
|
-
Note.nearest_note_frequency(39.00).should
|
571
|
+
Note.nearest_note_frequency(41.00).should eq(41.20)
|
572
|
+
Note.nearest_note_frequency(40.50).should eq(41.20)
|
573
|
+
Note.nearest_note_frequency(40.00).should eq(38.89)
|
574
|
+
Note.nearest_note_frequency(39.00).should eq(38.89)
|
566
575
|
end
|
567
576
|
end
|
568
577
|
|
569
|
-
describe
|
570
|
-
it
|
571
|
-
Note.frequency_adjustment(440.0, 0).should
|
572
|
-
Note.frequency_adjustment(440.0, 15).should
|
573
|
-
Note.frequency_adjustment(440.0, -10).should
|
578
|
+
describe '.frequency_adjustment(start_frequency, distance)' do
|
579
|
+
it 'Should find frequencies based on start frequency and distance' do
|
580
|
+
Note.frequency_adjustment(440.0, 0).should eq(440.0)
|
581
|
+
Note.frequency_adjustment(440.0, 15).should eq(1046.50)
|
582
|
+
Note.frequency_adjustment(440.0, -10).should eq(246.94)
|
574
583
|
|
575
|
-
Note.frequency_adjustment(1479.98, -6).should
|
576
|
-
Note.frequency_adjustment(1479.98, 7).should
|
584
|
+
Note.frequency_adjustment(1479.98, -6).should eq(1046.50)
|
585
|
+
Note.frequency_adjustment(1479.98, 7).should eq(2217.46)
|
577
586
|
end
|
578
587
|
end
|
579
588
|
|
580
|
-
describe
|
581
|
-
it
|
582
|
-
Note.new(698.46).next.should
|
583
|
-
Note.new(698.46).succ.should
|
589
|
+
describe 'Getting adjacent notes' do
|
590
|
+
it 'should allow getting of next note' do
|
591
|
+
Note.new(698.46).next.should eq(Note.new(739.99))
|
592
|
+
Note.new(698.46).succ.should eq(Note.new(739.99))
|
584
593
|
end
|
585
594
|
|
586
|
-
it
|
587
|
-
Note.new(739.99).prev.should
|
595
|
+
it 'should allow getting of previous note' do
|
596
|
+
Note.new(739.99).prev.should eq(Note.new(698.46))
|
588
597
|
end
|
589
598
|
end
|
590
599
|
end
|