Sha256: d93a168d7e064d54c21ab7b038a8177fdc63c373485404944b70c20e92380d0c

Contents?: true

Size: 871 Bytes

Versions: 2

Compression:

Stored size: 871 Bytes

Contents

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

2 entries across 2 versions & 1 rubygems

Version Path
coltrane-2.1.5 lib/coltrane/circle_of_fifths.rb
coltrane-2.1.0 lib/coltrane/circle_of_fifths.rb