Sha256: bd5293a215ba22b581fa45b2b6e36f41a5a54478caa4cbc547d487802d55ecc0
Contents?: true
Size: 1.95 KB
Versions: 5
Compression:
Stored size: 1.95 KB
Contents
# frozen_string_literal: true module Coltrane # Describes a musical note, independent of octave (that'd be pitch) class Note include Multiton attr_reader :name, :number alias id number alias to_s name NOTES = { 'C' => 0, 'C#' => 1, 'Db' => 1, 'D' => 2, 'D#' => 3, 'Eb' => 3, 'E' => 4, 'F' => 5, 'F#' => 6, 'Gb' => 6, 'G' => 7, 'G#' => 8, 'Ab' => 8, 'A' => 9, 'A#' => 10, 'Bb' => 10, 'B' => 11 }.freeze def initialize(name) @name = name @number = NOTES[name] end private_class_method :new def self.[](arg) name = case arg when Note then return arg when String then find_note(arg) when Numeric then NOTES.key(arg % 12) else raise InvalidNoteError, "Wrong type: #{arg.class}" end new(name) || (raise InvalidNoteError, arg.to_s) end def self.all %w[C C# D D# E F F# G G# A A# B].map { |n| Note[n] } end def self.find_note(str) NOTES.each_key { |k, _v| return k if str.casecmp?(k) } nil end def pretty_name @name.tr('b', "\u266D").tr('#', "\u266F") end alias to_s name def accident? [1, 3, 6, 8, 10].include?(number) end def +(other) case other when Interval then Note[number + other.semitones] when Numeric then Note[number + other] when Note then Chord.new(number + other.number) end end def -(other) case other when Numeric then Note[number - other] when Interval then Note[number - other.semitones] when Note then Interval[other.number - number] end end def interval_to(note_name) Note[note_name] - self end def enharmonic?(other) case other when String then number == Note[other].number when Note then number == other.number end end end end
Version data entries
5 entries across 5 versions & 1 rubygems
Version | Path |
---|---|
coltrane-1.2.4 | lib/coltrane/note.rb |
coltrane-1.2.3 | lib/coltrane/note.rb |
coltrane-1.2.2 | lib/coltrane/note.rb |
coltrane-1.2.1 | lib/coltrane/note.rb |
coltrane-1.2.0 | lib/coltrane/note.rb |