Class: HeadMusic::Style::Guidelines::SecondSpeciesBreak
Overview
A counterpoint guideline for fourth species counterpoint.
The syncopated texture is occasionally broken: the counterpoint moves on the
downbeat instead of sustaining. When this happens, a dissonant off-beat note
is permitted only if it is a passing tone. Breaks should be infrequent.
Constant Summary
collapse
- MAX_BREAK_RATIO =
0.25
Instance Method Summary
collapse
Instance Method Details
#break_bar?(bar) ⇒ Boolean
42
43
44
45
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 42
def break_bar?(bar)
downbeats, off_beats = notes_in_bar(bar).partition { |note| downbeat_position?(note.position) }
downbeats.any? && off_beats.any?
end
|
#break_bar_off_beat_notes ⇒ Object
47
48
49
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 47
def break_bar_off_beat_notes
break_bars.flat_map { |bar| notes_in_bar(bar).reject { |note| downbeat_position?(note.position) } }
end
|
#break_bars ⇒ Object
38
39
40
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 38
def break_bars
@break_bars ||= (first_bar..last_bar).select { |bar| break_bar?(bar) }
end
|
#dissonance_marks ⇒ Object
19
20
21
22
23
24
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 19
def dissonance_marks
break_bar_off_beat_notes
.select { |note| dissonant_with_cantus?(note) }
.reject { |note| passing_tone?(note) }
.map { |note| HeadMusic::Style::Mark.for(note) }
end
|
#first_bar ⇒ Object
59
60
61
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 59
def first_bar
cantus_firmus.notes.first.position.bar_number
end
|
#frequency_marks ⇒ Object
30
31
32
33
34
35
36
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 30
def frequency_marks
return [] if total_bars <= 0
return [] if break_bars.length <= total_bars * max_break_ratio
break_bar_notes = break_bars.flat_map { |bar| notes_in_bar(bar) }
[HeadMusic::Style::Mark.for_all(break_bar_notes, fitness: HeadMusic::SMALL_PENALTY_FACTOR)]
end
|
#last_bar ⇒ Object
63
64
65
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 63
def last_bar
cantus_firmus.notes.last.position.bar_number
end
|
#marks ⇒ Object
11
12
13
14
15
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 11
def marks
return [] unless cantus_firmus&.notes&.any?
dissonance_marks + frequency_marks
end
|
#max_break_ratio ⇒ Object
26
27
28
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 26
def max_break_ratio
options.fetch(:max_break_ratio) { self.class::MAX_BREAK_RATIO }
end
|
#notes_in_bar(bar) ⇒ Object
51
52
53
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 51
def notes_in_bar(bar)
notes.select { |note| note.position.bar_number == bar }
end
|
#total_bars ⇒ Object
55
56
57
|
# File 'lib/head_music/style/guidelines/second_species_break.rb', line 55
def total_bars
last_bar - first_bar + 1
end
|