head_music 0.16.0 → 0.16.2
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/style/analysis.rb +2 -2
- data/lib/head_music/style/annotations/avoid_crossing_voices.rb +1 -1
- data/lib/head_music/style/annotations/avoid_overlapping_voices.rb +1 -1
- data/lib/head_music/style/annotations/consonant_climax.rb +11 -5
- data/lib/head_music/style/annotations/consonant_downbeats.rb +1 -1
- data/lib/head_music/style/annotations/end_on_perfect_consonance.rb +1 -1
- data/lib/head_music/style/annotations/end_on_tonic.rb +1 -1
- data/lib/head_music/style/annotations/limit_octave_leaps.rb +1 -1
- data/lib/head_music/style/annotations/no_rests.rb +1 -1
- data/lib/head_music/style/annotations/prefer_contrary_motion.rb +1 -1
- data/lib/head_music/style/annotations/prepare_octave_leaps.rb +1 -1
- data/lib/head_music/style/annotations/recover_large_leaps.rb +1 -1
- data/lib/head_music/style/annotations/start_on_tonic.rb +1 -1
- data/lib/head_music/style/annotations/step_down_to_final_note.rb +1 -1
- data/lib/head_music/style/annotations/step_to_final_note.rb +20 -0
- data/lib/head_music/style/annotations/up_to_fourteen_notes.rb +1 -1
- data/lib/head_music/style/rulesets/first_species_harmony.rb +2 -2
- data/lib/head_music/style/rulesets/{davis_lybbert_cantus_firmus.rb → modern_cantus_firmus.rb} +2 -2
- data/lib/head_music/version.rb +1 -1
- data/lib/head_music/voice.rb +4 -3
- data/lib/head_music.rb +3 -2
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3eff7c01e7dbb6e69538d9cdcbad34c55fc9f05e
|
4
|
+
data.tar.gz: e78e38ddd5ec3e8c77aae6a9dc371df7183ef29d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98da361ccd151df8d8b8d31688a783cbf3586845e06bf5584e6131b0eb657f18f820f0111e86cdd6a38e65770a99a64588e5693d938aa364b317f590f01db330
|
7
|
+
data.tar.gz: 67bfc70343e9c9733671aea1e9d1d80291ee4233e70fe60899e22efe61f8f6132cff06e54804aa34e3b098080db22919ba38a695a615d42219ba04ee2a3f1c74
|
@@ -19,7 +19,7 @@ module HeadMusic
|
|
19
19
|
|
20
20
|
def fitness
|
21
21
|
return 1.0 if annotations.length == 0
|
22
|
-
fitness_scores.inject(:+).to_f / fitness_scores.length
|
22
|
+
@fitness ||= fitness_scores.inject(:+).to_f / fitness_scores.length
|
23
23
|
end
|
24
24
|
|
25
25
|
def adherent?
|
@@ -29,7 +29,7 @@ module HeadMusic
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def fitness_scores
|
32
|
-
annotations.map(&:fitness)
|
32
|
+
@fitness_scores ||= annotations.map(&:fitness)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -2,7 +2,7 @@ module HeadMusic::Style::Annotations
|
|
2
2
|
end
|
3
3
|
|
4
4
|
class HeadMusic::Style::Annotations::AvoidCrossingVoices < HeadMusic::Style::Annotation
|
5
|
-
MESSAGE = "Avoid crossing voices."
|
5
|
+
MESSAGE = "Avoid crossing voices. Maintain the high-low relationship between voices."
|
6
6
|
|
7
7
|
def marks
|
8
8
|
crossings.map do |crossing|
|
@@ -2,7 +2,7 @@ module HeadMusic::Style::Annotations
|
|
2
2
|
end
|
3
3
|
|
4
4
|
class HeadMusic::Style::Annotations::AvoidOverlappingVoices < HeadMusic::Style::Annotation
|
5
|
-
MESSAGE = "Avoid overlapping voices."
|
5
|
+
MESSAGE = "Avoid overlapping voices. Maintain the high-low relationship between voices even for adjacent notes."
|
6
6
|
|
7
7
|
def marks
|
8
8
|
overlappings
|
@@ -2,7 +2,7 @@ module HeadMusic::Style::Annotations
|
|
2
2
|
end
|
3
3
|
|
4
4
|
class HeadMusic::Style::Annotations::ConsonantClimax < HeadMusic::Style::Annotation
|
5
|
-
MESSAGE = "Peak on a consonant high note one time or twice with a step between."
|
5
|
+
MESSAGE = "Peak on a consonant high or low note one time or twice with a step between."
|
6
6
|
|
7
7
|
def marks
|
8
8
|
HeadMusic::Style::Mark.for_each(highest_notes) if !adherent_climax?
|
@@ -11,7 +11,7 @@ class HeadMusic::Style::Annotations::ConsonantClimax < HeadMusic::Style::Annotat
|
|
11
11
|
private
|
12
12
|
|
13
13
|
def adherent_climax?
|
14
|
-
|
14
|
+
descending_melody? ? adherent_low_pitch? : adherent_high_pitch?
|
15
15
|
end
|
16
16
|
|
17
17
|
def adherent_high_pitch?
|
@@ -21,7 +21,6 @@ class HeadMusic::Style::Annotations::ConsonantClimax < HeadMusic::Style::Annotat
|
|
21
21
|
|
22
22
|
def adherent_low_pitch?
|
23
23
|
notes? &&
|
24
|
-
only_goes_down? &&
|
25
24
|
lowest_pitch_consonant_with_tonic? &&
|
26
25
|
( lowest_pitch_appears_once? || lowest_pitch_appears_twice_with_step_between? )
|
27
26
|
end
|
@@ -101,7 +100,14 @@ class HeadMusic::Style::Annotations::ConsonantClimax < HeadMusic::Style::Annotat
|
|
101
100
|
notes[(indexes.first + 1)..(indexes.last - 1)] || []
|
102
101
|
end
|
103
102
|
|
104
|
-
def
|
105
|
-
|
103
|
+
def descending_melody?
|
104
|
+
# account for the possibility of opening with an octave leap
|
105
|
+
notes.length > 1 &&
|
106
|
+
[first_note.pitch, second_note.pitch].include?(highest_pitch) &&
|
107
|
+
highest_pitch.spelling == tonic_spelling
|
108
|
+
end
|
109
|
+
|
110
|
+
def second_note
|
111
|
+
notes && notes[1]
|
106
112
|
end
|
107
113
|
end
|
@@ -2,7 +2,7 @@ module HeadMusic::Style::Annotations
|
|
2
2
|
end
|
3
3
|
|
4
4
|
class HeadMusic::Style::Annotations::ConsonantDownbeats < HeadMusic::Style::Annotation
|
5
|
-
MESSAGE = "Use consonant harmonic intervals."
|
5
|
+
MESSAGE = "Use consonant harmonic intervals on every downbeat."
|
6
6
|
|
7
7
|
def marks
|
8
8
|
dissonant_pairs.map do |dissonant_pair|
|
@@ -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::EndOnPerfectConsonance < HeadMusic::Style::Annotation
|
6
|
-
MESSAGE = 'End on the
|
6
|
+
MESSAGE = 'End on the first or the fifth scale degree.'
|
7
7
|
|
8
8
|
def marks
|
9
9
|
if last_note && !ends_on_perfect_consonance?
|
@@ -2,7 +2,7 @@ module HeadMusic::Style::Annotations
|
|
2
2
|
end
|
3
3
|
|
4
4
|
class HeadMusic::Style::Annotations::LimitOctaveLeaps < HeadMusic::Style::Annotation
|
5
|
-
MESSAGE = "Use a maximum of one octave
|
5
|
+
MESSAGE = "Use a maximum of one octave leap."
|
6
6
|
|
7
7
|
def marks
|
8
8
|
if octave_leaps.length > 1
|
@@ -2,7 +2,7 @@ module HeadMusic::Style::Annotations
|
|
2
2
|
end
|
3
3
|
|
4
4
|
class HeadMusic::Style::Annotations::PreferContraryMotion < HeadMusic::Style::Annotation
|
5
|
-
MESSAGE = "Prefer contrary motion."
|
5
|
+
MESSAGE = "Prefer contrary motion. Move voices in different melodic directions."
|
6
6
|
|
7
7
|
def marks
|
8
8
|
return nil if notes.length < 2
|
@@ -14,7 +14,7 @@ class HeadMusic::Style::Annotations::PrepareOctaveLeaps < HeadMusic::Style::Anno
|
|
14
14
|
|
15
15
|
def external_entries
|
16
16
|
melodic_intervals.map.with_index do |melodic_interval, i|
|
17
|
-
if melodic_interval.octave? &&
|
17
|
+
if melodic_interval.octave? && i > 0 && !melodic_interval.spans?(notes[i-1].pitch)
|
18
18
|
notes[[i-1, 0].max..(i+1)]
|
19
19
|
end
|
20
20
|
end.compact
|
@@ -6,7 +6,7 @@ end
|
|
6
6
|
# unless another leap (in either direction) creates a consonant triad.
|
7
7
|
# - Brian
|
8
8
|
class HeadMusic::Style::Annotations::RecoverLargeLeaps < HeadMusic::Style::Annotation
|
9
|
-
MESSAGE = "Recover leaps by step in the opposite direction."
|
9
|
+
MESSAGE = "Recover large leaps by step in the opposite direction."
|
10
10
|
|
11
11
|
def marks
|
12
12
|
melodic_intervals.drop(1).to_a.map.with_index do |interval, i|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module HeadMusic::Style::Annotations
|
2
|
+
end
|
3
|
+
|
4
|
+
class HeadMusic::Style::Annotations::StepToFinalNote < HeadMusic::Style::Annotation
|
5
|
+
MESSAGE = 'Step to the final note.'
|
6
|
+
|
7
|
+
def marks
|
8
|
+
HeadMusic::Style::Mark.for_all(notes[-2..-1]) unless step_to_final_note?
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def step_to_final_note?
|
14
|
+
last_melodic_interval && last_melodic_interval.step?
|
15
|
+
end
|
16
|
+
|
17
|
+
def last_melodic_interval
|
18
|
+
@last_melodic_interval ||= melodic_intervals.last
|
19
|
+
end
|
20
|
+
end
|
@@ -7,10 +7,10 @@ class HeadMusic::Style::Rulesets::FirstSpeciesHarmony
|
|
7
7
|
HeadMusic::Style::Annotations::AvoidCrossingVoices,
|
8
8
|
HeadMusic::Style::Annotations::AvoidOverlappingVoices,
|
9
9
|
HeadMusic::Style::Annotations::ConsonantDownbeats,
|
10
|
-
HeadMusic::Style::Annotations::PreferContraryMotion,
|
11
|
-
HeadMusic::Style::Annotations::PreferImperfect,
|
12
10
|
HeadMusic::Style::Annotations::NoUnisonsInMiddle,
|
13
11
|
HeadMusic::Style::Annotations::OneToOne,
|
12
|
+
HeadMusic::Style::Annotations::PreferContraryMotion,
|
13
|
+
HeadMusic::Style::Annotations::PreferImperfect,
|
14
14
|
]
|
15
15
|
|
16
16
|
def self.analyze(voice)
|
data/lib/head_music/style/rulesets/{davis_lybbert_cantus_firmus.rb → modern_cantus_firmus.rb}
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
module HeadMusic::Style::Rulesets
|
2
2
|
end
|
3
3
|
|
4
|
-
class HeadMusic::Style::Rulesets::
|
4
|
+
class HeadMusic::Style::Rulesets::ModernCantusFirmus
|
5
5
|
RULESET = [
|
6
6
|
HeadMusic::Style::Annotations::AlwaysMove,
|
7
7
|
HeadMusic::Style::Annotations::AtLeastEightNotes,
|
@@ -18,7 +18,7 @@ class HeadMusic::Style::Rulesets::DavisLybbertCantusFirmus
|
|
18
18
|
HeadMusic::Style::Annotations::SingableRange,
|
19
19
|
HeadMusic::Style::Annotations::SingleLargeLeaps,
|
20
20
|
HeadMusic::Style::Annotations::StartOnTonic,
|
21
|
-
HeadMusic::Style::Annotations::
|
21
|
+
HeadMusic::Style::Annotations::StepToFinalNote,
|
22
22
|
HeadMusic::Style::Annotations::UpToFourteenNotes,
|
23
23
|
]
|
24
24
|
|
data/lib/head_music/version.rb
CHANGED
data/lib/head_music/voice.rb
CHANGED
@@ -54,9 +54,10 @@ class HeadMusic::Voice
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def melodic_intervals
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
@melodic_intervals ||=
|
58
|
+
notes.map.with_index do |note, i|
|
59
|
+
HeadMusic::MelodicInterval.new(self, notes[i-1], note) if i > 0
|
60
|
+
end.compact
|
60
61
|
end
|
61
62
|
|
62
63
|
def leaps
|
data/lib/head_music.rb
CHANGED
@@ -65,9 +65,9 @@ require 'head_music/style/annotations/frequent_direction_changes'
|
|
65
65
|
require 'head_music/style/annotations/limit_octave_leaps'
|
66
66
|
require 'head_music/style/annotations/moderate_direction_changes'
|
67
67
|
require 'head_music/style/annotations/mostly_conjunct'
|
68
|
+
require 'head_music/style/annotations/notes_same_length'
|
68
69
|
require 'head_music/style/annotations/no_rests'
|
69
70
|
require 'head_music/style/annotations/no_unisons_in_middle'
|
70
|
-
require 'head_music/style/annotations/notes_same_length'
|
71
71
|
require 'head_music/style/annotations/one_to_one'
|
72
72
|
require 'head_music/style/annotations/prefer_contrary_motion'
|
73
73
|
require 'head_music/style/annotations/prefer_imperfect'
|
@@ -80,11 +80,12 @@ require 'head_music/style/annotations/start_on_perfect_consonance'
|
|
80
80
|
require 'head_music/style/annotations/start_on_tonic'
|
81
81
|
require 'head_music/style/annotations/step_down_to_final_note'
|
82
82
|
require 'head_music/style/annotations/step_out_of_unison'
|
83
|
+
require 'head_music/style/annotations/step_to_final_note'
|
83
84
|
require 'head_music/style/annotations/step_up_to_final_note'
|
84
85
|
require 'head_music/style/annotations/up_to_fourteen_notes'
|
85
86
|
|
86
87
|
require 'head_music/style/rulesets/fux_cantus_firmus'
|
87
|
-
require 'head_music/style/rulesets/
|
88
|
+
require 'head_music/style/rulesets/modern_cantus_firmus'
|
88
89
|
require 'head_music/style/rulesets/first_species_melody'
|
89
90
|
require 'head_music/style/rulesets/first_species_harmony'
|
90
91
|
|
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.16.
|
4
|
+
version: 0.16.2
|
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-06-
|
11
|
+
date: 2017-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -181,13 +181,14 @@ files:
|
|
181
181
|
- lib/head_music/style/annotations/start_on_tonic.rb
|
182
182
|
- lib/head_music/style/annotations/step_down_to_final_note.rb
|
183
183
|
- lib/head_music/style/annotations/step_out_of_unison.rb
|
184
|
+
- lib/head_music/style/annotations/step_to_final_note.rb
|
184
185
|
- lib/head_music/style/annotations/step_up_to_final_note.rb
|
185
186
|
- lib/head_music/style/annotations/up_to_fourteen_notes.rb
|
186
187
|
- lib/head_music/style/mark.rb
|
187
|
-
- lib/head_music/style/rulesets/davis_lybbert_cantus_firmus.rb
|
188
188
|
- lib/head_music/style/rulesets/first_species_harmony.rb
|
189
189
|
- lib/head_music/style/rulesets/first_species_melody.rb
|
190
190
|
- lib/head_music/style/rulesets/fux_cantus_firmus.rb
|
191
|
+
- lib/head_music/style/rulesets/modern_cantus_firmus.rb
|
191
192
|
- lib/head_music/utilities/hash_key.rb
|
192
193
|
- lib/head_music/version.rb
|
193
194
|
- lib/head_music/voice.rb
|