Sha256: 46716c3f1519a860a69a775d8b87eae7949edc17daa1c8462bd72f3ad433fa7f

Contents?: true

Size: 905 Bytes

Versions: 1

Compression:

Stored size: 905 Bytes

Contents

# frozen_string_literal: true

module Coltrane
  class CircleOfFifths
    attr_reader :notes

    LETTER_SEQUENCE = %w[C G D A E B F].freeze

    def initialize(start_note = Note['C'], size = Float::INFINITY)
      index  = letters.index(start_note.name[0])
      @notes = fifths(note: start_note - Interval.perfect_fifth,
                      size: size,
                      index: (index - 1) % LETTER_SEQUENCE.size)
    end

    private

    def fifths(note:, index: nil, notes: [], size:)
      return notes if size == 0
      return notes if notes.any? && note.as(letters(index)).name == notes.first.name
      fifths note: note + Interval.perfect_fifth,
             notes: notes + [note.as(letters(index))],
             index: index + 1,
             size:  size - 1
    end

    def letters(i = nil)
      i.nil? ? LETTER_SEQUENCE : LETTER_SEQUENCE[i % LETTER_SEQUENCE.size]
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
coltrane-2.2.1 lib/coltrane/circle_of_fifths.rb