Class: HeadMusic::LetterName
- Inherits:
-
Object
- Object
- HeadMusic::LetterName
- Defined in:
- lib/head_music/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
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Class Method Summary collapse
- .all ⇒ Object
- .from_name(name) ⇒ Object
- .from_pitch_class(pitch_class) ⇒ Object
- .get(identifier) ⇒ Object
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#initialize(name) ⇒ LetterName
constructor
A new instance of LetterName.
- #pitch_class ⇒ Object
- #position ⇒ Object
- #series_ascending ⇒ Object
- #series_descending ⇒ Object
- #steps_down(num) ⇒ Object
- #steps_to(other, direction = :ascending) ⇒ Object
- #steps_up(num) ⇒ Object
Constructor Details
#initialize(name) ⇒ LetterName
Returns a new instance of LetterName.
47 48 49 |
# File 'lib/head_music/letter_name.rb', line 47 def initialize(name) @name = name end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
41 42 43 |
# File 'lib/head_music/letter_name.rb', line 41 def name @name end |
Class Method Details
.all ⇒ Object
17 18 19 |
# File 'lib/head_music/letter_name.rb', line 17 def self.all NAMES.map { |letter_name| get(letter_name) } end |
.from_name(name) ⇒ Object
25 26 27 28 29 |
# File 'lib/head_music/letter_name.rb', line 25 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
31 32 33 34 35 36 37 38 39 |
# File 'lib/head_music/letter_name.rb', line 31 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::PitchClass::SHARP_SPELLINGS[pitch_class].first @letter_names[name] ||= new(name) if NAMES.include?(name) end |
.get(identifier) ⇒ Object
21 22 23 |
# File 'lib/head_music/letter_name.rb', line 21 def self.get(identifier) from_name(identifier) || from_pitch_class(identifier) end |
Instance Method Details
#==(other) ⇒ Object
55 56 57 |
# File 'lib/head_music/letter_name.rb', line 55 def ==(other) to_s == other.to_s end |
#pitch_class ⇒ Object
51 52 53 |
# File 'lib/head_music/letter_name.rb', line 51 def pitch_class HeadMusic::PitchClass.get(NATURAL_PITCH_CLASS_NUMBERS[name]) end |
#position ⇒ Object
59 60 61 |
# File 'lib/head_music/letter_name.rb', line 59 def position NAMES.index(to_s) + 1 end |
#series_ascending ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/head_music/letter_name.rb', line 83 def series_ascending @series_ascending ||= begin series = NAMES series = series.rotate while series.first != to_s series end end |
#series_descending ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/head_music/letter_name.rb', line 91 def series_descending @series_descending ||= begin series = NAMES.reverse series = series.rotate while series.first != to_s series end end |
#steps_down(num) ⇒ Object
67 68 69 |
# File 'lib/head_music/letter_name.rb', line 67 def steps_down(num) HeadMusic::LetterName.get(series_descending[num % NAMES.length]) end |
#steps_to(other, direction = :ascending) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/head_music/letter_name.rb', line 71 def steps_to(other, direction = :ascending) other = HeadMusic::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
63 64 65 |
# File 'lib/head_music/letter_name.rb', line 63 def steps_up(num) HeadMusic::LetterName.get(series_ascending[num % NAMES.length]) end |