Class: InevitableCacophony::Polyrhythm

Inherits:
Rhythm
  • Object
show all
Defined in:
lib/inevitable_cacophony/polyrhythm.rb

Constant Summary

Constants inherited from Rhythm

Rhythm::AFTER_DELAY, Rhythm::START_DELAY

Instance Attribute Summary collapse

Attributes inherited from Rhythm

#beats

Instance Method Summary collapse

Methods inherited from Rhythm

#duration, #each_beat, #inspect

Constructor Details

#initialize(primary, secondaries) ⇒ Polyrhythm

Creates a new polyrhythm by combining two simpler component rhythms. It will have the same duration as the primary rhythm, but include beats from both it and all the secondaries.

TODO: do I want to emphasise the primary rhythm more?

Parameters:

  • primary (Rhythm)

    The rhythm that will be considered the primary.

  • secondaries (Array<Rhythm>)

    The other component rhythms.



18
19
20
21
22
23
24
25
# File 'lib/inevitable_cacophony/polyrhythm.rb', line 18

def initialize(primary, secondaries)
  @primary = primary
  @secondaries = secondaries
        
  unscaled_beats = beats_from_canonical(canonical)
  scaled_beats = scale_beats(unscaled_beats, @primary.duration)
  super(scaled_beats)
end

Instance Attribute Details

#primaryObject

Returns the value of attribute primary.



27
28
29
# File 'lib/inevitable_cacophony/polyrhythm.rb', line 27

def primary
  @primary
end

#secondariesObject

Returns the value of attribute secondaries.



27
28
29
# File 'lib/inevitable_cacophony/polyrhythm.rb', line 27

def secondaries
  @secondaries
end

Instance Method Details

#==(other) ⇒ Object



50
51
52
53
54
# File 'lib/inevitable_cacophony/polyrhythm.rb', line 50

def == other
  self.class == other.class &&
    self.primary == other.primary &&
    self.secondaries == other.secondaries
end

#canonicalArray<Float>

Calculates the canonical form by combining the two component rhythms.

Returns:

  • (Array<Float>)


36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/inevitable_cacophony/polyrhythm.rb', line 36

def canonical
        
  sounding = Set.new
  first, *rest = aligned_components
  unnormalised = first.zip(*rest).map do |beats_at_tick|
    beat, sounding = update_sounding_beats(sounding, beats_at_tick)
    beat
  end
        
  # Renormalise to a maximum volume of 100%
  max_amplitude = unnormalised.compact.max.to_f
  unnormalised.map { |b| b && b / max_amplitude }
end

#componentsArray<Rhythm>

Returns All the component rhythms that make up this polyrhythm.

Returns:

  • (Array<Rhythm>)

    All the component rhythms that make up this polyrhythm



30
31
32
# File 'lib/inevitable_cacophony/polyrhythm.rb', line 30

def components
  [primary, *secondaries]
end