# Envelope follower not smooth enough

With the following code, I get the "envelope" of a sound signal. However in the "envelope" there are small oscillations (high frequency) : it is not smooth enough...

I imagine that it's possible to apply a low-pass to the "envelope signal" in order to remove the high frequencies oscillations, but I also imagine it's probably better to do it directly by modifying this code :

double attack_coef = Math.Exp(Math.Log(0.01)/( 10 * 44100 * 0.001));   // 10 ms
double release_coef = Math.Exp(Math.Log(0.01)/( 100 * 44100 * 0.001));  // 100 ms
double envelope = 0.0;

for (int n = 0; n < file.Length; ++n)
{
double tmp = Math.Abs(x[n]);
if (tmp > envelope)
envelope = attack_coef * (envelope - tmp) + tmp;
else
envelope = release_coef * (envelope - tmp) + tmp;

env[n] = envelope;
}

Do you have an idea for that ?

• I tried by modifying attack and release, but with the values that I've tested, if I take higher values, it is smoother, but the peak doesn't reach the actual dBmax peak of my original signal... – Basj Oct 24 '13 at 10:12
• Pretty much anything you do to remove the high frequency content will be a low-pass filter, even if it doesn't look like the canonical filter setup you are used to. – nispio Oct 24 '13 at 22:48
• My first question would be: are you sure it isn't smooth enough? You're hardly ever going to get real-world signals that look like what you see in a textbook. In almost all cases, there will be some noise or jitter to your signal's structure, similar to what you showed above. What's important is whether those imperfections have any tangible effect on your application. – Jason R Oct 25 '13 at 15:58
• Thanks for your answers. It's not smooth enough because I use this envelope in order to modulate some other signal. I don't want small oscillations in the modulation... – Basj Oct 28 '13 at 15:41
• Is there a "standard method" for a better envlope following ? My envelope always starts with 0 (by design), so when I need to compute the minimum dB level of envelope, it is always 0. Of course I could compute the minimum of env[n] only for n > 20 000 in order to avoid the 0 values for the envelope, but I was wondering if there are some better methods for computing the envelope (avoiding the 0 values at beginning + avoiding the oscillation problem) – Basj Oct 28 '13 at 15:55

You are already just low-pass filtering the magnitude of the input signal. Right now, your envelope detection "circuit" is just a single-pole filter. Let $f[n]$ be the input to your system and, for simplicity sake, assume that attack_coef $=$ release_coef $= a_1$. Then we can express the output $y$ of your system as follows:
$$y[n] = a_1 \left(y[n-1] - |f[n]|\ \right) + |f[n]|$$
Which we can rearrange as a transfer function $h$ as follows: $$y = a_1 \left(y\,z^{-1} - |f|\right) + f$$ $$h = \frac{y}{|f|} = \frac{1 - a_1}{1 - a_1 z^{-1}}$$