head_music 0.3.0 → 0.3.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/letter.rb +8 -0
- data/lib/head_music/pitch.rb +5 -1
- data/lib/head_music/scale.rb +44 -22
- data/lib/head_music/spelling.rb +6 -0
- 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: 607c84eac4fe859f29c47a023d57f923b7d3d9dc
|
4
|
+
data.tar.gz: 6f2c73ba4b7ecfd7c5897668a270070f1082d3a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acb22d69a21f890b57e08e8a4a113ef491388222a33f3e0bf3ec1750673f2caaddd6928c5047023ef1d5bbe3a71f2f665adc23b2e934f4c0e252f7fad269d7c1
|
7
|
+
data.tar.gz: aeb7849fe4c6eb607804ebf6d3155c67f04dd477dcc412612dea0fd5929631859ea4f38992423599137659b338c3b3c6e6feb8a9bf40c5388b0d0b60bb0c7102
|
data/lib/head_music/letter.rb
CHANGED
data/lib/head_music/pitch.rb
CHANGED
@@ -4,7 +4,7 @@ class HeadMusic::Pitch
|
|
4
4
|
attr_reader :spelling
|
5
5
|
attr_reader :octave
|
6
6
|
|
7
|
-
delegate :letter, to: :spelling
|
7
|
+
delegate :letter, :letter_cycle, to: :spelling
|
8
8
|
delegate :accidental, :sharp?, :flat?, to: :spelling
|
9
9
|
delegate :pitch_class, to: :spelling
|
10
10
|
|
@@ -88,5 +88,9 @@ class HeadMusic::Pitch
|
|
88
88
|
self.midi_note_number <=> other.midi_note_number
|
89
89
|
end
|
90
90
|
|
91
|
+
def scale(scale_type_name = nil)
|
92
|
+
HeadMusic::Scale.get(self, scale_type_name)
|
93
|
+
end
|
94
|
+
|
91
95
|
private_class_method :new
|
92
96
|
end
|
data/lib/head_music/scale.rb
CHANGED
@@ -17,31 +17,14 @@ class HeadMusic::Scale
|
|
17
17
|
|
18
18
|
def pitches
|
19
19
|
@pitches ||= begin
|
20
|
-
|
21
|
-
letters_cycle = HeadMusic::Letter::NAMES
|
22
|
-
letters_cycle = letters_cycle.rotate while letters_cycle.first != root_pitch.letter.to_s
|
20
|
+
letter_cycle = root_pitch.letter_cycle
|
23
21
|
semitones_from_root = 0
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
semitones_from_root += semitones
|
29
|
-
pitch_number = root_pitch.pitch_class.to_i + semitones_from_root
|
30
|
-
if scale_type.intervals.length == 7
|
31
|
-
current_letter = letters_cycle[(i + 1) % 7]
|
32
|
-
elsif scale_type.intervals.length < 7 && scale_type.parent
|
33
|
-
current_letter = parent_scale_pitches.detect { |parent_scale_pitches|
|
34
|
-
parent_scale_pitches.pitch_class == (root_pitch + semitones_from_root).to_i % 12
|
35
|
-
}.letter
|
36
|
-
elsif root_pitch.flat?
|
37
|
-
current_letter = HeadMusic::PitchClass::FLAT_SPELLINGS[pitch_number % 12]
|
38
|
-
else
|
39
|
-
current_letter = HeadMusic::PitchClass::SHARP_SPELLINGS[pitch_number % 12]
|
22
|
+
[root_pitch].tap do |pitches|
|
23
|
+
scale_type.intervals.each_with_index do |semitones, i|
|
24
|
+
semitones_from_root += semitones
|
25
|
+
pitches << pitch_for_step(i+1, semitones_from_root)
|
40
26
|
end
|
41
|
-
pitch = HeadMusic::Pitch.from_number_and_letter(pitch_number, current_letter)
|
42
|
-
pitches << pitch
|
43
27
|
end
|
44
|
-
pitches
|
45
28
|
end
|
46
29
|
end
|
47
30
|
|
@@ -65,4 +48,43 @@ class HeadMusic::Scale
|
|
65
48
|
end
|
66
49
|
spellings
|
67
50
|
end
|
51
|
+
|
52
|
+
def letter_cycle
|
53
|
+
@letter_cycle ||= root_pitch.letter_cycle
|
54
|
+
end
|
55
|
+
|
56
|
+
def root_pitch_class
|
57
|
+
@root_pitch_class ||= root_pitch.pitch_class
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def parent_scale_pitches
|
63
|
+
HeadMusic::Scale.get(root_pitch, scale_type.parent_name).pitches if scale_type.parent
|
64
|
+
end
|
65
|
+
|
66
|
+
def parent_scale_pitch_for(semitones_from_root)
|
67
|
+
parent_scale_pitches.detect { |parent_scale_pitch|
|
68
|
+
parent_scale_pitch.pitch_class == (root_pitch + semitones_from_root).to_i % 12
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def letter_for_step(step, semitones_from_root)
|
73
|
+
pitch_class_number = (root_pitch.pitch_class.to_i + semitones_from_root) % 12
|
74
|
+
if scale_type.intervals.length == 7
|
75
|
+
letter_cycle[step % 7]
|
76
|
+
elsif scale_type.intervals.length < 7 && parent_scale_pitches
|
77
|
+
parent_scale_pitch_for(semitones_from_root).letter
|
78
|
+
elsif root_pitch.flat?
|
79
|
+
HeadMusic::PitchClass::FLAT_SPELLINGS[pitch_class_number]
|
80
|
+
else
|
81
|
+
HeadMusic::PitchClass::SHARP_SPELLINGS[pitch_class_number]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def pitch_for_step(step, semitones_from_root)
|
86
|
+
pitch_number = root_pitch_class.to_i + semitones_from_root
|
87
|
+
letter = letter_for_step(step, semitones_from_root)
|
88
|
+
HeadMusic::Pitch.from_number_and_letter(pitch_number, letter)
|
89
|
+
end
|
68
90
|
end
|
data/lib/head_music/spelling.rb
CHANGED
@@ -8,6 +8,8 @@ class HeadMusic::Spelling
|
|
8
8
|
attr_reader :accidental
|
9
9
|
|
10
10
|
delegate :number, to: :pitch_class, prefix: true
|
11
|
+
delegate :to_i, to: :pitch_class_number
|
12
|
+
delegate :cycle, to: :letter, prefix: true
|
11
13
|
|
12
14
|
def self.get(identifier)
|
13
15
|
from_name(identifier) || from_number(identifier)
|
@@ -75,5 +77,9 @@ class HeadMusic::Spelling
|
|
75
77
|
to_s == value.to_s
|
76
78
|
end
|
77
79
|
|
80
|
+
def scale(scale_type_name = nil)
|
81
|
+
HeadMusic::Scale.get(self, scale_type_name)
|
82
|
+
end
|
83
|
+
|
78
84
|
private_class_method :new
|
79
85
|
end
|
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.3.
|
4
|
+
version: 0.3.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-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|