Class: OutroRails::ChordChart

Inherits:
ApplicationRecord show all
Defined in:
app/models/outro_rails/chord_chart.rb,
app/models/outro_rails/chord_chart/voicing.rb

Defined Under Namespace

Classes: Voicing

Constant Summary collapse

KEY_OPTIONS =
(
  Theory::Key.canonical(:major).map(&:to_s) +
  Theory::Key.canonical(:minor).map(&:to_s)
).freeze

Instance Method Summary collapse

Instance Method Details

#chord_symbolsObject



42
43
44
# File 'app/models/outro_rails/chord_chart.rb', line 42

def chord_symbols
  Theory::Transposer.scan_chords(body.to_s)
end

#default_voicing_for(chord, instrument, bass: nil) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/outro_rails/chord_chart.rb', line 83

def default_voicing_for(chord, instrument, bass: nil)
  voicings = chord.voicings
                  .where(instrument: instrument)
                  .order(:position)

  if bass.present?
    bass_pitch_class = Theory::NoteName.parse(bass).pitch_class
    slash_voicing = voicings.detect do |voicing|
                      voicing.bass_pitch_class == bass_pitch_class
                    end
    return slash_voicing if slash_voicing
  end

  voicings.first
end

#display_chord_symbols(to_key: nil) ⇒ Object



46
47
48
49
50
51
52
53
54
# File 'app/models/outro_rails/chord_chart.rb', line 46

def display_chord_symbols(to_key: nil)
  target = to_key.presence || key
  symbols = chord_symbols
  return symbols if symbols.empty? || target.to_s == key.to_s

  Theory::Transposer.transpose_chords(symbols.join(" "),
                                      from: self.to_key,
                                      to: target).split(/\s+/)
end

#display_chords(to_key: nil) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
# File 'app/models/outro_rails/chord_chart.rb', line 56

def display_chords(to_key: nil)
  symbols = display_chord_symbols(to_key: to_key)
  base_symbols = symbols.index_with do |symbol|
    Theory::Transposer.split_bass(symbol).first
  end
  chords = Chord.where(symbol: base_symbols.values.uniq).index_by(&:symbol)

  symbols.each_with_object({}) do |symbol, found|
    chord = chords[base_symbols[symbol]]
    found[symbol] = chord if chord
  end
end

#to_keyObject



34
35
36
# File 'app/models/outro_rails/chord_chart.rb', line 34

def to_key
  Theory::Key.parse(key.presence || "C")
end

#to_tuningObject



38
39
40
# File 'app/models/outro_rails/chord_chart.rb', line 38

def to_tuning
  Instruments::Guitar::Tunings.fetch(tuning)
end

#voicing_for(chord, instrument, transposed: false, bass: nil) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'app/models/outro_rails/chord_chart.rb', line 69

def voicing_for(chord, instrument, transposed: false, bass: nil)
  unless transposed
    selection_bass = Voicing.normalize_bass(bass)
    selection = voicings.detect do |candidate|
      candidate.chord_id == chord.id &&
        candidate.instrument == instrument.to_s &&
        candidate.bass == selection_bass
    end
    return selection.chord_voicing if selection
  end

  default_voicing_for(chord, instrument, bass: bass)
end