Class: HeadMusic::Instruments::Stringing

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/instruments/stringing.rb

Overview

The string configuration for a stringed instrument.

A Stringing defines the courses (strings) of an instrument and their standard tuning pitches. Each course can have one or more strings.

Examples: guitar = HeadMusic::Instruments::Instrument.get("guitar") stringing = HeadMusic::Instruments::Stringing.for_instrument(guitar) stringing.courses.map(&:standard_pitch) # => [E2, A2, D3, G3, B3, E4]

Constant Summary collapse

STRINGINGS =
YAML.load_file(File.expand_path("stringings.yml", __dir__)).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instrument_key:, courses_data:) ⇒ Stringing

Returns a new instance of Stringing.



56
57
58
59
# File 'lib/head_music/instruments/stringing.rb', line 56

def initialize(instrument_key:, courses_data:)
  @instrument_key = instrument_key.to_sym
  @courses = build_courses(courses_data)
end

Instance Attribute Details

#coursesObject (readonly)

Returns the value of attribute courses.



15
16
17
# File 'lib/head_music/instruments/stringing.rb', line 15

def courses
  @courses
end

#instrument_keyObject (readonly)

Returns the value of attribute instrument_key.



15
16
17
# File 'lib/head_music/instruments/stringing.rb', line 15

def instrument_key
  @instrument_key
end

Class Method Details

.find_stringing_data(instrument_key, instrument) ⇒ Object (private)



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/head_music/instruments/stringing.rb', line 42

def find_stringing_data(instrument_key, instrument)
  # Direct match
  return STRINGINGS[instrument_key] if STRINGINGS.key?(instrument_key)

  # Try parent instrument if this is an Instrument object
  if instrument.is_a?(HeadMusic::Instruments::Instrument) && instrument.parent
    parent_key = instrument.parent.name_key.to_s
    return STRINGINGS[parent_key] if STRINGINGS.key?(parent_key)
  end

  nil
end

.for_instrument(instrument) ⇒ Stringing?

Find the stringing for an instrument

Parameters:

Returns:



21
22
23
24
25
26
27
28
29
# File 'lib/head_music/instruments/stringing.rb', line 21

def for_instrument(instrument)
  instrument_key = normalize_instrument_key(instrument)
  return nil unless instrument_key

  data = find_stringing_data(instrument_key, instrument)
  return nil unless data

  new(instrument_key: instrument_key, courses_data: data["courses"])
end

.normalize_instrument_key(instrument) ⇒ Object (private)



33
34
35
36
37
38
39
40
# File 'lib/head_music/instruments/stringing.rb', line 33

def normalize_instrument_key(instrument)
  case instrument
  when HeadMusic::Instruments::Instrument
    instrument.name_key.to_s
  else
    instrument.to_s
  end
end

Instance Method Details

#==(other) ⇒ Object



95
96
97
98
99
# File 'lib/head_music/instruments/stringing.rb', line 95

def ==(other)
  return false unless other.is_a?(self.class)

  instrument_key == other.instrument_key && courses == other.courses
end

#build_courses(courses_data) ⇒ Object (private)



107
108
109
110
111
112
113
114
# File 'lib/head_music/instruments/stringing.rb', line 107

def build_courses(courses_data)
  courses_data.map do |course_data|
    HeadMusic::Instruments::StringingCourse.new(
      standard_pitch: course_data["pitch"],
      course_semitones: course_data["course_semitones"] || []
    )
  end
end

#course_countInteger

Number of courses

Returns:

  • (Integer)


69
70
71
# File 'lib/head_music/instruments/stringing.rb', line 69

def course_count
  courses.length
end

#instrumentHeadMusic::Instruments::Instrument

The instrument this stringing belongs to



63
64
65
# File 'lib/head_music/instruments/stringing.rb', line 63

def instrument
  HeadMusic::Instruments::Instrument.get(instrument_key)
end

#pitches_with_tuning(tuning) ⇒ Array<HeadMusic::Rudiment::Pitch>

Apply an alternate tuning to get adjusted pitches

Parameters:

Returns:



88
89
90
91
92
93
# File 'lib/head_music/instruments/stringing.rb', line 88

def pitches_with_tuning(tuning)
  courses.each_with_index.map do |course, index|
    semitone_adjustment = tuning.semitones[index] || 0
    HeadMusic::Rudiment::Pitch.from_number(course.standard_pitch.to_i + semitone_adjustment)
  end
end

#standard_pitchesArray<HeadMusic::Rudiment::Pitch>

Standard pitches for each course (primary string only)

Returns:



81
82
83
# File 'lib/head_music/instruments/stringing.rb', line 81

def standard_pitches
  courses.map(&:standard_pitch)
end

#string_countInteger

Total number of physical strings across all courses

Returns:

  • (Integer)


75
76
77
# File 'lib/head_music/instruments/stringing.rb', line 75

def string_count
  courses.sum(&:string_count)
end

#to_sObject



101
102
103
# File 'lib/head_music/instruments/stringing.rb', line 101

def to_s
  "#{course_count}-course stringing for #{instrument_key}"
end