Sha256: 0687e306bf9dd66b422ffec68bb43469ded0bcc4a7203d6b4a2fe548c8d13e25

Contents?: true

Size: 1.6 KB

Versions: 6

Compression:

Stored size: 1.6 KB

Contents

# Module for style guidelines.
module HeadMusic::Style::Guidelines; end

# A counterpoint guideline
class HeadMusic::Style::Guidelines::NotesSameLength < HeadMusic::Style::Annotation
  MESSAGE = "Use consistent rhythmic unit."

  def marks
    HeadMusic::Style::Mark.for_each(all_wrong_length_notes)
  end

  private

  def all_wrong_length_notes
    (wrong_length_notes + [wrong_length_last_note]).compact
  end

  def wrong_length_notes
    all_but_last_note.reject do |note|
      note.rhythmic_value == first_most_common_rhythmic_value
    end
  end

  def wrong_length_last_note
    last_note unless acceptable_duration_of_last_note?
  end

  def acceptable_duration_of_last_note?
    last_note.nil? ||
      [
        first_most_common_rhythmic_value.total_value,
        first_most_common_rhythmic_value.total_value * 2
      ].include?(last_note.rhythmic_value.total_value)
  end

  def all_but_last_note
    notes[0..-2]
  end

  def first_most_common_rhythmic_value
    @first_most_common_rhythmic_value ||= begin
      candidates = most_common_rhythmic_values
      first_match = notes.detect { |note| candidates.include?(note.rhythmic_value) }
      first_match&.rhythmic_value
    end
  end

  def most_common_rhythmic_values
    return [] if notes.empty?

    occurrences = occurrences_by_rhythmic_value
    highest_count = occurrences.values.max
    occurrences.select { |_rhythmic_value, count| count == highest_count }.keys
  end

  def occurrences_by_rhythmic_value
    rhythmic_values.each_with_object(Hash.new(0)) { |value, hash| hash[value] += 1 }
  end

  def rhythmic_values
    notes.map(&:rhythmic_value)
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
head_music-7.0.5 lib/head_music/style/guidelines/notes_same_length.rb
head_music-7.0.4 lib/head_music/style/guidelines/notes_same_length.rb
head_music-7.0.3 lib/head_music/style/guidelines/notes_same_length.rb
head_music-7.0.2 lib/head_music/style/guidelines/notes_same_length.rb
head_music-7.0.1 lib/head_music/style/guidelines/notes_same_length.rb
head_music-7.0.0 lib/head_music/style/guidelines/notes_same_length.rb