Class: HeadMusic::Rudiment::LetterName

Inherits:
Base
  • Object
show all
Defined in:
lib/head_music/rudiment/letter_name.rb

Overview

Music has seven lette names that are used to identify pitches and pitch classes.

Constant Summary collapse

NAMES =
%w[C D E F G A B].freeze
PATTERN =
/[A-Ga-g]/
MATCHER =
/^#{PATTERN}$/
NATURAL_PITCH_CLASS_NUMBERS =
{
  "C" => 0,
  "D" => 2,
  "E" => 4,
  "F" => 5,
  "G" => 7,
  "A" => 9,
  "B" => 11
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ LetterName

Returns a new instance of LetterName.



50
51
52
# File 'lib/head_music/rudiment/letter_name.rb', line 50

def initialize(name)
  @name = name
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



44
45
46
# File 'lib/head_music/rudiment/letter_name.rb', line 44

def name
  @name
end

Class Method Details

.allObject



20
21
22
# File 'lib/head_music/rudiment/letter_name.rb', line 20

def self.all
  NAMES.map { |letter_name| get(letter_name) }
end

.from_name(name) ⇒ Object



28
29
30
31
32
# File 'lib/head_music/rudiment/letter_name.rb', line 28

def self.from_name(name)
  @letter_names ||= {}
  name = name.to_s.first.upcase
  @letter_names[name] ||= new(name) if NAMES.include?(name)
end

.from_pitch_class(pitch_class) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/head_music/rudiment/letter_name.rb', line 34

def self.from_pitch_class(pitch_class)
  @letter_names ||= {}
  return nil if pitch_class.to_s == pitch_class

  pitch_class = pitch_class.to_i % 12
  name = NAMES.detect { |candidate| pitch_class == NATURAL_PITCH_CLASS_NUMBERS[candidate] }
  name ||= HeadMusic::Rudiment::PitchClass::SHARP_SPELLINGS[pitch_class].first
  @letter_names[name] ||= new(name) if NAMES.include?(name)
end

.get(identifier) ⇒ Object



24
25
26
# File 'lib/head_music/rudiment/letter_name.rb', line 24

def self.get(identifier)
  from_name(identifier) || from_pitch_class(identifier)
end

Instance Method Details

#==(other) ⇒ Object



58
59
60
# File 'lib/head_music/rudiment/letter_name.rb', line 58

def ==(other)
  to_s == other.to_s
end

#pitch_classObject



54
55
56
# File 'lib/head_music/rudiment/letter_name.rb', line 54

def pitch_class
  HeadMusic::Rudiment::PitchClass.get(NATURAL_PITCH_CLASS_NUMBERS[name])
end

#positionObject



62
63
64
# File 'lib/head_music/rudiment/letter_name.rb', line 62

def position
  NAMES.index(to_s) + 1
end

#series_ascendingObject



86
87
88
89
90
91
92
# File 'lib/head_music/rudiment/letter_name.rb', line 86

def series_ascending
  @series_ascending ||= begin
    series = NAMES
    series = series.rotate while series.first != to_s
    series
  end
end

#series_descendingObject



94
95
96
97
98
99
100
# File 'lib/head_music/rudiment/letter_name.rb', line 94

def series_descending
  @series_descending ||= begin
    series = NAMES.reverse
    series = series.rotate while series.first != to_s
    series
  end
end

#steps_down(num) ⇒ Object



70
71
72
# File 'lib/head_music/rudiment/letter_name.rb', line 70

def steps_down(num)
  HeadMusic::Rudiment::LetterName.get(series_descending[num % NAMES.length])
end

#steps_to(other, direction = :ascending) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/head_music/rudiment/letter_name.rb', line 74

def steps_to(other, direction = :ascending)
  other = HeadMusic::Rudiment::LetterName.get(other)
  other_position = other.position
  if direction == :descending
    other_position -= NAMES.length if other_position > position
    position - other_position
  else
    other_position += NAMES.length if other_position < position
    other_position - position
  end
end

#steps_up(num) ⇒ Object



66
67
68
# File 'lib/head_music/rudiment/letter_name.rb', line 66

def steps_up(num)
  HeadMusic::Rudiment::LetterName.get(series_ascending[num % NAMES.length])
end