Module: OutroRails::Instruments::Guitar::Tunings

Defined in:
lib/outro_rails/instruments/guitar/tunings.rb

Overview

Registry of named guitar tunings. Each Tuning carries a URL slug, a display name, its open-string notes (low to high, i.e. string 6 first) and the accidental spelling that fits it best.

Defined Under Namespace

Classes: Tuning

Constant Summary collapse

ALL =

Slug, display name, open strings (low to high), preferred accidentals for note labels on the fretboard.

[
  [ "standard",       "Standard",             %w[E2 A2 D3 G3 B3 E4],       :sharps ],
  [ "half-step-down", "Half-Step Down",       %w[Eb2 Ab2 Db3 Gb3 Bb3 Eb4], :flats ],
  [ "perfect-fourth", "Perfect Fourth",       %w[E2 A2 D3 G3 C4 F4],       :sharps ],
  [ "a",              "A Tuning",             %w[A1 D2 G2 C3 E3 A3],       :sharps ],
  [ "b",              "B Tuning",             %w[B1 E2 A2 D3 F#3 B3],      :sharps ],
  [ "c",              "C Tuning",             %w[C2 F2 Bb2 Eb3 G3 C4],     :flats ],
  [ "c-sharp",        "C# Tuning",            %w[C#2 F#2 B2 E3 G#3 C#4],   :sharps ],
  [ "d",              "D Tuning",             %w[D2 G2 C3 F3 A3 D4],       :sharps ],
  [ "drop-a",         "Drop A",               %w[A1 E2 A2 D3 F#3 B3],      :sharps ],
  [ "drop-bb",        "Drop Bb",              %w[Bb1 F2 Bb2 Eb3 G3 C4],    :flats ],
  [ "drop-b",         "Drop B",               %w[B1 F#2 B2 E3 G#3 C#4],    :sharps ],
  [ "drop-c",         "Drop C",               %w[C2 G2 C3 F3 A3 D4],       :sharps ],
  [ "drop-db",        "Drop Db",              %w[Db2 Ab2 Db3 Gb3 Bb3 Eb4], :flats ],
  [ "drop-d",         "Drop D",               %w[D2 A2 D3 G3 B3 E4],       :sharps ],
  [ "open-c",         "Open C",               %w[C2 G2 C3 G3 C4 E4],       :sharps ],
  [ "open-d",         "Open D",               %w[D2 A2 D3 F#3 A3 D4],      :sharps ],
  [ "open-e",         "Open E",               %w[E2 B2 E3 G#3 B3 E4],      :sharps ],
  [ "open-g",         "Open G",               %w[D2 G2 D3 G3 B3 D4],       :sharps ],
  [ "celtic",         "Celtic (DADGAD)",      %w[D2 A2 D3 G3 A3 D4],       :sharps ]
].map { |slug, name, notes, prefer|
  # Instances are shared and frozen, so callers can't mutate the registry.
  Tuning.new(slug: slug,
             name: name,
             notes: notes.freeze,
             prefer: prefer).freeze
}.freeze
BY_SLUG =

Slug => Tuning lookup table built from ALL.

ALL.to_h { |tuning| [ tuning.slug, tuning ] }.freeze
DEFAULT_SLUG =

Tuning assumed when the request doesn't name one.

"standard"

Class Method Summary collapse

Class Method Details

.allObject

Every tuning, in the order declared above (i.e. menu order).



73
74
75
# File 'lib/outro_rails/instruments/guitar/tunings.rb', line 73

def self.all
  ALL
end

.defaultObject

The tuning fetch falls back to for blank input.



84
85
86
# File 'lib/outro_rails/instruments/guitar/tunings.rb', line 84

def self.default
  BY_SLUG.fetch(DEFAULT_SLUG)
end

.fetch(slug) ⇒ Object

Looks up a tuning by slug; nil/blank falls back to standard. Legacy underscore slugs ('drop_d') resolve to their dashed equivalents. Raises ArgumentError on unknown slugs (pair with InvalidParamsRedirectable to turn that into a redirect).



92
93
94
95
96
97
98
# File 'lib/outro_rails/instruments/guitar/tunings.rb', line 92

def self.fetch(slug)
  slug = slug.to_s.strip.tr("_", "-")
  return default if slug.empty?

  BY_SLUG.fetch(slug) { raise ArgumentError,
                              "unknown tuning #{slug.inspect}" }
end

.include?(slug) ⇒ Boolean

Whether slug names a known tuning. Accepts legacy underscores like fetch does, but does not treat blank as the default: include?("") is false even though fetch("") returns standard.

Returns:

  • (Boolean)


103
104
105
# File 'lib/outro_rails/instruments/guitar/tunings.rb', line 103

def self.include?(slug)
  BY_SLUG.key?(slug.to_s.tr("_", "-"))
end

.slugsObject

Just the slugs, same order. Useful for route constraints and inclusion validations.



79
80
81
# File 'lib/outro_rails/instruments/guitar/tunings.rb', line 79

def self.slugs
  ALL.map(&:slug)
end