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