Sha256: c132939e54c7116e5e4231baad0e3345b84e3ccd4aafda96ad9a148233372af5

Contents?: true

Size: 1.62 KB

Versions: 1

Compression:

Stored size: 1.62 KB

Contents

class HeadMusic::KeySignature
  attr_reader :tonic_spelling
  attr_reader :scale_type
  attr_reader :scale

  SHARPS = %w{F♯ C♯ G♯ D♯ A♯ E♯ B♯}
  FLATS = %w{B♭ E♭ A♭ D♭ G♭ C♭ F♭}

  def self.default
    @default ||= new('C', :major)
  end

  def self.get(identifier)
    return identifier if identifier.is_a?(HeadMusic::KeySignature)
    @key_signatures ||= {}
    tonic_spelling, scale_type_name = identifier.strip.split(/\s/)
    hash_key = HeadMusic::Utilities::HashKey.for(identifier.gsub(/#|♯/, 'sharp').gsub(/b|♭/, 'flat'))
    @key_signatures[hash_key] ||= new(tonic_spelling, scale_type_name)
  end

  delegate :pitch_class, to: :tonic_spelling, prefix: :tonic
  delegate :to_s, to: :name
  delegate :pitches, to: :scale

  def initialize(tonic_spelling, scale_type = nil)
    @tonic_spelling = HeadMusic::Spelling.get(tonic_spelling)
    @scale_type = HeadMusic::ScaleType.get(scale_type) if scale_type
    @scale_type ||= HeadMusic::ScaleType.default
    @scale_type = @scale_type.parent || @scale_type
    @scale = HeadMusic::Scale.get(@tonic_spelling, @scale_type)
  end

  def spellings
    pitches.map(&:spelling).uniq
  end

  def sharps
    spellings.select(&:sharp?).sort_by { |sharp| SHARPS.index(sharp.to_s) }
  end

  def flats
    spellings.select(&:flat?).sort_by { |flat| FLATS.index(flat.to_s) }
  end

  def num_sharps
    sharps.length
  end

  def num_flats
    flats.length
  end

  def sharps_or_flats
    flats.length > 0 ? flats : sharps
  end

  def name
    [tonic_spelling, scale_type].join(' ')
  end

  def ==(other)
    self.sharps_or_flats == self.class.get(other).sharps_or_flats
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
head_music-0.17.0 lib/head_music/key_signature.rb