Created
August 15, 2012 03:55
-
-
Save olexpono/3355702 to your computer and use it in GitHub Desktop.
little bitty LFO class for ruby-processing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# LFO for ruby-processing | |
# Calculates a triangle or sine function for a given frame. | |
# triangle wave min/rising/max/down ./`\ from [0..1] | |
# sine wave sine is 0/1/0/-1/0 | |
# The current location of the wave can skip if you change | |
# the tempo on the fly, each LFO location is not simulated. | |
# | |
# Usage: | |
# create new lfo with a some tempo in frames: | |
# @lfo_engine = BasicLFO.new(100) | |
# | |
# call every frame to run, don't call and the lfo will be paused: | |
# @lfo_engine.ping frame_count | |
# | |
# now the fun stuff: | |
# | |
# rect 0, 0, width * @lfo_engine.lfo(:sine), width * @lfo_engine.lfo(:triangle) | |
# | |
# 10.times do |i| | |
# sector_x = i * (width/10) | |
# sector_x2= (i+1) * (width/10) | |
# sec_height = height/2 + height/2 * @lfo_engine.lfo(:sine , 0.1 * i) | |
# rect sec_x, 0, (width/10), sec_height | |
# end | |
# | |
class BasicLFO | |
def initialize(tempo=120, frame_count=0) | |
# TODO - lfo half-rate needs to actually be tempo | |
@tempo = tempo.to_f | |
@frame_reset_count = frame_count | |
@count_this_frame = frame_count | |
end | |
# Resets logical frame count | |
def reset!(frame_count) | |
@frame_reset_count = frame_count | |
@count_this_frame = frame_count | |
end | |
# Pings and updates logical frame count | |
# i.e. call it at start of draw. | |
def ping(frame_count) | |
@count_this_frame = frame_count - @frame_reset_count | |
@rising = {} if @rising.nil? | |
@rising.clear | |
end | |
# number of frames for the animation / 2 | |
# this tempo is the time in frames for one rise or fall | |
# (full cycle = 2x tempo frames) | |
def tempo=(new_tempo) | |
@tempo = new_tempo.to_f | |
end | |
# phase [0.0..2.0] - rotates value 360 degrees through the function | |
# Returns value between 0.0 and 1.0 for :triangle | |
# Returns value between -1.0 and 1.0 for :sine (yeah I'm lazy) | |
# | |
# This is ripe for optimization around [current_frame & wave & phase] | |
def lfo(wavetype = :triangle, phase = 0.0) | |
triangle = (((@count_this_frame % @tempo) + (phase * @tempo)) % @tempo ) / @tempo | |
triangle = 1.0 - triangle unless rising?(phase) | |
return triangle if wavetype == :triangle | |
sine = Processing::App::sin(triangle * Math::PI) | |
sine = -sine unless rising?(phase) | |
return sine if wavetype == :sine | |
0.5 | |
end | |
# hmm... | |
def lfov2(wavetype = :triangle, phase = 0.0) | |
end | |
# Internal - calculates whether rising or not | |
# Returns true from frames [0..tempo], false for frames [tempo..2*tempo] | |
# | |
# this _definitely_ could be cached | |
def rising?(phase) | |
(((@count_this_frame + phase * @tempo) / @tempo).to_i % 2 ) == 1 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment