Sha256: 3ee80a4839f24df04a8da1a91516ed9e6a78b8eb3ec87272822cb24e9c64f5cf

Contents?: true

Size: 1.62 KB

Versions: 9

Compression:

Stored size: 1.62 KB

Contents

# frozen_string_literal: true

# The register is a numeric octave identifier used in scientific pitch notation.
#
# A pitch is a spelling plus a register. For example, C4 is middle C and C5 is the C one octave higher.
# The number changes between the letter names B and C regardless of sharps and flats,
# so as an extreme example, Cb5 is actually a semitone below B#4.
class HeadMusic::Register
  include Comparable

  DEFAULT = 4

  def self.get(identifier)
    from_number(identifier) || from_name(identifier) || default
  end

  def self.from_number(identifier)
    return nil unless identifier.to_s == identifier.to_i.to_s
    return nil unless (-2..12).cover?(identifier.to_i)

    @registers ||= {}
    @registers[identifier.to_i] ||= new(identifier.to_i)
  end

  def self.from_name(string)
    return unless string.to_s.match?(HeadMusic::Spelling::MATCHER)

    _letter, _sign, register_string = string.to_s.match(HeadMusic::Spelling::MATCHER).captures
    @registers ||= {}
    @registers[register_string.to_i] ||= new(register_string.to_i) if register_string
  end

  def self.default
    @registers[DEFAULT] ||= new(DEFAULT)
  end

  attr_reader :number

  delegate :to_i, :to_s, to: :number

  def initialize(number)
    @number = number
  end

  def <=>(other)
    to_i <=> other.to_i
  end

  def +(other)
    self.class.get(to_i + other.to_i)
  end

  def -(other)
    self.class.get(to_i - other.to_i)
  end

  def helmholtz_case
    return :upper if number < 3

    :lower
  end

  def helmholtz_marks
    return "," * (2 - number) if number < 2
    return "'" * (number - 3) if number > 3

    ""
  end

  private_class_method :new
end

Version data entries

9 entries across 9 versions & 1 rubygems

Version Path
head_music-4.0.1 lib/head_music/register.rb
head_music-4.0.0 lib/head_music/register.rb
head_music-3.0.1 lib/head_music/register.rb
head_music-3.0.0 lib/head_music/register.rb
head_music-2.0.1 lib/head_music/register.rb
head_music-2.0.0 lib/head_music/register.rb
head_music-1.0.0 lib/head_music/register.rb
head_music-0.29.0 lib/head_music/register.rb
head_music-0.28.0 lib/head_music/register.rb