Class: Coltrane::Theory::IntervalClass
Overview
Interval class here is not related to the Object Oriented Programming context but to the fact that there is a class of intervals that can all be categorized as having the same quality.
This class in specific still takes into account the order of intervals. C to D is a major second, but D to C is a minor seventh.
Constant Summary
collapse
- QUALITY_SEQUENCE =
[
%w[P],
%w[m M],
%w[m M],
%w[P A],
%w[P],
%w[m M],
%w[m M]
].freeze
- ALTERATIONS =
{
'A' => +1,
'd' => -1
}.freeze
- SINGLE_DISTANCES_NAMES =
%w[
Unison
Second
Third
Fourth
Fifth
Sixth
Seventh
].freeze
- COMPOUND_DISTANCES_NAMES =
[
'Octave',
'Ninth',
'Tenth',
'Eleventh',
'Twelfth',
'Thirteenth',
'Fourteenth',
'Double Octave'
].freeze
- DISTANCES_NAMES =
(SINGLE_DISTANCES_NAMES + COMPOUND_DISTANCES_NAMES).freeze
- QUALITY_NAMES =
{
'P' => 'Perfect',
'm' => 'Minor',
'M' => 'Major',
'A' => 'Augmented',
'd' => 'Diminished'
}.freeze
Instance Attribute Summary
#cents
Class Method Summary
collapse
Instance Method Summary
collapse
#<=>, #ascending?, #descending?, #interval_class, #opposite, #semitones
Constructor Details
Returns a new instance of IntervalClass.
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# File 'lib/coltrane/theory/interval_class.rb', line 118
def initialize(arg)
super case arg
when FrequencyInterval then arg.semitones
when String
self.class.names.index(arg) ||
self.class.full_names.index(arg) ||
self.class.all_names_including_compound.index(arg) ||
self.class.full_names_including_compound.index(arg)
when Numeric then arg
else
raise WrongArgumentsError,
'Provide: [interval] || [name] || [number of semitones]'
end % 12 * 100
end
|
Class Method Details
.all ⇒ Object
93
94
95
|
# File 'lib/coltrane/theory/interval_class.rb', line 93
def all
@all ||= names.map { |n| IntervalClass[n] }
end
|
.all_names_including_compound ⇒ Object
85
86
87
|
# File 'lib/coltrane/theory/interval_class.rb', line 85
def all_names_including_compound
@all_names_including_compound ||= names + compound_names
end
|
.compound_names ⇒ Object
81
82
83
|
# File 'lib/coltrane/theory/interval_class.rb', line 81
def compound_names
@compound_names ||= all.map(&:compound_name)
end
|
.distance_name(n) ⇒ Object
63
64
65
|
# File 'lib/coltrane/theory/interval_class.rb', line 63
def distance_name(n)
DISTANCES_NAMES[n - 1]
end
|
.distances_names ⇒ Object
59
60
61
|
# File 'lib/coltrane/theory/interval_class.rb', line 59
def distances_names
DISTANCES_NAMES
end
|
.expand_name(name) ⇒ Object
106
107
108
109
110
111
112
113
114
115
|
# File 'lib/coltrane/theory/interval_class.rb', line 106
def expand_name(name)
q, n = split(name)
(
case name
when /AA|dd/ then 'Double '
when /AAA|ddd/ then 'Triple '
else ''
end
) + "#{quality_name(q)} #{distance_name(n.to_i)}"
end
|
.full_names ⇒ Object
89
90
91
|
# File 'lib/coltrane/theory/interval_class.rb', line 89
def full_names
@full_names ||= names.map { |n| expand_name(n) }
end
|
.full_names_including_compound ⇒ Object
97
98
99
100
|
# File 'lib/coltrane/theory/interval_class.rb', line 97
def full_names_including_compound
@full_names_including_compound ||=
all_names_including_compound.map { |n| expand_name(n) }
end
|
.names ⇒ Object
71
72
73
74
75
76
77
78
79
|
# File 'lib/coltrane/theory/interval_class.rb', line 71
def names
@names ||= begin
SINGLE_DISTANCES_NAMES.each_with_index.reduce([]) do |i_names, (_d, i)|
i_names + QUALITY_SEQUENCE[i % 7].reduce([]) do |qs, q|
qs + ["#{q}#{i + 1}"]
end
end
end
end
|
.quality_name(q) ⇒ Object
67
68
69
|
# File 'lib/coltrane/theory/interval_class.rb', line 67
def quality_name(q)
QUALITY_NAMES[q]
end
|
.split(interval) ⇒ Object
102
103
104
|
# File 'lib/coltrane/theory/interval_class.rb', line 102
def split(interval)
interval.scan(/(\w)(\d\d?)/)[0]
end
|
Instance Method Details
#+(other) ⇒ Object
190
191
192
|
# File 'lib/coltrane/theory/interval_class.rb', line 190
def +(other)
IntervalClass[semitones + other]
end
|
#-(other) ⇒ Object
194
195
196
|
# File 'lib/coltrane/theory/interval_class.rb', line 194
def -(other)
IntervalClass[semitones - other]
end
|
#-@ ⇒ Object
198
199
200
|
# File 'lib/coltrane/theory/interval_class.rb', line 198
def -@
IntervalClass[-semitones]
end
|
#==(other) ⇒ Object
149
150
151
152
|
# File 'lib/coltrane/theory/interval_class.rb', line 149
def ==(other)
return false unless other.is_a? FrequencyInterval
(semitones % 12) == (other.semitones % 12)
end
|
#alteration ⇒ Object
154
155
156
|
# File 'lib/coltrane/theory/interval_class.rb', line 154
def alteration
name.chars.reduce(0) { |a, s| a + (ALTERATIONS[s] || 0) }
end
|
#ascending ⇒ Object
158
159
160
|
# File 'lib/coltrane/theory/interval_class.rb', line 158
def ascending
self.class[semitones.abs]
end
|
#compound_interval ⇒ Object
Also known as:
compound
139
140
141
142
143
144
145
|
# File 'lib/coltrane/theory/interval_class.rb', line 139
def compound_interval
Interval.new(
letter_distance: distance,
semitones: semitones,
compound: true
)
end
|
#compound_name ⇒ Object
178
179
180
|
# File 'lib/coltrane/theory/interval_class.rb', line 178
def compound_name
"#{quality}#{distance + 7}"
end
|
#descending ⇒ Object
162
163
164
|
# File 'lib/coltrane/theory/interval_class.rb', line 162
def descending
self.class[-semitones.abs]
end
|
#distance ⇒ Object
182
183
184
|
# File 'lib/coltrane/theory/interval_class.rb', line 182
def distance
self.class.split(name)[1].to_i
end
|
#full_name ⇒ Object
170
171
172
|
# File 'lib/coltrane/theory/interval_class.rb', line 170
def full_name
self.class.expand_name(name)
end
|
#interval ⇒ Object
135
136
137
|
# File 'lib/coltrane/theory/interval_class.rb', line 135
def interval
Interval.new(letter_distance: distance, semitones: semitones)
end
|
#inversion ⇒ Object
166
167
168
|
# File 'lib/coltrane/theory/interval_class.rb', line 166
def inversion
self.class[-semitones % 12]
end
|
#name ⇒ Object
174
175
176
|
# File 'lib/coltrane/theory/interval_class.rb', line 174
def name
self.class.names[semitones % 12]
end
|
#quality ⇒ Object
186
187
188
|
# File 'lib/coltrane/theory/interval_class.rb', line 186
def quality
self.class.split(name)[0]
end
|