If you have a problem or need to report a bug please email : support@dsprobotics.com
There are 3 sections to this support area:
DOWNLOADS: access to product manuals, support files and drivers
HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects
USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here
NEW REGISTRATIONS - please contact us if you wish to register on the forum
Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright
Magic IIR Biquad - testing
20 posts
• Page 1 of 2 • 1, 2
Magic IIR Biquad - testing
I am attaching a .fsm containing a "magic" IIR Biquad, F modulatable and Q modulatable, not requiring trigonometrics.
I discovered it inside a .fsm recently published by Martin Vicanek, nested into a hierarchical tree that's implementing a (supposedly) phase-synchronous 6-band frequency splitter. The examination of the x86 SSE code of the many IIR LP and HP Biquads revealed a surprise. The LP and HP variants are 99% identical. Their common x86 SSE code (from where it comes, who authored it, I ignore) is always computing the LP signal, the BP signal, and the HP signal, at very little CPU% expense, the code being so compact. Consequently, originally, the only difference between the LP and the HP variant, was the output pin assignation, as there was only one, LP or HP.
If I remember, Martin Vicanek had a difficulty in generating the AP (allpass) that was required for guaranteeing the phase synchronicity, this in the context of a multi Linkwitz-Riley arrangement.
A few days ago, I modded such magic IIR Biquad for transforming it into a "universal" IIR Biquad that's outputting the three fundamental signals: LP, BP and HP. Kind of audio prism. This way one can explore what's happening after externally mixing the LP, BP and HP outputs in various proportions between (-1.0 and +1.0). In case you've never done this, start now. The attached .fsm will help you. This is very rewarding.
Unfortunately, the magic IIR Biquad looks like it got published, not yet mature. I am saying this because the summation of its three outputs doesn't deliver unity.
Consequently, such "magic" IIR Biquad is not yet a recommendable building block. It may ruin an entire project. Let me tell the details. The output phases are incorrect, the Fr control must be a fraction of Fs/2 (like the Flowstone sine generator component) instead of a more easy to remember fraction of Fs, and the BP output is "constant skirt" which means it provides gain at high Q, which means it can easily saturate the hardware, and, most important, it prevents the LP + BP + LP summation to deliver unity.
I have not checked what's happening when specifying Q = zero.
I don't know if it crashes, then. I don't know it it gently folds back to a 1st order, then.
I think the time has come for me to learn the basics of x86 SSE coding. The required mods are probably trivial for somebody accustomed to modding a x86 SSE routine. Can somebody please show and explain, step by step, the mods that are required, always remaining cautious about denorm and other possible traps?
Much appreciated, would be that when the supplied Q value is below 0.1, that the magic Biquad folds back to a 1st order, the BP output becoming muted.
But wait a minute, one must ensure that such behavior never can trigger a denorm issue.
Therefore, please tell what is the more effective strategy, speaking of x86 SSE modules, for never triggering a denorm issue inside, and never triggering a denorm issue in the following modules.
Have a nice day.
I discovered it inside a .fsm recently published by Martin Vicanek, nested into a hierarchical tree that's implementing a (supposedly) phase-synchronous 6-band frequency splitter. The examination of the x86 SSE code of the many IIR LP and HP Biquads revealed a surprise. The LP and HP variants are 99% identical. Their common x86 SSE code (from where it comes, who authored it, I ignore) is always computing the LP signal, the BP signal, and the HP signal, at very little CPU% expense, the code being so compact. Consequently, originally, the only difference between the LP and the HP variant, was the output pin assignation, as there was only one, LP or HP.
If I remember, Martin Vicanek had a difficulty in generating the AP (allpass) that was required for guaranteeing the phase synchronicity, this in the context of a multi Linkwitz-Riley arrangement.
A few days ago, I modded such magic IIR Biquad for transforming it into a "universal" IIR Biquad that's outputting the three fundamental signals: LP, BP and HP. Kind of audio prism. This way one can explore what's happening after externally mixing the LP, BP and HP outputs in various proportions between (-1.0 and +1.0). In case you've never done this, start now. The attached .fsm will help you. This is very rewarding.
Unfortunately, the magic IIR Biquad looks like it got published, not yet mature. I am saying this because the summation of its three outputs doesn't deliver unity.
Consequently, such "magic" IIR Biquad is not yet a recommendable building block. It may ruin an entire project. Let me tell the details. The output phases are incorrect, the Fr control must be a fraction of Fs/2 (like the Flowstone sine generator component) instead of a more easy to remember fraction of Fs, and the BP output is "constant skirt" which means it provides gain at high Q, which means it can easily saturate the hardware, and, most important, it prevents the LP + BP + LP summation to deliver unity.
I have not checked what's happening when specifying Q = zero.
I don't know if it crashes, then. I don't know it it gently folds back to a 1st order, then.
I think the time has come for me to learn the basics of x86 SSE coding. The required mods are probably trivial for somebody accustomed to modding a x86 SSE routine. Can somebody please show and explain, step by step, the mods that are required, always remaining cautious about denorm and other possible traps?
Much appreciated, would be that when the supplied Q value is below 0.1, that the magic Biquad folds back to a 1st order, the BP output becoming muted.
But wait a minute, one must ensure that such behavior never can trigger a denorm issue.
Therefore, please tell what is the more effective strategy, speaking of x86 SSE modules, for never triggering a denorm issue inside, and never triggering a denorm issue in the following modules.
Have a nice day.
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: Magic IIR Biquad - testing
The filter is a ZDF implementation of a state variable filter (SVF) with trapezoidal integrators, taken from https://www.native-instruments.com/file ... _2.1.0.pdf.
For given cutoff frequency and Q-value (resonance) its transfer function is that of a biquad. A nice feature of the SVF topology is that you get three filters at the cost of one. You can combine the outputs to create even more filter types. The filter performs better at low frequencies compared to a direct form biquad. Perhaps the most desirable feature, however, is its robustness against fast modulation.
The calcualtion of the filter coefficients happens in the hopped preamble. I have used a very lightweight rational approximation of the tangent function which, however, results in a tuning accurate to a fraction of a semitone. In the schematic below I have rescaled the Bandpass output so the sum of all outputs adds to 1.
With increasing Q the filter gets more resonant. For Q<=0.5 the poles a real, which means you would get the same transfer curve with two cascaded 1st order filters. However, Q=0 is not a meaningful limit (not a 1st order filter).
For given cutoff frequency and Q-value (resonance) its transfer function is that of a biquad. A nice feature of the SVF topology is that you get three filters at the cost of one. You can combine the outputs to create even more filter types. The filter performs better at low frequencies compared to a direct form biquad. Perhaps the most desirable feature, however, is its robustness against fast modulation.
The calcualtion of the filter coefficients happens in the hopped preamble. I have used a very lightweight rational approximation of the tangent function which, however, results in a tuning accurate to a fraction of a semitone. In the schematic below I have rescaled the Bandpass output so the sum of all outputs adds to 1.
With increasing Q the filter gets more resonant. For Q<=0.5 the poles a real, which means you would get the same transfer curve with two cascaded 1st order filters. However, Q=0 is not a meaningful limit (not a 1st order filter).
- Attachments
-
- Magic IIR Biquad demystified.fsm
- (100.73 KiB) Downloaded 1350 times
Last edited by martinvicanek on Fri Feb 21, 2020 7:12 pm, edited 1 time in total.
-
martinvicanek - Posts: 1328
- Joined: Sat Jun 22, 2013 8:28 pm
Re: Magic IIR Biquad - testing
This is very exciting, and I would imagine it would also a great deal of CPU. GL, very exciting.
-
wlangfor@uoguelph.ca - Posts: 912
- Joined: Tue Apr 03, 2018 5:50 pm
- Location: North Bay, Ontario, Canada
Re: Magic IIR Biquad - testing
In the schematic below* I have rescaled the Bandpass output so the sum of all outputs adds to 1.
Absolutely sure? And the polarities, namely the lowpass phase inversion, you dealt with? And the frequency scaling? Please remember to upload the updated schematic.
For Q<=0.5 the poles a real, which means you would get the same transfer curve (function) with two cascaded 1st order filters. However, Q=0 is not a meaningful limit (not a 1st order filter).
I'm afraid, you misunderstood what's actually required. Fundamentally, a IIR Biquad filter remains a 2nd-order filter whatever the Q, even small, even very small. Like you pointed out, for Q values equal or below 0.5, the IIR Biquad filter implements two IIR 1st-order filters in series. For Fc = 1 kHz and a Q value equal to 0.1 then after tending to zero, the IIR Biquad implements two IIR 1st-order filters in series, whose Fc2/Fc1 ratio is large, say Fc1 = 100 Hz and Fc2 = 10 kHz at the beginning, then 50 Hz and 20 kHz later on, etc. Consequently, transforming the 1 kHz IIR Biquad filter into a 1 kHz 1st-order filter as soon the user specifies a Q equal to zero, will cause a giant discontinuity, giant project malfunction. Indeed, for Q=0.10, the filter will 1st-order cut at 100 Hz, then for Q=0.05 the filter will 1st-order cut at 50 Hz, but then, arriving at Q=0.0, the filter will suddenly 1st-order cut at 1 kHz. That's pure evil. Not what I suggested. I should have given the details.
The protective feature I envisioned, was that in case of Q= 0.01 or less, one is transforming the IIR Biquad filter into a gentle IIR 1st-order filter whose Fc is Fc/100. But wait a moment, this is about a lowpass filter. The exact opposite is required, speaking of a highpass filter. In case Q=0.01 or less, one must transform the IIR Biquad highpass filter into a gentle IIR 1st-order highpass filter whose Fc = Fc * 100. Concerning the bandpass, one is tempted, for Q=0.01 or less, to transform it into a bypass (a wire) whatever Fc.
Thus, it is perfectly feasible, an meaningful, to pursue a clash avoidance strategy, dealing with the accidental Q=0.0 case. This way a Q=0.0 case cannot lead to a divide by zero error or a stall. Next time you buy a flight ticket, ask if all IIR Biquads of the jet continue operating nominally, not stalling and not plagued by internal saturation, despite the existence of erratic, random or sabotage Q=0.0 requests.
In case one is designing a "universal" IIR Biquad filter that's outputting the three fundamental components (LP, BP, HP) in adjustable proportions, one is simply asked to can embed the three protective features separately, the Fc/100 for the LP section, the pure bypass for the BP section, and the Fc * 100 for the HP section.
Meanwhile, the fact that the protective feature allows to transform a BP section into a bypass, can be exploited. This is useful when managing IIR Biquad filters put in series. It suffices to systematically rely on universal IIR Biquad filters (see above), and ordering F = 1 kHz (any median, non stressing value is good), Q=0.0 (this triggers the bypass on the BP section), and LP=0.0, BP=1.0, HP=0.0 (for only outputting the BP, set at a 100% amplitude).
Arrived here, we realize that it suffices to add one more trick, small trick, for meeting the demand consisting in being able to transform such universal IIR Biquad filter that's operating at Fc, into a universal 1st-order filter that's operating at the same Fc. In case you find the solution, Martin, you'll never use again the inelegant selectors (signal routing) that one is currently forced to use for managing the IIR filters that we put in series for materializing the various flexible variable-order high-order filters, even orders and odd orders. Keep in mind that there is only one 1st/2nd-order reconfigurable block required, per filter chain, doing the even order / odd order changeover. What do you suggest, as trick?
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: Magic IIR Biquad - testing
Dunno how it works in Europe, but over here bringing a weapon of math distraction into an airport will get your butt arrested.steph_tsf wrote:Next time you buy a flight ticket, ask if all IIR Biquads of the jet continue operating nominally, not stalling and not plagued by internal saturation, despite the existence of erratic, random or sabotage Q=0.0 requests.
I keep a pair of oven mitts next to my computer so I don't get a concussion from slapping my forehead while I'm reading the responses to my questions.
- deraudrl
- Posts: 239
- Joined: Thu Nov 28, 2019 9:12 pm
- Location: SoCal
Re: Magic IIR Biquad - testing
math distraction
-
martinvicanek - Posts: 1328
- Joined: Sat Jun 22, 2013 8:28 pm
Re: Magic IIR Biquad - testing
steph_tsf wrote:a clash avoidance strategy, dealing with the accidental
Then you must decide whether you want efficiency or "idiot-proofing" - which are almost always contradictory requirements (not to mention just how resourceful idiots can be sometimes!)
There's a very old coder's saying; "fail fast and fail hard". Generally speaking, best practice is that if you don't want users to enter an out-of-bounds input value, you either don't allow them to (assert appropriate control ranges), or you abort execution and tell the user what the problem was. Secretly changing the algorithm just adds further complexity to the code (more code => more CPU cycles + more opportunity for bugs), and could even allow a program to continue running with unpredictable/unsafe data.
To continue your analogy: If an aircraft's control system encounters an unrecoverable failure, the system does not (or at least should not) conceal this from the pilot - warning lights flash, claxons sound, and the pilot is offered the opportunity to take corrective action (thankfully, civilian aircraft don't utilise the "relaxed stability" that many military jet fighters do!) Sadly, the absence of this has caused several tragic aircraft accidents; either because problems were not correctly reported to the pilot, or corrective action was prevented by automation which could not be overridden. There can be oversights and bugs in "protective" systems just as easily as in any other - and the fact that such accidents are so rare is a remarkable testament to QA/test engineers!
If you require protection against illegal cases, to use a non-standard (for FS) frequency scaling, etc., then it would be better done in 'green'/Ruby at the point where the input values are set by the user interface. Adding ever more requirements to the stream code is counter to your requirement for CPU optimisation, and may create unnecessary work for the people from whom you seek help.
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
Don't stagnate, mutate to create!
-
trogluddite - Posts: 1730
- Joined: Fri Oct 22, 2010 12:46 am
- Location: Yorkshire, UK
Re: Magic IIR Biquad - testing
Sometimes the choice is difficult, and sometimes there is opacity. Consider the built-in IIR Biquad named "2P2Z". Is there a protection inside against very smalls Q values? Is it recommended to rely on it even when implementing a 1st-order IIR filter?
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: Magic IIR Biquad - testing
Martin, thanks for correcting the wrong phase issue.
Thanks also for not allowing the BP output to provide gain anymore. What's the official name of such feature? Not-constant-skirt? Variable skirt?
By the way I feel sorry (for you) upon realizing that you were forced to keep the filter as is, still "constant-skirt" as you comment it in the x86 SSE code.
I guess that your initial intention was to keep everything "as" is, and simply divide the BP output by Q. Unfortunately, dividing audio "in blue" by a variable, is not trivial.
What's the cost of a division in x86 SSE?
Thus for avoiding the need to divide audio "in blue", you did the opposite. You let the "constant skirt" filter absorb 1/Q (that you compute using the 1/x function in green) instead of Q, and thus, for dimming the BP output that's now forcefully big when Q is small, it suffices to multiply the BP output by the 1/Q value that got computed by the "green". Such final, external multiplication is of course, easy in "blue". Nice. You don't embed such final multiplication in the x86 SSE code for keeping the x86 SSE code consistency and intelligibility, in case somebody reuses it, alone.
A little regret is that your construction is not anymore "full blue". Part of the gem is gone.
Meanwhile, the Magic is still there, and increased, now that you wiped the Padé coefficients out. I'm lost. How come they are not anymore required? One could pretend that you are demystifying something else than the original filter. That's no good.
I noticed that the hop (64) is gone in x86 SSE code, but not in the canvas DSP code. What's the intent?
You name this a "Zero Delay Feedback" filter, ZDF, 0DF. Can you explain and compare with other IIR Biquad filters implementations? Is it a Direct form 1, Direct form 2, State Variable form? Do you agree what's written here : https://www.kvraudio.com/forum/viewtopic.php?t=396440&start=75
Awaiting some light.
Thanks also for not allowing the BP output to provide gain anymore. What's the official name of such feature? Not-constant-skirt? Variable skirt?
By the way I feel sorry (for you) upon realizing that you were forced to keep the filter as is, still "constant-skirt" as you comment it in the x86 SSE code.
I guess that your initial intention was to keep everything "as" is, and simply divide the BP output by Q. Unfortunately, dividing audio "in blue" by a variable, is not trivial.
What's the cost of a division in x86 SSE?
Thus for avoiding the need to divide audio "in blue", you did the opposite. You let the "constant skirt" filter absorb 1/Q (that you compute using the 1/x function in green) instead of Q, and thus, for dimming the BP output that's now forcefully big when Q is small, it suffices to multiply the BP output by the 1/Q value that got computed by the "green". Such final, external multiplication is of course, easy in "blue". Nice. You don't embed such final multiplication in the x86 SSE code for keeping the x86 SSE code consistency and intelligibility, in case somebody reuses it, alone.
A little regret is that your construction is not anymore "full blue". Part of the gem is gone.
Meanwhile, the Magic is still there, and increased, now that you wiped the Padé coefficients out. I'm lost. How come they are not anymore required? One could pretend that you are demystifying something else than the original filter. That's no good.
I noticed that the hop (64) is gone in x86 SSE code, but not in the canvas DSP code. What's the intent?
You name this a "Zero Delay Feedback" filter, ZDF, 0DF. Can you explain and compare with other IIR Biquad filters implementations? Is it a Direct form 1, Direct form 2, State Variable form? Do you agree what's written here : https://www.kvraudio.com/forum/viewtopic.php?t=396440&start=75
Awaiting some light.
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: Magic IIR Biquad - testing
Constant gain.steph_tsf wrote:Thanks also for not allowing the BP output to provide gain anymore. What's the official name of such feature? Not-constant-skirt? Variable skirt?
About the same as 4 multiplies. Comparable to sqrt, by the way.What's the cost of a division in x86 SSE?
No big deal to do the mult in SSE.Thus for avoiding the need to divide audio "in blue", you did the opposite. You let the "constant skirt" filter absorb 1/Q (that you compute using the 1/x function in green) instead of Q, and thus, for dimming the BP output that's now forcefully big when Q is small, it suffices to multiply the BP output by the 1/Q value that got computed by the "green". Such final, external multiplication is of course, easy in "blue". Nice. You don't embed such final multiplication in the x86 SSE code for keeping the x86 SSE code consistency and intelligibility, in case somebody reuses it, alone.
A little regret is that your construction is not anymore "full blue". Part of the gem is gone.
I used a Padé approximation to tan(pi*f/2) in my earlier post. Later, as a measure of optimization, I replaced that by a cheaper approximation. Sorry, if that's confusing.Meanwhile, the Magic is still there, and increased, now that you wiped the Padé coefficients out. I'm lost. How come they are not anymore required? One could pretend that you are demystifying something else than the original filter. That's no good.
In my ASM modules I often include a code version for the purpose of documentation. Later I may make modifications to the ASM and forget to modify the code version accordingly. Very bad, very sorry.I noticed that the hop (64) is gone in x86 SSE code, but not in the canvas DSP code. What's the intent?
The topology is that of a State Variable Filter. It has the following advantages over direct forms: (i) no critical truncation errors at low frequencies (ii) three filter types at the cost of one.You name this a "Zero Delay Feedback" filter, ZDF, 0DF. Can you explain and compare with other IIR Biquad filters implementations? Is it a Direct form 1, Direct form 2, State Variable form?
Furthermore the filter is realised using trapezoidal integration, which is superior to the usual Euler integration. Trapezoidal integration, however, results in delayless loops - objects discarded in many textbooks as intractable. Vadim showed us how it can be done, and the additional benefits are (iii) robustness against fast modulation and (iv) simpler coefficient formulas.
Somebody at KVR put it this way: There is really no excuse for not using it!
I don't know the products mentioned there so I cannot comment.Do you agree what's written here : https://www.kvraudio.com/forum/viewtopic.php?t=396440&start=75.
-
martinvicanek - Posts: 1328
- Joined: Sat Jun 22, 2013 8:28 pm
20 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 58 guests