Help with envelope detector

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

I've playing with compressors, but I've some doubts. Here is a digital envelope follower:

Code: Select all

rect = abs(input);

if (rect > envelope) filterCoef = attackCoef;
else                 filterCoef = releaseCoef;

envelope = rcFilter.filter (rect, filterCoef);
ok, it works, but it sounds bad, in analog world the fullwave rectifier is done with diodes (I don’t know about electronics), the diode transfer curve is very different to abs:
http://www.learningelectronics.net/work ... zener.html
So, i’ve created my own rectify function to smooth the bottom part of the waveshaper. The compressor began to sound better.

Second, I don’t think there is something like “if” in analog compressors, I’ve tried with lowpass(filterCoef) and linear scale too, but these have not worked well.

so here is my question:
How can I replace the use of “if” to get a smooth transition between attack and release coefficients?
Thanks

Post

Search "smooth_abs" in this forum section.
I would not say it is enough, but there were a lot of suggestions there

Post

You could try putting a first order lowpass on your filter coefficient.

Post

camsr wrote:You could try putting a first order lowpass on your filter coefficient.
yes, I've tried that (I've said at the end of my post) but doesn't works well, at the end of the release envelope I get a kind of second release (release of release)
Zaphod (giancarlo) wrote:Search "smooth_abs" in this forum section.
I would not say it is enough, but there were a lot of suggestions there
Thanks, I will search it, but I have made a "smooth abs" function, is a polynomial aprox.

Post

How smooth are you attempting to make it? Is it just to reduce aliasing or it it supposed to be part of the sound?
You can use a triangle kernel filter to smooth the discontinuity from the instant switching, it looks like:
y[n]= 0.25*x[n-1] + 0.50*x[n] + 0.25*x[n+1]
if you apply this to filterCoef, anything that uses the result must be delayed by one sample.

Post

plusfer wrote:
camsr wrote:You could try putting a first order lowpass on your filter coefficient.
yes, I've tried that (I've said at the end of my post) but doesn't works well, at the end of the release envelope I get a kind of second release (release of release)
Zaphod (giancarlo) wrote:Search "smooth_abs" in this forum section.
I would not say it is enough, but there were a lot of suggestions there
Thanks, I will search it, but I have made a "smooth abs" function, is a polynomial aprox.
The trick is not about the abs, but how to use it for avoiding conditionals. It is just an idea, you need to merge it with a lot of clever things. Alone it is not enough

Post

Yip, Zaphod is correct, it's a combo usually - two other structures that might help:

Code: Select all

float att_coef = 1.f - expf(-(1.f/(attack * getSampleRate())));//in seconds
float rel_coef = 1.f - expf(-(1.f/(release * getSampleRate())));

//quite common in some hardware
float absIn = fabs(in);
buf1 = buf1+ att_coef*std::max(absIn - buf1,0.0f) - rel_coef*buf1;

//slightly more complex - release before attack - release is attack+release time
buf1 = std::max(in,buf1- rel_coef * buf1);
buf2 = buf2 + att_coef*(buf1-buf2);
Now you can also mess with the max() to get it smoother(max() is the diode btw), but take note that it will conduct less in the smoothing curve - some pedals actually choose there diodes very carefully and use it's characteristics to actually become the threshold.

Post

Hi plusfer

How is it sounding bad to you? Distortion? Aliasing? Un-musical dynamics control?

Do you want peak compression with fairly fast attack? RMS compression with fairly fast attack? Smoother, slower compression?

Something that seemed to make a "better sound" for me in analog and also digital in a peak compressor, was to have a preliminary short rectification-smoothing stage, ahead of the attack-release and further smoothing.

In analog with opamps, it can sometimes be hard to get "real fast" attack shorter than maybe 1 ms. And if you add more current drive to get "nearer to instant" attack, sometimes it just sounds bad anyway, clicky types of sound on transients. Things that sound like defects, even though technically it might not be a defect. The difficulty getting "instant" attack with an opamp driving a capacitor, being the limited current drive of the opamp.

So in analog, the first rectification stage could be maybe as much as 1 ms attack, 5 or 10 ms release. The times measured in time constants, the time it takes to attack to 63% or release to 37%. In old digital compressors I made, used 0 ms attack, 5 or 10 ms release on the first stage, but if I revisit might try backing off the attack a bit as in practical analog.

This is for peak compressors. In the past I was too fixated on riding peak levels. Not considering other possibilities.

Anyway, that first stage does initial smoothing, giving a fairly solid peak envelope with which to drive further smoothing with attack-release controls.

For instance, a 10 ms release time constant on the first smoothing stage-- With a first-order filter, an RC network, TC = 1 / (2 * pi * Fc). Therefore, Fc = 1 / (2 * pi * TC). Therefore, a 10 ms release would be a first order lowpass function with a cutoff frequency of about 16 Hz. It allows lots of audio ripple thru, but OTOH smooths a fair amount for driving subsequent stages. The first peak tracking stage would attenuate 16 Hz ripple by -3 dB, 32 Hz ripple by about -6 dB. Then about -6 dB per octave thereafter. So ripple is about -36 dB at 1 kHz, and about -56 dB at 10 kHz. Before it reaches an AR stage.
Last edited by JCJR on Sat Apr 02, 2016 4:10 pm, edited 1 time in total.

Post

Am ignorant of the "bad things" associated with raw abs or if-then in AR envelopes. Been thinking about it trying to understand. Whatever is the right thing to do on those issues, dunno.

Regardless how you rectify the signal or implement the AR, if you drive the raw rectified signal direct into an AR stage, the attack and release knob settings strongly influence the kind of level you get out of the smoother. Driven direct from the rectified audio, if attack and release knobs are set equal, the envelope will not be a peak envelope. It will be an average envelope. As the ratio between release and attack is increased, the envelope becomes more and more peak sensing. For instance with 10 ms attack and 100 ms release, it ought to be similar to a "smoothed" resistor divider tracking at about 91 percent of the peak.

With an initial fast smoother, I think the AR would be more reliably a "peak compressor" rather than drifting between various mixes of average vs peak compressor, depending on the attack and release settings. Perhaps more consistent, easier-to-set results or perhaps not. I may be thinking about it wrong.

Am still thinking about ichad's two AR examples. Can't say it is good or bad. Need to think about it more. There are various ways to do an analog AR.

Ichad's first example
buf1 = buf1+ att_coef*std::max(absIn - buf1,0.0f) - rel_coef*buf1;
I think that would be like driving a capacitor from a rectifier, either diodes or an opamp "precision rectifier" or whatever. The rectifier driving the capacitor thru an Attack Time variable resistor. And then the Release Time variable resistor connected from the same terminal of the cap, to ground.

So the attack and release pots would form a simple resistor divider attenuator if the cap was not in the circuit. The cap being there smooths the changes on the resistor divider. It would be fine for cases where attack is almost always much faster than release. This is not uncommon on guitar stompboxes and such, but it seems inelegant when attack and release times are at fairly low ratios. Maybe fine, just dunno.

Another typical method (however is the kewl way to implement without branching)--
if (In > Env) then AttackTowardInputVal;
else ReleaseTowardInputVal;
This would be like having two full-wave rectifiers driving the capacitor. Either diodes or precision rectifiers or whatever. One rectifier pulls the cap UP thru an attack pot, and the other rectifier pulls the cap DOWN thru a release pot.

In the past I believed that this method might have less ripple, given the same time constants. Because the release is always discharging into the "instantaneous rectified level" rather than always discharging to ground. But haven't thought about it for awhile and perhaps one method is really about as good as the other. Dunno. Merely mentioning the idea for whatever it may be worth.

Post

The issue is not which method you use - you can use one or the other one, but how to avoid the conditionals. It could be done in both methods, using the same technique.

Post

Thanks giancarlo

Am not dissing the importance of conditional avoidance.

I did not see plusfer explain how his compressor sounds bad. If it sounds displeasing because of low or mid intermod distortion or unmusical dynamics tracking, perhaps it would have about the same IMD or unmusical dynamics regardless how "perfect" is the branchless rectification and AR.

I re-read the threads related to "smooth_abs" last night. Interesting ideas.

If a final smoothed envelope were band-limited to 1 kHz, how much would the muliplied bandwidth expand?

Post

The smooth_abs has the problem of never reaching 0 unfortunately. There may be a way to HP filter it to get that desireable property. Or the other version which does reach 0 but changes either the gain or bias of the linear range.

Post

Guess it depends on whether wanting an RMS envelope, Peak envelope, or something else. And maybe how fast the envelope should be. Awhile ago was looking at simply using square / sqrt for rectification.

If wanting a peak envelope, and considering a simple sine wave test signal as example-- Simple abs has that pointy discontinuity at zero crossings.

A simple-- Val = (In ^ 2) ^ 0.5 without the smoothing factor, ought to merely give about the same result as abs, pointy discontinuity and all. No advantage there.

That smooth_abs turns the pointy discontinuity into a curve. The bigger the smooth factor, the rounder the discontinuity. However, with reasonable values of smooth factor-- The output is basically just a slightly-smoothed rectified sine-- With harmonics added by the smoothed discontinuity. Not so many added harmonics as a non-smoothed abs, but more harmonics to filter than the original sine wave input. This may be some kind of approximation of diode-drops in an analog rectifier, if one wanted to emulate that "defect" of analog envelope followers which used unadorned diodes for envelope steering.

However, a squared sine wave is a nice clean rectified sine wave at double the input frequency. No added harmonics at all except the doubling of frequency. And because the frequency is higher, a given time constant of smoothing filter may be more effective, depending on the topology.

On the idea of doing an initial rectification and peak envelope smoothing before driving subsequent smoothers or AR stages-- One might square the input signal. Then apply perhaps 0 ms attack, 10 ms release or whatever, then square root. On a sine wave input, the output would be a lightly-smoothed envelope perfectly riding the peaks, with no discontinuities (except possibly the 0 ms attacks).

On signals with strong transients, maybe 0 ms attack would be bad. For instance if a waveform is negative and rapidly spikes positive on a transient, guitar pluck or snare drum or whatever. The squared signal would make a brief "V notch" at the zero crossing which might exacerbate transient highs that will need filtering. The squaring alone would smooth the V notch somewhat, just as the squaring turns the zero-crossings of the input sine wave into a nice rounded sine wave at double the frequency. Dunno if the squaring would generate extra harmonics on fast transients or not.

So maybe an attack time slightly longer than 0 ms, and a "smooth" transition between attack and release could minimize problems with fast transients.

I noticed when applying simple first-order AR smoother to a squared signal-- The attack time gets shorter and the release time gets longer after sqrt has been applied to the envelope output. So if one desired to implement attack-release knobs on the squared signal, the knob settings would need compensation to allow for the TC change after the square root. Or maybe just do gain calculations based on the squared-smoothed signal, not bothering to sqrt at all.

But I like the idea of an initial short rectifier / smoother, applying AR later (after the initial square-smooth-sqrt has been performed).

Maybe for some reason this would a bad way to do it. Dunno. Might eventually test the idea.

Post

plusfer, google the AudioTK library, member miles here on this forum made it. It has a module, I think it's called atk-rel filter or envelope or something, works nicely.

Post

That library is full of "if". There is no smooth apparently. It seems the native simplified approach reported on dspguru

Yes jcr, stacking envelope followers has a way stronger effect. Anyway if you are going to replicate an envelope curve it will be good at particular settings, but "distorted" at different ones. That sigmoids we were discussing on gearslutz. The effect is good for the peak norm, just as stacking 2 of them, not more.

About smooth approach, the effect is indeed not very strong. As soon add you raise the constant all release values will be leading to the same "release action" and the compressor is "gone".

Post Reply

Return to “DSP and Plugin Development”