Sha256: 416efa1b535df7d32adf535dcfb842cc7805f8df023555b5a6a27e48c7669a3c
Contents?: true
Size: 1.66 KB
Versions: 1
Compression:
Stored size: 1.66 KB
Contents
# A Spelling is a pitch class with a letter and possibly an accidental class HeadMusic::Spelling MATCHER = /^\s*([A-G])([b#]*)(\-?\d+)?\s*$/ attr_reader :pitch_class attr_reader :letter attr_reader :accidental delegate :number, to: :pitch_class, prefix: true def self.get(identifier) @spellings ||= {} from_name(identifier) || from_number(identifier) end def self.match(string) string.to_s.match(MATCHER) end def self.from_name(name) if match(name) letter_name, accidental_string, _octave = match(name).captures letter = HeadMusic::Letter.get(letter_name) return nil unless letter accidental = HeadMusic::Accidental.get(accidental_string) fetch_or_create(letter, accidental) end end def self.from_number(number) return nil unless number == number.to_i pitch_class_number = number.to_i % 12 letter = HeadMusic::Letter.from_pitch_class(pitch_class_number) accidental = HeadMusic::Accidental.for_interval(pitch_class_number - letter.pitch_class.to_i) fetch_or_create(letter, accidental) end def self.fetch_or_create(letter, accidental) key = [letter, accidental].join @spellings[key] ||= new(letter, accidental) end def initialize(letter, accidental = nil) @letter = HeadMusic::Letter.get(letter.to_s) @accidental = HeadMusic::Accidental.get(accidental.to_s) accidental_semitones = @accidental ? @accidental.semitones : 0 @pitch_class = HeadMusic::PitchClass.get(letter.pitch_class + accidental_semitones) end def name [letter, accidental].join end def to_s name end def ==(value) to_s == value.to_s end private_class_method :new end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
head_music-0.1.5 | lib/head_music/spelling.rb |