From d5ae3fdde5b22fd0e66f6e9c27eb08c23f0274ba Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Thu, 15 Sep 2016 01:43:10 +0200 Subject: fixed SawOsc and support a scalar phase argument for all oscillators * SawOsc has been broken for a long time * phases are useful since they are trivial to implement at the Phasor level and cumbersome to emulate using SubStream (basically you would need :sub(sec(1)/freq*phase)). Also, this way, phases will work even for modulated frequencies or if the frequency is unknown. They should come with no additional runtime overhead. --- applause.lua | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/applause.lua b/applause.lua index 70aaf21..a52b617 100644 --- a/applause.lua +++ b/applause.lua @@ -375,41 +375,45 @@ end -- -- Ramp from 0 to 1 -function Stream.Phasor(freq) +function Stream.Phasor(freq, phase) + phase = phase or 0 + return ScanStream:new(freq, function(accu, f) - return ((accu or 0) + f/samplerate) % 1 + return ((accu or phase) + f/samplerate) % 1 end) end -- Saw tooth wave from -1 to 1 -function Stream.SawOsc(freq) +function Stream.SawOsc(freq, phase) + phase = (phase or 0)*2+1 + return ScanStream:new(freq, function(accu, f) - return ((accu or 1) + 2*f/samplerate) % 2 - end):sub(1) + return ((accu or phase) + 2*f/samplerate) % 2 + end):minus(1) end -function Stream.SinOsc(freq) - return Stream.Phasor(freq):mul(2*math.pi):sin() +function Stream.SinOsc(freq, phase) + return Stream.Phasor(freq, phase):mul(2*math.pi):sin() end Stream["\u{25CB}"] = Stream.SinOsc -- APL Circle -- Pulse between 0 and 1 in half a period (width = 0.5) -function Stream.PulseOsc(freq) - return Stream.Phasor(freq):map(function(x) +function Stream.PulseOsc(freq, phase) + return Stream.Phasor(freq, phase):map(function(x) return x < 0.5 and 1 or 0 end) end -function Stream.SqrOsc(freq) - return Stream.Phasor(freq):map(function(x) +function Stream.SqrOsc(freq, phase) + return Stream.Phasor(freq, phase):map(function(x) return x < 0.5 and 1 or -1 end) end -function Stream.TriOsc(freq) +function Stream.TriOsc(freq, phase) local abs = math.abs - return Stream.SawOsc(freq):map(function(x) + return Stream.SawOsc(freq, phase):map(function(x) return abs(x)*2 - 1 end) end -- cgit v1.2.3