# AUTO Make-up Gain for Compressor

**URL:** https://forum.juce.com/t/auto-make-up-gain-for-compressor/43140
**Category:** General JUCE discussion
**Created:** [December 8, 2020, 10:17pm UTC](https://forum.juce.com/t/auto-make-up-gain-for-compressor/43140 "2020-12-08T22:17:28Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![CupaState](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/cupastate/32/8615_2.png) [@CupaState](https://forum.juce.com/u/CupaState)
#### Post date: [December 8, 2020, 10:17pm UTC](https://forum.juce.com/t/auto-make-up-gain-for-compressor/43140/1 "2020-12-08T22:17:28Z")

</div>

Hello, everyone;  
I am finishing work on a compressor that I am writing based on scientific work (Michael Massberg). The last thing left for me to do is write an implementation for automatically Make-up. I have the Massberg`s code for example and all the formulas I need, but I don’t understand what numbers need to be inserted into these formulas. If we talk about the compressor without taking into account automatic make-up, it works very well, but when it comes to the last parameter, I stop understanding what I need to do. Please, help me.

Code for one sample, only for example:

> ```
> float sample_rate = 44100;
> float input_gain_in_db = -5.24;
> float input_gain = std::pow(10.0, input_gain_in_db / 20.0); //res = 0.547016
> float log_input_gain = std::log(input_gain ); //res = -0.603277
> float threshold = -10.14;
> float log_threshold = std::log(std::pow(10.0, threshold / 20.0)); //res = -1.167411
> float ratio = 8.0;
> 
> float attack_time = 0.025; //25 ms
> float release_time = 0.274; //274 ms
> 
> float alpha_attack = 1.0 - std::exp(-1.0 / (sample_rate * attack_time)); //res = 0.000907
> float alpha_release = 1.0 - std::exp(-1.0 / (sample_rate * attack_time)); // res = 0.000083
> 
> //Method which calculates samples from buffer.
> void DevilPumperInfinityAudioProcessor::compressorMath(AudioSampleBuffer& buffer)
> {
> //Buffer is initialized & all prepare to calc. Soft Knee is absent
>   
> float log_output_gian = log_threshold + (log_input_gain - log_threshold ) / ratio; //res = -1.096894
> float log_input_level = log_input_gain - log_output_gain; // res = 0.493617
> float log_output_level = alpha_attack * log_input_level; //res = 0.000448
> 
> float control_voltage = std::exp(-log_output_level); //res = 0.999552
> 
> ```

}

The compression has occurred. What do I need make to calculate auto-make-up gain???

Also I have this formulas from Massberg`s book. But no matter what values I checked them with, I never managed to achieve the desired result. Either the signal disappears, or goes into distortion, or no noticeable changes occur:

> ```
> CVavg[n] = CVavg[n-1] + alpha_avg * (CV[n] - CVest - CVavg[n-1]);
> CVmake-up = CV[n] - (CVavg[n] + CVest);
> 
> ```

Where:  
CVavg - average value of control voltage;  
[n] - current sample;  
[n-1] - previous sample;  
alpha\_avg - alpha-coefficient of average value of the time constant (not attack or release). The number is chosen empirically;  
CV - current control voltage. (In code - log\_output\_level);  
CVest - estimation of control voltage. Using for biasing the averaging filter. Calculating from: theshold \* -slope / 2.0;  
CVmake-up - The final value that is fed to VCA =\> out = input \* std::exp(CVmake-up);

---

<div class="post-metadata">

### Author: ![kamedin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/kamedin/32/11711_2.png) [@kamedin](https://forum.juce.com/u/kamedin)
#### Post date: [December 9, 2020, 10:12am UTC](https://forum.juce.com/t/auto-make-up-gain-for-compressor/43140/2 "2020-12-09T10:12:34Z")

</div>

I don’t have the book (didn’t know there was one), I have the paper (Parameter Automation in a Dynamic Range Compressor). c\_est estimates the average of the compressor’s gain c. c\_dev is the average deviation of the actual gain around the estimate. You set c\_est as `threshold * (1 - 1 / ratio) / 2` (half the max reduction). Then c\_dev is computed lowpassing the difference between c and c\_est: `a * c_dev[n - 1] + (1 - a) * (c[n] - c_est)`. a (alpha) is computed from the filter’s time constant as `exp (-1 / (sampleRate * time))`. The time chosen has to be slow but not excessively -they propose 2 seconds. Then your make-up gain is `-(c_dev[n] + c_est)` -the estimate average gain plus the actual, slow deviation around it. You apply this gain to the output y.

I think, though, there’s a mistake in the paper. They compute c\_est using threshold in dB, so c\_est is in log space. But `c[n] = 10 ^ (M - yL[n]) / 20`, so c is in linear space and it already includes the make-up gain M. I think c\_dev shouldn’t work on c but on -yL: `a * c_dev[n - 1] - (1 - a) * (yL[n] + c_est)`.

---

<div class="post-metadata">

### Author: ![CupaState](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/cupastate/32/8615_2.png) [@CupaState](https://forum.juce.com/u/CupaState)
#### Post date: [December 9, 2020, 6:11pm UTC](https://forum.juce.com/t/auto-make-up-gain-for-compressor/43140/3 "2020-12-09T18:11:46Z")

</div>

YES! IT WORKS! Thank you, very much!
