Class: HeadMusic::Style::Guidelines::SuspensionTreatment
- Inherits:
-
Annotation
- Object
- Annotation
- HeadMusic::Style::Guidelines::SuspensionTreatment
show all
- Defined in:
- lib/head_music/style/guidelines/suspension_treatment.rb
Overview
A counterpoint guideline for fourth species suspension treatment.
A suspension has three parts:
1. Preparation: The note is consonant with the current cantus firmus note.
2. Suspension: The cantus firmus moves; the counterpoint sustains, becoming dissonant.
3. Resolution: The counterpoint resolves by step down to a consonance.
Constant Summary
collapse
- MESSAGE =
"Treat suspensions with proper preparation and downward stepwise resolution."
Instance Method Summary
collapse
Instance Method Details
#dissonant_suspensions ⇒ Object
26
27
28
29
30
31
32
33
34
35
36
|
# File 'lib/head_music/style/guidelines/suspension_treatment.rb', line 26
def dissonant_suspensions
cantus_firmus.notes[1..].filter_map do |cf_note|
cp_note = voice.note_at(cf_note.position)
next unless cp_note && cp_note.position < cf_note.position
interval = HeadMusic::Analysis::HarmonicInterval.new(cantus_firmus, voice, cf_note.position)
next unless interval.notes.length == 2 && interval.dissonance?(:two_part_harmony)
[cp_note, cf_note]
end
end
|
#improperly_treated_suspensions ⇒ Object
22
23
24
|
# File 'lib/head_music/style/guidelines/suspension_treatment.rb', line 22
def improperly_treated_suspensions
dissonant_suspensions.reject { |note, cf_note| properly_treated?(note, cf_note) }.map(&:first)
end
|
#marks ⇒ Object
12
13
14
15
16
17
18
|
# File 'lib/head_music/style/guidelines/suspension_treatment.rb', line 12
def marks
return [] unless cantus_firmus&.notes&.any?
improperly_treated_suspensions.map do |note|
HeadMusic::Style::Mark.for(note)
end
end
|
#prepared?(cp_note, cf_note) ⇒ Boolean
42
43
44
45
46
47
48
|
# File 'lib/head_music/style/guidelines/suspension_treatment.rb', line 42
def prepared?(cp_note, cf_note)
prev_cf = previous_cf_note(cf_note)
return false unless prev_cf
interval = HeadMusic::Analysis::HarmonicInterval.new(cantus_firmus, voice, cp_note.position)
interval.notes.length == 2 && interval.consonance?(:two_part_harmony)
end
|
#previous_cf_note(cf_note) ⇒ Object
61
62
63
64
|
# File 'lib/head_music/style/guidelines/suspension_treatment.rb', line 61
def previous_cf_note(cf_note)
index = cantus_firmus.notes.index(cf_note)
cantus_firmus.notes[index - 1] if index && index > 0
end
|
#properly_treated?(cp_note, cf_note) ⇒ Boolean
38
39
40
|
# File 'lib/head_music/style/guidelines/suspension_treatment.rb', line 38
def properly_treated?(cp_note, cf_note)
prepared?(cp_note, cf_note) && resolved?(cp_note, cf_note)
end
|
#resolved?(cp_note, cf_note) ⇒ Boolean
50
51
52
53
54
55
56
57
58
59
|
# File 'lib/head_music/style/guidelines/suspension_treatment.rb', line 50
def resolved?(cp_note, cf_note)
next_cp = voice.note_following(cp_note.position)
return false unless next_cp
melodic = HeadMusic::Analysis::MelodicInterval.new(cp_note, next_cp)
return false unless melodic.step? && melodic.descending?
resolution_interval = HeadMusic::Analysis::HarmonicInterval.new(cantus_firmus, voice, next_cp.position)
resolution_interval.notes.length == 2 && resolution_interval.consonance?(:two_part_harmony)
end
|