head_music 0.1.0 → 0.1.1
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/lib/head_music/accidental.rb +6 -2
- data/lib/head_music/circle.rb +4 -0
- data/lib/head_music/key_signature.rb +21 -2
- data/lib/head_music/letter.rb +10 -10
- data/lib/head_music/pitch_class.rb +2 -0
- data/lib/head_music/spelling.rb +4 -6
- 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: 161df8f1795f4e70adcdc8d7298cdbf1dd2af984
|
4
|
+
data.tar.gz: 621aac81ec102840a879186df55eb9aeed040b8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 947631876b0c2c74a807515783a22783836838d75d2a21eab2f66e8863a5b25d5849e92874885007a99dd0596acacb5c795ad0ffc153d47cac616322ec566fef
|
7
|
+
data.tar.gz: 9ff5a2e01209ccd7f515d9d152f49159a0f18518f7bfb17e289609cb519395b96e7ae4399dd321346b3b971f05ae970d2095fb4556ca1bb666b36d268f46fe2c
|
@@ -8,9 +8,13 @@ class HeadMusic::Accidental
|
|
8
8
|
|
9
9
|
attr_reader :string
|
10
10
|
|
11
|
-
def self.get(
|
11
|
+
def self.get(identifier)
|
12
12
|
@accidentals ||= {}
|
13
|
-
@accidentals[
|
13
|
+
@accidentals[identifier] ||= for_symbol(identifier) || for_interval(identifier)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.for_symbol(identifier)
|
17
|
+
new(identifier) if ACCIDENTAL_SEMITONES.keys.include?(identifier)
|
14
18
|
end
|
15
19
|
|
16
20
|
def self.for_interval(semitones)
|
data/lib/head_music/circle.rb
CHANGED
@@ -21,11 +21,17 @@ class HeadMusic::KeySignature
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def num_sharps
|
24
|
-
(HeadMusic::Circle.of_fifths.
|
24
|
+
(HeadMusic::Circle.of_fifths.index(tonic_pitch_class) - scale_type_adjustment) % 12
|
25
25
|
end
|
26
26
|
|
27
27
|
def num_flats
|
28
|
-
(HeadMusic::Circle.of_fourths.
|
28
|
+
(HeadMusic::Circle.of_fourths.index(tonic_pitch_class) + scale_type_adjustment) % 12
|
29
|
+
end
|
30
|
+
|
31
|
+
def sharps_or_flats
|
32
|
+
return sharps if @tonic_spelling.to_s =~ /#/
|
33
|
+
return flats if @tonic_spelling.to_s =~ /b/
|
34
|
+
num_sharps <= num_flats ? sharps : flats
|
29
35
|
end
|
30
36
|
|
31
37
|
private
|
@@ -33,4 +39,17 @@ class HeadMusic::KeySignature
|
|
33
39
|
def scale_type_adjustment
|
34
40
|
scale_type == :minor ? 3 : 0
|
35
41
|
end
|
42
|
+
|
43
|
+
def major?
|
44
|
+
@scale_type.to_sym == :major
|
45
|
+
end
|
46
|
+
|
47
|
+
def minor?
|
48
|
+
@scale_type.to_sym == :minor
|
49
|
+
end
|
50
|
+
|
51
|
+
def relative_major_pitch_class
|
52
|
+
return tonic_pitch_class if major?
|
53
|
+
return (tonic_pitch_class.to_i + 3) % 12 if minor?
|
54
|
+
end
|
36
55
|
end
|
data/lib/head_music/letter.rb
CHANGED
@@ -17,23 +17,23 @@ class HeadMusic::Letter
|
|
17
17
|
NAMES.map { |letter_name| get(letter_name)}
|
18
18
|
end
|
19
19
|
|
20
|
-
def self.get(
|
20
|
+
def self.get(identifier)
|
21
21
|
@letters ||= {}
|
22
|
+
@letters[identifier] ||= from_name(identifier) || from_pitch_class(identifier)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_name(name)
|
22
26
|
name = name.to_s.first.upcase
|
23
|
-
if NAMES.include?(name)
|
24
|
-
@letters[name] ||= new(name)
|
25
|
-
end
|
27
|
+
new(name) if NAMES.include?(name)
|
26
28
|
end
|
27
29
|
|
28
30
|
def self.from_pitch_class(pitch_class)
|
29
31
|
@letters ||= {}
|
32
|
+
return nil if pitch_class.to_s == pitch_class
|
30
33
|
pitch_class = pitch_class.to_i % 12
|
31
|
-
name =
|
32
|
-
|
33
|
-
|
34
|
-
if NAMES.include?(name)
|
35
|
-
@letters[name] ||= new(name)
|
36
|
-
end
|
34
|
+
name = NAMES.detect { |name| pitch_class == NATURAL_PITCH_CLASS_NUMBERS[name] }
|
35
|
+
name ||= HeadMusic::PitchClass::PREFERRED_SPELLINGS[pitch_class].first
|
36
|
+
return new(name) if NAMES.include?(name)
|
37
37
|
end
|
38
38
|
|
39
39
|
attr_reader :name
|
data/lib/head_music/spelling.rb
CHANGED
@@ -5,7 +5,7 @@ class HeadMusic::Spelling
|
|
5
5
|
attr_reader :accidental
|
6
6
|
attr_reader :pitch_class
|
7
7
|
|
8
|
-
SPELLING_MATCHER =
|
8
|
+
SPELLING_MATCHER = /^\s*([A-G])([b#]*)(\-?\d+)?\s*$/
|
9
9
|
|
10
10
|
def self.get(identifier)
|
11
11
|
@spellings ||= {}
|
@@ -14,19 +14,17 @@ class HeadMusic::Spelling
|
|
14
14
|
|
15
15
|
def self.from_name(name)
|
16
16
|
return nil unless name == name.to_s
|
17
|
-
match = name.match(SPELLING_MATCHER)
|
17
|
+
match = name.to_s.match(SPELLING_MATCHER)
|
18
18
|
if match
|
19
19
|
letter_name, accidental_string, _octave = match.captures
|
20
20
|
letter = HeadMusic::Letter.get(letter_name)
|
21
|
-
if letter
|
22
|
-
return new(letter, HeadMusic::Accidental.get(accidental_string))
|
23
|
-
end
|
21
|
+
new(letter, HeadMusic::Accidental.get(accidental_string)) if letter
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
25
|
def self.from_number(number)
|
28
26
|
return nil unless number == number.to_i
|
29
|
-
pitch_class_number = number % 12
|
27
|
+
pitch_class_number = number.to_i % 12
|
30
28
|
letter = HeadMusic::Letter.from_pitch_class(pitch_class_number)
|
31
29
|
if letter.pitch_class != pitch_class_number
|
32
30
|
accidental = HeadMusic::Accidental.for_interval(pitch_class_number - letter.pitch_class.to_i)
|
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.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Head
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|