Class: Coltrane::Scale
Overview
Musical scale creation and manipulation
Constant Summary
ClassicScales::GREEK_MODES, ClassicScales::SCALES
Instance Attribute Summary collapse
Instance Method Summary
collapse
fetch, having_chords, having_notes, known_scales, major, minor, standard_scales
Constructor Details
#initialize(*distances, tone: 'C', mode: 1, name: nil, notes: nil) ⇒ Scale
Returns a new instance of Scale.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/coltrane/scale.rb', line 13
def initialize(*distances, tone: 'C', mode: 1, name: nil, notes: nil)
@name = name
if distances.any? && tone
@tone = Note[tone]
distances = distances.rotate(mode - 1)
@interval_sequence = IntervalSequence.new(distances: distances)
elsif notes
@notes = NoteSet[*notes]
@tone = @notes.first
ds = @notes.interval_sequence.distances
@interval_sequence = IntervalSequence.new(distances: ds)
else
raise WrongKeywordsError, '[*distances, tone: "C", mode: 1] || [notes:]'
end
end
|
Instance Attribute Details
#interval_sequence ⇒ Object
Returns the value of attribute interval_sequence.
11
12
13
|
# File 'lib/coltrane/scale.rb', line 11
def interval_sequence
@interval_sequence
end
|
#tone ⇒ Object
Returns the value of attribute tone.
11
12
13
|
# File 'lib/coltrane/scale.rb', line 11
def tone
@tone
end
|
Instance Method Details
#&(other) ⇒ Object
75
76
77
78
|
# File 'lib/coltrane/scale.rb', line 75
def &(other)
raise HasNoNotesError unless other.respond_to?(:notes)
notes & other
end
|
#chords(size = 3..12) ⇒ Object
Also known as:
all_chords
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# File 'lib/coltrane/scale.rb', line 128
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:
[]
55
56
57
58
|
# File 'lib/coltrane/scale.rb', line 55
def degree(d)
raise WrongDegreeError, d if d < 1 || d > size
tone + interval_sequence[d - 1].semitones
end
|
#degree_of_chord(chord) ⇒ Object
66
67
68
69
|
# File 'lib/coltrane/scale.rb', line 66
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
71
72
73
|
# File 'lib/coltrane/scale.rb', line 71
def degree_of_note(note)
notes.index(note)
end
|
#degrees ⇒ Object
62
63
64
|
# File 'lib/coltrane/scale.rb', line 62
def degrees
(1..size)
end
|
#id ⇒ Object
29
30
31
|
# File 'lib/coltrane/scale.rb', line 29
def id
[(name || @interval_sequence), tone.number]
end
|
#include_notes?(arg) ⇒ Boolean
Also known as:
include?
80
81
82
83
|
# File 'lib/coltrane/scale.rb', line 80
def include_notes?(arg)
noteset = arg.is_a?(Note) ? NoteSet[arg] : arg
(self & noteset).size == noteset.size
end
|
#interval(i) ⇒ Object
91
92
93
|
# File 'lib/coltrane/scale.rb', line 91
def interval(i)
interval_sequence[(i - 1) % size]
end
|
#name ⇒ Object
33
34
35
36
37
38
39
40
41
42
43
|
# File 'lib/coltrane/scale.rb', line 33
def name
@name = begin
is = interval_sequence.distances
(0...is.size).each do |i|
if (scale_name = Coltrane::ClassicScales::SCALES.key(is.rotate(i)))
return scale_name
end
end
nil
end
end
|
#notes ⇒ Object
87
88
89
|
# File 'lib/coltrane/scale.rb', line 87
def notes
@notes ||= NoteSet[*degrees.map { |d| degree(d) }]
end
|
#pentads ⇒ Object
120
121
122
|
# File 'lib/coltrane/scale.rb', line 120
def pentads
tertians(5)
end
|
#pretty_name ⇒ Object
Also known as:
full_name
49
50
51
|
# File 'lib/coltrane/scale.rb', line 49
def pretty_name
"#{tone.name} #{name}"
end
|
#progression(*degrees) ⇒ Object
124
125
126
|
# File 'lib/coltrane/scale.rb', line 124
def progression(*degrees)
Progression.new(self, degrees)
end
|
#sevenths ⇒ Object
116
117
118
|
# File 'lib/coltrane/scale.rb', line 116
def sevenths
tertians(4)
end
|
#size ⇒ Object
95
96
97
|
# File 'lib/coltrane/scale.rb', line 95
def size
interval_sequence.size
end
|
#tertians(n = 3) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
|
# File 'lib/coltrane/scale.rb', line 99
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
|
#to_s ⇒ Object
45
46
47
|
# File 'lib/coltrane/scale.rb', line 45
def to_s
"#{tone} #{name}"
end
|
#triads ⇒ Object
112
113
114
|
# File 'lib/coltrane/scale.rb', line 112
def triads
tertians(3)
end
|