summaryrefslogtreecommitdiff
path: root/scripts/HiAndLowPass.lua
diff options
context:
space:
mode:
authorJulien _FrnchFrgg_ RIVAUD <frnchfrgg@free.fr>2016-07-18 11:09:01 +0200
committerRobin Gareus <robin@gareus.org>2016-07-18 11:15:09 +0200
commitd527fdf30a565e11d39edea1183237e98d15a788 (patch)
tree884c160c29c1bb07968bdbeb49288c12c2fd2b3d /scripts/HiAndLowPass.lua
parent7e1a722a15e02ef159b54bd294736f328d42ff29 (diff)
Simplify the logic in HiAndLowPass filter
And beef up comments for readers using the filter as an example.
Diffstat (limited to 'scripts/HiAndLowPass.lua')
-rw-r--r--scripts/HiAndLowPass.lua81
1 files changed, 43 insertions, 38 deletions
diff --git a/scripts/HiAndLowPass.lua b/scripts/HiAndLowPass.lua
index f9e18f4912..fce099b6e9 100644
--- a/scripts/HiAndLowPass.lua
+++ b/scripts/HiAndLowPass.lua
@@ -4,7 +4,7 @@ ardour {
category = "Filter",
license = "GPLv2",
author = "Ardour Team",
- description = [[High Low Pass filter with up to 48dB / octave]]
+ description = [[An Ardour High and Low Pass Filter with de-zipped controls, written in Lua]]
}
function dsp_ioconfig ()
@@ -85,6 +85,12 @@ function dsp_configure (ins, outs)
lp[c] = {}
-- initialize filters
-- http://manual.ardour.org/lua-scripting/class_reference/#ARDOUR:DSP:Biquad
+
+ -- A different Biquad is needed for each pass and channel because they
+ -- remember the last two samples seen during the last call of Biquad:run().
+ -- For continuity these have to come from the previous audio chunk of the
+ -- same channel and pass and would be clobbered if the same Biquad was
+ -- called several times by cycle.
for k = 1,4 do
hp[c][k] = ARDOUR.DSP.Biquad (tbl['samplerate'])
lp[c][k] = ARDOUR.DSP.Biquad (tbl['samplerate'])
@@ -160,59 +166,58 @@ function dsp_run (ins, outs, n_samples)
-- process all channels
for c = 1, #ins do
+ -- High Pass
local xfade = cur[1] - ho
+ -- prepare scratch memory
ARDOUR.DSP.copy_vector (mem:to_float (off), ins[c]:offset (off), siz)
- -- initialize output
- if cur[1] == 0 then
- -- high pass is disabled, just copy data.
- ARDOUR.DSP.copy_vector (outs[c]:offset (off), mem:to_float (off), siz)
- else
- -- clear output, The filter mixes into the output buffer
- ARDOUR.DSP.memset (outs[c]:offset (off), 0, siz)
+ -- run at least |ho| biquads...
+ for k = 1,ho do
+ hp[c][k]:run (mem:to_float (off), siz)
+ end
+ ARDOUR.DSP.copy_vector (outs[c]:offset (off), mem:to_float (off), siz)
+
+ -- mix the output of |ho| biquads (with weight |1-xfade|)
+ -- with the output of |ho+1| biquads (with weight |xfade|)
+ if xfade > 0 then
+ ARDOUR.DSP.apply_gain_to_buffer (outs[c]:offset (off), siz, 1 - xfade)
+ hp[c][ho+1]:run (mem:to_float (off), siz)
+ ARDOUR.DSP.mix_buffers_with_gain (outs[c]:offset (off), mem:to_float (off), siz, 1 - xfade)
+ ho = ho + 1 -- to avoid running another time the biguad |ho+1|
end
- -- high pass
- -- allways run all filters so that we can interplate as needed.
- for k = 1,4 do
- if xfade > 0 and k == ho + 1 then
- ARDOUR.DSP.mix_buffers_with_gain (outs[c]:offset (off), mem:to_float (off), siz, 1 - xfade)
- end
-
+ -- run remaining biquads because they need to have the correct state
+ -- in case they start affecting the next chunck of output
+ -- TODO: only run the ones that have a chance to run next cycle
+ for k = ho+1,4 do
hp[c][k]:run (mem:to_float (off), siz)
-
- if k == ho and xfade == 0 then
- ARDOUR.DSP.copy_vector (outs[c]:offset (off), mem:to_float (off), siz)
- elseif k == ho + 1 then
- ARDOUR.DSP.mix_buffers_with_gain (outs[c]:offset (off), mem:to_float (off), siz, xfade)
- end
end
- -- low pass
+ -- Low Pass
xfade = cur[4] - lo
- -- copy output of high-pass into "processing memory"
+ -- prepare scratch memory (from high pass output)
ARDOUR.DSP.copy_vector (mem:to_float (off), outs[c]:offset (off), siz)
- if cur[4] > 0 then
- -- Clear output, Low-pass mixes interpolated data into output.
- -- (Except if the filter is disabled (0) in which case we just keep the output.)
- ARDOUR.DSP.memset (outs[c]:offset (off), 0, siz)
+ -- run at least |lo| biquads...
+ for k = 1,lo do
+ lp[c][k]:run (mem:to_float (off), siz)
+ end
+ ARDOUR.DSP.copy_vector (outs[c]:offset (off), mem:to_float (off), siz)
+
+ -- mix the output of |lo| biquads (with weight |1-xfade|)
+ -- with the output of |lo+1| biquads (with weight |xfade|)
+ if xfade > 0 then
+ ARDOUR.DSP.apply_gain_to_buffer (outs[c]:offset (off), siz, 1 - xfade)
+ lp[c][lo+1]:run (mem:to_float (off), siz)
+ ARDOUR.DSP.mix_buffers_with_gain (outs[c]:offset (off), mem:to_float (off), siz, 1 - xfade)
+ lo = lo + 1 -- to avoid running another time the biguad |lo+1|
end
- for k = 1,4 do
- if xfade > 0 and k == lo + 1 then
- ARDOUR.DSP.mix_buffers_with_gain (outs[c]:offset (off), mem:to_float (off), siz, 1 - xfade)
- end
-
+ -- again, run remaining biquads
+ for k = lo+1,4 do
lp[c][k]:run (mem:to_float (off), siz)
-
- if k == lo and xfade == 0 then
- ARDOUR.DSP.copy_vector (outs[c]:offset (off), mem:to_float (off), siz)
- elseif k == lo + 1 then
- ARDOUR.DSP.mix_buffers_with_gain (outs[c]:offset (off), mem:to_float (off), siz, xfade)
- end
end
end