Reverse engineering the auto-wah
Posted: Sun Jul 24, 2022 12:51 pm
This code comes from the ga_demo_wah code. I'm just going to go a step at a time because this is seriously strange stuff and I believe it exposes but does not really explain some very powerful strategies that might come in handy from time to time.
Here's the first bit.
Simple enough. Full wave rectifier into a low pass filter. If I have my stuff together properly, at fs = 32768 the corner frequency is 52.4 Hz.
f = -log(1 - K) * fs/(2 * pi)
My handy dandy Wolfram Alpha calculator:
https://www.wolframalpha.com/input?i2d= ... 5D+*+32768
So far, not mysterious. Result is saved in "avg" and ACC = 0.
Next up,
lavg is not previously referred to, so assume it’s zero to start.
So we read it in, then scale again by -0.01 (so now it’s -0.00001 * lavg)
And then add lavg again, so that’s 0.99999 * lavg, which gets written to temp.
Why didn’t we just do “rdax lavg, -0.00001”? Or "rdax lavg, 0.99999"?
I THINK:
Because the coefficient C in an RDAX or RDFX instruction is S1.14. So the smallest bit of this, 2^(-14) is the smallest number you can use. What is 2^(-14)? It’s 0.000061035-something, which is bigger than 0.00001, meaning you can’t represent a number that small in these instructions. The biggest number less than one that you can represent is 1 - 2^(-14) or 16383/16384 or 0.99993896484375.
So you have to get close and then scale down further using a SOF.
IS THIS CORRECT?
If so, is there any particular reason to use:
Or would:
or any other combination that didn't edge too close to the resolution limit be just as OK?
OK as we move forward, remember that "lavg" is also stored in "temp".
Next bit:
OK, this is clearly the peak detector "virtual diode". Whichever the MAXX of AVG or TEMP gets shoved back into LAVG.
While it's tempting to think of this section as a low pass filter, it is not. It only takes input when the input is higher than the current REG value (I always think of this as a capacitor voltage). When the input goes below that, the REG value/ "cap voltage" decays on its own. There is no further influence by the input signal. In a real low pass filter, if you start feeding it zeroes on the input it goes down faster because it is influenced by the input as well as its prior state. But the MAXX/"diode" takes us out of linear theory territory.
How am I doing so far? The next part is where it gets really bizarre.
DL
Here's the first bit.
Code: Select all
absa
rdfx avg, 0.01
wrax avg, 0
f = -log(1 - K) * fs/(2 * pi)
My handy dandy Wolfram Alpha calculator:
https://www.wolframalpha.com/input?i2d= ... 5D+*+32768
So far, not mysterious. Result is saved in "avg" and ACC = 0.
Next up,
Code: Select all
rdax lavg,0.001
sof -0.01,0
rdax lavg,1
wrax temp,0
So we read it in, then scale again by -0.01 (so now it’s -0.00001 * lavg)
And then add lavg again, so that’s 0.99999 * lavg, which gets written to temp.
Why didn’t we just do “rdax lavg, -0.00001”? Or "rdax lavg, 0.99999"?
I THINK:
Because the coefficient C in an RDAX or RDFX instruction is S1.14. So the smallest bit of this, 2^(-14) is the smallest number you can use. What is 2^(-14)? It’s 0.000061035-something, which is bigger than 0.00001, meaning you can’t represent a number that small in these instructions. The biggest number less than one that you can represent is 1 - 2^(-14) or 16383/16384 or 0.99993896484375.
So you have to get close and then scale down further using a SOF.
IS THIS CORRECT?
If so, is there any particular reason to use:
Code: Select all
rdax lavg,0.001
sof -0.01,0
Code: Select all
rdax lavg,0.01
sof -0.001,0
OK as we move forward, remember that "lavg" is also stored in "temp".
Next bit:
Code: Select all
rdax avg,1
maxx temp,1 ;filter a long average
wrax lavg,0
While it's tempting to think of this section as a low pass filter, it is not. It only takes input when the input is higher than the current REG value (I always think of this as a capacitor voltage). When the input goes below that, the REG value/ "cap voltage" decays on its own. There is no further influence by the input signal. In a real low pass filter, if you start feeding it zeroes on the input it goes down faster because it is influenced by the input as well as its prior state. But the MAXX/"diode" takes us out of linear theory territory.
How am I doing so far? The next part is where it gets really bizarre.
DL