head_music 0.14.5 → 0.14.7
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/functional_interval.rb +8 -4
- data/lib/head_music/note.rb +4 -0
- data/lib/head_music/placement.rb +4 -0
- data/lib/head_music/scale_degree.rb +1 -1
- data/lib/head_music/style/annotation.rb +9 -1
- data/lib/head_music/style/annotations/consonant_climax.rb +1 -5
- data/lib/head_music/style/annotations/start_on_perfect_consonance.rb +1 -1
- data/lib/head_music/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ee796cb3bb39a7c883ef5fecff41ead56379c3a
|
4
|
+
data.tar.gz: 35bc35b0515ea35214ee16b8a6375db44ad87ed2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f95982b86a3367e79908aba86aa4b718d57fe29be9ddd101bd5cf718be0d12d34b746050e57286258e4f2894188e0741615f48af96b90fba974ce5f8c4bd9ee7
|
7
|
+
data.tar.gz: def4f16467102b4d9b8e3cf8a1dbdd8e36af1d3e76a8c5410d9ac331ece35e06083fbddd6543cf8cab7f7f19b11183d06374ea5f915f49ad090e20101fd57f6a
|
@@ -191,8 +191,12 @@ class HeadMusic::FunctionalInterval
|
|
191
191
|
self.semitones <=> other.semitones
|
192
192
|
end
|
193
193
|
|
194
|
-
NUMBER_NAMES.each do |
|
195
|
-
define_method(:"#{
|
194
|
+
NUMBER_NAMES.each do |interval_name|
|
195
|
+
define_method(:"#{interval_name}?") { number_name == interval_name }
|
196
|
+
end
|
197
|
+
|
198
|
+
NUMBER_NAMES.first(8).each do |method_name|
|
199
|
+
define_method(:"#{method_name}_or_compound?") { simple_number_name == method_name }
|
196
200
|
end
|
197
201
|
|
198
202
|
private
|
@@ -202,10 +206,10 @@ class HeadMusic::FunctionalInterval
|
|
202
206
|
end
|
203
207
|
|
204
208
|
def consonance_for_major_and_minor
|
205
|
-
HeadMusic::Consonance.get((
|
209
|
+
HeadMusic::Consonance.get((third_or_compound? || sixth_or_compound?) ? :imperfect : :dissonant) if (major? || minor?)
|
206
210
|
end
|
207
211
|
|
208
212
|
def dissonant_fourth?(style = :standard_practice)
|
209
|
-
|
213
|
+
fourth_or_compound? && style == :two_part_harmony
|
210
214
|
end
|
211
215
|
end
|
data/lib/head_music/note.rb
CHANGED
@@ -15,6 +15,10 @@ class HeadMusic::Note
|
|
15
15
|
@placement ||= HeadMusic::Placement.new(voice, position, rhythmic_value, pitch)
|
16
16
|
end
|
17
17
|
|
18
|
+
def to_s
|
19
|
+
"#{pitch} at #{position}"
|
20
|
+
end
|
21
|
+
|
18
22
|
def method_missing(method_name, *args, &block)
|
19
23
|
placement.send(method_name, *args, &block)
|
20
24
|
end
|
data/lib/head_music/placement.rb
CHANGED
@@ -31,6 +31,10 @@ class HeadMusic::Placement
|
|
31
31
|
(other_placement.position <= position && other_placement.next_position >= next_position)
|
32
32
|
end
|
33
33
|
|
34
|
+
def to_s
|
35
|
+
"#{pitch ? pitch : 'rest'} at #{position}"
|
36
|
+
end
|
37
|
+
|
34
38
|
private
|
35
39
|
|
36
40
|
def ensure_attributes(voice, position, rhythmic_value, pitch)
|
@@ -21,7 +21,7 @@ class HeadMusic::ScaleDegree
|
|
21
21
|
scale_degree_usual_spelling.accidental
|
22
22
|
accidental_semitones = spelling.accidental && spelling.accidental.semitones || 0
|
23
23
|
usual_accidental_semitones = scale_degree_usual_spelling.accidental && scale_degree_usual_spelling.accidental.semitones || 0
|
24
|
-
Accidental.for_interval(accidental_semitones - usual_accidental_semitones)
|
24
|
+
HeadMusic::Accidental.for_interval(accidental_semitones - usual_accidental_semitones)
|
25
25
|
end
|
26
26
|
|
27
27
|
def to_s
|
@@ -84,7 +84,11 @@ class HeadMusic::Style::Annotation
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def functional_interval_from_tonic(note)
|
87
|
-
|
87
|
+
tonic_to_use = tonic_pitch
|
88
|
+
while tonic_to_use > note.pitch
|
89
|
+
tonic_to_use -= Interval.named(:perfect_octave)
|
90
|
+
end
|
91
|
+
HeadMusic::FunctionalInterval.new(tonic_to_use, note.pitch)
|
88
92
|
end
|
89
93
|
|
90
94
|
def bass_voice?
|
@@ -128,4 +132,8 @@ class HeadMusic::Style::Annotation
|
|
128
132
|
def unsorted_lower_voices
|
129
133
|
other_voices.select { |part| part.lowest_pitch && lowest_pitch && part.lowest_pitch < lowest_pitch }
|
130
134
|
end
|
135
|
+
|
136
|
+
def tonic_pitch
|
137
|
+
@tonic_pitch ||= HeadMusic::Pitch.get(tonic_spelling)
|
138
|
+
end
|
131
139
|
end
|
@@ -24,10 +24,6 @@ class HeadMusic::Style::Annotations::ConsonantClimax < HeadMusic::Style::Annotat
|
|
24
24
|
HeadMusic::FunctionalInterval.new(tonic_pitch, highest_pitch)
|
25
25
|
end
|
26
26
|
|
27
|
-
def tonic_pitch
|
28
|
-
@tonic_pitch ||= HeadMusic::Pitch.get(tonic_spelling)
|
29
|
-
end
|
30
|
-
|
31
27
|
def highest_pitch_appears_once?
|
32
28
|
highest_notes.length == 1
|
33
29
|
end
|
@@ -43,7 +39,7 @@ class HeadMusic::Style::Annotations::ConsonantClimax < HeadMusic::Style::Annotat
|
|
43
39
|
end
|
44
40
|
|
45
41
|
def step_between_highest_notes?
|
46
|
-
MelodicInterval.new(voice, highest_notes.first, notes_between_highest_notes.first).step?
|
42
|
+
HeadMusic::MelodicInterval.new(voice, highest_notes.first, notes_between_highest_notes.first).step?
|
47
43
|
end
|
48
44
|
|
49
45
|
def single_note_between_highest_notes?
|
@@ -3,7 +3,7 @@ end
|
|
3
3
|
|
4
4
|
# marks the voice if the first note is not the first or fifth scale degree of the key.
|
5
5
|
class HeadMusic::Style::Annotations::StartOnPerfectConsonance < HeadMusic::Style::Annotation
|
6
|
-
MESSAGE = 'Start on the tonic or a perfect consonance above the tonic.'
|
6
|
+
MESSAGE = 'Start on the tonic or a perfect consonance above the tonic (unless bass voice).'
|
7
7
|
|
8
8
|
def marks
|
9
9
|
if first_note && ((bass_voice? && !starts_on_tonic?) || !starts_on_perfect_consonance?)
|
data/lib/head_music/version.rb
CHANGED