lib/head_music/pitch.rb in head_music-0.5.3 vs lib/head_music/pitch.rb in head_music-0.5.4
- old
+ new
@@ -2,11 +2,11 @@
include Comparable
attr_reader :spelling
attr_reader :octave
- delegate :letter, :letter_cycle, to: :spelling
+ delegate :letter_name, :letter_name_cycle, to: :spelling
delegate :accidental, :sharp?, :flat?, to: :spelling
delegate :pitch_class, to: :spelling
delegate :semitones, to: :accidental, prefix: true, allow_nil: true
delegate :smallest_interval_to, to: :pitch_class
@@ -26,18 +26,18 @@
spelling = HeadMusic::Spelling.from_number(number)
octave = (number.to_i / 12) - 1
fetch_or_create(spelling, octave)
end
- def self.from_number_and_letter(number, letter)
- letter = HeadMusic::LetterName.get(letter)
- natural_letter_pitch = get(HeadMusic::LetterName.get(letter).pitch_class)
+ def self.from_number_and_letter(number, letter_name)
+ letter_name = HeadMusic::LetterName.get(letter_name)
+ natural_letter_pitch = get(HeadMusic::LetterName.get(letter_name).pitch_class)
natural_letter_pitch += 12 while (number - natural_letter_pitch.to_i).to_i >= 11
natural_letter_pitch = get(natural_letter_pitch)
accidental_interval = natural_letter_pitch.smallest_interval_to(HeadMusic::PitchClass.get(number))
accidental = HeadMusic::Accidental.for_interval(accidental_interval)
- spelling = HeadMusic::Spelling.fetch_or_create(letter, accidental)
+ spelling = HeadMusic::Spelling.fetch_or_create(letter_name, accidental)
fetch_or_create(spelling, natural_letter_pitch.octave)
end
def self.fetch_or_create(spelling, octave)
@pitches ||= {}
@@ -55,11 +55,11 @@
def name
[spelling, octave].join
end
def midi_note_number
- (octave + 1) * 12 + letter.pitch_class.to_i + accidental_semitones.to_i
+ (octave + 1) * 12 + letter_name.pitch_class.to_i + accidental_semitones.to_i
end
alias_method :midi, :midi_note_number
alias_method :number, :midi_note_number
@@ -69,10 +69,14 @@
def to_i
midi_note_number
end
+ def natural
+ HeadMusic::Pitch.get(self.to_s.gsub(/[#b]/, ''))
+ end
+
def enharmonic?(other)
self.midi_note_number == other.midi_note_number
end
def +(value)
@@ -97,9 +101,21 @@
self.midi_note_number <=> other.midi_note_number
end
def scale(scale_type_name = nil)
HeadMusic::Scale.get(self, scale_type_name)
+ end
+
+ def natural_steps(num_steps)
+ target_letter_name = self.letter_name.steps(num_steps)
+ direction = num_steps >= 0 ? 1 : -1
+ octaves_delta = (num_steps.abs / 7) * direction
+ if num_steps < 0 && target_letter_name.position > letter_name.position
+ octaves_delta -= 1
+ elsif num_steps > 0 && target_letter_name.position < letter_name.position
+ octaves_delta += 1
+ end
+ HeadMusic::Pitch.get([target_letter_name, octave + octaves_delta].join)
end
private_class_method :new
end