Class: Coltrane::Theory::Scale
- Inherits:
-
Object
- Object
- Coltrane::Theory::Scale
show all
- Extended by:
- ClassicScales, Forwardable
- Defined in:
- lib/coltrane/theory/scale.rb
Overview
Musical scale creation and manipulation
Constant Summary
ClassicScales::SCALES
Instance Attribute Summary collapse
Instance Method Summary
collapse
fetch, having_chords, having_notes, known_scales, major, minor, standard_scales
Constructor Details
#initialize(*relative_intervals, tone: 'C', mode: 1, name: nil, notes: nil) ⇒ Scale
Returns a new instance of Scale.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# File 'lib/coltrane/theory/scale.rb', line 14
def initialize(*relative_intervals, tone: 'C',
mode: 1,
name: nil,
notes: nil)
@name = name
if relative_intervals.any? && tone
@tone = Note[tone]
relative_intervals = relative_intervals.rotate(mode - 1)
@interval_sequence = IntervalSequence.new(
relative_intervals: relative_intervals
)
elsif notes
@notes = NoteSet[*notes]
@tone = @notes.first
ds = @notes.interval_sequence.relative_intervals
@interval_sequence = IntervalSequence.new(relative_intervals: ds)
else
raise WrongKeywordsError,
'[*relative_intervals, tone: "C", mode: 1] || [notes:]'
end
end
|
Instance Attribute Details
#interval_sequence ⇒ Object
Returns the value of attribute interval_sequence.
12
13
14
|
# File 'lib/coltrane/theory/scale.rb', line 12
def interval_sequence
@interval_sequence
end
|
#tone ⇒ Object
Returns the value of attribute tone.
12
13
14
|
# File 'lib/coltrane/theory/scale.rb', line 12
def tone
@tone
end
|
Instance Method Details
#&(other) ⇒ Object
88
89
90
91
|
# File 'lib/coltrane/theory/scale.rb', line 88
def &(other)
raise HasNoNotesError unless other.respond_to?(:notes)
notes & other
end
|
#==(other) ⇒ Object
40
41
42
|
# File 'lib/coltrane/theory/scale.rb', line 40
def ==(other)
id == other.id
end
|
#chords(size = 3..12) ⇒ Object
Also known as:
all_chords
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
# File 'lib/coltrane/theory/scale.rb', line 141
def chords(size = 3..12)
size = (size..size) if size.is_a?(Integer)
scale_rotations = interval_sequence.inversions
ChordQuality.intervals_per_name.reduce([]) do |memo1, (qname, qintervals)|
next memo1 unless size.include?(qintervals.size)
memo1 + scale_rotations.each_with_index
.reduce([]) do |memo2, (rot, index)|
if (rot & qintervals).size == qintervals.size
memo2 + [Chord.new(root_note: degree(index + 1),
quality: ChordQuality.new(name: qname))]
else
memo2
end
end
end
end
|
#degree(d) ⇒ Object
Also known as:
[]
68
69
70
71
|
# File 'lib/coltrane/theory/scale.rb', line 68
def degree(d)
raise WrongDegreeError, d if d < 1 || d > size
tone + interval_sequence[d - 1].semitones
end
|
#degree_of_chord(chord) ⇒ Object
79
80
81
82
|
# File 'lib/coltrane/theory/scale.rb', line 79
def degree_of_chord(chord)
return if chords(chord.size).map(&:name).include?(chord.name)
degree_of_note(chord.root_note)
end
|
#degree_of_note(note) ⇒ Object
84
85
86
|
# File 'lib/coltrane/theory/scale.rb', line 84
def degree_of_note(note)
notes.index(note)
end
|
#degrees ⇒ Object
75
76
77
|
# File 'lib/coltrane/theory/scale.rb', line 75
def degrees
(1..size)
end
|
#id ⇒ Object
36
37
38
|
# File 'lib/coltrane/theory/scale.rb', line 36
def id
[(name || @interval_sequence), tone.number]
end
|
#include_notes?(arg) ⇒ Boolean
Also known as:
include?
93
94
95
96
|
# File 'lib/coltrane/theory/scale.rb', line 93
def include_notes?(arg)
noteset = arg.is_a?(Note) ? NoteSet[arg] : arg
(self & noteset).size == noteset.size
end
|
#interval(i) ⇒ Object
104
105
106
|
# File 'lib/coltrane/theory/scale.rb', line 104
def interval(i)
interval_sequence[(i - 1) % size]
end
|
#name ⇒ Object
44
45
46
47
48
49
50
51
52
53
54
|
# File 'lib/coltrane/theory/scale.rb', line 44
def name
@name ||= begin
is = interval_sequence.relative_intervals
(0...is.size).each do |i|
if (scale_name = ClassicScales::SCALES.key(is.rotate(i)))
return scale_name
end
end
nil
end
end
|
#notes ⇒ Object
100
101
102
|
# File 'lib/coltrane/theory/scale.rb', line 100
def notes
@notes ||= NoteSet[*degrees.map { |d| degree(d) }]
end
|
#pentads ⇒ Object
133
134
135
|
# File 'lib/coltrane/theory/scale.rb', line 133
def pentads
tertians(5)
end
|
#pretty_name ⇒ Object
Also known as:
full_name
62
63
64
|
# File 'lib/coltrane/theory/scale.rb', line 62
def pretty_name
"#{tone.pretty_name} #{name}"
end
|
#progression(*degrees) ⇒ Object
137
138
139
|
# File 'lib/coltrane/theory/scale.rb', line 137
def progression(*degrees)
Progression.new(self, degrees)
end
|
#sevenths ⇒ Object
129
130
131
|
# File 'lib/coltrane/theory/scale.rb', line 129
def sevenths
tertians(4)
end
|
#size ⇒ Object
108
109
110
|
# File 'lib/coltrane/theory/scale.rb', line 108
def size
interval_sequence.size
end
|
#tertians(n = 3) ⇒ Object
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/coltrane/theory/scale.rb', line 112
def tertians(n = 3)
degrees.size.times.reduce([]) do |memo, d|
ns = NoteSet[ *Array.new(n) { |i| notes[(d + (i * 2)) % size] } ]
begin
chord = Chord.new(notes: ns)
rescue ChordNotFoundError
memo
else
memo + [chord]
end
end
end
|
#triads ⇒ Object
125
126
127
|
# File 'lib/coltrane/theory/scale.rb', line 125
def triads
tertians(3)
end
|