Class: HeadMusic::Style::Guidelines::ThirdSpeciesDissonanceTreatment
- Inherits:
-
Annotation
- Object
- Annotation
- HeadMusic::Style::Guidelines::ThirdSpeciesDissonanceTreatment
show all
- Defined in:
- lib/head_music/style/guidelines/third_species_dissonance_treatment.rb
Overview
A counterpoint guideline for third-species dissonance treatment.
Every dissonant note on beats 2, 3, or 4 must be treated as a passing tone,
neighbor tone, nota cambiata, or double neighbor figure.
Constant Summary
collapse
- MESSAGE =
"Treat dissonances as passing tones, neighbor tones, cambiata, or double neighbor figures."
Instance Method Summary
collapse
Instance Method Details
#cambiata_as_note_2?(index) ⇒ Boolean
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 61
def cambiata_as_note_2?(index)
return false if index < 1 || index + 3 > notes.length - 1
n1 = notes[index - 1]
n2 = notes[index]
n3 = notes[index + 1]
n4 = notes[index + 2]
n5 = notes[index + 3]
approach = melodic_interval_between(n1, n2)
leap = melodic_interval_between(n2, n3)
step_back_1 = melodic_interval_between(n3, n4)
step_back_2 = melodic_interval_between(n4, n5)
approach.step? &&
leap.number == 3 && approach.direction == leap.direction &&
step_back_1.step? && step_back_2.step? &&
step_back_1.direction != leap.direction &&
step_back_2.direction != leap.direction &&
consonant_with_cantus?(n1) && consonant_with_cantus?(n3) && consonant_with_cantus?(n5)
end
|
#cambiata_dissonance?(note) ⇒ Boolean
Nota cambiata: a five-note figure where note 2 is dissonant,
approached by step from note 1, leaps a third in the same direction to note 3,
then notes 3-4-5 proceed stepwise in the opposite direction.
Notes 1, 3, and 5 must be consonant with the CF.
54
55
56
57
58
59
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 54
def cambiata_dissonance?(note)
index = notes.index(note)
return false unless index
cambiata_as_note_2?(index)
end
|
#cantus_firmus_positions ⇒ Object
139
140
141
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 139
def cantus_firmus_positions
@cantus_firmus_positions ||= Set.new(cantus_firmus.notes.map { |n| n.position.to_s })
end
|
#consonant_with_cantus?(note) ⇒ Boolean
148
149
150
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 148
def consonant_with_cantus?(note)
!dissonant_with_cantus?(note)
end
|
#dissonant_weak_beat_notes ⇒ Object
127
128
129
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 127
def dissonant_weak_beat_notes
weak_beat_notes.select { |note| dissonant_with_cantus?(note) }
end
|
#dissonant_with_cantus?(note) ⇒ Boolean
143
144
145
146
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 143
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
|
#double_neighbor_as_note_2?(index) ⇒ Boolean
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 93
def double_neighbor_as_note_2?(index)
return false if index < 1 || index + 2 > notes.length - 1
n1 = notes[index - 1]
n2 = notes[index]
n3 = notes[index + 1]
n4 = notes[index + 2]
approach = melodic_interval_between(n1, n2)
middle = melodic_interval_between(n2, n3)
departure = melodic_interval_between(n3, n4)
approach.step? && middle.number == 3 && departure.step? &&
n1.pitch == n4.pitch &&
consonant_with_cantus?(n1) && consonant_with_cantus?(n4)
end
|
#double_neighbor_as_note_3?(index) ⇒ Boolean
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 110
def double_neighbor_as_note_3?(index)
return false if index < 2 || index + 1 > notes.length - 1
n1 = notes[index - 2]
n2 = notes[index - 1]
n3 = notes[index]
n4 = notes[index + 1]
approach = melodic_interval_between(n1, n2)
middle = melodic_interval_between(n2, n3)
departure = melodic_interval_between(n3, n4)
approach.step? && middle.number == 3 && departure.step? &&
n1.pitch == n4.pitch &&
consonant_with_cantus?(n1) && consonant_with_cantus?(n4)
end
|
#double_neighbor_member?(note) ⇒ Boolean
Double neighbor: a four-note figure within one bar.
Beats 1 and 4 are the same pitch (consonant), beats 2 and 3 are
upper and lower neighbors connected by a leap of a third.
86
87
88
89
90
91
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 86
def double_neighbor_member?(note)
index = notes.index(note)
return false unless index
double_neighbor_as_note_2?(index) || double_neighbor_as_note_3?(index)
end
|
#downbeat_position?(position) ⇒ Boolean
135
136
137
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 135
def downbeat_position?(position)
cantus_firmus_positions.include?(position.to_s)
end
|
#following_note(note) ⇒ Object
161
162
163
164
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 161
def following_note(note)
index = notes.index(note)
notes[index + 1] if index && index < notes.length - 1
end
|
#marks ⇒ Object
10
11
12
13
14
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 10
def marks
return [] unless cantus_firmus&.notes&.any?
unresolved_dissonant_notes.map { |note| HeadMusic::Style::Mark.for(note) }
end
|
#melodic_interval_between(note1, note2) ⇒ Object
152
153
154
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 152
def melodic_interval_between(note1, note2)
HeadMusic::Analysis::MelodicInterval.new(note1, note2)
end
|
#neighbor_tone?(note) ⇒ Boolean
Neighbor tone: approached by step, left by step in the opposite direction.
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 39
def neighbor_tone?(note)
prev = preceding_note(note)
foll = following_note(note)
return false unless prev && foll
approach = melodic_interval_between(prev, note)
departure = melodic_interval_between(note, foll)
approach.step? && departure.step? && approach.direction != departure.direction
end
|
#passing_tone?(note) ⇒ Boolean
Passing tone: approached by step and left by step in the same direction.
27
28
29
30
31
32
33
34
35
36
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 27
def passing_tone?(note)
prev = preceding_note(note)
foll = following_note(note)
return false unless prev && foll
approach = melodic_interval_between(prev, note)
departure = melodic_interval_between(note, foll)
approach.step? && departure.step? && approach.direction == departure.direction
end
|
#preceding_note(note) ⇒ Object
156
157
158
159
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 156
def preceding_note(note)
index = notes.index(note)
notes[index - 1] if index && index > 0
end
|
22
23
24
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 22
def recognized_figure?(note)
passing_tone?(note) || neighbor_tone?(note) || cambiata_dissonance?(note) || double_neighbor_member?(note)
end
|
#unresolved_dissonant_notes ⇒ Object
18
19
20
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 18
def unresolved_dissonant_notes
dissonant_weak_beat_notes.reject { |note| recognized_figure?(note) }
end
|
#weak_beat_notes ⇒ Object
131
132
133
|
# File 'lib/head_music/style/guidelines/third_species_dissonance_treatment.rb', line 131
def weak_beat_notes
notes.reject { |note| downbeat_position?(note.position) }
end
|