Class: HeadMusic::Style::Guidelines::FirstBarEntry

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

Overview

Base class for first-bar guidelines. Rules: (a) at least one note, (b) each note is the correct beat unit, (c) at most one rest, and only on the first beat.

Instance Method Summary collapse

Constructor Details

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

Instance Method Details

#all_correct_beat_unit?(bar_notes) ⇒ Boolean (private)

Returns:

  • (Boolean)


31
32
33
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 31

def all_correct_beat_unit?(bar_notes)
  bar_notes.all? { |note| note.rhythmic_value == expected_rhythmic_value }
end

#expected_notes_in_first_barObject (private)



41
42
43
44
45
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 41

def expected_notes_in_first_bar
  meter = composition.meter_at(1)
  bar_duration = meter.count_unit.relative_value * meter.counts_per_bar
  (bar_duration / expected_rhythmic_value.total_value).round
end

#expected_rhythmic_valueObject (private)

Raises:

  • (NotImplementedError)


20
21
22
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 20

def expected_rhythmic_value
  raise NotImplementedError
end

#marksObject



8
9
10
11
12
13
14
15
16
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 8

def marks
  return unless notes.any?

  bar_notes = notes_in_first_bar
  bar_rests = rests_in_first_bar
  return if valid_first_bar?(bar_notes, bar_rests)

  HeadMusic::Style::Mark.for_all(bar_notes.any? ? bar_notes : [first_note])
end

#notes_in_first_barObject (private)



54
55
56
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 54

def notes_in_first_bar
  notes.select { |note| note.position.bar_number == 1 }
end

#rests_in_first_barObject (private)



58
59
60
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 58

def rests_in_first_bar
  rests.select { |rest| rest.position.bar_number == 1 }
end

#valid_first_bar?(bar_notes, bar_rests) ⇒ Boolean (private)

Returns:

  • (Boolean)


24
25
26
27
28
29
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 24

def valid_first_bar?(bar_notes, bar_rests)
  bar_notes.any? &&
    all_correct_beat_unit?(bar_notes) &&
    valid_note_count?(bar_notes) &&
    valid_rests?(bar_rests)
end

#valid_note_count?(bar_notes) ⇒ Boolean (private)

Returns:

  • (Boolean)


35
36
37
38
39
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 35

def valid_note_count?(bar_notes)
  expected = expected_notes_in_first_bar
  bar_notes.length == expected ||
    (bar_notes.length == expected - 1 && bar_notes.first.position.count > 1)
end

#valid_rests?(bar_rests) ⇒ Boolean (private)

Returns:

  • (Boolean)


47
48
49
50
51
52
# File 'lib/head_music/style/guidelines/first_bar_entry.rb', line 47

def valid_rests?(bar_rests)
  bar_rests.empty? ||
    (bar_rests.length == 1 &&
      bar_rests.first.position.count == 1 &&
      bar_rests.first.rhythmic_value == expected_rhythmic_value)
end