Knowledge needed: RMS vs Iir approximation window size ...

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

Post

UPDATE: I've change the formula but am looking for a second opinion on what I've said.

Just wanted to confirm a small detail whilst sanity checking my results and understanding.

So I've ran an RMS vs Iir RMS approximation side by side and found the Iir version needed twice the "window size" to give an equivalent step response and curve when using the following calculations.

Code: Select all

iirPole = exp(log(0.01) / (windowSize * sampleRate));
meanSquared = sampleSquared + iirPole * (meanSquared - sampleSquared);
Now my understanding is that at point n a RMS calculation that is performed on a range r where r <= n, the RMS calculation is half of the window size behind the actual RMS value for sample n.

So first of all, is my calculation off? and is this normal? Secondly, what is the meaning of this.

Edit: it seems, given my description, that the step response for an RMS would be windowSize, while the formula for the iirPole to give a step response based on desired windowSize should in fact be:

Code: Select all

iirPole = exp(log(0.1) / (windowSize * sampleRate));

Post

What is the log(0.1) about?

For a standard time-constant, you'd normally just use exp(-1/(time*samplerate)) where time is in seconds, though I don't know if that's actually ideal in terms of approximating a boxcar. The step-response won't be exactly the same in any case though (whatever window-size scaling you use) because the exponential moving average weights the most recent values higher than older ones (impulse response has exponential decay). Depending on what you want this can be an advantage or disadvantage.

Also, it's worth noting that simple exponential moving average is not the only possibility for IIR windows, you can use steeper low-pass filters as well, as long as you make sure the impulse response is strictly non-negative... anything with real-only poles will work, as will some pseudo-gaussian filters etc. Essentially the goal of the averaging is nothing more than to separate the low-freq components (= "moving DC values") from the high-freq ripple of the squared input.

Finally, if you for some reason would prefer the boxcar window, it's possible to implement it in "IIR" form as well: you put the samples "currently inside window" into a ring-buffer delay and keep the total sum in a separate variable, adding new samples and subtracting those coming out of the delay. In floating-point this would accumulate some error, so you'd need to use slightly leaky integrator for the sum, and then slightly attenuate the subtracted samples to make sure it doesn't go negative (you can still get pretty close to boxcar in practice). If it's done in fixed-point instead (to avoid any rounding), then it'll be exact in the sense that the added and subtracted values always cancel exactly and you get proper boxcar. The processing cost in either case is roughly the same as a single-pole IIR.

Post

Oh, well log(0.1) = -1, FIXED!

And thanks for that ring-buffer delay method, just implemented it and it works a treat.

Edit: log10(0.1) = -1, while log_e(0.1) provides a coefficient that brings the envelope from 0 .. (0.9) in a step response, and seems to mirror the RMS attack quite well.

Post Reply

Return to “DSP and Plugin Development”