This document describes the processing steps of the compressor. Included parameters:

threshold | slope = 1 - (1 / ratio) | attack | release | average | knee | lookahead | link | input gain | dry/wet

Compressor chain Fig.1 Processing chain of the compressor plugin.

Input Gain

The first element in the processing chain of the compressor is the input gain. This multiplies a set gain to the currently processed buffer and smoothes it with a gain ramp if its value has changed.

At the beginning input signal x(n) is splitted into two identical signals. Signal 1 is delayed for the lookahead feature (see below), signal 2 is processed to calculate the resulting gain reduction. Gain reduction starts with level measurement of the incoming signal samples.

Level Measurement

The compressor has two modes for calculating the current level. A simple peak algorithm is reading the level of each sample and uses them for further calculations. This enables the compressor to quickly react to level changes in this mode. The second mode is rms (“root mean square”) level measurement, calculating a quadratic mean value for a (user-)chosen time window. This mode does not react as fast as the peak algorithm but the result is closer to the perceived loudness of the signal. The rms calculation is based on an algorithm developed by Udo Zölzer (1) and is implemented as follows:

float CompressorAudioProcessor::getNewAmpSquare(float sample, float rmsSquare)
{
    if (*rmsModus)
        return (1. - avCo) * rmsSquare + avCo * (sample * sample);
    else
        return sample * sample;
}

The “avCo” parameter represents the average coefficient, its value depends on the chosen time window (calculation adopted from (1)).

Gain Reduction

Knee Fig. 2: I/O graph in dB - knee at right hand side example

After level measurement is performed the resulting level is converted to dB and then used to calculate the gain reduction for the current sample. This is made by determining the difference between level and threshold and multiplying it by the slope. If a knee > 0dB is chosen at the UI (User Interface), the gain reduction at the area around the threshold (+/- knee/2) is described by a smoothing function instead of a hard transition between no compression and compression (see Fig.2).

Stereo Link

As the reduction gain is calculated separately for each channel at stereo compression, the compressor allows to link those values by a factor of 0 to 100%.

float CompressorAudioProcessor::getLinkedRGain(float gain, float linkedGain)
{
    return gain + *link * (linkedGain - gain);
}

(gain = smaller gain reduction, linkedGain = greater gain reduction, not bound to channels)

Attack/Release Time

As the next step the linked gain reduction per channel is now transferred to an actual output gain for each sample while including the set attack and release times. This procedure works similar to the rms calculation described above except the average coefficient is replaced by an attack coefficient or release coefficient. Those coefficients are determined the same way the average coefficient (see (1)). The value of gain reduction (being smaller or greater than the last output gain) determines which coefficient is used. The reduction gain is converted back to linear number space from its logarithmic dB value prior to the comparison. In the UI the attack and release times are set in ms which define the period of time from achieving 10% of the expected gain reduction to 90%.

Attack and release time Fig.3: Attack time and release time on a square wave

The Fig.3 shows a square wave similar to the signal used to test the attack/release implementation during development. The resulting output gain is now multiplied with the original input sample when there is no lookahead > 0 ms.

Lookahead

Because the rms level measurement is taking some time to represent a fast change of the input level, it can be useful to provide the compressor some future samples (depending on expected achievements). When a lookahead is set, the output gain is not multiplied with the same input sample which it was calculated with. The second splitted signal is delayed by using a queue with a buffer of up to 10 ms in front of the original signal samples. The output gain is multiplied with the front sample in the queue and thereby the lookahead is accomplished (in acceptance of a small delay).

Dry/Wet

In the dry/wet function the compressed samples are mixed with the uncompressed input signal. The user has the choice of a mix from 0% (totally dry) up to 100% (totally wet).

Reference

(1) Udo Zölzer (2008) Digital Audio Signal Processing, 2nd ed., Chichester: Wiley