class ChordFinder

Attributes

fretboard[R]
printer[R]

Public Class Methods

new(tuning = :EADGBE, fret_count = 20) click to toggle source
# File lib/chord_finder.rb, line 11
def initialize(tuning = :EADGBE, fret_count = 20)
  @fretboard = Fretboard.new(tuning, fret_count)
  @printer = ChartPrinter.new
end

Public Instance Methods

display(chord, options) click to toggle source
# File lib/chord_finder.rb, line 16
def display(chord, options)
  chord = build_chord(chord)
  positions = find(chord, options)

  if options[:simple]
    positions.each { |position| puts position.to_s }
  else
    positions.each { |position| printer.call(position, fretboard.open_notes) }
  end

  "Notes: #{chord.notes.join(" ")}"
end
find(chord, options) click to toggle source
# File lib/chord_finder.rb, line 29
def find(chord, options)
  chord_frets = fretboard.filter_frets(chord, options)
  positions   = create_positions(chord_frets, chord)
  valid_positions = select_valid_positions(positions, chord)

  # prioritize positions with chord root in the bass
  first_in_bass, fifth_in_bass =
    valid_positions.partition { |pos| pos.bass_note == chord.first }

  (first_in_bass + fifth_in_bass).take(options[:limit] || 5)
end

Private Instance Methods

build_chord(chord) click to toggle source
# File lib/chord_finder.rb, line 42
def build_chord(chord)
  case chord
  when String then Chord.new(chord)
  when Symbol then Chord.new(chord)
  when Chord  then chord
  end
end
create_positions(chord_frets, chord) click to toggle source
# File lib/chord_finder.rb, line 69
def create_positions(chord_frets, chord)
  ChordPosition.create_list(chord_frets[0].product(*chord_frets[1..-1]), chord)
end
select_valid_positions(positions, chord) click to toggle source
# File lib/chord_finder.rb, line 50
def select_valid_positions(positions, chord)
  valid_positions = []
  positions.each do |position|
    next unless position.valid?
    i = valid_positions.find_index { |prev_position|
                          position.same_form?(prev_position) }

    if i
      prev_position = valid_positions[i]
      valid_positions[i] =
        position.num_sounding_strings > prev_position.num_sounding_strings ?
        position : prev_position
    else
      valid_positions << position
    end
  end
  valid_positions
end