head_music 0.3.0 → 0.3.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/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
|