Sha256: 464a7e0d47a81ab3e5596e9a24652b50fe890ed398d224d5eb259c7303d621c9

Contents?: true

Size: 1.71 KB

Versions: 9

Compression:

Stored size: 1.71 KB

Contents

# frozen_string_literal: true

# 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 distinct_values
    all_but_last_note.map(&:rhythmic_value).uniq.length
  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

9 entries across 9 versions & 1 rubygems

Version Path
head_music-4.0.1 lib/head_music/style/guidelines/notes_same_length.rb
head_music-4.0.0 lib/head_music/style/guidelines/notes_same_length.rb
head_music-3.0.1 lib/head_music/style/guidelines/notes_same_length.rb
head_music-3.0.0 lib/head_music/style/guidelines/notes_same_length.rb
head_music-2.0.1 lib/head_music/style/guidelines/notes_same_length.rb
head_music-2.0.0 lib/head_music/style/guidelines/notes_same_length.rb
head_music-1.0.0 lib/head_music/style/guidelines/notes_same_length.rb
head_music-0.29.0 lib/head_music/style/guidelines/notes_same_length.rb
head_music-0.28.0 lib/head_music/style/guidelines/notes_same_length.rb