head_music 0.19.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/lib/head_music/clef.rb +2 -2
- data/lib/head_music/key_signature.rb +47 -1
- data/lib/head_music/pitch.rb +1 -1
- data/lib/head_music/pitch_class.rb +1 -1
- data/lib/head_music/scale.rb +3 -2
- data/lib/head_music/spelling.rb +8 -2
- data/lib/head_music/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84558801b5df822669de2d7be0b1316dc711511a
|
4
|
+
data.tar.gz: c246dbb35d11e8b7815d56a6535420e00096c791
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 851820181797720920c79212516349316722dac6a4cd7889f917d2659543dbba5a39f7fce51ac8e5ed08302a1d51d7daa820e93f121bc8d3c681f1321441230e
|
7
|
+
data.tar.gz: ec6881d59cd432e3c392eeafcba2a34edc1c9d51f3842bb0832641546a86c3656c381ac0226c9865152532696e36e16644e59d7b3e54554eec6e9978c25d8c64
|
data/.rubocop.yml
CHANGED
data/lib/head_music/clef.rb
CHANGED
@@ -7,7 +7,7 @@ class HeadMusic::Clef
|
|
7
7
|
CLEFS = [
|
8
8
|
{ pitch: 'G4', line: 2, names: ['treble', 'G-clef'], modern: true },
|
9
9
|
{ pitch: 'G4', line: 1, names: ['French', 'French violin'] },
|
10
|
-
{ pitch: 'G3', line: 2, names: ['tenor'], modern: true },
|
10
|
+
{ pitch: 'G3', line: 2, names: ['choral tenor', 'tenor'], modern: true },
|
11
11
|
|
12
12
|
{ pitch: 'F3', line: 3, names: ['baritone'] },
|
13
13
|
{ pitch: 'F3', line: 4, names: ['bass', 'F-clef'], modern: true },
|
@@ -15,7 +15,7 @@ class HeadMusic::Clef
|
|
15
15
|
|
16
16
|
{ pitch: 'C4', line: 1, names: ['soprano'] },
|
17
17
|
{ pitch: 'C4', line: 2, names: ['mezzo-soprano'] },
|
18
|
-
{ pitch: 'C4', line: 3, names: ['alto', 'viola', 'counter-tenor', 'countertenor'], modern: true },
|
18
|
+
{ pitch: 'C4', line: 3, names: ['alto', 'viola', 'counter-tenor', 'countertenor', 'C-clef'], modern: true },
|
19
19
|
{ pitch: 'C4', line: 4, names: ['tenor'], modern: true },
|
20
20
|
{ pitch: 'C4', line: 5, names: ['baritone'] },
|
21
21
|
|
@@ -17,7 +17,7 @@ class HeadMusic::KeySignature
|
|
17
17
|
return identifier if identifier.is_a?(HeadMusic::KeySignature)
|
18
18
|
@key_signatures ||= {}
|
19
19
|
tonic_spelling, scale_type_name = identifier.strip.split(/\s/)
|
20
|
-
hash_key = HeadMusic::Utilities::HashKey.for(identifier.gsub(/#|♯/, 'sharp').gsub(/b
|
20
|
+
hash_key = HeadMusic::Utilities::HashKey.for(identifier.gsub(/#|♯/, ' sharp').gsub(/(\w)[b♭]/, '\\1 flat'))
|
21
21
|
@key_signatures[hash_key] ||= new(tonic_spelling, scale_type_name)
|
22
22
|
end
|
23
23
|
|
@@ -67,4 +67,50 @@ class HeadMusic::KeySignature
|
|
67
67
|
def ==(other)
|
68
68
|
signs == self.class.get(other).signs
|
69
69
|
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
if sharps.any?
|
73
|
+
sharps.length == 1 ? '1 sharp' : "#{sharps.length} sharps"
|
74
|
+
elsif flats.any?
|
75
|
+
flats.length == 1 ? '1 flat' : "#{flats.length} flats"
|
76
|
+
else
|
77
|
+
'no sharps or flats'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def enharmonic_equivalent?(other)
|
82
|
+
other = KeySignature.get(other)
|
83
|
+
enharmonic_equivalence.equivalent?(other)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def enharmonic_equivalence
|
89
|
+
@enharmonic_equivalence ||= EnharmonicEquivalence.get(self)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Key signatures are enharmonic when all pitch classes in one are respellings of the pitch classes in the other.
|
93
|
+
class EnharmonicEquivalence
|
94
|
+
def self.get(key_signature)
|
95
|
+
key_signature = HeadMusic::KeySignature.get(key_signature)
|
96
|
+
@enharmonic_equivalences ||= {}
|
97
|
+
@enharmonic_equivalences[key_signature.to_s] ||= new(key_signature)
|
98
|
+
end
|
99
|
+
|
100
|
+
attr_reader :key_signature
|
101
|
+
|
102
|
+
def initialize(key_signature)
|
103
|
+
@key_signature = HeadMusic::KeySignature.get(key_signature)
|
104
|
+
end
|
105
|
+
|
106
|
+
def enharmonic_equivalent?(other)
|
107
|
+
other = HeadMusic::KeySignature.get(other)
|
108
|
+
(key_signature.signs | other.signs).map(&:to_s).uniq.length == 12
|
109
|
+
end
|
110
|
+
|
111
|
+
alias enharmonic? enharmonic_equivalent?
|
112
|
+
alias equivalent? enharmonic_equivalent?
|
113
|
+
|
114
|
+
private_class_method :new
|
115
|
+
end
|
70
116
|
end
|
data/lib/head_music/pitch.rb
CHANGED
@@ -171,7 +171,7 @@ class HeadMusic::Pitch
|
|
171
171
|
@target_letter_name[num_steps] ||= letter_name.steps(num_steps)
|
172
172
|
end
|
173
173
|
|
174
|
-
#
|
174
|
+
# An enharmonic equivalent pitch is the same frequency spelled differently, such as D# and Eb.
|
175
175
|
class EnharmonicEquivalence
|
176
176
|
def self.get(pitch)
|
177
177
|
pitch = HeadMusic::Pitch.get(pitch)
|
data/lib/head_music/scale.rb
CHANGED
@@ -9,8 +9,9 @@ class HeadMusic::Scale
|
|
9
9
|
root_pitch = HeadMusic::Pitch.get(root_pitch)
|
10
10
|
scale_type = HeadMusic::ScaleType.get(scale_type || :major)
|
11
11
|
@scales ||= {}
|
12
|
-
|
13
|
-
|
12
|
+
hash_key = HeadMusic::Utilities::HashKey.for(
|
13
|
+
[root_pitch, scale_type].join(' ').gsub(/#|♯/, 'sharp').gsub(/(\w)[b♭]/, '\\1flat')
|
14
|
+
)
|
14
15
|
@scales[hash_key] ||= new(root_pitch, scale_type)
|
15
16
|
end
|
16
17
|
|
data/lib/head_music/spelling.rb
CHANGED
@@ -13,7 +13,7 @@ class HeadMusic::Spelling
|
|
13
13
|
delegate :number, to: :pitch_class, prefix: true
|
14
14
|
delegate :to_i, to: :pitch_class_number
|
15
15
|
delegate :cycle, to: :letter_name, prefix: true
|
16
|
-
delegate :enharmonic?, to: :
|
16
|
+
delegate :enharmonic?, to: :enharmonic_equivalence
|
17
17
|
|
18
18
|
def self.get(identifier)
|
19
19
|
return identifier if identifier.is_a?(HeadMusic::Spelling)
|
@@ -88,7 +88,13 @@ class HeadMusic::Spelling
|
|
88
88
|
|
89
89
|
private_class_method :new
|
90
90
|
|
91
|
-
|
91
|
+
private
|
92
|
+
|
93
|
+
def enharmonic_equivalence
|
94
|
+
@enharmonic_equivalence ||= EnharmonicEquivalence.get(self)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Enharmonic equivalence occurs when two spellings refer to the same pitch class, such as D# and Eb.
|
92
98
|
class EnharmonicEquivalence
|
93
99
|
def self.get(spelling)
|
94
100
|
spelling = HeadMusic::Spelling.get(spelling)
|
data/lib/head_music/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: head_music
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.20.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Head
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|