class Coltrane::Theory::Interval
Attributes
cents[R]
letter_distance[R]
Public Class Methods
[](arg)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 80 def self.[](arg) new(arg) end
all()
click to toggle source
Calls superclass method
# File lib/coltrane/theory/interval.rb, line 10 def all @all ||= super.map(&:interval) end
all_augmented()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 22 def all_augmented @all_augmented ||= all_including_compound.select(&:has_augmented?) .map(&:augmented) end
all_compound()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 14 def all_compound @all_compound ||= all.map(&:compound) end
all_diminished()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 27 def all_diminished @all_diminished ||= all_including_compound.select(&:has_diminished?) .map(&:diminished) end
all_including_compound()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 18 def all_including_compound @all_including_compound ||= all + all_compound end
all_including_compound_and_altered()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 32 def all_including_compound_and_altered @all_including_compound_and_altered ||= all_including_compound + all_diminished + all_augmented end
new(arg_1 = nil, arg_2 = nil, ascending: true, letter_distance: nil, semitones: nil, compound: false)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 40 def initialize(arg_1 = nil, arg_2 = nil, ascending: true, letter_distance: nil, semitones: nil, compound: false) if arg_1 && !arg_2 # assumes arg_1 is a letter @compound = compound IntervalClass[arg_1].interval.yield_self do |interval| @letter_distance = interval.letter_distance @cents = interval.cents end elsif arg_1 && arg_2 # assumes those are notes if ascending @compound = compound @cents = (arg_1.frequency / arg_2.frequency) .interval_class .cents @letter_distance = calculate_letter_distance arg_1.letter, arg_2.letter, ascending else self.class.new(arg_1, arg_2).descending.yield_self do |base_interval| @compound = base_interval.compound? @cents = base_interval.cents @letter_distance = base_interval.letter_distance end end elsif letter_distance && semitones @compound = compound || letter_distance > 8 @cents = semitones * 100 @letter_distance = letter_distance else raise WrongKeywordsError, '[interval_class_name]' \ 'Provide: [first_note, second_note] || ' \ '[letter_distance:, semitones:]' end end
Public Instance Methods
accidentals()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 100 def accidentals if distance_to_starting.positive? then 'A' * distance_to_starting.abs elsif distance_to_starting.negative? then 'd' * distance_to_starting.abs else '' end end
as(n)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 117 def as(n) i = clone(letter_distance: n) i if i.name.match?(n.to_s) end
as!(n)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 122 def as!(n) i = as(n) i unless i&.name&.match? /d|A/ end
as_augmented(n = 1)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 131 def as_augmented(n = 1) as(letter_distance - n) end
as_diminished(n = 1)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 127 def as_diminished(n = 1) as(letter_distance + n) end
ascending()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 159 def ascending ascending? ? self : opposite end
augment(n = 1)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 149 def augment(n = 1) clone(semitones: semitones + n) end
Also aliased as: augmented
clone(override_args = {})
click to toggle source
# File lib/coltrane/theory/interval.rb, line 135 def clone(override_args = {}) self.class.new(**{ semitones: semitones, letter_distance: letter_distance, compound: compound? }.merge(override_args)) end
compound?()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 88 def compound? @compound end
descending()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 163 def descending descending? ? self : opposite end
diminish(n = 1)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 143 def diminish(n = 1) clone(semitones: semitones - n) end
Also aliased as: diminished
has_augmented?()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 92 def has_augmented? name.match? /M|P|A/ end
has_diminished?()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 96 def has_diminished? name.match? /m|P|d/ end
interval_class()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 84 def interval_class FrequencyInterval[cents].interval_class end
name()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 107 def name @name ||= begin if distance_to_starting.zero? || distance_to_starting.abs > 2 compound? ? interval_class.compound_name : interval_class.name else "#{accidentals}#{starting_interval.distance + (compound? ? 7 : 0)}" end end end
opposite()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 155 def opposite clone(semitones: -semitones, letter_distance: (-letter_distance % 8) + 1) end
Private Instance Methods
all_letters()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 192 def all_letters PitchClass.all_letters end
calculate_letter_distance(a, b, asc)
click to toggle source
# File lib/coltrane/theory/interval.rb, line 196 def calculate_letter_distance(a, b, asc) all_letters .rotate(all_letters.index(asc ? a : b)) .index(b) + 1 end
distance_to_starting()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 187 def distance_to_starting # calculate the closts distance to it d = semitones - starting_interval.semitones [(d % 12), (d % -12)].min_by(&:abs) end
normalized_letter_distance()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 182 def normalized_letter_distance return letter_distance if letter_distance < 8 (letter_distance % 8) + 1 end
starting_interval()
click to toggle source
# File lib/coltrane/theory/interval.rb, line 169 def starting_interval # select the closest interval possible to start from @starting_interval ||= begin IntervalClass.all .select { |i| i.distance == normalized_letter_distance } .sort_by do |i| (cents - i.cents) .yield_self { |d| [(d % 1200), (d % -1200)].min_by(&:abs) } .abs end .first end end