coltrane 2.1.5 → 2.2.1
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 +4 -4
- data/.travis.yml +17 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +9 -21
- data/README.md +4 -2
- data/bin/console +1 -1
- data/coltrane.gemspec +1 -1
- data/lib/cli.rb +1 -1
- data/lib/cli/chord.rb +1 -1
- data/lib/cli/config.rb +4 -3
- data/lib/cli/guitar_chords.rb +31 -31
- data/lib/cli/scale.rb +1 -1
- data/lib/coltrane.rb +4 -3
- data/lib/coltrane/chord_quality.rb +4 -4
- data/lib/coltrane/circle_of_fifths.rb +4 -2
- data/lib/coltrane/classic_scales.rb +2 -2
- data/lib/coltrane/diatonic_scale.rb +3 -1
- data/lib/coltrane/frequency.rb +1 -1
- data/lib/coltrane/frequency_interval.rb +81 -0
- data/lib/coltrane/interval.rb +177 -33
- data/lib/coltrane/interval_class.rb +147 -49
- data/lib/coltrane/interval_sequence.rb +53 -54
- data/lib/coltrane/key.rb +3 -1
- data/lib/coltrane/notable_progressions.rb +0 -1
- data/lib/coltrane/note.rb +4 -10
- data/lib/coltrane/note_set.rb +2 -2
- data/lib/coltrane/pitch_class.rb +24 -2
- data/lib/coltrane/qualities.rb +171 -169
- data/lib/coltrane/scale.rb +22 -15
- data/lib/coltrane/version.rb +1 -1
- data/lib/coltrane/voicing.rb +3 -2
- data/lib/coltrane_game/question.rb +4 -3
- data/lib/coltrane_instruments/guitar.rb +1 -1
- data/lib/coltrane_instruments/guitar/base.rb +1 -1
- data/lib/coltrane_instruments/guitar/chord.rb +18 -16
- data/lib/coltrane_synth.rb +3 -1
- data/lib/coltrane_synth/base.rb +9 -7
- data/lib/coltrane_synth/synth.rb +3 -1
- data/lib/core_ext.rb +1 -30
- data/lib/os.rb +4 -2
- metadata +19 -3
@@ -7,58 +7,47 @@ module Coltrane
|
|
7
7
|
attr_reader :intervals
|
8
8
|
|
9
9
|
def_delegators :@intervals, :map, :each, :[], :size,
|
10
|
-
:reduce, :delete, :reject!, :delete_if
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
(1..15).each do |i|
|
19
|
-
# defines methods like :fifth, :third, eleventh:
|
20
|
-
define_method i.interval_name.underscore do
|
21
|
-
priority = send("#{i.interval_name.underscore}!")
|
22
|
-
return priority unless priority.nil?
|
23
|
-
@intervals.each do |ix|
|
24
|
-
ix.full_names.detect do |ixx|
|
25
|
-
return ixx if ixx.match?(/#{i.interval_name}/)
|
26
|
-
end
|
10
|
+
:reduce, :delete, :reject!, :delete_if, :detect, :to_a
|
11
|
+
|
12
|
+
def initialize(*intervals, notes: nil, relative_intervals: nil)
|
13
|
+
if intervals.any?
|
14
|
+
@intervals = if intervals.first.is_a?(Interval)
|
15
|
+
intervals
|
16
|
+
else
|
17
|
+
intervals.map { |i| Interval[i] }
|
27
18
|
end
|
28
|
-
nil
|
29
|
-
end
|
30
|
-
|
31
|
-
define_method "#{i.interval_name.underscore}!" do
|
32
|
-
@intervals.each do |ix|
|
33
|
-
ix.full_names.detect do |ixx|
|
34
|
-
next if ixx.match?(/Diminished|Augmented/)
|
35
|
-
return ixx if ixx.match? /#{i.interval_name}/
|
36
|
-
end
|
37
|
-
end
|
38
|
-
nil
|
39
|
-
end
|
40
|
-
|
41
|
-
# defines methods like :has_fifth?, :has_third?, has_eleventh?:
|
42
|
-
define_method "has_#{i.interval_name.underscore}?" do
|
43
|
-
!!@intervals.detect { |ix| ix.full_name.match(/#{i.interval_name}/) }
|
44
|
-
end
|
45
|
-
end
|
46
19
|
|
47
|
-
|
48
|
-
if notes
|
20
|
+
elsif notes
|
49
21
|
notes = NoteSet[*notes] if notes.is_a?(Array)
|
50
22
|
@intervals = intervals_from_notes(notes)
|
51
|
-
elsif
|
52
|
-
@
|
53
|
-
|
54
|
-
@distances = distances
|
55
|
-
@intervals = intervals_from_distances(distances)
|
23
|
+
elsif relative_intervals
|
24
|
+
@relative_intervals = relative_intervals
|
25
|
+
@intervals = intervals_from_relative_intervals(relative_intervals)
|
56
26
|
else
|
57
|
-
raise
|
27
|
+
raise WrongKeywordsError,
|
28
|
+
'Provide: [notes:] || [intervals:] || [relative_intervals:]'
|
58
29
|
end
|
59
30
|
end
|
60
31
|
|
61
|
-
|
32
|
+
Interval.all_including_compound_and_altered.each do |interval|
|
33
|
+
# Creates methods such as major_third, returning it if it finds
|
34
|
+
define_method(interval.full_name.underscore.to_s) { find(interval) }
|
35
|
+
# Creates methods such as has_major_third?, returning a boolean
|
36
|
+
define_method("has_#{interval.full_name.underscore}?") { has?(interval) }
|
37
|
+
end
|
38
|
+
|
39
|
+
Interval.distances_names.map(&:underscore).each_with_index do |distance, i|
|
40
|
+
# Creates methods such as has_third?, returning a boolean
|
41
|
+
define_method("has_#{distance}?") { !!find_by_distance(i + 1) }
|
42
|
+
# Creates methods such third, returning any third it finds
|
43
|
+
define_method(distance.to_s) { find_by_distance(i + 1) }
|
44
|
+
# Creates methods such third!, returning thirds that arent aug or dim
|
45
|
+
define_method("#{distance}!") { find_by_distance(i + 1, false) }
|
46
|
+
end
|
47
|
+
|
48
|
+
instance_eval { alias [] new }
|
49
|
+
|
50
|
+
def relative_intervals
|
62
51
|
intervals_semitones[1..-1].each_with_index.map do |n, i|
|
63
52
|
if i.zero?
|
64
53
|
n
|
@@ -72,8 +61,20 @@ module Coltrane
|
|
72
61
|
intervals.map(&:name)
|
73
62
|
end
|
74
63
|
|
75
|
-
def
|
76
|
-
|
64
|
+
def find(interval)
|
65
|
+
interval.clone if detect { |i| interval == i }
|
66
|
+
end
|
67
|
+
|
68
|
+
def has?(interval)
|
69
|
+
!!find(interval)
|
70
|
+
end
|
71
|
+
|
72
|
+
def find_by_distance(n, accept_altered = true)
|
73
|
+
strategy = (accept_altered ? :as : :as!)
|
74
|
+
map { |interval| interval.send(strategy, n) }
|
75
|
+
.compact
|
76
|
+
.sort_by { |i| i.alteration.abs }
|
77
|
+
.first
|
77
78
|
end
|
78
79
|
|
79
80
|
alias interval_names names
|
@@ -87,7 +88,7 @@ module Coltrane
|
|
87
88
|
end
|
88
89
|
|
89
90
|
def shift(ammount)
|
90
|
-
|
91
|
+
self.class.new(*intervals.map do |i|
|
91
92
|
(i.semitones + ammount) % 12
|
92
93
|
end)
|
93
94
|
end
|
@@ -97,7 +98,7 @@ module Coltrane
|
|
97
98
|
end
|
98
99
|
|
99
100
|
def inversion(index)
|
100
|
-
|
101
|
+
self.class.new(*intervals.rotate(index)).zero_it
|
101
102
|
end
|
102
103
|
|
103
104
|
def next_inversion
|
@@ -109,9 +110,7 @@ module Coltrane
|
|
109
110
|
end
|
110
111
|
|
111
112
|
def inversions
|
112
|
-
Array.new(intervals.length)
|
113
|
-
inversion(index)
|
114
|
-
end
|
113
|
+
Array.new(intervals.length) { |i| inversion(i) }
|
115
114
|
end
|
116
115
|
|
117
116
|
def intervals_semitones
|
@@ -143,14 +142,14 @@ module Coltrane
|
|
143
142
|
|
144
143
|
private
|
145
144
|
|
146
|
-
def
|
147
|
-
|
145
|
+
def intervals_from_relative_intervals(relative_intervals)
|
146
|
+
relative_intervals[0..-2].reduce([Interval[0]]) do |memo, d|
|
148
147
|
memo + [memo.last + d]
|
149
148
|
end
|
150
149
|
end
|
151
150
|
|
152
151
|
def intervals_from_notes(notes)
|
153
|
-
notes.map { |n|
|
152
|
+
notes.map { |n| notes.root - n }.sort_by(&:semitones)
|
154
153
|
end
|
155
154
|
end
|
156
155
|
end
|
data/lib/coltrane/key.rb
CHANGED
data/lib/coltrane/note.rb
CHANGED
@@ -83,22 +83,16 @@ module Coltrane
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def -(other)
|
86
|
-
|
87
|
-
result.is_a?(Note) ? result.alter(alteration) : result
|
86
|
+
super(other).yield_self { |r| r.is_a?(Note) ? r.alter(alteration) : r }
|
88
87
|
end
|
89
88
|
|
90
89
|
def +(other)
|
91
|
-
|
92
|
-
result.is_a?(Note) ? result.alter(alteration) : result
|
93
|
-
end
|
94
|
-
|
95
|
-
def interval_to(note_name)
|
96
|
-
Note[note_name] - self
|
90
|
+
super(other).yield_self { |r| r.is_a?(Note) ? r.alter(alteration) : r }
|
97
91
|
end
|
98
92
|
|
99
93
|
def as(letter)
|
100
|
-
a = (
|
101
|
-
alter([a.semitones, -(
|
94
|
+
a = (Note[letter] - self)
|
95
|
+
alter([a.semitones, -(-a).semitones].min_by(&:abs))
|
102
96
|
end
|
103
97
|
end
|
104
98
|
end
|
data/lib/coltrane/note_set.rb
CHANGED
@@ -75,11 +75,11 @@ module Coltrane
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def alter(alteration)
|
78
|
-
NoteSet[*map {|n| n.alter(alteration)}]
|
78
|
+
NoteSet[*map { |n| n.alter(alteration) }]
|
79
79
|
end
|
80
80
|
|
81
81
|
def alter_accidentals(alteration)
|
82
|
-
NoteSet[*map {|n| n.alter(alteration) if n.accidental?}]
|
82
|
+
NoteSet[*map { |n| n.alter(alteration) if n.accidental? }]
|
83
83
|
end
|
84
84
|
|
85
85
|
def interval_sequence
|
data/lib/coltrane/pitch_class.rb
CHANGED
@@ -16,11 +16,15 @@ module Coltrane
|
|
16
16
|
|
17
17
|
NOTATION = %w[C C# D D# E F F# G G# A A# B].freeze
|
18
18
|
|
19
|
+
def self.all_letters
|
20
|
+
%w[C D E F G A B]
|
21
|
+
end
|
22
|
+
|
19
23
|
def self.all
|
20
24
|
NOTATION.map { |n| new(n) }
|
21
25
|
end
|
22
26
|
|
23
|
-
def initialize(arg=nil, frequency: nil)
|
27
|
+
def initialize(arg = nil, frequency: nil)
|
24
28
|
@integer = case arg
|
25
29
|
when String then NOTATION.index(arg)
|
26
30
|
when Frequency then frequency_to_integer(Frequency.new(arg))
|
@@ -46,6 +50,24 @@ module Coltrane
|
|
46
50
|
NOTATION[integer]
|
47
51
|
end
|
48
52
|
|
53
|
+
def letter
|
54
|
+
name[0]
|
55
|
+
end
|
56
|
+
|
57
|
+
def ascending_interval_to(other)
|
58
|
+
Interval.new(self, (other.is_a?(PitchClass) ? other : Note.new(other)))
|
59
|
+
end
|
60
|
+
|
61
|
+
alias interval_to ascending_interval_to
|
62
|
+
|
63
|
+
def descending_interval_to(other)
|
64
|
+
Interval.new(
|
65
|
+
self,
|
66
|
+
(other.is_a?(PitchClass) ? other : Note.new(other)),
|
67
|
+
ascending: false
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
49
71
|
alias name true_notation
|
50
72
|
|
51
73
|
def pretty_name
|
@@ -80,7 +102,7 @@ module Coltrane
|
|
80
102
|
case other
|
81
103
|
when Interval then self.class[integer - other.semitones]
|
82
104
|
when Integer then self.class[integer - other]
|
83
|
-
when PitchClass then
|
105
|
+
when PitchClass then Interval.new(self, other)
|
84
106
|
when Frequency then self.class.new(frequency: frequency - other)
|
85
107
|
end
|
86
108
|
end
|
data/lib/coltrane/qualities.rb
CHANGED
@@ -1,251 +1,253 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Qualities
|
2
4
|
QUALITIES = {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
'Perfect Unison' => {
|
6
|
+
'Minor Third' => {
|
7
|
+
'Diminished Fifth' => {
|
8
|
+
'name' => 'dim',
|
9
|
+
'Diminished Seventh' => {
|
10
|
+
'name' => 'dim7',
|
11
|
+
'Minor Ninth' => {
|
12
|
+
'name' => 'dim9'
|
11
13
|
},
|
12
|
-
|
13
|
-
|
14
|
+
'Major Ninth' => {
|
15
|
+
'name' => 'dim(b9)'
|
14
16
|
}
|
15
17
|
},
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
'Minor Seventh' => {
|
19
|
+
'name' => 'm7b5',
|
20
|
+
'Minor Ninth' => {
|
21
|
+
'name' => 'm7b5b9',
|
22
|
+
'Perfect Eleventh' => {
|
23
|
+
'name' => 'm7b5b11',
|
24
|
+
'Major Thirteenth' => {
|
25
|
+
'name' => 'm7b5b13'
|
24
26
|
}
|
25
27
|
}
|
26
28
|
},
|
27
|
-
|
28
|
-
|
29
|
+
'Major Ninth' => {
|
30
|
+
'name' => 'm7b5(9)'
|
29
31
|
}
|
30
32
|
}
|
31
33
|
},
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
'Perfect Fifth' => {
|
35
|
+
'name' => 'm',
|
36
|
+
'Major Sixth' => {
|
37
|
+
'name' => 'm6'
|
36
38
|
},
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
'Minor Seventh' => {
|
40
|
+
'name' => 'm7',
|
41
|
+
'Minor Ninth' => {
|
42
|
+
'name' => 'm9',
|
43
|
+
'Perfect Eleventh' => {
|
44
|
+
'name' => 'm11'
|
43
45
|
}
|
44
46
|
}
|
45
47
|
},
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
'Major Seventh' => {
|
49
|
+
'name' => 'm(M7)',
|
50
|
+
'Major Ninth' => {
|
51
|
+
'name' => 'm(M9)',
|
52
|
+
'Perfect Eleventh' => {
|
53
|
+
'name' => 'm(M11)',
|
54
|
+
'Major Thirteenth' => {
|
55
|
+
'name' => 'm(M13)'
|
54
56
|
}
|
55
57
|
}
|
56
58
|
}
|
57
59
|
}
|
58
60
|
}
|
59
61
|
},
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
62
|
+
'Major Third' => {
|
63
|
+
'Perfect Fifth' => {
|
64
|
+
'name' => 'M',
|
65
|
+
'Major Sixth' => {
|
66
|
+
'name' => 'M6',
|
67
|
+
'Major Ninth' => {
|
68
|
+
'name' => '6/9',
|
69
|
+
'Perfect Eleventh' => {
|
70
|
+
'name' => '6/9(add11)'
|
69
71
|
}
|
70
72
|
}
|
71
73
|
},
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
74
|
+
'Minor Seventh' => {
|
75
|
+
'name' => '7',
|
76
|
+
'Major Ninth' => {
|
77
|
+
'name' => '9',
|
78
|
+
'Perfect Eleventh' => {
|
79
|
+
'name' => '11',
|
80
|
+
'Major Thirteenth' => {
|
81
|
+
'name' => '13'
|
80
82
|
}
|
81
83
|
}
|
82
84
|
}
|
83
85
|
},
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
86
|
+
'Major Seventh' => {
|
87
|
+
'name' => 'M7',
|
88
|
+
'Major Ninth' => {
|
89
|
+
'name' => 'M9',
|
90
|
+
'Perfect Eleventh' => {
|
91
|
+
'name' => 'M11',
|
92
|
+
'Major Thirteenth' => {
|
93
|
+
'name' => 'M13'
|
92
94
|
}
|
93
95
|
}
|
94
96
|
}
|
95
97
|
}
|
96
98
|
},
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
99
|
+
'Augmented Fifth' => {
|
100
|
+
'name' => '+',
|
101
|
+
'Minor Seventh' => {
|
102
|
+
'name' => '+7',
|
103
|
+
'Major Ninth' => {
|
104
|
+
'name' => '+9',
|
105
|
+
'Perfect Eleventh' => {
|
106
|
+
'name' => '+11',
|
107
|
+
'Major Thirteenth' => {
|
108
|
+
'name' => '+13'
|
107
109
|
}
|
108
110
|
}
|
109
111
|
}
|
110
112
|
},
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
113
|
+
'Major Seventh' => {
|
114
|
+
'name' => '+M7',
|
115
|
+
'Major Ninth' => {
|
116
|
+
'name' => '+M9',
|
117
|
+
'Perfect Eleventh' => {
|
118
|
+
'name' => '+M11',
|
119
|
+
'Major Thirteenth' => {
|
120
|
+
'name' => '+M13'
|
119
121
|
}
|
120
122
|
}
|
121
123
|
}
|
122
124
|
}
|
123
125
|
}
|
124
126
|
},
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
127
|
+
'Major Second' => {
|
128
|
+
'Perfect Fifth' => {
|
129
|
+
'name' => 'Msus2',
|
130
|
+
'Major Sixth' => {
|
131
|
+
'name' => 'M6sus2',
|
132
|
+
'Major Ninth' => {
|
133
|
+
'name' => '6/9sus2',
|
134
|
+
'Perfect Eleventh' => {
|
135
|
+
'name' => '6/9(add11)sus2'
|
134
136
|
}
|
135
137
|
}
|
136
138
|
},
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
139
|
+
'Minor Seventh' => {
|
140
|
+
'name' => '7sus2',
|
141
|
+
'Major Ninth' => {
|
142
|
+
'name' => '9sus2',
|
143
|
+
'Perfect Eleventh' => {
|
144
|
+
'name' => '11sus2',
|
145
|
+
'Major Thirteenth' => {
|
146
|
+
'name' => '13sus2'
|
145
147
|
}
|
146
148
|
}
|
147
149
|
}
|
148
150
|
},
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
151
|
+
'Major Seventh' => {
|
152
|
+
'name' => 'M7sus2',
|
153
|
+
'Major Ninth' => {
|
154
|
+
'name' => 'M9sus2',
|
155
|
+
'Perfect Eleventh' => {
|
156
|
+
'name' => 'M11sus2',
|
157
|
+
'Major Thirteenth' => {
|
158
|
+
'name' => 'M13sus2'
|
157
159
|
}
|
158
160
|
}
|
159
161
|
}
|
160
162
|
}
|
161
163
|
},
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
164
|
+
'Augmented Fifth' => {
|
165
|
+
'name' => '+sus2',
|
166
|
+
'Minor Seventh' => {
|
167
|
+
'name' => '+7sus2',
|
168
|
+
'Major Ninth' => {
|
169
|
+
'name' => '+9sus2',
|
170
|
+
'Perfect Eleventh' => {
|
171
|
+
'name' => '+11sus2',
|
172
|
+
'Major Thirteenth' => {
|
173
|
+
'name' => '+13sus2'
|
172
174
|
}
|
173
175
|
}
|
174
176
|
}
|
175
177
|
},
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
178
|
+
'Major Seventh' => {
|
179
|
+
'name' => '+M7sus2',
|
180
|
+
'Major Ninth' => {
|
181
|
+
'name' => '+M9sus2',
|
182
|
+
'Perfect Eleventh' => {
|
183
|
+
'name' => '+M11sus2',
|
184
|
+
'Major Thirteenth' => {
|
185
|
+
'name' => '+M13sus2'
|
184
186
|
}
|
185
187
|
}
|
186
188
|
}
|
187
189
|
}
|
188
190
|
}
|
189
191
|
},
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
192
|
+
'Perfect Fourth' => {
|
193
|
+
'Perfect Fifth' => {
|
194
|
+
'name' => 'Msus4',
|
195
|
+
'Major Sixth' => {
|
196
|
+
'name' => 'M6sus4',
|
197
|
+
'Major Ninth' => {
|
198
|
+
'name' => '6/9sus4',
|
199
|
+
'Perfect Eleventh' => {
|
200
|
+
'name' => '6/9(add11)sus4'
|
199
201
|
}
|
200
202
|
}
|
201
203
|
},
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
204
|
+
'Minor Seventh' => {
|
205
|
+
'name' => '7sus4',
|
206
|
+
'Major Ninth' => {
|
207
|
+
'name' => '9sus4',
|
208
|
+
'Perfect Eleventh' => {
|
209
|
+
'name' => '11sus4',
|
210
|
+
'Major Thirteenth' => {
|
211
|
+
'name' => '13sus4'
|
210
212
|
}
|
211
213
|
}
|
212
214
|
}
|
213
215
|
},
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
216
|
+
'Major Seventh' => {
|
217
|
+
'name' => 'M7sus4',
|
218
|
+
'Major Ninth' => {
|
219
|
+
'name' => 'M9sus4',
|
220
|
+
'Perfect Eleventh' => {
|
221
|
+
'name' => 'M11sus4',
|
222
|
+
'Major Thirteenth' => {
|
223
|
+
'name' => 'M13sus4'
|
222
224
|
}
|
223
225
|
}
|
224
226
|
}
|
225
227
|
}
|
226
228
|
},
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
229
|
+
'Augmented Fifth' => {
|
230
|
+
'name' => '+sus4',
|
231
|
+
'Minor Seventh' => {
|
232
|
+
'name' => '+7sus4',
|
233
|
+
'Major Ninth' => {
|
234
|
+
'name' => '+9sus4',
|
235
|
+
'Perfect Eleventh' => {
|
236
|
+
'name' => '+11sus4',
|
237
|
+
'Major Thirteenth' => {
|
238
|
+
'name' => '+13sus4'
|
237
239
|
}
|
238
240
|
}
|
239
241
|
}
|
240
242
|
},
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
243
|
+
'Major Seventh' => {
|
244
|
+
'name' => '+M7sus4',
|
245
|
+
'Major Ninth' => {
|
246
|
+
'name' => '+M9sus4',
|
247
|
+
'Perfect Eleventh' => {
|
248
|
+
'name' => '+M11sus4',
|
249
|
+
'Major Thirteenth' => {
|
250
|
+
'name' => '+M13sus4'
|
249
251
|
}
|
250
252
|
}
|
251
253
|
}
|
@@ -253,5 +255,5 @@ module Qualities
|
|
253
255
|
}
|
254
256
|
}
|
255
257
|
}
|
256
|
-
}
|
257
|
-
end
|
258
|
+
}.freeze
|
259
|
+
end
|