How does a dynamic eq work?

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

One of these days I might try the "ZDF" trapezoid-calculated second order state variable filter for dynamic EQ.

For one thing, the coff calc seems a little simpler (possibly faster, dunno). For another, supposedly that form is less likely to misbehave on fast coefficient changes.

Though IMO any kind of dynamics processing needs to be time-smoothed to avoid unmusical artifacts. The filter frequency/Q/gain change would probably not be drastic for any single sample. Even with a "fast attack" of 1 ms at 44.1 kHz, the total change would get spread out over (most likely) multiples of 44 samples.

OTOH the coffs would probably get recalculated for "small changes" on every sample so long as the audio is over-threshold and in a state of change. The only time the coffs would not get recalculated on every sample, would be for below-threshold audio or over-threshold steady-state signals.

Post

JCJR wrote:For one thing, the coff calc seems a little simpler (possibly faster, dunno). For another, supposedly that form is less likely to misbehave on fast coefficient changes.
If you want to do it per sample, there is a tan() in the formula if you are modifying the frequency, so I would not recommend it. But you can try (with ATK, although I haven't optimized the gain, you still need to recompute frequencies) how it behaves and for instance recompute the parameters every 32 samples, and smooth the parameters with a simple AR(1).

Post

Thanks Miles

In my ignorant expectation, a dynamic effect not updated every sample might not sound so great.

For a dynamic EQ, in my visualization anyway, the filter center frequency would be static during routine processing, only changed when the user manually tweaks the frequency of a dynamic EQ band.

On such as old fashioned mutron envelope followers or burwen single-ended noise reduction, the Q might typically remain static during routine operation, but the Fc might get modulated near constantly.

My main retirement time-sinks lately were trying to "polish up" an RMS compressor and building some new speakers. A month or two ago waded thru "The Art of VA Filter Design" sufficiently to pencil-and-paper write a state variable filter that "ought to work" but haven't done significant testing. If I ever get it tested good enough, will post the code.

So far as I can tell, there are two coffs, g sets the Fc, and R sets the Q. So with a dynamic EQ which only occasionally changes Fc according to user input, g would rarely be calculated (requiring the tan()), only when the user tweaks a frequency control.

R would commonly need recalc per-sample. The total per-band, per-sample calculations might include--

1. Band-limited envelope detection and smoothing.
2. Dynamic gain calculation based on envelope state.
3. "Mixing coefficient" calculation to implement the needed gain.
4. Recalculation of R to adjust the filter bandwidth according to the gain, to preserve the "constant Q" dynamic peaking shape regardless of the gain amount.
5. Solving the filter for the current input sample, and mixing filter output with the input to accomplish the peaking filter.

So far as I know given my woeful state of "incomplete understanding", it looks like dynamic recalculation of factors related to R (when Q needs to constantly change per-sample)-- About 4 muls and 2 adds, but unfortunately also 2 divides. Maybe it could be streamlined.

It is said that modern CPU's do not make divides as expensive as they once were, dunno. I'm currently not concerned with code efficiency. Am primarily concerned with the nature of the results. But old habits die hard and I still get "offended" by "unavoidable" divides in per-sample code. :)

Post

JCJR wrote:It is said that modern CPU's do not make divides as expensive as they once were, dunno. I'm currently not concerned with code efficiency. Am primarily concerned with the nature of the results. But old habits die hard and I still get "offended" by "unavoidable" divides in per-sample code. :)
Looking up SSE instructions here: https://software.intel.com/sites/landin ... sicsGuide/

It is unfortunately still true that divs are generally 5-20 times as expensive as multiplies, depending on the platform (in throughput).

Post

So can dynamic eq be realized using other designs as well and does the implementation remind of tunable filters in the sense that the gain changes are also done by recalculating the coefficients for different gains?

Post

Here's a paper that presents the allpass filter based structures:
http://users.spa.aalto.fi/mak/PUB/DAFX01_fontana_mk.pdf

Anyone know something similar, particularly if there's some text that goes through the derivation of these equations?

Post

Mayae wrote:Looking up SSE instructions here: https://software.intel.com/sites/landin ... sicsGuide/

It is unfortunately still true that divs are generally 5-20 times as expensive as multiplies, depending on the platform (in throughput).
Thanks Mayae

Post

Hi Fluky

You could consider your plugin's requirements-- The only reason for recalculating a filter per-sample in a dynamic EQ, would be to preserve the "constant Q" EQ expectation.

If you don't recalc the filter, and keep the filter Q constant regardless of dynamic gain, then the difference in width between boost and cut is fairly small with small boosts and cuts. Differences in width only become ridiculous past maybe 3 or 6 dB of gain adjustment. Depends on yer definition of "ridiculous". :)

For instance with a dynamic EQ implemented as a feedback suppressor, the feedback suppressor filters are already narrow (by design) and it may be discovered an ADVANTAGE if the notches get narrower the deeper you cut detected feedback frequencies. If the default "slight cut" feedback suppression notch is 1/10 octave, maybe it would be less damaging to the audio if a heavy feedback cut narrows down to 1/20th or 1/40th of an octave? If the narrow deep cut will still kill the microphone squeal, it might not kill off so much of the desirable audio, compared to maintaining a cut width 1/10th octave all the way down?

Maybe for special FX or extreme surgery on ruined tracks, you might want to enable very strong dynamic EQ cuts and boosts. However, for mastering or "tasteful enhancement" of a well-recorded track, practitioners may only use a "tasteful" max of 1 or 3 dB gain change on a band. In that range, the difference in boost/cut width isn't extreme.

Even if a musician is pumping the snot out of dynamic EQ bands, maybe it doesn't matter if the boost/cut width is variable according to gain. The musician will presumably use his ears. If his dynamic expansion boosts are too wide to please his ear, then he will adjust the bandwidth narrower. If his dynamic compression cuts are too narrow to please his ear, then he will adjust the bandwidth wider.

You could make a prototype dynamic EQ just using fixed-frequency, fixed-Q bandpass filters, simple. Use RBJ cookbook bandpass filters or whatever. Put up UI knobs for Fc, Bandwidth, Threshold and Ratio.

For a feedforward compression/expansion, create two bandpass filters per band. One bandpass filter feeds the envelope detector smoother, and the other bandpass filter changes gain, controlled by the envelope. For a feedback compression/expansion, you only need one bandpass filter, but those can be "tricky".

Change the filter Fc and Q when the user touches knobs, but otherwise just run the filters with no adjustment at all. The only per-sample adjustment would be calculating the envelopes and calculating how much of the bandpass filter output to add or subtract from the input signal in order to achieve the gain change.

Such a dynamic EQ, done right will work FINE, and possibly as simple as you can make one. The ONLY disadvantage will be that the width of boosts and cuts will vary according to gain, and in cases as described above, maybe that is not even a problem in the plugin operation. Maybe some users will like it BETTER operating that way.

After you get the above dynamic EQ working to your satisfaction, if you are unhappy about the bandwidth changing according to gain, all you have to do is replace the "signal path" filters with fancier versions.

Post

Fluky wrote:Here's a paper that presents the allpass filter based structures:
http://users.spa.aalto.fi/mak/PUB/DAFX01_fontana_mk.pdf

Anyone know something similar, particularly if there's some text that goes through the derivation of these equations?
Hi Fluky

Apologies for the TLDR messages.

Figure 3 in that paper shows why it could be desirable to recalculate the filter width according to the amount of boost or cut. To avoid deep cuts getting narrower, and big boosts getting wider.

On cursory reading, the paper seems to approach a "zero delay feedback" technique, but on the surface it appears a more complex way to get there, compared to more recent methods described by Vadim Zavalishin "The Art of VA Filter Design" and other people.

But maybe it would be "about the same" if examined more closely. The paper describes solving the output (along with the feedback) before solving the state variables against the input, which is at least a similar trick to the ZDF techniques, so far as I understand, which isn't much.

Vadim's book explains about adjusting Q according to boost/cut. As do many papers. RBJ's old filter cookbook formulas for peaking and shelving filters have concise lines of practical code showing a way to do it that works nicely so far as I've experienced.

The problem with using such as an RBJ peaking filter for dynamic EQ, (in addition to POSSIBLE stability problems with fast gain changes), is that ALL the filter coffs have to be recomputed in order to merely keep the frequency the same, but change the peaking gain with Q adjustment. So far as I know. Its been a dog's age since I looked at that, and maybe there would be some shortcuts if Fc is kept the same but gain/Q is the only thing that gets changed.

I didn't read that allpass EQ paper closely enough to learn whether the filter coffs might be quicker-calculated than RBJ's approach, but the method of per-sample solving the filter output APPEARS that it might take more CPU cycles than RBJ's simple filter solving method.

That allpass EQ seems to use two coffs, alpha and beta. I didn't read the paper close enough to know whether they are independent, with alpha responsible for frequency alone, and beta responsible for Q alone, or whatever. If the coffs are independent of each other, maybe you would only need to worry about calculating beta.

Conventional textbook second-order active analog filters such as sallen-key, or passive resistor-inductor-capacitor analog filters, had a similar problem as the 5 or 6 coff IIR second order filter, using input sample x[0], along with x[-1], x[-2], y[-1] and y[-2]-- They worked great but were not easily tunable. If you had a filter with the desired frequency and Q, you couldn't just change one component value and change the frequency but keep the Q the same, or change the Q but keep the frequency the same.

Multiple components had to be changed for any trivial change in the filter performance, and typically not in a "sane" fashion. For instance, you couldn't often just insert a stacked potentiometer in the circuit to change all the resistors by the same amount, because the resistors might need to change different amounts or in different directions.

The analog state variable filter was easier to tune. You could tune frequency with a pair of tracking resistors, and change Q with one resistor, and a "four opamp" implementation made frequency, Q and gain independent of each other. And it didn't cause brain damage solving for the component values needed.

The digital state variable filter always had the same advantages, but Hal Chamberlin's innovative early variation had various problems making it far less than ideal for many tasks. The ZDF state variable filter appears to have solved most of the Chamberlin SVF's problems.

So that allpass paper's solution appears to use two coffs, perhaps independent of each other. And the ZDF state variable filter also uses two coffs, independent of each other. Maybe they both use about the same CPU. Or maybe not. The ZDF appears fairly "lean and mean" for coff calculation and not horribly inefficient at solving the per-sample output as well.

If one needed to sweep frequency of a ZDF and couldn't afford lots of tan() calls, two options--

1. It appears very friendly to using an interpolated lookup table for frequency-setting, because there is only one frequency-setting coff, and it appears to continuously change in one direction as it sweeps from low- to high-frequency.

2. For "non-precise" sweeping, just don't use the tan() at all. For lower frequencies, the tuning is near-identical regardless of the tan() call, and for instance a mutron swept filter or quick'n'dirty synth filter, the user may never notice that the filter quits tracking "perfectly linear" at higher frequencies.

Similarly, perhaps an interpolated lookup table for R (the Q adjustment) would work good for a dynamic EQ. Sometimes interpolated tables "use fewer math lines per sample" but do not perform a lot faster than brute-force calculation per sample. That is because sometimes you can do a bunch of accelerated math operations in the time required to fetch values from a memory table. When attempting optimization, there's no substitute for actually testing both ways to see which is faster. Even then you don't know fer sure-- Maybe method A works better on yer test computer but method B works better on some other computer with faster/slower memory, or faster/slower math.

Apologies writing so tldr. That allpass method, or a ZDF SFV might both be posssibles for a dynamic EQ. I think I'd try the ZDF SVF first, because I already "almost understand" that approach.

Post

The bandpass approach you give above sounds simple, but did you mean that there should be an entire filter bank? Or bandpasses whose cutoff can be moved around?

Also what about the phase of the bandpasses? Since one's mixing a bandpassed signal back to the input signal, then how are they going to be in the same phase?

What about other filter shapes using this approach?

Post

Anyone can summarize what features are desirable and are not desirable in filters meant for dynamic equalization? I.e. what kind of filters are suited and why and what kind of aren't?

Post

Any usual form out of the BLT are out. You need explicit integrators, like described in Vadim's book (i.e. ZDF filters). One option that is quite good are the SVF filters from cytomic, as they map second order BLT filters.

Post

Fluky wrote:What about other filter shapes using this approach?
Hi Fluky.

You can make a variable hi-shelving EQ by adding or subtracting a hipass filter output to the input signal. You can make a variable lo-shelving EQ by adding or subtracting a lopass filter output to the input signal. If you don't "tune" the hipass or lowpass according to gain, then boost shapes will not be identical to the cut shapes, but it will work fine except for the asymmetrical boost/cut shapes. Some "well loved" analog EQ sections in guitar amp tone stacks and even some famous old mixing consoles, have quirky asymmetrical boost/cut shapes, so it isn't always an unpardonable sin. Some users might like it thataway. Just tell the users that your quirky EQ shape is a deluxe "Vintage British EQ". :)

You MAY need to consider the hipass or lopass filter phase when setting up the shelving EQ done thataway. For instance, the hipass MAY turn out to be 180 degrees out of phase with the input at high frequencies. In that case, adding the hipass output to the input would make a cut, and subtracting the hipass output from the input would make a boost. Its not rocket science. If you notice that boost/cut is reversed, just multiply the hipass output by -1 somewhere in your calculations.

Post

Fluky wrote:The bandpass approach you give above sounds simple, but did you mean that there should be an entire filter bank? Or bandpasses whose cutoff can be moved around?

Also what about the phase of the bandpasses? Since one's mixing a bandpassed signal back to the input signal, then how are they going to be in the same phase?
In the description I was visualizing a "small number" of tunable bands of dynamic EQ. It would depend on "how many bands are sufficient for the job at hand?"

Have seen some nice EQ's with a graphic display rather than fixed rows/columns of knobs or sliders. You start with one filter but can add as many filters as needed, until ultimately you might add so many filters that the graphic grid display becomes a completely confusing mess of curvy colored lines. :)

The dynamic EQ things I did in the past used relatively few bands. Sometimes parallel and sometimes serial. With only a few bands, maybe it would be fine running them all in parallel-- IOW, all the bandpass inputs fed by the input signal, then the bandpass outputs multiplied by gain coffs and added to the input signal to make the final output.

Unless the bands are sparse and well-separated from each other, parallel would give so much phase interaction that it might be painful trying to write code that would display an accurate animated graphic of the "actual" instantaneous composite frequency response.

But even with the phase interaction, the plugin MAY be useful. Or maybe not. Depends on expectations and results.

I grew up with analog EQ, where the "natural" way to do it was with parallel filter banks. The first digital EQ's I made copied the analog parallel topology and had inter-band phase interactions and cuts that were narrower than boosts. Those first old EQ's were "far less than ideal". On the other had they still worked. Adjusting the EQ by ear, knob settings could often be found that would EQ the music OK even if the actual frequency response may have been different than the knob settings might lead you imagine.

(trying to avoid tldr, continued in next message)

Post

This one is just gonna be tldr.

Ways of making a first dynamic EQ, depending on what you want--

One method might have 3 or 6 parametric bands or whatever. Each band's column of knobs might include frequency, bandwidth, ratio, threshold, attack, release, and makeup gain. Each band is just a compressor (or expander, or compressor/expander, whatever is the plugin's purpose). Except that each compressor modulates the cut/boost of a parametric band rather than directly modulating the broadband level.

That MAY be good enough for a "repair/enhancement" tool, and MIGHT be usable even with the warts of inter-band phase interaction and variable-width cuts and boosts.

A more ambitious method might be "about the same thing" except that the plugin wants to be BOTH a nice parametric EQ and ALSO a nice dynamics tool. You can boost/cut all the bands as in a nice parametric EQ, and then switch-in compress/expand on some of the bands if a band needs it. Making a "double duty" tool like this-- There would be bigger user expectations on the quality of the Equalization function. Perhaps users would not appreciate warts such as inter-band phase interaction or non-constant-Q EQ bands.

That kind of tool would need more work, and may not be the first one to write unless you have yer heart set on it. Might be better to learn some about what works and what don't work, with a simpler first try. Then apply that knowledge to a second more-ambitious attempt.

I don't know what would be the best topology for a dynamic EQ which needs constant-Q bands, no phase interaction, and will work even with close-spaced, overlapping bands.

As stated many times before, for digital multi-band simple EQ, I think its hard to beat serial peaking filters. Each filter in the chain is "flat amplitude" except for the band it boosts/cuts. So well-spaced filters work as expected, and if you think about it, even overlapped filters work as expected, so long as you expect the right thang. For instance if you +10 dB boost 100 Hz with a quarter octave bandwidth and then -5 dB cut 100 Hz with a 2 octave bandwidth, you will get a smooth wide cut with a narrow peak in the middle.

The serial config does not eliminate phase shift in the final output. It just keeps each band's phase shift from mucking with the amplitude response of other bands. Mixed parallel, the overlapping band-edge phase shift causes "unpredictable gain" in-between the bands. A user MIGHT like it thataway, but I don't like the unpredictability.

With serial filters, the amplitude response will be fairly predictable. A plugin could display the resultant weird phase response if you want to do that. In case the user cares what he's doing to the phase along with his EQ efforts. You could do the serial filter either with something like RBJ's nice pre-fab peaking and shelving filters, or "roll your own" with each filter mixing its output against its input.

But dunno if serial filters would be so friendly to dynamic EQ. Maybe or maybe not, depending on the plugin design goals.

One possible method-- Run the EQ filters in series, but run all the envelope detectors off the main input signal. If the parallel 100 Hz envelope detector responds to the original input, it causes the serial 100 Hz peaking filter to change gain. If the parallel 1000 Hz envelope detector responds to the original input, it causes the serial 1000 Hz peaking filter to change gain.

Alternately, each band of envelope detector could measure the same thing seen by its paired peaking filter. If the series chain has 100 Hz, 1000 Hz, and 10000 Hz dynamic bands, then the 1000 Hz envelope detector would be responding to whatever had been performed by the 100 Hz band, and the 10000 Hz envelope detector would be responding to whatever had been performed by BOTH the 100 Hz and 1000 Hz bands. Possibly you would get different output results if you switch the series order, 10000 Hz first and 100 Hz last or whatever.

That might be a great effect or it might be a disaster. Some things are best solved by experiment rather than spending forever figuring out the theoretical best method. It is wasted time if months figuring out the perfect theoretical method turns out to suck when one finally gets around to writing code. :)

Post Reply

Return to “DSP and Plugin Development”