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