music 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.rubocop.yml +72 -0
- data/.rubocop_todo.yml +47 -0
- data/.travis.yml +5 -4
- data/CHANGELOG.md +15 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +90 -51
- 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 +60 -70
- data/lib/music/version.rb +1 -1
- data/lib/music.rb +0 -1
- data/music.gemspec +13 -13
- 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 +18 -16
data/lib/music/note.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
module Music
|
2
2
|
class Note
|
3
|
-
|
4
|
-
NOTES = ['C', 'C#/Db', 'D', 'D#/Eb', 'E', 'F', 'F#/Gb', 'G', 'G#/Ab', 'A', 'A#/Bb', 'B']
|
3
|
+
NOTES = [['C', 'B#'], ['C#', 'Db'], ['D'], ['D#', 'Eb'], ['E', 'Fb'], ['F', 'E#'], ['F#', 'Gb'], ['G'], ['G#', 'Ab'], ['A'], ['A#', 'Bb'], ['B', 'Cb']]
|
5
4
|
NOTE_STRINGS = ['Ab', 'A', 'A#', 'Bb', 'B', 'C', 'C#', 'Db', 'D', 'D#', 'Eb', 'E', 'F', 'Gb', 'G', 'G#']
|
6
5
|
|
7
6
|
attr_accessor :frequency
|
8
7
|
|
9
8
|
include Comparable
|
10
|
-
def <=>(
|
11
|
-
self.frequency <=>
|
9
|
+
def <=>(other)
|
10
|
+
self.frequency <=> other.frequency
|
12
11
|
end
|
12
|
+
|
13
13
|
def hash
|
14
14
|
self.frequency.hash
|
15
15
|
end
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
def eql?(other)
|
18
|
+
self.frequency == other.frequency
|
18
19
|
end
|
19
20
|
|
20
21
|
def to_s
|
@@ -28,10 +29,10 @@ module Music
|
|
28
29
|
# @returns [Note] Note specified
|
29
30
|
def initialize(descriptor, assumed_octave = nil)
|
30
31
|
self.frequency = if descriptor.is_a? Numeric
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
Note.nearest_note_frequency(descriptor)
|
33
|
+
else
|
34
|
+
Note.calculate_frequency(descriptor, assumed_octave)
|
35
|
+
end
|
35
36
|
end
|
36
37
|
|
37
38
|
# Returns string representing note with letter, accidental, and octave number
|
@@ -82,7 +83,7 @@ module Music
|
|
82
83
|
def succ
|
83
84
|
Note.new(Note.frequency_adjustment(self.frequency, 1))
|
84
85
|
end
|
85
|
-
|
86
|
+
alias_method :next, :succ
|
86
87
|
|
87
88
|
# Return the distance (in semitones) to a note
|
88
89
|
#
|
@@ -100,21 +101,21 @@ module Music
|
|
100
101
|
end
|
101
102
|
|
102
103
|
{
|
103
|
-
:
|
104
|
-
:
|
104
|
+
minor_second: 1,
|
105
|
+
major_second: 2,
|
105
106
|
|
106
|
-
:
|
107
|
-
:
|
107
|
+
minor_third: 3,
|
108
|
+
major_third: 4,
|
108
109
|
|
109
|
-
:
|
110
|
+
perfect_fourth: 5,
|
110
111
|
|
111
|
-
:
|
112
|
-
:
|
113
|
-
:
|
112
|
+
tritone: 6, diminished_fifth: 6, flat_fifth: 6, augmented_fourth: 6,
|
113
|
+
perfect_fifth: 7,
|
114
|
+
augmented_fifth: 8, minor_sixth: 8,
|
114
115
|
|
115
|
-
:
|
116
|
-
:
|
117
|
-
:
|
116
|
+
major_sixth: 9, diminished_seventh: 9,
|
117
|
+
minor_seventh: 10,
|
118
|
+
major_seventh: 11
|
118
119
|
}.each do |interval, semitones_count|
|
119
120
|
define_method interval do
|
120
121
|
adjust_by_semitones(semitones_count)
|
@@ -126,12 +127,12 @@ module Music
|
|
126
127
|
# @returns [Array<Note>] Notes in major scale
|
127
128
|
def major_scale
|
128
129
|
[self,
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
130
|
+
self.major_second,
|
131
|
+
self.major_third,
|
132
|
+
self.perfect_fourth,
|
133
|
+
self.perfect_fifth,
|
134
|
+
self.major_sixth,
|
135
|
+
self.major_seventh
|
135
136
|
]
|
136
137
|
end
|
137
138
|
|
@@ -140,26 +141,26 @@ module Music
|
|
140
141
|
# @returns [Array<Note>] Notes in minor scale
|
141
142
|
def minor_scale
|
142
143
|
[self,
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
144
|
+
self.major_second,
|
145
|
+
self.minor_third,
|
146
|
+
self.perfect_fourth,
|
147
|
+
self.perfect_fifth,
|
148
|
+
self.minor_sixth,
|
149
|
+
self.minor_seventh
|
149
150
|
]
|
150
151
|
end
|
151
152
|
|
152
153
|
CHORD_INTERVALS = {
|
153
|
-
:
|
154
|
-
:
|
155
|
-
:
|
156
|
-
:
|
157
|
-
:
|
158
|
-
:
|
159
|
-
:
|
160
|
-
:
|
161
|
-
:
|
162
|
-
:
|
154
|
+
minor: [:minor_third, :perfect_fifth],
|
155
|
+
major: [:major_third, :perfect_fifth],
|
156
|
+
fifth: [:perfect_fifth],
|
157
|
+
diminished: [:minor_third, :diminished_fifth],
|
158
|
+
augmented: [:major_third, :augmented_fifth],
|
159
|
+
major_seventh: [:major_third, :perfect_fifth, :major_seventh],
|
160
|
+
minor_seventh: [:minor_third, :perfect_fifth, :minor_seventh],
|
161
|
+
diminished_seventh: [:minor_third, :diminished_fifth, :diminished_seventh],
|
162
|
+
augmented_seventh: [:major_third, :augmented_fifth, :minor_seventh],
|
163
|
+
half_diminished_seventh: [:minor_third, :diminished_fifth, :minor_seventh]
|
163
164
|
}
|
164
165
|
|
165
166
|
CHORD_ALIASES = {
|
@@ -218,21 +219,21 @@ module Music
|
|
218
219
|
:half_dim_7 => :half_diminished_seventh,
|
219
220
|
:half_dim_7th => :half_diminished_seventh,
|
220
221
|
:half_dim7 => :half_diminished_seventh,
|
221
|
-
:half_dim7th => :half_diminished_seventh
|
222
|
+
:half_dim7th => :half_diminished_seventh
|
222
223
|
}
|
223
224
|
|
224
225
|
def chord(description)
|
225
226
|
description = :major if description.to_s.empty?
|
226
227
|
|
227
228
|
description = description.to_s
|
228
|
-
description.downcase! unless
|
229
|
+
description.downcase! unless %w(M M7).include?(description)
|
229
230
|
description.gsub!(/[\s\-]+/, '_')
|
230
231
|
description = description.to_sym
|
231
232
|
|
232
233
|
intervals = CHORD_INTERVALS[description] || CHORD_INTERVALS[CHORD_ALIASES[description]]
|
233
234
|
|
234
235
|
if intervals
|
235
|
-
Chord.new([self] + intervals.collect {|interval| self.send(interval) })
|
236
|
+
Chord.new([self] + intervals.collect { |interval| self.send(interval) })
|
236
237
|
end
|
237
238
|
end
|
238
239
|
|
@@ -246,9 +247,9 @@ module Music
|
|
246
247
|
def parse_note_string(note_string, assumed_octave = nil)
|
247
248
|
match = note_string.match(/^([A-Ga-g])([#b]?)([0-8]?)$/)
|
248
249
|
|
249
|
-
|
250
|
-
|
251
|
-
|
250
|
+
fail ArgumentError, "Did not recognize note string: #{note_string}" if !match
|
251
|
+
fail ArgumentError, 'No octave found or specified' if match[3].empty? && assumed_octave.nil?
|
252
|
+
fail ArgumentError if match[3].to_i > 8 || (assumed_octave && !(0..8).include?(assumed_octave))
|
252
253
|
|
253
254
|
octave = match[3].empty? ? assumed_octave : match[3]
|
254
255
|
[match[1].upcase, match[2] == '' ? nil : match[2], octave.to_i]
|
@@ -258,17 +259,9 @@ module Music
|
|
258
259
|
letter1, accidental1, octave1 = parse_note_string(note_string1)
|
259
260
|
letter2, accidental2, octave2 = parse_note_string(note_string2)
|
260
261
|
|
261
|
-
get_index =
|
262
|
-
NOTES.index do |
|
263
|
-
|
264
|
-
when '#' then
|
265
|
-
/^#{letter}#/
|
266
|
-
when 'b' then
|
267
|
-
/#{letter}b$/
|
268
|
-
else
|
269
|
-
/^#{letter}$/
|
270
|
-
end
|
271
|
-
note.match(regex)
|
262
|
+
get_index = proc do |letter, accidental|
|
263
|
+
NOTES.index do |notes|
|
264
|
+
notes.include?("#{letter}#{accidental}")
|
272
265
|
end
|
273
266
|
end
|
274
267
|
|
@@ -279,7 +272,7 @@ module Music
|
|
279
272
|
end
|
280
273
|
|
281
274
|
def frequency_adjustment(start_frequency, distance)
|
282
|
-
result = (start_frequency * (2.0
|
275
|
+
result = (start_frequency * (2.0**(distance.to_f / NOTES.size)))
|
283
276
|
|
284
277
|
# Would like to use #round(2), but want to support Ruby 1.8
|
285
278
|
(result * 100.0).round / 100.0
|
@@ -294,7 +287,7 @@ module Music
|
|
294
287
|
when 3
|
295
288
|
letter, accidental, octave = args
|
296
289
|
else
|
297
|
-
|
290
|
+
fail ArgumentError, 'Invalid octave of arguments'
|
298
291
|
end
|
299
292
|
|
300
293
|
distance = note_distance('A4', "#{letter}#{accidental}#{octave}")
|
@@ -313,14 +306,12 @@ module Music
|
|
313
306
|
octave = 4 + (index / NOTES.size) # 4 is because we're using A4
|
314
307
|
index = (index % NOTES.size)
|
315
308
|
|
316
|
-
parts = "#{NOTES[index]}".split('/')
|
317
309
|
note = if give_flat
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
310
|
+
NOTES[index].last
|
311
|
+
else
|
312
|
+
NOTES[index].first
|
313
|
+
end
|
322
314
|
|
323
|
-
"#{note}#{octave}"
|
324
315
|
note_parts = note.split('')
|
325
316
|
note_parts + (note_parts.size == 1 ? [nil] : []) + [octave.to_i]
|
326
317
|
end
|
@@ -328,7 +319,6 @@ module Music
|
|
328
319
|
def nearest_note_frequency(frequency)
|
329
320
|
Note.calculate_frequency(Note.calculate_note(frequency).join)
|
330
321
|
end
|
331
|
-
|
332
322
|
end
|
333
323
|
end
|
334
324
|
end
|
data/lib/music/version.rb
CHANGED
data/lib/music.rb
CHANGED
data/music.gemspec
CHANGED
@@ -1,26 +1,26 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
require
|
2
|
+
$LOAD_PATH.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'music/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
# Basic Info
|
7
|
-
s.name =
|
7
|
+
s.name = 'music'
|
8
8
|
s.version = Music::VERSION
|
9
9
|
s.platform = Gem::Platform::RUBY
|
10
|
-
s.authors = [
|
11
|
-
s.email = [
|
12
|
-
s.homepage =
|
13
|
-
s.summary =
|
14
|
-
s.description =
|
15
|
-
s.license =
|
10
|
+
s.authors = ['Brian Underwood']
|
11
|
+
s.email = ['ml+musicgem@semi-sentient.com']
|
12
|
+
s.homepage = 'http://github.com/cheerfulstoic/music'
|
13
|
+
s.summary = 'Library for performing calculations on musical elements'
|
14
|
+
s.description = 'Library for classifying notes and chords and performing calculations on them. See README.md'
|
15
|
+
s.license = 'MIT'
|
16
16
|
|
17
17
|
# Files
|
18
18
|
s.files = `git ls-files`.split("\n")
|
19
19
|
s.test_files = `git ls-files -- {spec,factories}/*`.split("\n")
|
20
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
-
s.require_paths = [
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
21
|
+
s.require_paths = ['lib']
|
22
22
|
|
23
23
|
# Dependencies
|
24
|
-
s.add_development_dependency
|
25
|
-
s.add_development_dependency
|
24
|
+
s.add_development_dependency 'rake', '~> 0.9'
|
25
|
+
s.add_development_dependency 'rspec', '~> 2'
|
26
26
|
end
|
data/spec/classes/chord_spec.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
include Music
|
2
3
|
|
3
4
|
describe Music::Chord do
|
4
5
|
before :all do
|
5
6
|
@standard_tuning_notes = [Note.new('E2'), Note.new('A2'), Note.new('D3'), Note.new('G3'), Note.new('B3'), Note.new('E4')]
|
6
7
|
|
7
|
-
@c_minor = Chord.new(
|
8
|
-
@c_major = Chord.new(
|
9
|
-
@c_diminished = Chord.new(
|
8
|
+
@c_minor = Chord.new(%w(C4 Eb4 G4))
|
9
|
+
@c_major = Chord.new(%w(C4 E4 G4))
|
10
|
+
@c_diminished = Chord.new(%w(C4 Eb4 Gb4))
|
10
11
|
@c_augmented = Chord.new(['C4', 'E4', 'G#4'])
|
11
|
-
@c_major_seventh = Chord.new(
|
12
|
-
@c_minor_seventh = Chord.new(
|
13
|
-
@c_diminished_seventh = Chord.new(
|
12
|
+
@c_major_seventh = Chord.new(%w(C4 E4 G4 B4))
|
13
|
+
@c_minor_seventh = Chord.new(%w(C4 Eb4 G4 Bb4))
|
14
|
+
@c_diminished_seventh = Chord.new(%w(C4 Eb4 Gb4 A4))
|
14
15
|
@c_augmented_seventh = Chord.new(['C4', 'E4', 'G#4', 'Bb4'])
|
15
|
-
@c_half_diminished_seventh = Chord.new(
|
16
|
+
@c_half_diminished_seventh = Chord.new(%w(C4 Eb4 Gb4 Bb4))
|
16
17
|
end
|
17
18
|
|
18
19
|
describe '#new(notes)' do
|
@@ -32,7 +33,7 @@ describe Music::Chord do
|
|
32
33
|
|
33
34
|
describe '#==' do
|
34
35
|
it 'should recognize that the order of notes in the chord does not matter' do
|
35
|
-
Chord.new(
|
36
|
+
Chord.new(%w(C4 Eb4 G4)).should eq(Chord.new(%w(G4 Eb4 C4)))
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
@@ -40,98 +41,97 @@ describe Music::Chord do
|
|
40
41
|
it 'should return a set of note strings' do
|
41
42
|
chord = Chord.new(@standard_tuning_notes)
|
42
43
|
|
43
|
-
chord.note_strings.should
|
44
|
+
chord.note_strings.should eq(Set.new(@standard_tuning_notes.collect(&:note_string)))
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
48
|
describe '#to_s' do
|
48
49
|
it 'should output just the sorted note descriptions separated by slashes' do
|
49
|
-
@c_minor.to_s.should
|
50
|
+
@c_minor.to_s.should eq('C4 / D#4 / G4')
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
54
|
describe '#describe' do
|
54
|
-
describe
|
55
|
+
describe 'triads' do
|
55
56
|
it 'should recognize C major' do
|
56
|
-
@c_major.describe.should
|
57
|
+
@c_major.describe.should eq(['C', :major])
|
57
58
|
end
|
58
59
|
|
59
60
|
it 'should recognize C minor' do
|
60
|
-
Chord.new(
|
61
|
+
Chord.new(%w(C4 Eb4 G4)).describe.should eq(['C', :minor])
|
61
62
|
end
|
62
63
|
|
63
64
|
it 'should recognize C diminished' do
|
64
|
-
Chord.new(
|
65
|
+
Chord.new(%w(C4 Eb4 Gb4)).describe.should eq(['C', :diminished])
|
65
66
|
end
|
66
67
|
it 'should recognize C augmented' do
|
67
|
-
Chord.new(['C4', 'E4', 'G#4']).describe.should
|
68
|
+
Chord.new(['C4', 'E4', 'G#4']).describe.should eq(['C', :augmented])
|
68
69
|
end
|
69
70
|
end
|
70
|
-
describe
|
71
|
+
describe 'seven chords' do
|
71
72
|
it 'should recognize Cmaj7' do
|
72
|
-
Chord.new(
|
73
|
+
Chord.new(%w(C4 E4 G4 B4)).describe.should eq(['C', :major_7])
|
73
74
|
end
|
74
75
|
it 'should recognize Cmin7' do
|
75
|
-
Chord.new(
|
76
|
+
Chord.new(%w(C4 Eb4 G4 Bb4)).describe.should eq(['C', :minor_7])
|
76
77
|
end
|
77
78
|
it 'should recognize Cdim7' do
|
78
|
-
Chord.new(
|
79
|
+
Chord.new(%w(C4 Eb4 Gb4 A4)).describe.should eq(['C', :diminished_7])
|
79
80
|
end
|
80
81
|
it 'should recognize Cmin7b5' do
|
81
|
-
Chord.new(
|
82
|
+
Chord.new(%w(C4 Eb4 Gb4 Bb4)).describe.should eq(['C', :half_diminished_7])
|
82
83
|
end
|
83
84
|
it 'should recognize Caug7' do
|
84
|
-
Chord.new(['C4', 'E4', 'G#4', 'Bb4']).describe.should
|
85
|
+
Chord.new(['C4', 'E4', 'G#4', 'Bb4']).describe.should eq(['C', :augmented_7])
|
85
86
|
end
|
86
87
|
end
|
87
88
|
end
|
88
89
|
|
89
90
|
describe '.parse_chord_string' do
|
90
91
|
it 'should recognize C major' do
|
91
|
-
Chord.parse_chord_string('Cmajor4').should
|
92
|
-
Chord.parse_chord_string('CMajor4').should
|
93
|
-
Chord.parse_chord_string('Cmaj4').should
|
94
|
-
Chord.parse_chord_string('CMaj4').should
|
95
|
-
Chord.parse_chord_string('CM4').should
|
96
|
-
Chord.parse_chord_string('C4').should
|
92
|
+
Chord.parse_chord_string('Cmajor4').should eq(@c_major)
|
93
|
+
Chord.parse_chord_string('CMajor4').should eq(@c_major)
|
94
|
+
Chord.parse_chord_string('Cmaj4').should eq(@c_major)
|
95
|
+
Chord.parse_chord_string('CMaj4').should eq(@c_major)
|
96
|
+
Chord.parse_chord_string('CM4').should eq(@c_major)
|
97
|
+
Chord.parse_chord_string('C4').should eq(@c_major)
|
97
98
|
|
98
99
|
expect { Chord.parse_chord_string('C') }.to raise_error ArgumentError
|
99
|
-
Chord.parse_chord_string('C', 4).should
|
100
|
+
Chord.parse_chord_string('C', 4).should eq(@c_major)
|
100
101
|
end
|
101
102
|
|
102
103
|
it 'should recognize C minor' do
|
103
|
-
Chord.parse_chord_string('Cminor4').should
|
104
|
-
Chord.parse_chord_string('CMinor4').should
|
105
|
-
Chord.parse_chord_string('Cmin4').should
|
106
|
-
Chord.parse_chord_string('CMin4').should
|
107
|
-
Chord.parse_chord_string('Cm4').should
|
104
|
+
Chord.parse_chord_string('Cminor4').should eq(@c_minor)
|
105
|
+
Chord.parse_chord_string('CMinor4').should eq(@c_minor)
|
106
|
+
Chord.parse_chord_string('Cmin4').should eq(@c_minor)
|
107
|
+
Chord.parse_chord_string('CMin4').should eq(@c_minor)
|
108
|
+
Chord.parse_chord_string('Cm4').should eq(@c_minor)
|
108
109
|
|
109
110
|
expect { Chord.parse_chord_string('Cm') }.to raise_error ArgumentError
|
110
|
-
Chord.parse_chord_string('Cm', 4).should
|
111
|
-
|
111
|
+
Chord.parse_chord_string('Cm', 4).should eq(@c_minor)
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'should recognize C diminished' do
|
115
|
-
Chord.parse_chord_string('Cdiminished4').should
|
116
|
-
Chord.parse_chord_string('CDiminished4').should
|
117
|
-
Chord.parse_chord_string('Cdim4').should
|
118
|
-
Chord.parse_chord_string('CDim4').should
|
119
|
-
Chord.parse_chord_string('CDIM4').should
|
115
|
+
Chord.parse_chord_string('Cdiminished4').should eq(@c_diminished)
|
116
|
+
Chord.parse_chord_string('CDiminished4').should eq(@c_diminished)
|
117
|
+
Chord.parse_chord_string('Cdim4').should eq(@c_diminished)
|
118
|
+
Chord.parse_chord_string('CDim4').should eq(@c_diminished)
|
119
|
+
Chord.parse_chord_string('CDIM4').should eq(@c_diminished)
|
120
120
|
|
121
|
-
expect { Chord.parse_chord_string('Cdim')
|
122
|
-
Chord.parse_chord_string('Cdim', 4).should
|
121
|
+
expect { Chord.parse_chord_string('Cdim') }.to raise_error ArgumentError
|
122
|
+
Chord.parse_chord_string('Cdim', 4).should eq(@c_diminished)
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'should recognize C augmented' do
|
126
|
-
Chord.parse_chord_string('Caugmented4').should
|
127
|
-
Chord.parse_chord_string('Caugmented4').should
|
128
|
-
Chord.parse_chord_string('Caug4').should
|
129
|
-
Chord.parse_chord_string('CAug4').should
|
130
|
-
Chord.parse_chord_string('CAUG4').should
|
131
|
-
Chord.parse_chord_string('C+4').should
|
126
|
+
Chord.parse_chord_string('Caugmented4').should eq(@c_augmented)
|
127
|
+
Chord.parse_chord_string('Caugmented4').should eq(@c_augmented)
|
128
|
+
Chord.parse_chord_string('Caug4').should eq(@c_augmented)
|
129
|
+
Chord.parse_chord_string('CAug4').should eq(@c_augmented)
|
130
|
+
Chord.parse_chord_string('CAUG4').should eq(@c_augmented)
|
131
|
+
Chord.parse_chord_string('C+4').should eq(@c_augmented)
|
132
132
|
|
133
|
-
expect { Chord.parse_chord_string('Caug')
|
134
|
-
Chord.parse_chord_string('Caug', 4).should
|
133
|
+
expect { Chord.parse_chord_string('Caug') }.to raise_error ArgumentError
|
134
|
+
Chord.parse_chord_string('Caug', 4).should eq(@c_augmented)
|
135
135
|
end
|
136
136
|
|
137
137
|
# TODO: Fill out other chords
|
@@ -139,13 +139,13 @@ describe Music::Chord do
|
|
139
139
|
|
140
140
|
describe '#inversion' do
|
141
141
|
it 'should adjust the lowest n notes up by an octive' do
|
142
|
-
@c_major.inversion(1).should
|
143
|
-
Chord.new(
|
142
|
+
@c_major.inversion(1).should eq(Chord.new(%w(E4 G4 C5)))
|
143
|
+
Chord.new(%w(Eb4 C4 Gb4)).inversion(1).should eq(Chord.new(%w(Eb4 C5 Gb4)))
|
144
144
|
|
145
|
-
@c_major.inversion(2).should
|
146
|
-
Chord.new(
|
145
|
+
@c_major.inversion(2).should eq(Chord.new(%w(E5 G4 C5)))
|
146
|
+
Chord.new(%w(Eb4 C4 Gb4)).inversion(2).should eq(Chord.new(%w(Eb5 C5 Gb4)))
|
147
147
|
|
148
|
-
@c_augmented_seventh.inversion(3).should
|
148
|
+
@c_augmented_seventh.inversion(3).should eq(Chord.new(['E5', 'G#5', 'C5', 'Bb4']))
|
149
149
|
end
|
150
150
|
|
151
151
|
it 'should raise an error when the inversion amount is too great' do
|
@@ -164,19 +164,19 @@ describe Music::Chord do
|
|
164
164
|
|
165
165
|
describe '#first_inversion' do
|
166
166
|
it 'should adjust the lowest note up by an octive' do
|
167
|
-
@c_major.first_inversion.should
|
167
|
+
@c_major.first_inversion.should eq(Chord.new(%w(E4 G4 C5)))
|
168
168
|
end
|
169
169
|
end
|
170
170
|
|
171
171
|
describe '#second_inversion' do
|
172
172
|
it 'should adjust the lowest two notes up by an octive' do
|
173
|
-
@c_major.second_inversion.should
|
173
|
+
@c_major.second_inversion.should eq(Chord.new(%w(E5 G4 C5)))
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
177
|
describe '#third_inversion' do
|
178
178
|
it 'should adjust the lowest three notes up by an octive' do
|
179
|
-
@c_augmented_seventh.third_inversion.should
|
179
|
+
@c_augmented_seventh.third_inversion.should eq(Chord.new(['E5', 'G#5', 'C5', 'Bb4']))
|
180
180
|
end
|
181
181
|
end
|
182
|
-
end
|
182
|
+
end
|