Class: HeadMusic::Style::Guidelines::FloridDissonanceTreatment
- Inherits:
-
Annotation
- Object
- Annotation
- HeadMusic::Style::Guidelines::FloridDissonanceTreatment
show all
- Defined in:
- lib/head_music/style/guidelines/florid_dissonance_treatment.rb
Overview
Unified dissonance handling for mixed-species (florid) contexts.
- Strong beat dissonances must be properly prepared suspensions from a tie.
- Weak beat dissonances must be passing tones or neighbor tones.
- Tied notes dissonant at the new CF note must resolve by step to a consonance.
Constant Summary
collapse
- MESSAGE =
"Treat dissonances appropriately: passing tones on weak beats, proper suspension treatment for tied notes."
Instance Method Summary
collapse
Instance Method Details
#cantus_firmus_positions ⇒ Object
56
57
58
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 56
def cantus_firmus_positions
@cantus_firmus_positions ||= Set.new(cantus_firmus.notes.map { |note| note.position.to_s })
end
|
#current_cf_note_at(position) ⇒ Object
60
61
62
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 60
def current_cf_note_at(position)
cantus_firmus.note_at(position)
end
|
#dissonant_with_cantus?(note) ⇒ Boolean
64
65
66
67
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 64
def dissonant_with_cantus?(note)
interval = HeadMusic::Analysis::HarmonicInterval.new(cantus_firmus, voice, note.position)
interval.notes.length == 2 && interval.dissonance?(:two_part_harmony)
end
|
#following_note(note) ⇒ Object
92
93
94
95
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 92
def following_note(note)
index = notes.index(note)
notes[index + 1] if index && index < notes.length - 1
end
|
#improperly_treated_notes ⇒ Object
19
20
21
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 19
def improperly_treated_notes
notes.select { |note| dissonant_with_cantus?(note) && !properly_treated?(note) }
end
|
#marks ⇒ Object
11
12
13
14
15
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 11
def marks
return [] unless cantus_firmus&.notes&.any?
improperly_treated_notes.map { |note| HeadMusic::Style::Mark.for(note) }
end
|
#neighbor_tone?(note) ⇒ Boolean
73
74
75
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 73
def neighbor_tone?(note)
stepwise_figure?(note, same_direction: false)
end
|
#on_strong_beat?(note) ⇒ Boolean
52
53
54
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 52
def on_strong_beat?(note)
cantus_firmus_positions.include?(note.position.to_s)
end
|
#passing_tone?(note) ⇒ Boolean
69
70
71
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 69
def passing_tone?(note)
stepwise_figure?(note, same_direction: true)
end
|
#preceding_note(note) ⇒ Object
87
88
89
90
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 87
def preceding_note(note)
index = notes.index(note)
notes[index - 1] if index && index > 0
end
|
#properly_treated?(note) ⇒ Boolean
23
24
25
26
27
28
29
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 23
def properly_treated?(note)
if on_strong_beat?(note)
properly_treated_suspension?(note)
else
passing_tone?(note) || neighbor_tone?(note)
end
end
|
#properly_treated_suspension?(note) ⇒ Boolean
A note on a strong beat that is dissonant must be a tied suspension
(its position is before the CF note position, meaning it was held over).
33
34
35
36
37
38
39
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 33
def properly_treated_suspension?(note)
cf_note = current_cf_note_at(note.position)
return false unless cf_note
note.position < cf_note.position && resolved_by_step?(note)
end
|
#resolved_by_step?(note) ⇒ Boolean
41
42
43
44
45
46
47
48
49
50
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 41
def resolved_by_step?(note)
next_cp = following_note(note)
return false unless next_cp
melodic = HeadMusic::Analysis::MelodicInterval.new(note, next_cp)
return false unless melodic.step?
!dissonant_with_cantus?(next_cp)
end
|
77
78
79
80
81
82
83
84
85
|
# File 'lib/head_music/style/guidelines/florid_dissonance_treatment.rb', line 77
def stepwise_figure?(note, same_direction:)
prev_note = preceding_note(note)
next_note = following_note(note)
return false unless prev_note && next_note
approach = HeadMusic::Analysis::MelodicInterval.new(prev_note, note)
departure = HeadMusic::Analysis::MelodicInterval.new(note, next_note)
approach.step? && departure.step? && (approach.direction == departure.direction) == same_direction
end
|