Class: HeadMusic::Content::Voice::Continuity

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/content/voice/continuity.rb

Overview

Examines a voice’s placements for the first break in its coverage of time. A voice is continuous when its first placement starts a bar and every later placement begins where the one before it ends.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(composition, placements) ⇒ Continuity

Returns a new instance of Continuity.



8
9
10
11
# File 'lib/head_music/content/voice/continuity.rb', line 8

def initialize(composition, placements)
  @composition = composition
  @placements = placements
end

Instance Attribute Details

#compositionObject (readonly)

Returns the value of attribute composition.



6
7
8
# File 'lib/head_music/content/voice/continuity.rb', line 6

def composition
  @composition
end

#placementsObject (readonly)

Returns the value of attribute placements.



6
7
8
# File 'lib/head_music/content/voice/continuity.rb', line 6

def placements
  @placements
end

Instance Method Details

#bar_start_position(placement) ⇒ Object (private)



43
44
45
# File 'lib/head_music/content/voice/continuity.rb', line 43

def bar_start_position(placement)
  HeadMusic::Content::Position.new(composition, placement.position.bar_number, 1, 0)
end

#first_gapObject

Returns nil when the placements are contiguous, or [expected_position, found_placement] for the first gap.



15
16
17
18
19
# File 'lib/head_music/content/voice/continuity.rb', line 15

def first_gap
  return if placements.empty?

  leading_gap || interior_gap
end

#interior_gapObject (private)



30
31
32
33
34
35
36
# File 'lib/head_music/content/voice/continuity.rb', line 30

def interior_gap
  placements.each_cons(2) do |previous, current|
    expected_position = previous.next_position
    return [expected_position, current] unless current.position == expected_position
  end
  nil
end

#leading_gapObject (private)



23
24
25
26
27
28
# File 'lib/head_music/content/voice/continuity.rb', line 23

def leading_gap
  first = placements.first
  return if starts_its_bar?(first)

  [bar_start_position(first), first]
end

#starts_its_bar?(placement) ⇒ Boolean (private)

Returns:

  • (Boolean)


38
39
40
41
# File 'lib/head_music/content/voice/continuity.rb', line 38

def starts_its_bar?(placement)
  position = placement.position
  position.count == 1 && position.tick.zero?
end