Page 1 of 1

Trying to understand RMS limiter example in knowledge base

Posted: Mon May 02, 2016 7:56 am
by dkleinjans
I can make sense of most of the code in the example below, but I'm confused by the line
rdfx avg,0.001
I understand that it is preparing a number to be saved as the running average of the (halved, summed, and squared) inputs. I don't understand how it is getting the average. As I read the code, it looks like it takes 0.001*(new value - running average) and adds it to the running average. Is the 0.001 to make it a slower change over time? So at 32k clock, it would take about 30mS for a constant offset to accumulate? Could the 0.001 be changed to make a faster or slower reacting sensor?
Thanks

This is the example from the knowledge base:
The RMS limiter could be built this way:

;rms limiter, approx 10dB limiting range.
equ sigin reg0
equ avg reg1
rdax adcl,0.5
rdax adcr,0.5
wrax sigin,1
mulx sigin ;square
rdfx avg,0.001
wrax avg,1 ;average
log 0.5,0 ;[square
exp 1,0 ;root]
log -1,-0.125 ;[1/X, set thresh @2 bits (2/16ths)
exp 1,0 ;]
mulx sigin ;gain reduce
sof 1.5,0 ;restore level
wrax dacl,1
wrax dacr,0

Posted: Mon May 02, 2016 10:21 am
by Digital Larry
This pair of instructions is the basis of a low pass filter.

rdfx avg,0.001
wrax avg,1 ;average

The 0.001 value sets the corner frequency. If you look around the knowledge base, you can find the expression for the filter frequency as it relates to this number. It's not clearly spelled out in the Spin ASM user manual.

Just like in the analog world, too fast of a filter frequency will allow some feedthrough of your lowest audio frequencies into the control signal. This creates a really bad sounding distortion.

Posted: Mon May 02, 2016 11:33 am
by dkleinjans
Thanks, Larry.

I see that the pair of instructions can be used as part of a low pass filter. Using the formula, I come up with a corner frequency of about 36k, which seems awfully high.
K = e^(-2*pi*F*t)
ln(K) = -2*pi*F*t
F = (ln(K)*32768)/(-2*pi)
F = (ln(.001)*32768)/(-2*pi) = about 36k

Is that pair actually functioning as a low pass filter in this application? It looks to me that the instructions are being used for averaging, and that they are taking 0.001 of the new rms and adding it to 0.999 of the running average rms to make a slow moving average.

Posted: Mon May 02, 2016 2:11 pm
by frank
You can look at it either way but that instruction pair uses 1-K as the coefficient so run the frequency calc again but keep in mind we use 1-K in the instructions so it should be done with 0.999 not 0.001 giving just over 5Hz as the corner freq.

Posted: Mon May 02, 2016 2:40 pm
by Aaron
The coefficient for the lpf can be changed to change the attack/release time. Using the formula:

AT = 1-e^(-2.2T/tat)

where AT = filter coefficient
T = 1/32768
tat = desired attack time in sec

So a coefficient of 0.001 will yield an attack time of around 65ms.

A lot of good info on dynamic processing can be found in chapter 5 of DAFX by Zolzer

Posted: Fri May 06, 2016 11:14 am
by dkleinjans
Oops, I see my errors. I made an algebraic error in my previous calculations, putting t in the numerator when it should be in the denominator. And I used the clock frequency instead of the time per sample. Here is the corrected calculation.

Clock =32768, so t~0.00003 seconds.

K = e^(-2*pi*F*t)
ln(K) = -2*pi*F*t
F = ln(K)/(-2*pi*0.00003)
F = ln(.001)/(-2*0.00003) ~ 36k

But that's still wrong. Using Frank's note to use 0.999 (1-K) instead of 0.001,
F ~ 5.3,
which agrees with Frank's calculations.

If, instead, I use a K of 0.6, similar to what I've seen in the sample programs,
F ~ 2.7k.
That seems in the ballpark.

Thanks, all.