head_music 0.19.2 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|