class RBMusic::Note

Attributes

coord[RW]

Public Class Methods

from_latin(name) click to toggle source
# File lib/rb-music/note.rb, line 10
def self.from_latin(name)
  raise ArgumentError unless name.is_a?(String)

  note_parts = name.split(/(\d+)/)
  note_name = note_parts.first
  octave = note_parts.last.to_i

  unless NOTES.has_key?(note_name) && note_parts.size < 3
    raise ArgumentError
  end

  coordinate = [NOTES[note_name][0] + octave, NOTES[note_name][1]]

  coordinate[0] -= BASE_OFFSET[0]
  coordinate[1] -= BASE_OFFSET[1]

  Note.new(coordinate)
end
new(coord) click to toggle source
# File lib/rb-music/note.rb, line 6
def initialize(coord)
  self.coord = coord
end

Public Instance Methods

==(other) click to toggle source
# File lib/rb-music/note.rb, line 49
def ==(other)
  other.is_a?(Note) && other.latin == latin && other.octave == octave
end
accidental() click to toggle source
# File lib/rb-music/note.rb, line 33
def accidental
  @accidental ||= ((coord[1] + BASE_OFFSET[1]) / 7.0).round
end
add(that) click to toggle source
# File lib/rb-music/note.rb, line 70
def add(that)
  # if input is an array return an array
  if that.is_a?(Array)
    notes = that.map { |thing| add(thing) }
    return NoteSet.new(notes)
  end

  # if input is string/symbol try to parse it as interval
  if that.is_a?(String) || that.is_a?(Symbol)
    that = Interval.from_name(that)
  end

  Note.new([coord[0] + that.coord[0], coord[1] + that.coord[1]])
end
enharmonic?(other) click to toggle source
# File lib/rb-music/note.rb, line 53
def enharmonic?(other)
  raise ArgumentError unless other.is_a?(Note)

  other.frequency == frequency
end
enharmonically_equivalent_to?(other)
Alias for: enharmonic?
frequency() click to toggle source
# File lib/rb-music/note.rb, line 29
def frequency
  BASE_FREQ * (2.0 ** ((coord[0] * 1200 + coord[1] * 700.0) / 1200.0))
end
latin() click to toggle source
# File lib/rb-music/note.rb, line 42
def latin
  return @latin if @latin
  noteName = NOTE_NAMES[coord[1] + BASE_OFFSET[1] - accidental * 7 + 3]
  accidentalName = ACCIDENTALS[accidental + 2]
  @latin ||= noteName + accidentalName
end
octave() click to toggle source
# File lib/rb-music/note.rb, line 37
def octave
  # calculate octave of base note without accidentals
  @octave ||= coord[0] + BASE_OFFSET[0] + 4 * accidental + ((coord[1] + BASE_OFFSET[1] - 7 * accidental) / 2).floor
end
scale(name) click to toggle source
# File lib/rb-music/note.rb, line 60
def scale(name)
  notes = [add(:unison)]

  SCALES[name.to_sym].each do |interval_name|
    notes << add(Interval.from_name(interval_name))
  end

  notes << add(:octave)
end
subtract(that) click to toggle source
# File lib/rb-music/note.rb, line 85
def subtract(that)
  if that.is_a?(Array)
    notes = that.map { |thing| subtract(thing) }
    return NoteSet.new(notes)
  end

  # if input is string try to parse it as interval
  if that.is_a?(String) || that.is_a?(Symbol)
    that = Interval.from_name(that)
  end

  coordinate = [coord[0] - that.coord[0], coord[1] - that.coord[1]]

  # if input is another note return the difference as an Interval
  that.is_a?(Note) ? Interval.new(coordinate) : Note.new(coordinate)
end