Anyone know how to do RBJ EQ filters with an SVF? | Algorithm Design | Forum

Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Anyone know how to do RBJ EQ filters with an SVF?
Avatar
Member
Members
December 17, 2021 - 1:07 pm
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

G'day everyone. Hope all is well. Sorry for the long post.

Can anybody help me figure out how to translate biquad filter designs into something that can be realized with Will's State Variable filter structure?

I sort of understand biquads, but biquads simply do not behave well under heavy modulation, even with transposed canonical form and double precision coefficients.

Is there some set of steps I can follow to take the s domain transfer functions in RBJ's EQ cookbook, and convert them to coefficients for an SVF or Sallen Key filter? Or better still, how can I map z domain biquad transfer function coefficients to these VA/TPT SVF filter coefficients?

Andy Simper has a paper where they do exactly what I want to achieve, but the maths and matlab syntax go above my head, and it looks like they have built a different filter in code than the one will implements. (although it could be the matlab syntax obfuscating things for me.) https://cytomic.com/files/dsp/SvfLinearTrapOptimised2.pdf I haven't tied building the generalized version they illustrate in pseudo code yet, but it should be a trivial thing to do. If someone can help me figure out the similarities between this and Will's filter, if they exist, that would be lovely. I don't want to use the code from here as is, because I simply don't understand it and I don't want to use black boxes. (if it breaks, I'm helpless to fix it)

There's another paper http://www.dafx14.fau.de/paper.....s_for_.pdf which gets a bit closer to being a "how to convert a biquadratic z domain transfer function to a set of SVF coefficients." But I'm a bit fuzzy on what it is they're actually saying to do. And again, I'm not convinced they're using the same filter structure; but that's just because they've chosen to detail it in a mathematical form I simply do not understand or recognize. Code for this can be found here: https://github.com/iZotope/time_varying_filters_paper/blob/master/code/src/filter.cpp

Finally, there's this article, which does a similar job to the one above, although it actually suggests that for good time varying behavior, you can just break your filter into multiple smaller sections with the FIR part all in the first filter, and the IIR parts (to order n all being implemented serially after that. It's a good read, and very approachable as well. http://www.solostuff.net/wp-co.....v1.1.1.pdf

Avatar
Anglia
Member
Members
December 18, 2021 - 9:23 am
Member Since: June 2, 2014
Forum Posts: 46
sp_UserOfflineSmall Offline

... but the maths and matlab syntax go above my head, and it looks like they have built a different filter in code than the one will implements. (although it could be the matlab syntax obfuscating things for me.) ...

A little off topic, for which I apologise, but still:

Why don't people stop using Matlab and start using Python for mathematical applications?

The whole world (OK, a little exaggerated) speaks Python; it's taught in schools, used in the IT Industry, on the Pi, and is supported with a plethora of open-source libraries, such as scipy & numpy for scientific & mathematical applications, Jupyter Notebooks for communicating ideas, etc., etc. The list of good reasons to use Python never ends.

Seems like a no-brainer to me...

Avatar
Admin
December 22, 2021 - 7:19 am
Member Since: January 1, 2020
Forum Posts: 107
sp_UserOfflineSmall Offline

Hi Nikolai

The structure of a TPT/ZDF filter has no feed forward/back coefficients as in the RBJ & SVF biquads so a direct mapping isn't possible. If you wanted you could work backwards and derive the Omega and Q from those a and b coeffs and then use those to derive the coeffs of the corresponding ZDF filter but you'll need knowledge of it's type.

The 2pole SVF filter on p.5 of the third link you posted is exactly the implementation that I have been using for some time now. Sounds great and is completely stable. Handles high resonance much better than the biquads do. For bass sounds the difference is night and day. Cost is just a couple of extra operations compared to using the TDFII form. Another benefit is that you can utilize all the output taps simultaneously for band splitting purposes.

Maybe you missed it or didn't realize (there's some confusion surrounding the synonyms ZDF and TPT) but that exact p.5 code is already implemented in Will's ZVAFilter object in fxobjects (see p.330 of the effects book).

As well as the 2pole SVF variants with optional nonlinearity, you'll find there all the 1-pole ZDF types as well.

Those can be used as the building blocks for most other filter structures ( Butterworth/Shelves/Elliptic ) excepting ladder types. Sallen-Key for instance has a slightly different structure made from cascading two individual ZDF 1-poles (rather than individual integrators) within an encompassing ZDF loop. You may have to reference Vadim's work to derive a specific formulation for that.

Cheers

Avatar
Member
Members
December 23, 2021 - 6:23 pm
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

jim said
Hi Nikolai

The structure of a TPT/ZDF filter has no feed forward/back coefficients as in the RBJ & SVF biquads so a direct mapping isn't possible. If you wanted you could work backwards and derive the Omega and Q from those a and b coeffs and then use those to derive the coeffs of the corresponding ZDF filter but you'll need knowledge of it's type. . .

. . . . .
Maybe you missed it or didn't realize (there's some confusion surrounding the synonyms ZDF and TPT) but that exact p.5 code is already implemented in Will's ZVAFilter object in fxobjects (see p.330 of the effects book).

As well as the 2pole SVF variants with optional nonlinearity, you'll find there all the 1-pole ZDF types as well.

Those can be used as the building blocks for most other filter structures ( Butterworth/Shelves/Elliptic ) excepting ladder types. Sallen-Key for instance has a slightly different structure made from cascading two individual ZDF 1-poles (rather than individual integrators) within an encompassing ZDF loop. You may have to reference Vadim's work to derive a specific formulation for that.

Cheers  

G'day Jim. 🙂

I am aware of will's filters. I mentioned them explicitly to compare them with Andy Simper's derivation. They seem to be using similar thinking -- both are a kind of integrator replacement method -- but the coefficient calculations and difference equations for the SVF's are pretty different, and as I said, I don't have the head to grasp the maths behind why Simper's and Will's are different. (not for lack of trying or continuing to try, mind you. 😛 I'm missing something and dunno exactly how to describe it to others)

Ideally, I'd be able to read Vadim's book and understand how he goes from the standard "mother filter" types that will implemented in his book, to the conventional EQ cookbook filters, like what Andy Simper did. (Vadim even shows this happening in a keynote they did for ADC, but they don't appear to have shared those reaktor ensembles, nor did they explain how it works in the keynote.) I don't know what it is I'm missing, but it just isn't clear to me how Vadim goes from one to the other. It isn't a very practical text for laymen.

You mentioned the SVF described on page five of (I assume) "Fast Modulation of Filter Parameters: A Practical Guide. " I kept this around, as well as some other documents because I felt it might help explain how to go from an arbitrary transfer function, such as those available in RBJ's EQ cookbook, to a set of coefficients for our 2 pole SVF. . . But I've not worked out how to do that yet. 🙁 (which is frustrating, because it's all right there, freely available in Vadim's book! >.< ) Perhaps you know of a resource that might help me understand how to derive the coefficients for the SVF, given an s domain transfer function?

Avatar
Admin
December 29, 2021 - 11:20 am
Member Since: January 1, 2020
Forum Posts: 107
sp_UserOfflineSmall Offline

Andy's doing some pretty heady math there and approaches the problem differently via Nodal Analysis (°_°>) But on p.7 of his work note that allpass and notch types are derived very simply from his SVF outputs.

 

Practically speaking all of the RBJ eq types can be obtained just from mixing the SVF taps already available;

BPn = BP / Q                             /// bandpass normalized to unity

Input = LP + HP + BPn              /// no effect, flat freq/phase response for comparison

APF = LP + HP - BPn                 /// reforms the input but with a 180° phase flip at the cutoff

Notch = LP + HP                       /// phases diverge 180° approaching the cutoff creating a notch on summing

 

Adding/subtracting the bandpass to the dry signal forms a peaking eq but the bell width shifts depending on the gain, rescale resonance to compensate.

A = 10^( gain/20 )                    /// gain factor ( -12db = .25, 0db = 1, +12db = 4.)

Peak = In + BPn * ( A - 1 )         /// with modified Q = Q * sqrt( A );

 

The shelves shift their effective cutoff depending on the gain, rescale ω to compensate.

Low Shelf  = In + LP * ( A - 1 ) + BPn * ( sqrt(A) - 1. )              /// modified cutoff = cutoff * 1/sqrt(sqrt(A))

High Shelf = In + HP * ( A - 1 ) + BPn * ( sqrt(A) - 1. )              /// modified cutoff = cutoff * sqrt(sqrt(A))

 

Note that sqrt(sqrt(A)) = 10^( gain/80 ) so for those implementations you can compute that & then square back to A.

I highly recommend Reaktor both as a resource and a prototyping tool.  Additionally to Vadim's ZDF framework there's a ton of other cool stuff lurking in the User Library including (off-topic) a FFT based autotuner.

Avatar
Member
Members
December 29, 2021 - 10:33 pm
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

I appreciate that, Jim. Thanks for sharing.  🙂

How did you come up with that stuff? I feel like I have no idea. Vadim goes over the normalized bandpass SVF -- not sure if its the same off the top of my head. I'm sure I read some of the other stuff you mentioned somewhere, either in RBJ''s cookbook/other notes, or in Vadim's book.

Where did you learn about filter design? I would really like to be able to do this kind of thing for myself. (don't like being a bother to others, even though I often think I am. ) I feel like Vadim's book has everything one would need, but it's far from an introductory text for folks like me. Even Julius Smith's dense introduction to digital filters is a bit easier to follow than Vadim's book (provided you read some of the prerequisite material and come with an algebra reference textbook. Still nowhere near as comprehensible as most of Will's effects book though.) . . . I thought I could pair these texts with Will's books and a few other notes and texts I've found to fill in the gaps, but something is still missing. Will gives a super thorough introduction to biquads and going from analog to digital filters with the bilinear transform, but I don't know of a very general: "given a transfer function, build a VA/TPT filter that implements it -- perhaps using pole/zero analysis."  Maybe my maths foundation isn't strong enough to see how obvious it really is.

Avatar
Admin
January 10, 2022 - 9:49 am
Member Since: January 1, 2020
Forum Posts: 107
sp_UserOfflineSmall Offline

Happy to help Nick (^v^)

There was a recent KVR discussion about implementing the peaking filters here that's relevant, generally pay attention to anything Mystran says.

I feel the same as you about those authors though, am much happier with practical examples. I've achieved most of my learning through building/experimentation and focused less on theory where possible. A few of years ago Vadim began a tutorial on the Reaktor forums to explain an exceptional (inefficient!&*) sounding 4pole he had derived. He took an overly rigorous, theoretical approach and unfortunately stopped short with no-one wanting to formally explain the correctness of saying A+B = B+A for the nth time in the thread. Some info up to there may help though.

A good source is at Earlevel Engineering. His Biquad calculator has been updated & you can see the Javascript implementations for the transfer functions there by clicking into the websites code.

More good info on ZDF's here from Urs

It's still reasonable btw to use RBJ DFII biquads in situations where modulation or resonance aren't required ie. for IIR oversampling I don't think there is anything to be gained with ZDF so it's better to save the operations.

A quick prototyping workflow is best for trying out as many ideas as possible. There's an art to dsp so experimentation is beneficial. I used Reaktor as a vst hosted within plugin dr. while writing the above post for assistance.

Cheers

Avatar
Member
Members
January 12, 2022 - 12:12 pm
Member Since: June 16, 2021
Forum Posts: 43
sp_UserOfflineSmall Offline

jim said

It's still reasonable btw to use RBJ DFII biquads in situations where modulation or resonance aren't required ie. for IIR oversampling I don't think there is anything to be gained with ZDF so it's better to save the operations.

What's wrong with adding a little resonance or moderate Q to RBJ direct form filters? To my knowledge, they are identical to the TPT filters when you aren't moving the cutoff, so for a static EQ they should be the same; apart from the TPT filter's superior saturation and extremely high Q behavior. But for more typical resonating filters found in most EQ's, wouldn't double precision TDF 2 filters with a snudge of oversampling or analog matching be all you need? (and even the TPT filters need to be over-sampled to get the bells and shelves to behave as you'd expect them to. ) Am I missing something? (I'm aware of some other precision limits associated with DF biquads, particularly high pass filters, but that's why I mentioned double precision -- I'm pretty sure most if not all of those errors become vanishingly small in that case. )

And even for time varying filters, I'm told a lattice structure works well. . . Not that anyone said it was more efficient. And I can't even find anything on building lattice filters that aren't all pas filters. (Will uses lattice structures for his all pass filters in the reverb section of the effects book) . . . It may be that you can only do lattice all passes, and you're supposed to sum that with the dry signal to obtain the response you want. Which makes some sense to me; after all, you can build an all pass out of a first order low or high pass, or a second order band pass with simple polarity inversion and output mixing. No reason it shouldn't work the other way around, I suppose. 😛 (actually, isn't that how the 'mitra' filters work as well? . . . hmmmm  Gosh this stuff is fun to speculate about. 😛 )

Forum Timezone: America/New_York

Most Users Ever Online: 152

Currently Online:
2 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

Chaes: 56

Skyler: 48

StevieD: 46

Derek: 46

Frodson: 45

Peter: 43

TheSmile: 43

Nickolai: 43

clau_ste: 39

jeanlecode: 37

Member Stats:

Guest Posters: 2

Members: 782

Moderators: 1

Admins: 6

Forum Stats:

Groups: 13

Forums: 42

Topics: 849

Posts: 3370

Moderators: W Pirkle: 693