Class: HeadMusic::KeySignature

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/key_signature.rb

Overview

Represents a key signature. In French, sharps and flats in the key signature are called “altérations”.

Defined Under Namespace

Classes: EnharmonicEquivalence

Constant Summary collapse

ORDERED_LETTER_NAMES_OF_SHARPS =
%w[F C G D A E B].freeze
ORDERED_LETTER_NAMES_OF_FLATS =
ORDERED_LETTER_NAMES_OF_SHARPS.reverse.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tonic_spelling, scale_type = nil) ⇒ KeySignature

Returns a new instance of KeySignature.



26
27
28
29
30
31
32
# File 'lib/head_music/key_signature.rb', line 26

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

Instance Attribute Details

#scaleObject (readonly)

Returns the value of attribute scale.



4
5
6
# File 'lib/head_music/key_signature.rb', line 4

def scale
  @scale
end

#scale_typeObject (readonly)

Returns the value of attribute scale_type.



4
5
6
# File 'lib/head_music/key_signature.rb', line 4

def scale_type
  @scale_type
end

#tonic_spellingObject (readonly)

Returns the value of attribute tonic_spelling.



4
5
6
# File 'lib/head_music/key_signature.rb', line 4

def tonic_spelling
  @tonic_spelling
end

Class Method Details

.defaultObject



9
10
11
# File 'lib/head_music/key_signature.rb', line 9

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

.get(identifier) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/head_music/key_signature.rb', line 13

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(/(\w)[b♭]/, '\\1 flat'))
  @key_signatures[hash_key] ||= new(tonic_spelling, scale_type_name)
end

Instance Method Details

#==(other) ⇒ Object



85
86
87
# File 'lib/head_music/key_signature.rb', line 85

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

#alterationsObject Also known as: sharps_and_flats, accidentals



74
75
76
# File 'lib/head_music/key_signature.rb', line 74

def alterations
  flats.any? ? (double_flats + flats) : (double_sharps + sharps)
end

#double_flatsObject



56
57
58
59
60
# File 'lib/head_music/key_signature.rb', line 56

def double_flats
  spellings.select(&:double_flat?).sort_by do |spelling|
    ORDERED_LETTER_NAMES_OF_FLATS.index(spelling.letter_name.to_s)
  end
end

#double_sharpsObject



44
45
46
47
48
# File 'lib/head_music/key_signature.rb', line 44

def double_sharps
  spellings.select(&:double_sharp?).sort_by do |spelling|
    ORDERED_LETTER_NAMES_OF_SHARPS.index(spelling.letter_name.to_s)
  end
end

#enharmonic_equivalent?(other) ⇒ Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/head_music/key_signature.rb', line 99

def enharmonic_equivalent?(other)
  enharmonic_equivalence.enharmonic_equivalent?(other)
end

#flatsObject



50
51
52
53
54
# File 'lib/head_music/key_signature.rb', line 50

def flats
  spellings.select(&:flat?).sort_by do |spelling|
    ORDERED_LETTER_NAMES_OF_FLATS.index(spelling.letter_name.to_s)
  end
end

#nameObject



81
82
83
# File 'lib/head_music/key_signature.rb', line 81

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

#num_alterationsObject



70
71
72
# File 'lib/head_music/key_signature.rb', line 70

def num_alterations
  num_sharps + num_flats
end

#num_flatsObject



66
67
68
# File 'lib/head_music/key_signature.rb', line 66

def num_flats
  flats.length + double_flats.length * 2
end

#num_sharpsObject



62
63
64
# File 'lib/head_music/key_signature.rb', line 62

def num_sharps
  sharps.length + double_sharps.length * 2
end

#sharpsObject



38
39
40
41
42
# File 'lib/head_music/key_signature.rb', line 38

def sharps
  spellings.select(&:sharp?).sort_by do |spelling|
    ORDERED_LETTER_NAMES_OF_SHARPS.index(spelling.letter_name.to_s)
  end
end

#spellingsObject



34
35
36
# File 'lib/head_music/key_signature.rb', line 34

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

#to_sObject



89
90
91
92
93
94
95
96
97
# File 'lib/head_music/key_signature.rb', line 89

def to_s
  if sharps.any?
    (sharps.length == 1) ? "1 sharp" : "#{sharps.length} sharps"
  elsif flats.any?
    (flats.length == 1) ? "1 flat" : "#{flats.length} flats"
  else
    "no sharps or flats"
  end
end