Page 1 of 1

Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 4:54 pm
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.

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 5:02 pm
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...

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 5:19 pm
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.

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 5:31 pm
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

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 6:52 pm
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.

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 7:30 pm
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?

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 8:05 pm
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)

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 8:49 pm
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.

Re: Peak detection: add "attack?"

Posted: Tue Aug 26, 2014 11:36 pm
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.