Class: HeadMusic::Rudiment::LetterName

Inherits:
Object
  • 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
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.



48
49
50
# File 'lib/head_music/rudiment/letter_name.rb', line 48

def initialize(name)
  @name = name
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



42
43
44
# File 'lib/head_music/rudiment/letter_name.rb', line 42

def name
  @name
end

Class Method Details

.allObject



18
19
20
# File 'lib/head_music/rudiment/letter_name.rb', line 18

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

.from_name(name) ⇒ Object



26
27
28
29
30
# File 'lib/head_music/rudiment/letter_name.rb', line 26

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



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

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



22
23
24
# File 'lib/head_music/rudiment/letter_name.rb', line 22

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

Instance Method Details

#==(other) ⇒ Object



56
57
58
# File 'lib/head_music/rudiment/letter_name.rb', line 56

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

#pitch_classObject



52
53
54
# File 'lib/head_music/rudiment/letter_name.rb', line 52

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

#positionObject



60
61
62
# File 'lib/head_music/rudiment/letter_name.rb', line 60

def position
  NAMES.index(to_s) + 1
end

#series_ascendingObject



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

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

#series_descendingObject



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

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

#steps_down(num) ⇒ Object



68
69
70
# File 'lib/head_music/rudiment/letter_name.rb', line 68

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

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



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

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



64
65
66
# File 'lib/head_music/rudiment/letter_name.rb', line 64

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