Class: OutroRails::Instruments::Guitar
- Inherits:
-
Object
- Object
- OutroRails::Instruments::Guitar
- Defined in:
- lib/outro_rails/instruments/guitar.rb,
lib/outro_rails/instruments/guitar/capo.rb,
lib/outro_rails/instruments/guitar/tunings.rb,
lib/outro_rails/instruments/guitar/chord_shapes.rb
Overview
A guitar with a particular tuning. Strings are numbered 1 (highest pitch) to N (lowest).
Defined Under Namespace
Modules: Capo, ChordShapes, Tunings
Constant Summary collapse
- STANDARD_TUNING =
Open strings low to high, i.e. string 6 first.
%w[E2 A2 D3 G3 B3 E4].freeze
- MIN_FRET =
Playable fret range; 0 is the open string.
0- MAX_FRET =
24- SINGLE_MARKER_FRETS =
Fret inlay markers.
[ 3, 5, 7, 9, 15, 17, 19, 21 ].freeze
- DOUBLE_MARKER_FRETS =
[ 12, 24 ].freeze
Instance Attribute Summary collapse
-
#tuning ⇒ Object
readonly
Open-string Pitches, low to high, as given to the constructor.
Class Method Summary collapse
-
.in_tuning(tuning) ⇒ Object
Builds a Guitar from a named tuning: a Tunings::Tuning, a slug ("drop_d"), or nil/"" for standard.
-
.normalize_positions(positions) ⇒ Object
Normalizes highlight positions to [string, fret] integer pairs.
Instance Method Summary collapse
-
#initialize(tuning: STANDARD_TUNING) ⇒ Guitar
constructor
Parses the tuning into Pitches.
-
#midi_at(string, fret) ⇒ Object
MIDI number sounded at a string and fret - one semitone per fret.
-
#open_midis ⇒ Object
Open-string MIDI numbers keyed by string number: { 1 => 64, 2 => 59, 3 => 55, 4 => 50, 5 => 45, 6 => 40 }.
-
#open_pitch(string) ⇒ Object
Open Pitch of a string, counting 1 as the highest.
-
#pitch_at(string, fret, prefer: :sharps) ⇒ Object
That note as a Pitch, spelled with sharps or flats as preferred.
-
#pitch_class_at(string, fret) ⇒ Object
Pitch class (0-11) sounded at a string and fret, ignoring octave.
-
#positions_in(scale, min_fret: MIN_FRET, max_fret: MAX_FRET) ⇒ Object
Every [string, fret] position whose pitch class belongs to the scale, covering open strings through max_fret on every string: guitar.positions_in(Theory::Scale.new('C')) => [[1, 0], [1, 1], ...].
-
#positions_of(note, min_fret: MIN_FRET, max_fret: MAX_FRET) ⇒ Object
Every [string, fret] position sounding a note (any octave): guitar.positions_of('C') => [[1, 8], [1, 20], [2, 1], ...].
-
#string_count ⇒ Object
Number of strings, taken from the tuning.
Constructor Details
#initialize(tuning: STANDARD_TUNING) ⇒ Guitar
Parses the tuning into Pitches. Instances are immutable.
50 51 52 53 |
# File 'lib/outro_rails/instruments/guitar.rb', line 50 def initialize(tuning: STANDARD_TUNING) @tuning = tuning.map { |note| Theory::Pitch.parse(note) }.freeze freeze end |
Instance Attribute Details
#tuning ⇒ Object (readonly)
Open-string Pitches, low to high, as given to the constructor
24 25 26 |
# File 'lib/outro_rails/instruments/guitar.rb', line 24 def tuning @tuning end |
Class Method Details
.in_tuning(tuning) ⇒ Object
Builds a Guitar from a named tuning: a Tunings::Tuning, a slug
("drop_d"), or nil/"" for standard.
Guitar.in_tuning("open_g") => #
44 45 46 47 |
# File 'lib/outro_rails/instruments/guitar.rb', line 44 def self.in_tuning(tuning) tuning = Tunings.fetch(tuning) unless tuning.is_a?(Tunings::Tuning) new(tuning: tuning.notes) end |
.normalize_positions(positions) ⇒ Object
Normalizes highlight positions to [string, fret] integer pairs. Accepts [string, fret] pairs or "string:fret" strings:
normalize_positions([[5, 3], '4:2']) => [[5, 3], [4, 2]]
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/outro_rails/instruments/guitar.rb', line 29 def self.normalize_positions(positions) Array(positions).map do |position| string, fret = if position.is_a?(String) position.split(":", 2) else position.to_a end [ Integer(string), Integer(fret) ] end end |
Instance Method Details
#midi_at(string, fret) ⇒ Object
MIDI number sounded at a string and fret - one semitone per fret
73 74 75 |
# File 'lib/outro_rails/instruments/guitar.rb', line 73 def midi_at(string, fret) open_pitch(string).midi + fret end |
#open_midis ⇒ Object
Open-string MIDI numbers keyed by string number:
{ 1 => 64, 2 => 59, 3 => 55, 4 => 50, 5 => 45, 6 => 40 }
68 69 70 |
# File 'lib/outro_rails/instruments/guitar.rb', line 68 def open_midis (1..string_count).to_h { |string| [ string, midi_at(string, MIN_FRET) ] } end |
#open_pitch(string) ⇒ Object
Open Pitch of a string, counting 1 as the highest. The tuning is stored low to high, so the index is inverted.
62 63 64 |
# File 'lib/outro_rails/instruments/guitar.rb', line 62 def open_pitch(string) tuning.fetch(string_count - string) end |
#pitch_at(string, fret, prefer: :sharps) ⇒ Object
That note as a Pitch, spelled with sharps or flats as preferred
78 79 80 |
# File 'lib/outro_rails/instruments/guitar.rb', line 78 def pitch_at(string, fret, prefer: :sharps) Theory::Pitch.from_midi(midi_at(string, fret), prefer: prefer) end |
#pitch_class_at(string, fret) ⇒ Object
Pitch class (0-11) sounded at a string and fret, ignoring octave
83 84 85 |
# File 'lib/outro_rails/instruments/guitar.rb', line 83 def pitch_class_at(string, fret) midi_at(string, fret) % Theory::Interval::SEMITONES_PER_OCTAVE end |
#positions_in(scale, min_fret: MIN_FRET, max_fret: MAX_FRET) ⇒ Object
Every [string, fret] position whose pitch class belongs to the scale, covering open strings through max_fret on every string:
guitar.positions_in(Theory::Scale.new('C')) => [[1, 0], [1, 1], ...]
90 91 92 93 94 |
# File 'lib/outro_rails/instruments/guitar.rb', line 90 def positions_in(scale, min_fret: MIN_FRET, max_fret: MAX_FRET) positions_with_pitch_classes(scale.pitch_classes, min_fret: min_fret, max_fret: max_fret) end |
#positions_of(note, min_fret: MIN_FRET, max_fret: MAX_FRET) ⇒ Object
Every [string, fret] position sounding a note (any octave):
guitar.positions_of('C') => [[1, 8], [1, 20], [2, 1], ...]
98 99 100 101 102 103 |
# File 'lib/outro_rails/instruments/guitar.rb', line 98 def positions_of(note, min_fret: MIN_FRET, max_fret: MAX_FRET) pitch_class = Theory::NoteName.parse(note).pitch_class positions_with_pitch_classes([ pitch_class ], min_fret: min_fret, max_fret: max_fret) end |
#string_count ⇒ Object
Number of strings, taken from the tuning
56 57 58 |
# File 'lib/outro_rails/instruments/guitar.rb', line 56 def string_count tuning.size end |