head_music 0.16.0 → 0.16.2
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/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
|