Class: Coltrane::Representation::Guitar::Chord
- Inherits:
-
Object
- Object
- Coltrane::Representation::Guitar::Chord
- Includes:
- Comparable
- Defined in:
- lib/coltrane/representation/guitar/chord.rb
Overview
This class represents a group of guitar notes, strummed at the same time
Constant Summary collapse
- MAX_FRET_SPAN =
3
Instance Attribute Summary collapse
-
#barre ⇒ Object
readonly
Returns the value of attribute barre.
-
#free_fingers ⇒ Object
readonly
Returns the value of attribute free_fingers.
-
#guitar ⇒ Object
readonly
Returns the value of attribute guitar.
-
#guitar_notes ⇒ Object
readonly
Returns the value of attribute guitar_notes.
-
#target_chord ⇒ Object
readonly
Returns the value of attribute target_chord.
Class Method Summary collapse
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #analysis ⇒ Object
- #barre? ⇒ Boolean
- #completeness ⇒ Object
- #discontinuity ⇒ Object
- #easyness ⇒ Object
- #fetch_descendant_chords ⇒ Object
- #fret_expansion_range ⇒ Object
- #fret_range ⇒ Object
- #frets ⇒ Object
- #fullness ⇒ Object
- #highest_fret ⇒ Object
- #highest_possible_fret ⇒ Object
-
#initialize(target_chord, guitar_notes: [], free_fingers: 4, barre: nil, guitar:) ⇒ Chord
constructor
A new instance of Chord.
- #lowest_fret ⇒ Object
- #lowest_possible_fret ⇒ Object
- #max_fret_span ⇒ Object
- #non_zero_frets ⇒ Object
- #notes ⇒ Object
- #notes_available ⇒ Object
- #notes_left ⇒ Object
- #possible_span ⇒ Object
- #rank ⇒ Object
- #spreadness ⇒ Object
- #strings_available ⇒ Object
- #target_notes ⇒ Object
- #to_s(debug = false) ⇒ Object
- #voicing ⇒ Object
Constructor Details
#initialize(target_chord, guitar_notes: [], free_fingers: 4, barre: nil, guitar:) ⇒ Chord
Returns a new instance of Chord.
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 46 def initialize(target_chord, guitar_notes: [], free_fingers: 4, barre: nil, guitar:) @target_chord = target_chord @guitar_notes = guitar_notes @free_fingers = free_fingers @guitar = guitar @barre = end |
Instance Attribute Details
#barre ⇒ Object
Returns the value of attribute barre.
9 10 11 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 9 def @barre end |
#free_fingers ⇒ Object (readonly)
Returns the value of attribute free_fingers.
9 10 11 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 9 def free_fingers @free_fingers end |
#guitar ⇒ Object (readonly)
Returns the value of attribute guitar.
9 10 11 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 9 def guitar @guitar end |
#guitar_notes ⇒ Object (readonly)
Returns the value of attribute guitar_notes.
9 10 11 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 9 def guitar_notes @guitar_notes end |
#target_chord ⇒ Object (readonly)
Returns the value of attribute target_chord.
9 10 11 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 9 def target_chord @target_chord end |
Class Method Details
.find(chord, guitar:) ⇒ Object
13 14 15 16 17 18 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 13 def self.find(chord, guitar:) new(chord, guitar: guitar) .fetch_descendant_chords .sort .reverse end |
.find_by_notation(guitar, chord_notation) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 20 def self.find_by_notation(guitar, chord_notation) chord_notation .split('-') .map .with_index do |n, i| next if n == 'x' n = Guitar::Note.new(guitar.strings[i], n.to_i).pitch.pitch_class end .yield_self do |notes| notes .map .with_index do |note, index| begin Theory::Chord.new(notes: notes.rotate(index)) rescue Theory::ChordNotFoundError next end end .compact .yield_self do |chords| raise(Theory::ChordNotFoundError) if chords.empty? chords.compact.uniq &:name end end end |
Instance Method Details
#<=>(other) ⇒ Object
63 64 65 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 63 def <=>(other) rank <=> other.rank end |
#analysis ⇒ Object
75 76 77 78 79 80 81 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 75 def analysis %i[completeness discontinuity fullness spreadness easyness] .reduce({}) do |output, criteria| output.merge(criteria => send(criteria).round(2)) end .merge(rank: rank.round(4)) end |
#barre? ⇒ Boolean
103 104 105 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 103 def !@barre.nil? end |
#completeness ⇒ Object
87 88 89 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 87 def completeness (target_chord.notes.size.to_f - notes_left.size) / target_chord.notes.size end |
#discontinuity ⇒ Object
99 100 101 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 99 def discontinuity voicing.discontinuity end |
#easyness ⇒ Object
91 92 93 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 91 def easyness frets.count(0).to_f / guitar_notes.size end |
#fetch_descendant_chords ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 107 def fetch_descendant_chords return [self] if guitar_notes.size >= guitar.strings.size possible_new_notes(notes_available.positive?).reduce([]) do |memo, n| = n.fret if guitar_notes.last == n.fret fingers_change = n.fret == || n.fret.zero? ? 0 : 1 next memo if (free_fingers - fingers_change).negative? self.class.new(target_chord, guitar_notes: guitar_notes + [n], free_fingers: free_fingers - fingers_change, guitar: guitar, barre: ).fetch_descendant_chords + memo end end |
#fret_expansion_range ⇒ Object
181 182 183 184 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 181 def fret_expansion_range (lowest_possible_fret..highest_possible_fret).to_a + [(0 unless )].compact end |
#fret_range ⇒ Object
165 166 167 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 165 def fret_range (lowest_fret..highest_fret) end |
#frets ⇒ Object
149 150 151 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 149 def frets @frets ||= guitar_notes.map(&:fret) end |
#fullness ⇒ Object
95 96 97 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 95 def fullness (guitar.strings.size.to_f - frets.count(nil)) / guitar.strings.size end |
#highest_fret ⇒ Object
161 162 163 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 161 def highest_fret non_zero_frets.max || 0 end |
#highest_possible_fret ⇒ Object
173 174 175 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 173 def highest_possible_fret [(possible_span + (highest_fret == 0 ? guitar.frets : highest_fret)), guitar.frets].min end |
#lowest_fret ⇒ Object
157 158 159 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 157 def lowest_fret non_zero_frets.any? ? non_zero_frets.min : 0 end |
#lowest_possible_fret ⇒ Object
169 170 171 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 169 def lowest_possible_fret lowest_fret.zero? ? 0 : [(lowest_fret - possible_span), 0].max end |
#max_fret_span ⇒ Object
59 60 61 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 59 def max_fret_span MAX_FRET_SPAN end |
#non_zero_frets ⇒ Object
153 154 155 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 153 def non_zero_frets frets.reject { |f| f.nil? || f.zero? } end |
#notes ⇒ Object
145 146 147 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 145 def notes guitar_notes.map(&:pitch) end |
#notes_available ⇒ Object
122 123 124 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 122 def notes_available strings_available - notes_left.size end |
#notes_left ⇒ Object
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 130 def notes_left @notes_left ||= begin target_chord.notes - Theory::NoteSet[ *guitar_notes.map do |n| next if n.pitch.nil? n.pitch.pitch_class end ] end end |
#possible_span ⇒ Object
177 178 179 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 177 def possible_span MAX_FRET_SPAN - fret_range.size end |
#rank ⇒ Object
67 68 69 70 71 72 73 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 67 def rank +completeness * 10_000 + +fullness * 1_000 + -spreadness * 10 + -discontinuity * 1 + +easyness * 1 end |
#spreadness ⇒ Object
83 84 85 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 83 def spreadness fret_range.size.to_f / MAX_FRET_SPAN end |
#strings_available ⇒ Object
126 127 128 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 126 def strings_available guitar.strings.size - guitar_notes.size end |
#target_notes ⇒ Object
141 142 143 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 141 def target_notes notes_left.any? ? notes_left : target_chord.notes end |
#to_s(debug = false) ⇒ Object
186 187 188 189 190 |
# File 'lib/coltrane/representation/guitar/chord.rb', line 186 def to_s(debug = false) guitar_notes.map { |n| n.fret.nil? ? 'x' : n.fret }.join('-') + (debug ? ' ' + analysis.to_s : '') end |