Cheap non-linear zero-delay filters

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

This also works with aliasing suppression for the tanh harmonics:

viewtopic.php?f=33&t=486252&p=6822981#p6822981

Post

mystran wrote: Sat Jul 13, 2013 12:11 pm
andy_cytomic wrote:In emails with Mystran he has said that his method of using f(x)/x for non-linearities is already contained in the source code of certain circuit simulation packages, possibly as fallback methods for stability.
Well I haven't really found any source code utilizing the code, but in a book (and I regret forgetting which one it was, couldn't find it later) about circuit simulation methods there was a comparison between various iterative methods, including fixed-point, secant, this method and Newton. The author referred to the method mentioned here as the "BLAS-3" method and basically said that it's not been studied too carefully, but suspected the convergence (with iteration) should be somewhere between linear and that of secant method (which is about sqrt(2)).

Personally, from empirical observations, I suspect the convergence is damn near linear. As far as I'm concerned, the only advantage over Newton (or secant) is that a truncated iteration (most notably single evaluation only) tends to result in something that isn't totally useless (as could happen with Newton).
I actually followed this up and the book you are referring to that mentions the BIAS-3-A method is:
https://books.google.com.au/books?id=PZ ... navlinks_s
Fundamentals of Computer-Aided Circuit Simulation (2012)
William J. McCalla

Which reference this paper:
https://ieeexplore.ieee.org/abstract/document/1050153
BIAS-3-A program for the nonlinear D.C. analysis of bipolar transistor circuits (1972)
W.J. McCalla ; W.G. Howard

It is also called the "Line through the origin method" or "Conductance only" method etc etc.

Google got the image to text wrong, so you can only find this book by searching for "BLAS-3" but the actual method was called "BIAS-3-A"
The Glue, The Drop, The Scream - www.cytomic.com

Post

Right... in any case the method isn't something original I came up, except as far as I rediscovered it before finding out that it was a rediscovery... which is what often happens when you try to figure out something that other people have also worked on in the past. :)

Post

mystran wrote: Mon May 18, 2020 2:57 pm Right... in any case the method isn't something original I came up, except as far as I rediscovered it before finding out that it was a rediscovery... which is what often happens when you try to figure out something that other people have also worked on in the past. :)
Mystran: thanks so much for your multiple contributions to music-dsp, really appreciated.

I realise you didn't try and claim you came up with it, I just wanted to tie up the loose ends and show where it actually came from for everyone else here, since the names of the papers / books were never shown, and I think it's good for people to have references to read when it comes to different methods, so they can see them in a larger context.

I've made some variations based on this conductance only method which I use in production code for The Drop, so thanks again for making me aware of it :)
The Glue, The Drop, The Scream - www.cytomic.com

Post

mystran wrote: Fri May 18, 2012 2:40 pm Regarding CEM3320 datasheet 91k vs 100k: if my limited EE understanding doesn't fail me, and we assume the stages are true low-pass stages, then one would expect voltage gain of 100k/91k ~ 1.1 per stage which results in total gain of 1.458 or so, eg (still assuming tanh()):

Code: Select all

 dV0/dt = f * tanh( 1.1 * in - r * limit(V3) - v0) 
 dV1/dt = f * tanh( 1.1 * v0 - v1 ) 
 dV2/dt = f * tanh( 1.1 * v1 - v2 ) 
 dV3/dt = f * tanh( 1.1 * v2 - v3 ) 
The resonance VCA is still a question mark. If it's safe to assume it's a simple OTA and the input resistor to ground (3.5k) is also what the other gain cells have (or had if they were OTAs), then we'd have roughly a gain of 1.96 ~ 2 from 51k resistor from audio out. Maybe one could calculate that from the values given in the datasheet but I'm too tired to figure out an obvious way right now. Anyway, the assumption would give:

Code: Select all


 r' = r / (1.458 * 1.96) ~ r / ( 2.86 ) 

 dV0/dt = f * tanh( 1.1 * in - r' * tanh(1.96 * V3) - v0) 
 dV1/dt = f * tanh( 1.1 * v0 - v1 ) 
 dV2/dt = f * tanh( 1.1 * v1 - v2 ) 
 dV3/dt = f * tanh( 1.1 * v2 - v3 )


That sounds quite reasonable actually (with resonance clipping before the stages start going foobar). Unfortunately I have no such filter to measure against..

edit: sound sample for the above (if I didn't make any mistakes) http://www.signaldust.com/files/cascade.mp3
(mp3 but high bitrate.. oh and 44.1kHz host rate with x4 oversampling)

I think that's not too bad, whether or not it models anything :D
What is "a typical" input level for such a filter model. I noticed -1 -> 1 sounds too saturated
giq

Post

If you read the original patent, a CEM 3320 model wouldn't have many tanh() terms. The distortion is asymmetric, but each stage is inverting, thus some distortion cancels out, but at low cutoffs you get considerable modulation bleed-through in a lowpass setting. At audio rate modulation, you can actually hear the modulation signal almost 1:1 on the output when Cutoff is all the way down.

(also, the levels within the stages are all over the place and vary from unit to unit, where "unit" for me are specimen in old Sequential synths - part of the differences we put into our models is simply gain staging based on measurements)

Post

Urs wrote: Sat Mar 27, 2021 2:38 am If you read the original patent, a CEM 3320 model wouldn't have many tanh() terms.
Yeah, that quoted old post of mine is really old and I wrote it before I'd looked into the patent for details. Such a tanh() filter is closed to the later (assuming the part numbers go roughly in order; not in the mood to start hunting for release dates) Curtis filters.

From memory, the short version of the patent (for CEM3320) is that ignoring the current mirrors (which are probably not negligible), there is an exp(vIn + vCV) terms for each stage where the signal itself is "small" such that the response is "approximately linear" where as the CV term is "large" and sets the bias such that the signal is (approximately) multiplied by the slope set by the CV term. There is one of these per pole and then one extra without a signal, where the latter is subtracted to (supposedly) cancel out the exp(vCV) part.

ps. Also before you try, I'll save you some trouble: the CEM3320 type circuit doesn't work well with the cheap method.

Post

Doesn't work well with Newton Raphson either, because an overshoot in the exp() terms can have heavy consequence. Worse even when you try to reverse the computation (as described for the SEM-style filter in Vadim's book), because you'll easily get NaNs (when log() terms undershoot 0)

Post

Urs wrote: Sat Mar 27, 2021 4:01 am Doesn't work well with Newton Raphson either, because an overshoot in the exp() terms can have heavy consequence. Worse even when you try to reverse the computation (as described for the SEM-style filter in Vadim's book), because you'll easily get NaNs (when log() terms undershoot 0)
In my experience NR almost always works perfectly fine with exp() as long as you iterate log() whenever the voltage is large and then exp() again when it's small.

Post

Sorry my electronics knowledge is quite basic, reading about bleeding and trying to imagine this, is each stage like?

dV1/dt = exp( (V0 - V1)*a + cv )
giq

Post

itoa wrote: Sat Mar 27, 2021 7:49 am Sorry my electronics knowledge is quite basic, reading about bleeding and trying to imagine this, is each stage like?

dV1/dt = exp( (V0 - V1)*a + cv )
I'm not sure what "a" here is supposed to be, but you need to subtract the constant cv-term, something like:

dv1/dt = exp(v0 - v1 + cv) - exp(cv)

Also the current mirrors are probably not negligible, but I don't think I ever really looked into those too carefully, because personally I don't like the sound of this type of filter.

Post

Thanks a lot.. "a" is an "unknown scaling factor" :)

I wonder how important is using exp here, while probably it operates in a small, "almost linear" exp curve range.
giq

Post

Hi mystran I was wondering if you knew if it’s possible to cheat lambertsw with the pivotal method

Currently using boost but it’s still pretty cpu heavy for 6 stage wavefolder

Post

Marvinh wrote: Wed Dec 04, 2024 12:43 pm Hi mystran I was wondering if you knew if it’s possible to cheat lambertsw with the pivotal method

Currently using boost but it’s still pretty cpu heavy for 6 stage wavefolder
If you want someone to help you, then you will have to describe in at least some detail what it is that you are trying to do. I suspect the answer might still be "no" because Lambert W isn't really the sort of symmetric function that this method works best with .. but like.. that's just a wild guess when I have no idea whatsoever what it might be that you're trying to do.

Post

Sorry about that it is a single stage of a wave folder I have 6 of them in series
The function is described like this for lamberts w

y*exp(y)=x

This is the W() in the photo

I don’t understand myself really but it’s from this paper

Virtual Analog Models of the Lockhart and
Serge Wavefolders

As a final step, we insert Equation (38) into Equation (31) to derive a complete expression for the
transfer function of a single wavefolding stage in the Serge middle VCM:

I have one feeding into the next in series of 6

Didn’t mean to be rude my bad

It is iterating to a solution every time I call the Lambertw I am trying to prevent that with a cheaper guess or do it all in one iteration or split to 2 and 4 series

Everything is a constant in the equation vin is the input except that w() function

Edit: Shockley diode equation evaluates to almost the same thing in this configuration actually but I couldnt ignore one of the resistors like he does in the paper
You do not have the required permissions to view the files attached to this post.

Return to “DSP and Plugin Development”