Sha256: a5c99a25a6765e90882d35cb2324334a944b761db20749aa08191000b09b0bca

Contents?: true

Size: 1.37 KB

Versions: 5

Compression:

Stored size: 1.37 KB

Contents

# frozen_string_literal: true

# A harmonic interval is the functional interval between two notes sounding together.
class HeadMusic::HarmonicInterval
  attr_reader :voice1, :voice2, :position

  def initialize(voice1, voice2, position)
    @voice1 = voice1
    @voice2 = voice2
    @position = position.is_a?(String) ? HeadMusic::Position.new(voice1.composition, position) : position
  end

  def functional_interval
    @functional_interval ||= HeadMusic::FunctionalInterval.new(lower_pitch, upper_pitch)
  end

  def voices
    [voice1, voice2].compact
  end

  def notes
    @notes ||= voices.map { |voice| voice.note_at(position) }.compact.sort_by(&:pitch)
  end

  def lower_note
    notes.first
  end

  def upper_note
    notes.last
  end

  def pitches
    @pitches ||= notes.map(&:pitch).sort_by(&:to_i)
  end

  def lower_pitch
    pitches.first
  end

  def upper_pitch
    pitches.last
  end

  def pitch_orientation
    return if lower_pitch == upper_pitch
    if lower_note.voice == voice1
      :up
    elsif lower_note.voice == voice2
      :down
    end
  end

  def to_s
    "#{functional_interval} at #{position}"
  end

  def method_missing(method_name, *args, &block)
    respond_to_missing?(method_name) ? functional_interval.send(method_name, *args, &block) : super
  end

  def respond_to_missing?(method_name, *_args)
    functional_interval.respond_to?(method_name)
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
head_music-0.20.0 lib/head_music/harmonic_interval.rb
head_music-0.19.2 lib/head_music/harmonic_interval.rb
head_music-0.19.1 lib/head_music/harmonic_interval.rb
head_music-0.19.0 lib/head_music/harmonic_interval.rb
head_music-0.18.0 lib/head_music/harmonic_interval.rb