aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2016-05-30 00:23:16 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2016-06-01 13:40:17 +0200
commitabdcfb5ec271fe585e93f7d79bd109996d5294b2 (patch)
treeb5a09638c07cb538a970836290493ac993b5f97f
parentec26104cb74ad525d0883700ddc878fa71aee2b5 (diff)
downloadapplause2-abdcfb5ec271fe585e93f7d79bd109996d5294b2.tar.gz
implemented delay lines and echo effect
* DelayStream must currently have a constant length (ie. duration) * Stream:mix() allows mixing two streams by a constant wet/dryness factor. 0 means only the first stream, while 1 is only the second stream. * Stream:echo() builds on this for an echo effect with constant delay and wetness factor. The source stream is automatically synced.
-rw-r--r--applause.lua51
1 files changed, 51 insertions, 0 deletions
diff --git a/applause.lua b/applause.lua
index 06e3242..91c879a 100644
--- a/applause.lua
+++ b/applause.lua
@@ -327,6 +327,20 @@ function Stream:ravel()
return RavelStream:new(self)
end
+function Stream:mix(other, wetness)
+ wetness = wetness or 0.5
+ return self:mul(1 - wetness) + other:mul(wetness)
+end
+
+function Stream:delay(length)
+ return DelayStream:new(self, length)
+end
+
+function Stream:echo(length, wetness)
+ local synced = self:sync()
+ return synced:mix(synced:delay(length), wetness)
+end
+
-- This is a linear resampler thanks to the
-- semantics of IndexStream
function Stream:resample(factor)
@@ -1510,6 +1524,43 @@ function PinkNoiseStream:tick()
end
--
+-- Delay Lines
+-- NOTE: Echoing could be implemented here as well since
+-- delay lines are only an application of echoing with a wetness of 1.0.
+-- However this complicates matters because we have to handle nil.
+--
+
+DelayStream = DeriveClass(MuxableStream)
+
+DelayStream.sig_last_stream = 1
+
+function DelayStream:muxableCtor(stream, length)
+ self.streams = {stream}
+ self.length = length
+ if length < 1 then error("Invalid delay line length") end
+end
+
+function DelayStream:tick()
+ local tick = self.streams[1]:tick()
+ local length = self.length
+ local buffer = table.new(length, 0)
+ local buffer_pos = 1
+
+ for i = 1, length do buffer[i] = 0 end
+
+ return function()
+ local sample = buffer[buffer_pos]
+ buffer[buffer_pos] = tick()
+ buffer_pos = (buffer_pos % length) + 1
+ return sample
+ end
+end
+
+function DelayStream:len()
+ return self.length + self.streams[1]:len()
+end
+
+--
-- MIDI Support
--