Reverse engineering the auto-wah

Algorithm development and general DSP issues

Moderator: frank

Post Reply
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Reverse engineering the auto-wah

Post by Digital Larry »

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.

Code: Select all

absa
rdfx avg, 0.01
wrax avg, 0
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,

Code: Select all

    rdax    lavg,0.001
    sof    -0.01,0
    rdax    lavg,1
    wrax    temp,0
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:

Code: Select all

rdax    lavg,0.001
sof    -0.01,0
Or would:

Code: Select all

rdax    lavg,0.01
sof    -0.001,0
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:

Code: Select all

rdax    avg,1
maxx    temp,1     ;filter a long average
wrax    lavg,0
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
potul
Posts: 76
Joined: Tue Sep 26, 2017 12:33 am

Re: Reverse engineering the auto-wah

Post by potul »

Now I'm intrigued.... when is the next chapter released?
Sweetalk
Posts: 141
Joined: Thu Oct 15, 2009 5:13 am

Re: Reverse engineering the auto-wah

Post by Sweetalk »

This is one of the codes that I'm most intrigued and coulnd't figure it out so, bring the next!!
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Re: Reverse engineering the auto-wah

Post by frank »

Since Keith did not like to write documentation but we did discuss the operation of the filter control I'm going to take a shot at explaining this from what I recall of the conversation. I have added additional comments in the code as well as a high level view of what that block is doing. I do look forward to Digital Larry's analysis as it is always interesting to see someone else's understanding of code.

Code: Select all

;Now do wah, a 2 pole LPF, peaking.
;begin by getting control level into detector:

;Get the input
rdax	mono,1		;get input

;Absoulte value so all positive
absa			;absolute value

;An averaging filter, looks like a low pass but is different due to the above absa we only have positive values never negative
rdfx	avg,0.01		;average input level
wrax	avg,0		;write avg level, pass on

;Get the "long average" value, the above averaging filter uses a shorter time constant
rdax	lavg,0.001

;Now make it even smaller and negative 
sof	-0.01,0	

;Doing lavg - 0.00000*lavg, basically a leaky capacitor that will slowly decay to 0 if lavg is never updated below
rdax	lavg,1	
wrax	temp,0

;Select the larger of lavg and avg and put into lavg as the new lavg
rdax	avg,1
maxx	temp,1		;filter a long average
wrax	lavg,0
Now an explanation about what we just did above. Basically we have 2 averaging filters in series, the first one is looking at the input signal and averaging it over a shorter period of time. This is good for catching attacks but not so good for a signal trailing off so we have a second filter with a much longer time constant that looks at he output of the first. This second filter is good for a long, smooth trailing off of the signal. Using maxx we always choose the larger of the 2 values so we can catch an attack or trail off slowly.

Code: Select all

;now set up a means by which the sensitivity control can affect the filter frequency:

;lavg holds the largest value from above so make sure it is never 0 so log works
rdax	lavg,1
sof 	1,0.002		;never let lavg go to zero
log	1,0

;save it to temp
wrax	temp,0

;Get the log of avg which represent the "immediate" signal average level
rdax	avg,1
log	1,0

;now do log(avg)-log(lavg) which is division in linear domain so we are calculating avg/lavg
;this value can only range from 0 to 1 since lavg is always equal to or greater than avg due to the maxx above.
rdax	temp,-1

;scale result by the sensitivity pot
mulx 	pot1

;and back to linear
exp	1,0

;yet one more averaging filter to keep it sounding smooth
rdfx	ffil,0.0005
wrax	ffil,1		

;Limit the range of the filter sweep
sof	0.7,0.02		;limit frequency range
wrax	wf,0
What we have done is calculated avg/lavg which will range from 0 to (almost) 1.0. If it is 1.0 we have an attack or very strong signal since lavg=avg. If <1.0 then we have a decaying sound since lavg > avg. This ratio is scaled by POT1 as the sensitivity control.

This method is nice as it eliminates using the actual absolute signal level since we are always calculating avg/lavg which will always range from 0 to 1.0. So if the input level only ranges +/-0.5 avg/lavg will still range 0 to 1.0.

After this we are into the filter its self and I think most people understand the actual filter.
Frank Thomson
Experimental Noize
Sweetalk
Posts: 141
Joined: Thu Oct 15, 2009 5:13 am

Re: Reverse engineering the auto-wah

Post by Sweetalk »

Awesome Frank, I have to get deep into that but I got the general idea. Cool idea to get a filter for the fast attack and another for the trailing
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Re: Reverse engineering the auto-wah

Post by frank »

I think one of the things that throws people is the log subtraction simply because most people have not thought about log functions in all the years since they let school and forget that subtraction in log domain is division in linear domain. LOG and EXP are really powerful and useful so a short cheat sheet:

A/B = EXP(LOG(A) - LOG(B))
A*B = EXP(LOG(A) + LOG(B))
A^N = EXP(LOG(A)*N) NOTE: In FV-1 N must be < 1.0 so this is really good for calculating roots since the root N of A is A^(1/N) so:
Square root of A is A^(1/2) so it is EXP(LOG(A) * 0.5)
For cube root it is A^(1/3) so EXP(LOG(A) * 0.33333)
So the Nth root of A is EXP(LOG(A) * (1/N))

It becomes trivial to do an RMS detector as you simply square each input, put it into an averaging filter to get the mean then take the square root using EXP(LOG(A) * 0.5).
Frank Thomson
Experimental Noize
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Re: Reverse engineering the auto-wah

Post by Digital Larry »

Well, I was trying to let the suspense build a bit so people would come pay to find out (as there is a more in depth analysis at https://www.patreon.com/posts/spin-auto-wah-i-69482282). But here's a summary of what I came up with.

When the Sensitivity pot is at zero, the output is 1.

When the Sensitivity pot is all the way up, at 1.0, each one of these signals has its log taken, but the slow one (the peak held signal) has 0.002 added to it first. 0.002 is about -54.0 dB. So if avg = 0.002 also, the adjusted lavg' will be 0.004. avg/lavg' = 0.5.

We saw that taking the exponent of the result of subtracting the log of lavg' from the log of avg gives avg/lavg'.

So as avg is increasing (the front edge of a note) avg/lavg' gets closer and closer to 1.0 but never reaches it. It's a very fast non-clipping trigger. It does pass through another low pass filter to smooth things out and give a bit of attack. I also wonder as to how sensitive this is to real signals, as -50 something dB is pretty quiet. I'll have to look closer and try some things out.

What I can see, that makes this code so special, is that at minimum sensitivity , the output is 1. As you turn up the sensitivity, the output level starts to drop when there is no input. With the input signal above the magical threshold you get back to an output rapidly approaching 1.0. This means you can set your filter's top frequency (the "wah-to" frequency) rather than the base frequency of a from-zero envelope detector (the "wah-from" frequency). Note that I am omitting the influence of the SOF which dials in the sweep to the sweet spot of the filter in the actual auto-wah.

The sensitivity sets the width of the sweep but we always end up at the same place. Certainly this is going to have a different sound than the "from-zero" envelope detector and most likely both have their place.

At my Patreon site I have additional diagrams etc. but that's it in a nutshell. I did not see anything that looks like strict RMS. It's more like continuously-variable root-exponent. The only thing really level sensitive is the threshold which is hard coded at 0.002. Once you're over the threshold, it goes pretty quickly to the max so it's not like playing twice as hard gives you twice the wah.

Whattya think? I could be wrong.

DL
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Re: Reverse engineering the auto-wah

Post by Digital Larry »

I shut down the Patreon site.

Article is now here.

https://holy-city-audio.gitbook.io/spin ... k-detector
Post Reply