Delay line filter with fixed dampening time?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Hi,I have a problem implementing a filter on a delay line.
I realise it should be straight forward, but I just can't get it right now (well for a few hours anyway :hihi: )
I'm trying to low pass filter a delay line so that it dampens at the same rate no matter what the delay buffer length or sample rate is set to.

My current filter is a simple iterator of the form:
lastSample += (delay[n] - lastSample) * dampCoeff;
delay[n] = lastSample;

Which works nicely until the user changes the delay length, then it changes dampening time. Which is not what I wanted the user experience to be.

I've tried using the calculations for a fading a delay line e.g. here:
viewtopic.php?f=33&t=529125
But that doesn't work with low pass filter, as it's just more complex than multiplying the delay by a fade factor. I think this is what's messed up my thinking / or lack of...

Can anybody point me in the right direction please?
Thanks,
Dave H.
Last edited by quikquak on Tue Oct 01, 2019 3:57 pm, edited 2 times in total.

Post

a couple of years ago (read: "if i remember correctly"), i was experimenting with FDNs (and, of course, we may treat a single delayline as an FDN of size 1) and the typical approach to tune the decay time is via scaling the feedback coefficient (there's a formula for the decay-time in terms of delayline length and feedback coeff). i think, it's formula 20 here:

https://ccrma.stanford.edu/~jos/cfdn/Fe ... works.html

then i made the feedback coeff frequency dependent by inserting and tuning shelving filters appropriately, so if you want the high frequencies decay faster, it would be a high shelving filter with an attenuation gain determined by the feedback-coeff formula

edit: the link doesn't really say, what the alpha means, so i just looked it up in the DAFX book (1st edition, page 183). it gives the formula: T_d = (-3*T_s) / log(alpha) where T_s is the sampling interval and T_d is the decay time (in the given context of reverb, the RT60).

so that's what i did: plug my desired (high-frequency) decay time into the formula to compute alpha, from that and the delayline length (m_i) compute the desired gain and then set up a shelving filter in the feedback path with that gain
Last edited by Music Engineer on Tue Oct 01, 2019 3:54 pm, edited 3 times in total.
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

...of course, i'm ignoring the phase shift of the shelving filter here which actually makes the delay a bit longer than m_i samples and frequency dependent. but it was good enough. also, you will need to make a choice for the shelver's frequency (i actually used high and low shelvers with user adjustable frequencies an gains - gains indirectly via desired RT60 via the formula, as said, so i had a basic RT60 setting and additional high- and low- damping parameters with adjustable frequencies). you can also have a parametrization in terms of RT60_low, RT60_mid, RT60_high with adjustable crossover frequencies, which are the shelver frequencies
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Thanks Music Engineer, hopefully that helps. I'll have a good read through. I think I've seen something like 'T_d = (-3*T_s) / log(alpha)' before somewhere as well.

Post

It was a long time since playing with HF/LF damping in decaying delay lines. Some dumb (as usual) ideas:

The first-order HP (LF damping) and first-order LP (HF damping) seemed "natural to the ear" but I don't recall trying higher orders. Higher order filters might decay unnaturally fast, or not. Maybe (or not) a 2nd order filter would not be too weird if it is configured as a shelving filter-- Reasoning to follow.

If we first calc broadband feedback gain Gb for a target RT60. Then we could calc a high frequency feedback gain Gh for the high-frequency target RT60. We probably need to pick some target turnaround frequency for the Gh, the particular high frequency, 5 kHz or 10 kHz or whatever where we get the target high frequency RT60.

Because the LP filter is in series with the broadband feedback gain, for instance if Gb turns out to be 0.7 and Gh turns out to be 0.6, then at the target high frequency, the LP filter needs a gain of 0.6 / 0.7 = 0.857.

So if we use a simple 1st order LP filter, and for instance the HF RT60 is targeted to 5 kHz, we need to find a LP center frequency which would result in a gain of 0.857 at 5 kHz. Because of different sample rates, and frequency warping, finding the 1st order center frequency would be a little tricky. Not for smart people with big brains, but I would have to go studying on it to remember enough to figure out how to do it.

Also, doing it thataway might be somewhat variable in perceived result, just tuning a LP up and down to get a target gain at a target frequency.

Therefore it may (or may not) sound more consistent to use a 1st or 2nd order LP shelving filter rather than a lowpass filter. If 5 kHz is your chosen HF RT60 calc frequency, you could just always tune the shelving filter to 5 kHz and then easily quickly set the gain of the shelving filter to get your target HF RT60 regardless whether the required HF cut is tiny or large, because shelving filters are very simple, fast and predictable for changing gain. Maybe because of frequency warping the shelving center frequency wouldn't be EXACTLY what we expected, but it would be "in the ballpark" and consistent results regardless what gain we need out of the shelving filter?

Though perhaps unnecessary features, we could even perhaps put Lo and Hi shelving filters, maybe 100 Hz and 5 kHz in the delay feedback loop, and give the user three RT60 knobs, for midband RT60, Lo RT60, and Hi RT60, and if the user wants it for some reason the Hi or Lo RT60's could be set either bigger or smaller than the midband RT60. I recall some of the old Lexicon reverbs had a "bass multiply" parm of more importance than a "HF damp" parm.

Post

quikquak wrote: Tue Oct 01, 2019 2:52 pm I think I've seen something like 'T_d = (-3*T_s) / log(alpha)' before somewhere as well.
yes - probably in some article on FDNs or something. i guess, it could be that they mean the base 10 logarithm there, so watch out for this. ah - and i have just found a paper on filter design for an FDN:

https://ant-s4.unibw-hamburg.de/dafx/pa ... per_11.pdf

...they go through great lengths to optimize the gains of a serial parametric eq to achieve the desired target RT60 as exactly as possible. a nice exercise in numerical optimization but for practical purposes, i tend to consider that overkill - because the user adjusts the parameters by ear rather than by numbers anyway

edit: just looking at the plots in figure 5. in (a) we see that the filter-response of the dashed red curve exceeds 0dB above 10^3 Hz, giving a loop gain >1 in this frequency range - leading to infinite decay times (i.e. an unstable overall system) in plot (b) - or, well, it's actually wrong to talk about "decay" here because we actually see growth. using shelving filters with gains <= 1 (on top of the global feedback gain < 1) should be fine to avoid such situations
My website: rs-met.com, My presences on: YouTube, GitHub, Facebook

Post

Uh, I'm still stuck on this. If anyone has a more 'programmery' solution to this, there's a beer or 7 in it for you. :)
I'm in a fair amount of 'post stroke pain' at the moment, and I'm using it as an excuse to be crap at maths!

Post

JCJR wrote: Tue Oct 01, 2019 7:34 pmTherefore it may (or may not) sound more consistent to use a 1st or 2nd order LP shelving filter rather than a lowpass filter. If 5 kHz is your chosen HF RT60 calc frequency, you could just always tune the shelving filter to 5 kHz and then easily quickly set the gain of the shelving filter to get your target HF RT60 regardless whether the required HF cut is tiny or large, because shelving filters are very simple, fast and predictable for changing gain. Maybe because of frequency warping the shelving center frequency wouldn't be EXACTLY what we expected, but it would be "in the ballpark" and consistent results regardless what gain we need out of the shelving filter?

Though perhaps unnecessary features, we could even perhaps put Lo and Hi shelving filters, maybe 100 Hz and 5 kHz in the delay feedback loop, and give the user three RT60 knobs, for midband RT60, Lo RT60, and Hi RT60, and if the user wants it for some reason the Hi or Lo RT60's could be set either bigger or smaller than the midband RT60. I recall some of the old Lexicon reverbs had a "bass multiply" parm of more importance than a "HF damp" parm.
Hmm, isn't what JCJR writes above the correct answer, for what you're after? You want to remove X dB of high frequency energy per second, regardless of the delay lengths. So you use a high-shelf filter rather than a lowpass filter, and tune the gain reduction dB to the delay length. Your reverb can then have "bands", with different release times.
Arne @ noteperformer.com

Post

I think the delay lengths do matter because, the shorter it is the more it loops over and re-filters the already filtered delay buffer samples - so it diminishes faster.

Post

I will try to compose a more concrete example in about an hour if someone doesn't write something better and clearer beforehand. I just remember an rt60 formula from Chamberlin musical applications of microprocessors or some other old source I want to look at again. Nothing against music engineer's rt60 equation. I just remembered another one being easier to understand.

Post

Music Engineer wrote: Wed Oct 02, 2019 9:06 am ...they go through great lengths to optimize the gains of a serial parametric eq to achieve the desired target RT60 as exactly as possible. a nice exercise in numerical optimization but for practical purposes, i tend to consider that overkill - because the user adjusts the parameters by ear rather than by numbers anyway
The basic problem is that with a low-order filter, you can pick the RT60 only for a limited number of frequencies and everywhere else the damping will vary depending on the delay time, which can lead to quite obvious ringing at particular frequency ranges if the deviations grow too large.

As for the formula to compute the desired gain (at some chosen frequency) for a particular RT60 (in seconds) and a given delay time (of nSamples): 10^(-3*nSamples/(RT60*samplingRate))

Post

Yeah, the old quote from Chamberlin (which is in ln rather than log10) and would need solving for F, the feedback gain) "The reverberation time of a single stage is the number of delay recirculations required to attenuate the signal 60 dB times the delay time. Thus, Rt=-6.9D/Ln(F), where Rt is the reverberation time in seconds, F is the feedback factor, and D is the delay in seconds." mystran supplies a clearer equation.

Let's posit a first-order high shelving filter. For concrete example maybe tune it to 5 kHz or whatever seems reasonable for the application. A first-order shelving filter that doesn't have any "gain bumps" and smoothly changes from unity gain in the pass band up to the shelf gain. Maybe similar smooth 2nd order shelving filter would do just as good, dunno. I'm a fried geezer, maybe the following contains brain farts. Using mystran's formula:

Code: Select all

Knobs:
DelayLineSecs, Midband_RT60, HF_RT60

DelayLineSamps = DelayLineSecs * SamplingRate;
Midband_FB_Gain = 10^(-3 * DelayLineSamps / (Midband_RT60 * SamplingRate));
HF_FB_Gain = 10^(-3 * DelayLineSamps / (HF_RT60 * SamplingRate));
HiShelfGain = HF_FB_Gain / Midband_FB_Gain;
TheShelvingFilter->SetGain(HiShelfGain);
/*******************/
//then in process loop each sample feedback is calculated
FeedbackSamp = TheShelvingFilter->Process(DelayLineTailSamp) * Midband_FB_Gain;
Assuming the shelving filter is well-behaved with no bumps, I don't think that would "run away" even if you set the high frequency RT60 a lot longer than the midband RT60. Unless the RT60 gets so big, the feedback gain gets so near 1.0 that rounding errors tip it into regenerations somehow?

Post

Simple first order shelves work reasonably well, mytran's formula looks like the right one for the job(assuming this is for regular delay and not physical modelling).

Edit: 'Cause I didn't read the question properly :dog:
Last edited by Ichad.c on Tue Oct 08, 2019 7:05 pm, edited 1 time in total.

Post

Wow guys, does that work with the simple filter I posted? I’ll give it a go tomorrow...

Post

quikquak wrote: Wed Oct 02, 2019 6:28 pm Wow guys, does that work with the simple filter I posted? I’ll give it a go tomorrow...
Hi Dave. In my first impression it would be easier with a high shelving filter but maybe the biggest hassle in using your posted filter would be finding the correct (and simple enough) equation for tuning the filter to get the attenuation you want at a certain frequency.

Your filter:
lastSample += (delay[n] - lastSample) * dampCoeff;
delay[n] = lastSample;

Seems to be a simple first order lowpass filter. The -3 dB frequency point is tuned by the value of dampCoeff.

In my previous simple-minded example, where I decided to use a fixed 5000 Hz shelving filter (or whatever) and find the gain of the High Frequency cut with HighFrequencyFeedbackGain/MidBandFeedbackGain. Then just tell the shelving filter to have that much gain.

You could do the same with the simple lowpass filter, but you would need to figure out how to find the filter cutoff frequency that would give you that required amount of cut at whatever high frequency target frequency you pick. And find the dampCoeff value which would tune your filter to that value.

For example if the target HF frequency is 5000 Hz but it turns out that you only need -0.5 dB cut at 5000 Hz to get the damping time required, then you would need to find some filter tuning frequency above 5000 Hz where the lowpass filter has only a -0.5 dB cut.

Or if it turns out that you need -5.2 dB gain at 5000 Hz then you would have to find some filter tuning frequency below 5000 Hz where the lowpass filter has a -5.2 dB cut at 5000 Hz.

There are equations for that, which I would have to look up because my memory sucks. The analog equations are simplest. However in digital filters there is "frequency warping" at high frequencies, and the high frequency gain ain't the same as the analog equation, and it is different frequency warping at different sample rates. So the bestest formula would calculate dampCoeff based on a given attenuation at a given frequency, taking into account the samplerate.

There are several big-brained people here who might be able to give fairly simple couple of lines of code equations to do that, off the top of their heads from memory but I'd have to study on it.

If I had to suggest something, it would take me less study to give you pseudo-code for a first order shelving filter. I don't have one laying around but it wouldn't take as much study to figure one out. Vadim describes such in his excellent free filter book.

Post Reply

Return to “DSP and Plugin Development”