Class: HeadMusic::Rudiment::KeySignature

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

Overview

Represents a key signature (traditionally associated with a key) This class maintains backward compatibility while delegating to Key/Mode internally

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.



39
40
41
42
43
44
45
# File 'lib/head_music/rudiment/key_signature.rb', line 39

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

Instance Attribute Details

#scaleObject (readonly)

Returns the value of attribute scale.



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

def scale
  @scale
end

#scale_typeObject (readonly)

Returns the value of attribute scale_type.



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

def scale_type
  @scale_type
end

#tonic_spellingObject (readonly)

Returns the value of attribute tonic_spelling.



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

def tonic_spelling
  @tonic_spelling
end

Class Method Details

.defaultObject



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

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

.from_scale(scale) ⇒ Object



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

def self.from_scale(scale)
  # Find a key or mode that uses this scale
  tonic = scale.root_pitch.spelling
  scale_type = scale.scale_type
  new(tonic, scale_type)
end

.get(identifier) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/head_music/rudiment/key_signature.rb', line 14

def self.get(identifier)
  return identifier if identifier.is_a?(HeadMusic::Rudiment::KeySignature)

  if identifier.is_a?(String)
    tonic_spelling, scale_type_name = identifier.strip.split(/\s/)
    hash_key = HeadMusic::Utilities::HashKey.for(identifier)
    fetch_or_register(hash_key, tonic_spelling, scale_type_name)
  elsif identifier.is_a?(HeadMusic::Rudiment::DiatonicContext)
    identifier.key_signature
  end
end

Instance Method Details

#==(other) ⇒ Object



90
91
92
# File 'lib/head_music/rudiment/key_signature.rb', line 90

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

#alterationsObject Also known as: sharps_and_flats, accidentals



79
80
81
# File 'lib/head_music/rudiment/key_signature.rb', line 79

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

#altered_spellings(predicate, letter_name_order) ⇒ Object (private)



107
108
109
110
111
# File 'lib/head_music/rudiment/key_signature.rb', line 107

def altered_spellings(predicate, letter_name_order)
  spellings.select(&predicate).sort_by do |spelling|
    letter_name_order.index(spelling.letter_name.to_s)
  end
end

#double_flatsObject



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

def double_flats
  altered_spellings(:double_flat?, ORDERED_LETTER_NAMES_OF_FLATS)
end

#double_sharpsObject



55
56
57
# File 'lib/head_music/rudiment/key_signature.rb', line 55

def double_sharps
  altered_spellings(:double_sharp?, ORDERED_LETTER_NAMES_OF_SHARPS)
end

#enharmonic_equivalenceObject (private)



117
118
119
# File 'lib/head_music/rudiment/key_signature.rb', line 117

def enharmonic_equivalence
  @enharmonic_equivalence ||= HeadMusic::Rudiment::KeySignature::EnharmonicEquivalence.get(self)
end

#enharmonic_equivalent?(other) ⇒ Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/head_music/rudiment/key_signature.rb', line 101

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

#flatsObject



59
60
61
# File 'lib/head_music/rudiment/key_signature.rb', line 59

def flats
  altered_spellings(:flat?, ORDERED_LETTER_NAMES_OF_FLATS)
end

#nameObject



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

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

#num_alterationsObject



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

def num_alterations
  num_sharps + num_flats
end

#num_flatsObject



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

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

#num_sharpsObject



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

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

#pluralize(count, noun) ⇒ Object (private)



113
114
115
# File 'lib/head_music/rudiment/key_signature.rb', line 113

def pluralize(count, noun)
  (count == 1) ? "1 #{noun}" : "#{count} #{noun}s"
end

#sharpsObject



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

def sharps
  altered_spellings(:sharp?, ORDERED_LETTER_NAMES_OF_SHARPS)
end

#spellingsObject



47
48
49
# File 'lib/head_music/rudiment/key_signature.rb', line 47

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

#to_sObject



94
95
96
97
98
99
# File 'lib/head_music/rudiment/key_signature.rb', line 94

def to_s
  return pluralize(sharps.length, "sharp") if sharps.any?
  return pluralize(flats.length, "flat") if flats.any?

  "no sharps or flats"
end