Class: HeadMusic::Style::Guidelines::AvoidOverlappingVoices

Inherits:
Annotation
  • Object
show all
Defined in:
lib/head_music/style/guidelines/avoid_overlapping_voices.rb

Overview

A counterpoint guideline

Constant Summary collapse

MESSAGE =
"Avoid overlapping voices. Maintain the high-low relationship between voices even for adjacent notes."

Instance Method Summary collapse

Constructor Details

This class inherits a constructor from HeadMusic::Style::Annotation

Instance Method Details

#marksObject



8
9
10
# File 'lib/head_music/style/guidelines/avoid_overlapping_voices.rb', line 8

def marks
  overlappings
end

#overlappingsObject (private)



14
15
16
# File 'lib/head_music/style/guidelines/avoid_overlapping_voices.rb', line 14

def overlappings
  overlappings_of_lower_voices + overlappings_of_higher_voices
end

#overlappings_for_voices(voices, comparison_operator) ⇒ Object (private)



26
27
28
29
30
31
32
33
# File 'lib/head_music/style/guidelines/avoid_overlapping_voices.rb', line 26

def overlappings_for_voices(voices, comparison_operator)
  [].tap do |marks|
    voices.each do |a_voice|
      overlapped_notes = overlappings_with_voice(a_voice, comparison_operator)
      marks << HeadMusic::Style::Mark.for_each(overlapped_notes)
    end
  end.flatten.compact
end

#overlappings_of_higher_voicesObject (private)



22
23
24
# File 'lib/head_music/style/guidelines/avoid_overlapping_voices.rb', line 22

def overlappings_of_higher_voices
  overlappings_for_voices(higher_voices, :<)
end

#overlappings_of_lower_voicesObject (private)



18
19
20
# File 'lib/head_music/style/guidelines/avoid_overlapping_voices.rb', line 18

def overlappings_of_lower_voices
  overlappings_for_voices(lower_voices, :>)
end

#overlappings_with_voice(other_voice, comparison_operator) ⇒ Object (private)



35
36
37
38
39
40
41
42
# File 'lib/head_music/style/guidelines/avoid_overlapping_voices.rb', line 35

def overlappings_with_voice(other_voice, comparison_operator)
  voice.notes.drop(1).select do |note|
    preceding_note = other_voice.note_preceding(note.position)
    following_note = other_voice.note_following(note.position)
    preceding_note&.pitch&.send(comparison_operator, note.pitch) ||
      following_note&.pitch&.send(comparison_operator, note.pitch)
  end
end