class Coltrane::Theory::Scale
Musical scale creation and manipulation
Attributes
interval_sequence[R]
tone[R]
Public Class Methods
new(*relative_intervals, tone: 'C', mode: 1, name: nil, notes: nil)
click to toggle source
# 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
Public Instance Methods
&(other)
click to toggle source
# File lib/coltrane/theory/scale.rb, line 88 def &(other) raise HasNoNotesError unless other.respond_to?(:notes) notes & other end
==(other)
click to toggle source
# File lib/coltrane/theory/scale.rb, line 40 def ==(other) id == other.id end
chords(size = 3..12)
click to toggle source
# 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
Also aliased as: all_chords
degree(d)
click to toggle source
# 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
Also aliased as: []
degree_of_chord(chord)
click to toggle source
# 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)
click to toggle source
# File lib/coltrane/theory/scale.rb, line 84 def degree_of_note(note) notes.index(note) end
degrees()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 75 def degrees (1..size) end
full_name()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 56 def full_name "#{tone} #{name}" end
Also aliased as: to_s
id()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 36 def id [(name || @interval_sequence), tone.number] end
include_notes?(arg)
click to toggle source
# 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
Also aliased as: include?
interval(i)
click to toggle source
# File lib/coltrane/theory/scale.rb, line 104 def interval(i) interval_sequence[(i - 1) % size] end
name()
click to toggle source
# 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()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 100 def notes @notes ||= NoteSet[*degrees.map { |d| degree(d) }] end
pentads()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 133 def pentads tertians(5) end
pretty_name()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 62 def pretty_name "#{tone.pretty_name} #{name}" end
Also aliased as: full_name
progression(*degrees)
click to toggle source
# File lib/coltrane/theory/scale.rb, line 137 def progression(*degrees) Progression.new(self, degrees) end
sevenths()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 129 def sevenths tertians(4) end
size()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 108 def size interval_sequence.size end
tertians(n = 3)
click to toggle source
# 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()
click to toggle source
# File lib/coltrane/theory/scale.rb, line 125 def triads tertians(3) end