Class: HeadMusic::Rudiment::Pitch
- Inherits:
-
Object
- Object
- HeadMusic::Rudiment::Pitch
- Includes:
- Comparable
- Defined in:
- lib/head_music/rudiment/pitch.rb
Overview
A pitch is a named frequency represented by a spelling and a register.
Defined Under Namespace
Classes: EnharmonicEquivalence, OctaveEquivalence
Instance Attribute Summary collapse
-
#register ⇒ Object
readonly
Returns the value of attribute register.
-
#spelling ⇒ Object
readonly
Returns the value of attribute spelling.
Class Method Summary collapse
-
.concert_a ⇒ Object
-
.fetch_or_create(spelling, register = nil) ⇒ Object
-
.from_name(name) ⇒ Object
-
.from_number(number) ⇒ Object
-
.from_number_and_letter(number, letter_name) ⇒ Object
-
.from_pitch_class(pitch_class) ⇒ Object
-
.get(value) ⇒ Object
Fetches a pitch identified by the information passed in.
-
.middle_c ⇒ Object
-
.natural_letter_pitch(number, letter_name) ⇒ Object
Instance Method Summary collapse
-
#+(other) ⇒ Object
-
#-(other) ⇒ Object
-
#<=>(other) ⇒ Object
-
#==(other) ⇒ Object
-
#enharmonic_equivalence ⇒ Object
private
-
#frequency ⇒ Object
-
#helmholtz_letter_name ⇒ Object
private
-
#helmholtz_marks ⇒ Object
private
-
#helmholtz_notation ⇒ Object
-
#initialize(spelling, register) ⇒ Pitch
constructor
A new instance of Pitch.
-
#midi_note_number ⇒ Object
(also: #midi, #number)
-
#name ⇒ Object
-
#natural ⇒ Object
-
#natural_steps(num_steps) ⇒ Object
-
#octave_adjustment_to(other) ⇒ Object
private
-
#octave_changes_to(other) ⇒ Object
private
-
#octave_equivalence ⇒ Object
private
-
#octaves_delta(num_steps) ⇒ Object
private
-
#pitch_class_above?(other) ⇒ Boolean
private
-
#scale(scale_type_name = nil) ⇒ Object
-
#steps_to(other) ⇒ Object
-
#target_letter_name(num_steps) ⇒ Object
private
-
#to_i ⇒ Object
-
#to_s ⇒ Object
-
#tuning ⇒ Object
private
-
#wrapped_down?(num_steps) ⇒ Boolean
private
-
#wrapped_up?(num_steps) ⇒ Boolean
private
Constructor Details
Instance Attribute Details
#register ⇒ Object (readonly)
Returns the value of attribute register.
8 9 10 |
# File 'lib/head_music/rudiment/pitch.rb', line 8 def register @register end |
#spelling ⇒ Object (readonly)
Returns the value of attribute spelling.
8 9 10 |
# File 'lib/head_music/rudiment/pitch.rb', line 8 def spelling @spelling end |
Class Method Details
.concert_a ⇒ Object
41 42 43 |
# File 'lib/head_music/rudiment/pitch.rb', line 41 def self.concert_a get("A4") end |
.fetch_or_create(spelling, register = nil) ⇒ Object
79 80 81 82 83 84 85 86 |
# File 'lib/head_music/rudiment/pitch.rb', line 79 def self.fetch_or_create(spelling, register = nil) register ||= HeadMusic::Rudiment::Register::DEFAULT return unless spelling && (-1..9).cover?(register) @pitches ||= {} hash_key = [spelling, register].join @pitches[hash_key] ||= new(spelling, register) end |
.from_name(name) ⇒ Object
51 52 53 54 55 |
# File 'lib/head_music/rudiment/pitch.rb', line 51 def self.from_name(name) return nil unless name == name.to_s fetch_or_create(HeadMusic::Rudiment::Spelling.get(name), HeadMusic::Rudiment::Register.get(name).to_i) end |
.from_number(number) ⇒ Object
57 58 59 60 61 |
# File 'lib/head_music/rudiment/pitch.rb', line 57 def self.from_number(number) return nil unless number == number.to_i fetch_or_create(HeadMusic::Rudiment::Spelling.from_number(number), (number.to_i / 12) - 1) end |
.from_number_and_letter(number, letter_name) ⇒ Object
63 64 65 66 67 68 69 70 |
# File 'lib/head_music/rudiment/pitch.rb', line 63 def self.from_number_and_letter(number, letter_name) letter_name = HeadMusic::Rudiment::LetterName.get(letter_name) natural_letter_pitch = natural_letter_pitch(number, letter_name) alteration_interval = natural_letter_pitch.smallest_interval_to(HeadMusic::Rudiment::PitchClass.get(number)) alteration = HeadMusic::Rudiment::Alteration.by(:semitones, alteration_interval) if alteration_interval != 0 spelling = HeadMusic::Rudiment::Spelling.fetch_or_create(letter_name, alteration) fetch_or_create(spelling, natural_letter_pitch.register) end |
.from_pitch_class(pitch_class) ⇒ Object
45 46 47 48 49 |
# File 'lib/head_music/rudiment/pitch.rb', line 45 def self.from_pitch_class(pitch_class) return nil unless pitch_class.is_a?(HeadMusic::Rudiment::PitchClass) fetch_or_create(pitch_class.sharp_spelling) end |
.get(value) ⇒ Object
Fetches a pitch identified by the information passed in.
Accepts: - a Pitch instance - a PitchClass instance - a name string, such as ‘Ab4’ - a number corresponding to the midi note number
31 32 33 34 35 |
# File 'lib/head_music/rudiment/pitch.rb', line 31 def self.get(value) from_pitch_class(value) || from_name(value) || from_number(value) end |
.middle_c ⇒ Object
37 38 39 |
# File 'lib/head_music/rudiment/pitch.rb', line 37 def self.middle_c get("C4") end |
.natural_letter_pitch(number, letter_name) ⇒ Object
72 73 74 75 76 77 |
# File 'lib/head_music/rudiment/pitch.rb', line 72 def self.natural_letter_pitch(number, letter_name) natural_letter_pitch = get(HeadMusic::Rudiment::LetterName.get(letter_name).pitch_class) natural_letter_pitch += 12 while (number.to_i - natural_letter_pitch.to_i) >= 6 natural_letter_pitch -= 12 while (number.to_i - natural_letter_pitch.to_i) <= -6 get(natural_letter_pitch) end |
Instance Method Details
#+(other) ⇒ Object
120 121 122 123 124 125 126 127 128 |
# File 'lib/head_music/rudiment/pitch.rb', line 120 def +(other) if other.is_a?(HeadMusic::Analysis::DiatonicInterval) # return a pitch other.above(self) else # assume value represents an interval in semitones and return another pitch HeadMusic::Rudiment::Pitch.get(to_i + other.to_i) end end |
#-(other) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/head_music/rudiment/pitch.rb', line 130 def -(other) case other when HeadMusic::Analysis::DiatonicInterval # return a pitch other.below(self) when HeadMusic::Rudiment::Pitch # return an interval HeadMusic::Rudiment::ChromaticInterval.get(to_i - other.to_i) else # assume value represents an interval in semitones and return another pitch HeadMusic::Rudiment::Pitch.get(to_i - other.to_i) end end |
#<=>(other) ⇒ Object
149 150 151 |
# File 'lib/head_music/rudiment/pitch.rb', line 149 def <=>(other) midi_note_number <=> other.midi_note_number end |
#==(other) ⇒ Object
144 145 146 147 |
# File 'lib/head_music/rudiment/pitch.rb', line 144 def ==(other) other = HeadMusic::Rudiment::Pitch.get(other) to_s == other.to_s end |
#enharmonic_equivalence ⇒ Object (private)
186 187 188 |
# File 'lib/head_music/rudiment/pitch.rb', line 186 def enharmonic_equivalence @enharmonic_equivalence ||= HeadMusic::Rudiment::Pitch::EnharmonicEquivalence.get(self) end |
#frequency ⇒ Object
161 162 163 |
# File 'lib/head_music/rudiment/pitch.rb', line 161 def frequency tuning.frequency_for(self) end |
#helmholtz_letter_name ⇒ Object (private)
221 222 223 224 225 |
# File 'lib/head_music/rudiment/pitch.rb', line 221 def helmholtz_letter_name return spelling.to_s.downcase if HeadMusic::Rudiment::Register.get(register).helmholtz_case == :lower spelling.to_s end |
#helmholtz_marks ⇒ Object (private)
227 228 229 |
# File 'lib/head_music/rudiment/pitch.rb', line 227 def helmholtz_marks HeadMusic::Rudiment::Register.get(register).helmholtz_marks end |
#helmholtz_notation ⇒ Object
112 113 114 |
# File 'lib/head_music/rudiment/pitch.rb', line 112 def helmholtz_notation helmholtz_letter_name + helmholtz_marks end |
#midi_note_number ⇒ Object Also known as: midi, number
97 98 99 |
# File 'lib/head_music/rudiment/pitch.rb', line 97 def midi_note_number (register + 1) * 12 + letter_name.pitch_class.to_i + alteration_semitones.to_i end |
#name ⇒ Object
93 94 95 |
# File 'lib/head_music/rudiment/pitch.rb', line 93 def name [spelling, register].join end |
#natural ⇒ Object
116 117 118 |
# File 'lib/head_music/rudiment/pitch.rb', line 116 def natural HeadMusic::Rudiment::Pitch.get(to_s.gsub(HeadMusic::Rudiment::Alteration.matcher, "")) end |
#natural_steps(num_steps) ⇒ Object
157 158 159 |
# File 'lib/head_music/rudiment/pitch.rb', line 157 def natural_steps(num_steps) HeadMusic::Rudiment::Pitch.get([target_letter_name(num_steps), register + octaves_delta(num_steps)].join) end |
#octave_adjustment_to(other) ⇒ Object (private)
178 179 180 |
# File 'lib/head_music/rudiment/pitch.rb', line 178 def octave_adjustment_to(other) (pitch_class_above?(other) ? 1 : 0) end |
#octave_changes_to(other) ⇒ Object (private)
174 175 176 |
# File 'lib/head_music/rudiment/pitch.rb', line 174 def octave_changes_to(other) other.register - register - octave_adjustment_to(other) end |
#octave_equivalence ⇒ Object (private)
190 191 192 |
# File 'lib/head_music/rudiment/pitch.rb', line 190 def octave_equivalence @octave_equivalence ||= HeadMusic::Rudiment::Pitch::OctaveEquivalence.get(self) end |
#octaves_delta(num_steps) ⇒ Object (private)
198 199 200 201 202 203 204 205 206 |
# File 'lib/head_music/rudiment/pitch.rb', line 198 def octaves_delta(num_steps) octaves_delta = (num_steps.abs / 7) * ((num_steps >= 0) ? 1 : -1) if wrapped_down?(num_steps) octaves_delta -= 1 elsif wrapped_up?(num_steps) octaves_delta += 1 end octaves_delta end |
#pitch_class_above?(other) ⇒ Boolean (private)
182 183 184 |
# File 'lib/head_music/rudiment/pitch.rb', line 182 def pitch_class_above?(other) natural_pitch_class_number > other.natural_pitch_class_number end |
#scale(scale_type_name = nil) ⇒ Object
153 154 155 |
# File 'lib/head_music/rudiment/pitch.rb', line 153 def scale(scale_type_name = nil) HeadMusic::Rudiment::Scale.get(self, scale_type_name) end |
#steps_to(other) ⇒ Object
165 166 167 168 |
# File 'lib/head_music/rudiment/pitch.rb', line 165 def steps_to(other) other = HeadMusic::Rudiment::Pitch.get(other) letter_name_steps_to(other) + 7 * octave_changes_to(other) end |
#target_letter_name(num_steps) ⇒ Object (private)
216 217 218 219 |
# File 'lib/head_music/rudiment/pitch.rb', line 216 def target_letter_name(num_steps) @target_letter_name ||= {} @target_letter_name[num_steps] ||= letter_name.steps_up(num_steps) end |
#to_i ⇒ Object
108 109 110 |
# File 'lib/head_music/rudiment/pitch.rb', line 108 def to_i midi_note_number end |
#to_s ⇒ Object
104 105 106 |
# File 'lib/head_music/rudiment/pitch.rb', line 104 def to_s name end |
#tuning ⇒ Object (private)
194 195 196 |
# File 'lib/head_music/rudiment/pitch.rb', line 194 def tuning @tuning ||= HeadMusic::Rudiment::Tuning.new end |
#wrapped_down?(num_steps) ⇒ Boolean (private)
208 209 210 |
# File 'lib/head_music/rudiment/pitch.rb', line 208 def wrapped_down?(num_steps) num_steps.negative? && target_letter_name(num_steps).position > letter_name.position end |
#wrapped_up?(num_steps) ⇒ Boolean (private)
212 213 214 |
# File 'lib/head_music/rudiment/pitch.rb', line 212 def wrapped_up?(num_steps) num_steps.positive? && target_letter_name(num_steps).position < letter_name.position end |