class Coltrane::Theory::IntervalSequence

It describes a sequence of intervals

Attributes

intervals[R]

Public Class Methods

new(*intervals, notes: nil, relative_intervals: nil) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 13
def initialize(*intervals, notes: nil, relative_intervals: nil)
  if intervals.any?
    @intervals = if intervals.first.is_a?(Interval)
                   intervals
                 else
                   intervals.map { |i| Interval[i] }
    end

  elsif notes
    notes = NoteSet[*notes] if notes.is_a?(Array)
    @intervals = intervals_from_notes(notes)
  elsif relative_intervals
    @relative_intervals = relative_intervals
    @intervals = intervals_from_relative_intervals(relative_intervals)
  else
    raise WrongKeywordsError,
          'Provide: [notes:] || [intervals:] || [relative_intervals:]'
  end
end

Public Instance Methods

&(other) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 137
def &(other)
  case other
  when Array then intervals & other
  when IntervalSequence then intervals & other.semitones
  end
end
[](x) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 87
def [](x)
  intervals[x]
end
all() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 83
def all
  intervals
end
find(interval) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 65
def find(interval)
  interval.clone if detect { |i| interval == i }
end
find_by_distance(n, accept_altered = true) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 73
def find_by_distance(n, accept_altered = true)
  strategy = (accept_altered ? :as : :as!)
  map { |interval| interval.send(strategy, n) }
    .compact
    .sort_by { |i| i.alteration.abs }
    .first
end
full_names() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 125
def full_names
  map(&:full_name)
end
has?(interval) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 69
def has?(interval)
  !!find(interval)
end
interval_names()
Alias for: names
intervals_semitones() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 117
def intervals_semitones
  map(&:semitones)
end
inversion(index) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 101
def inversion(index)
  self.class.new(*intervals.rotate(index)).zero_it
end
inversions() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 113
def inversions
  Array.new(intervals.length) { |i| inversion(i) }
end
names() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 61
def names
  intervals.map(&:name)
end
Also aliased as: interval_names
next_inversion() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 105
def next_inversion
  inversion(index + 1)
end
notes_for(root_note) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 129
def notes_for(root_note)
  NoteSet[
    *intervals.reduce([]) do |memo, interval|
      memo + [root_note + interval]
    end
  ]
end
previous_inversion() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 109
def previous_inversion
  inversion(index - 1)
end
relative_intervals() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 51
def relative_intervals
  intervals_semitones[1..-1].each_with_index.map do |n, i|
    if i.zero?
      n
    elsif i < intervals_semitones.size
      n - intervals_semitones[i]
    end
  end + [12 - intervals_semitones.last]
end
shift(ammount) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 91
def shift(ammount)
  self.class.new(*intervals.map do |i|
    (i.semitones + ammount) % 12
  end)
end
zero_it() click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 97
def zero_it
  shift(-intervals.first.semitones)
end

Private Instance Methods

intervals_from_notes(notes) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 152
def intervals_from_notes(notes)
  notes.map { |n| notes.root - n }.sort_by(&:semitones)
end
intervals_from_relative_intervals(relative_intervals) click to toggle source
# File lib/coltrane/theory/interval_sequence.rb, line 146
def intervals_from_relative_intervals(relative_intervals)
  relative_intervals[0..-2].reduce([Interval[0]]) do |memo, d|
    memo + [memo.last + d]
  end
end