From b377e9e8be96812ce19b5b942531e3847393ba92 Mon Sep 17 00:00:00 2001 From: Christopher Arndt Date: Mon, 29 Apr 2024 18:07:00 +0200 Subject: [PATCH] Implement dynamic cutoff param smoothing Signed-off-by: Christopher Arndt --- examples/dynparamsmooth.nim | 48 +++++++++++++++++++++++++++++++++++ examples/multimode_filter.nim | 6 ++--- 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 examples/dynparamsmooth.nim diff --git a/examples/dynparamsmooth.nim b/examples/dynparamsmooth.nim new file mode 100644 index 0000000..acdb97e --- /dev/null +++ b/examples/dynparamsmooth.nim @@ -0,0 +1,48 @@ +## Dynamic Smoothing Using Self Modulating Filter +## Andrew Simper, Cytomic, 2014, andy@cytomic.com +## public release: 6th Dec 2016 +## https://cytomic.com/files/dsp/DynamicSmoothing.pdf + +type + DynParamSmooth* = object + baseFreq: float + sensitivity: float + wc: float + low1: float + low2: float + inz: float + + +proc reset*(self: var DynParamSmooth) = + self.low1 = 0.0 + self.low2 = 0.0 + self.inz = 0.0 + + +proc setSampleRate*(self: var DynParamSmooth, sampleRate: float) = + self.wc = self.baseFreq / sampleRate + self.reset() + + +proc process*(self: var DynParamSmooth, sample: float): float = + let low1z = self.low1 + let low2z = self.low2 + let bandz = low1z - low2z + let wd = self.wc + self.sensitivity * abs(bandz) + let g = min(wd * (5.9948827 + wd * (-11.969296 + wd * 15.959062)), 1.0) + self.low1 = low1z + g * (0.5 * (sample + self.inz) - low1z) + self.low2 = low2z + g * (0.5 * (self.low1 + low1z) - low2z) + self.inz = sample + return self.low2 + + +proc initDynParamSmooth*( + baseFreq: float = 2.0, + sensitivity: float = 2.0, + sampleRate: float = 48_000.0 +): DynParamSmooth = + result.baseFreq = baseFreq + result.sensitivity = sensitivity + result.wc = result.baseFreq / sampleRate + result.reset() + diff --git a/examples/multimode_filter.nim b/examples/multimode_filter.nim index 8604d66..3c2c6c8 100644 --- a/examples/multimode_filter.nim +++ b/examples/multimode_filter.nim @@ -2,7 +2,7 @@ import nymph -import paramsmooth +import dynparamsmooth import svf const PluginUri = "urn:nymph:examples:multimode-filter" @@ -20,7 +20,7 @@ type q: ptr cfloat mode: ptr cfloat svf: FilterSV - smoothCutoff: ParamSmooth + smoothCutoff: DynParamSmooth proc instantiate(descriptor: ptr Lv2Descriptor; sampleRate: cdouble; @@ -28,7 +28,7 @@ proc instantiate(descriptor: ptr Lv2Descriptor; sampleRate: cdouble; Lv2Handle {.cdecl.} = let plug = createShared(SVFPlugin) plug.svf = initFilterSV(fmLowPass, sampleRate) - plug.smoothCutoff = initParamSmooth(20.0, sampleRate) + plug.smoothCutoff = initDynParamSmooth(sampleRate=sampleRate) return plug