Peak detection: add "attack?"

DSP related issues, mathematics, processing and techniques
Post Reply
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Peak detection: add "attack?"

Post by Perfect Human Interface »

Hi friends.

I have this peak detector here (attached) I dug up made by cytoSonic. It has a "decay" parameter. I'm interested in adding an "attack" parameter. I don't know Assembler, so I'm wondering if there's a simple way to add this in, or if I should just write something from scratch using DSP. Looking for some direction. Much thanks.
Attachments
Peak Detector CytoSonic.fsm
(815 Bytes) Downloaded 1511 times
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Peak detection: add "attack?"

Post by KG_is_back »

I don't see any simple way to add attack into it, but here is a code version:

Code: Select all


streamin in;
streamin rCoeff;
streamout out;

float holdR=0.0;
float floor=1e-008;

out=max(holdR,abs(in));
holdR=max(floor,rCoeff*out);

Note that original assembly code is slightly different because is optimized, but output will be identical. If someone see any way to add attack, other then rewriting the thing from scratch please do so...
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: Peak detection: add "attack?"

Post by Perfect Human Interface »

Ah okay, thanks!

So it should just be a matter of using comparatives rather than using the max function. I'll work on it.
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: Peak detection: add "attack?"

Post by Perfect Human Interface »

Not tested yet but I think this is right, where rCoeff is < 1 and rCoeff2 is > 1.

Code: Select all

streamin in;
streamin rCoeff;
streamin rCoeff2;
streamout out;

float holdR=0.0;
float floor=1e-008;

holdR = (holdR>abs(in) & holdR*rCoeff);
holdR = (holdR<abs(in) & holdR*rCoeff2);

out = holdR;


edit: yeah it's wrong, give me a minute. :P
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: Peak detection: add "attack?"

Post by Perfect Human Interface »

Code: Select all

streamin in;
streamin rCoeff;
streamin rCoeff2;
streamout out;

float holdR=1e-008;
float floor=1e-008;

out = (out>abs(in) & max(out*rCoeff, abs(in))) + (out<=abs(in) & min(out*rCoeff2, abs(in)));


out = max(floor,out);


This seems to do it. Only thing is that when attack is 0 rCoeff2 ends up being 2, so it's not technically a 0 ms attack. Though it may be entirely inconsequential and I'm not sure if this coefficient thing is 100% accurate anyways.
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: Peak detection: add "attack?"

Post by Perfect Human Interface »

Sorry to spam post. I have a big question about the math in the "Coeff" module in the schematic uploaded above. It's calculating a coefficient for the peak detector's "release"... that's about as much as I understand of it.

For the "attack" function I needed to invert the value somehow. I observed that as you increased the "release" input ("milliseconds") the output approaches 1. So in order to flip it (around the value 1), I simply did 2 minus the output. Seems to work, but I'm wondering if that's actually mathematically correct.

As it is now, when release goes to 0, the output goes to zero. When release goes to inf, the output goes to 1.
When attack goes to inf, the output goes to 1, but when attack goes to zero, the output goes to 2.

My feeling is that the output should go to inf, not 2. I'm not sure if that's correct but I think a zero ms attack would technically equal an infinitely fast attack.

Does somebody understand this math enough to offer an explanation of what should be done here? Is the math completely different for the attack?
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Peak detection: add "attack?"

Post by KG_is_back »

envelope follower in general is a modified one one pole lowpass filter. In envelope follower, you first calculate the absolute value of input and then use different coefficient for rising and falling. Each coefficient represents different cutoff frequency for the filter. When you invert cutoff frequency you have the time constant which is what you control on most compressors (the attack and release).
General formula for the one pole lowpass is:

Code: Select all

a1=-1*e^(-2*pi*fc); //fc is normalized cutoff frequency
b0=1-abs(a1);
y=x*b0-y*a1;

where a0 is the coefficient
to turn it into a envelope follower you make the input absolute value and switch between attack coefficient and realease coefficient based on relation between input and output:

Code: Select all

streamin x;
streamout y;
streamin aCoeff;
streamin rCoeff;
float aX,c;
aX=abs(x);
c=aCoeff&(aX>y)+rCoeff&(aX<=y);

y=c*(y-aX)+aX; //this is simplified version of y=c*y+(1-c)*aX


both attack and release coefficients are calculated the same, in this case as e^-2pi/time (time=1/cutoff)
Perfect Human Interface
Posts: 643
Joined: Sun Mar 10, 2013 7:32 pm

Re: Peak detection: add "attack?"

Post by Perfect Human Interface »

Hmm. So how is this different from the peak meter by cytoSonic? They seem to output almost identical (with attack at 0), but your code decays just slightly slower. I also noticed that it bottoms out at 2e-008 rather than 1e-008, but it takes longer to get there.

I appreciate all the help, big time.
KG_is_back
Posts: 1196
Joined: Tue Oct 22, 2013 5:43 pm
Location: Slovakia

Re: Peak detection: add "attack?"

Post by KG_is_back »

Perfect Human Interface wrote:Hmm. So how is this different from the peak meter by cytoSonic? They seem to output almost identical (with attack at 0), but your code decays just slightly slower. I also noticed that it bottoms out at 2e-008 rather than 1e-008, but it takes longer to get there.

I appreciate all the help, big time.


I do not have an explanation for that. It is probably just some kind of rounding error because my uses different form of equation and does not have the floor parameter (which might be wise to add to prevent denormals). By the way my code is the same as in the stock envelope follower.
Post Reply