Class: InevitableCacophony::Rhythm

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

Direct Known Subclasses

Polyrhythm

Defined Under Namespace

Classes: Beat

Constant Summary collapse

START_DELAY =

Amount of silence before a note, as a fraction of the note’s duration

(0.3).rationalize
AFTER_DELAY =

Amount of silence after notes, as a fraction of duration.

(0.3).rationalize

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(beats) ⇒ Rhythm

Returns a new instance of Rhythm.



77
78
79
# File 'lib/inevitable_cacophony/rhythm.rb', line 77

def initialize(beats)
	@beats = beats
end

Instance Attribute Details

#beatsObject (readonly)

Returns the value of attribute beats.



81
82
83
# File 'lib/inevitable_cacophony/rhythm.rb', line 81

def beats
  @beats
end

Instance Method Details

#==(other) ⇒ Object



122
123
124
125
# File 'lib/inevitable_cacophony/rhythm.rb', line 122

def == other
	self.class == other.class &&
		self.beats == other.beats
end

#canonicalArray<Numeric,NilClass>

Returns An array where a is the amplitude of the beat at time-step i (rests are 0), or nil if no beat is played then. This will be as long as necessary to represent the rhythm accurately, including early and late beats.

Returns:

  • (Array<Numeric,NilClass>)

    An array where a is the amplitude of the beat at time-step i (rests are 0), or nil if no beat is played then. This will be as long as necessary to represent the rhythm accurately, including early and late beats.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/inevitable_cacophony/rhythm.rb', line 96

def canonical
	if duration != duration.to_i
		raise "Cannot yet canonicalise rhythms with non-integer length"
	end
        
	# Figure out the timing offset we need to allow for,
	# and space the beats enough to make it work.
	timing_offset_denominators = self.beats.map do |beat|
		beat.start_offset.rationalize.denominator
	end
	denominator = timing_offset_denominators.inject(1, &:lcm)
        
	scaled_duration = duration * denominator
	Array.new(scaled_duration).tap do |spaced_beats|
		self.beats.each_with_index do |beat, index|
			offset_index = index + beat.start_offset
			scaled_index = offset_index * denominator
			spaced_beats[scaled_index] = beat.amplitude
		end
	end
end

#durationInteger

Returns Total duration of all beats in this rhythm.

Returns:

  • (Integer)

    Total duration of all beats in this rhythm.



88
89
90
# File 'lib/inevitable_cacophony/rhythm.rb', line 88

def duration
	each_beat.sum(&:duration)
end

#each_beat(&block) ⇒ Object



83
84
85
# File 'lib/inevitable_cacophony/rhythm.rb', line 83

def each_beat(&block)
	@beats.each(&block)
end

#inspectObject



118
119
120
# File 'lib/inevitable_cacophony/rhythm.rb', line 118

def inspect
	"<#Rhythm duration=#{duration} @beats=#{beats.inspect}>"
end