Search guides and the APICtrl K
  1. API reference
  2. DSP

compressors.h

The hardware compressors: opto, FET, VCA.

#include <sonore/compressors.h>
On this page

Design notes

dsp.h's Compressor is the textbook feed-forward design: a detector, a gain computer with a soft knee, a multiplier. Every classic compressor is that diagram with one box replaced by a piece of hardware whose physics is the sound, and "make it sound like an LA-2A" was being answered by turning the textbook's release knob. These are the three gain elements that define the three families, each modelled from what the element does:

OptoCompressor   the LA-2A's T4 cell: an electroluminescent panel driven
                 by the sidechain, lighting a cadmium-sulphide photocell
                 whose resistance sets the gain. The panel is fast; the
                 photocell is not, and its recovery depends on how long
                 and how brightly it was lit. The manufacturer's own
                 figures, which the model reproduces: 10 ms attack, 50%
                 of the release in about 60 ms and the rest in 0.5 to
                 5 seconds, longer after longer compression. Two states
                 -- a fast one and a slow "memory" that fills while the
                 cell is lit -- and the release follows whichever is
                 higher, which is exactly that shape. No ratio control:
                 the T4's own curve is a soft 3:1 in Compress and steeper
                 in Limit, and Peak Reduction sets how hard it is lit.

FetCompressor    the 1176: a FET as the shunt leg of an attenuator, its
                 channel resistance set by the sidechain. Two things the
                 circuit does that a gain computer does not: it is a
                 FEEDBACK compressor (the sidechain reads the OUTPUT), so
                 the ratio buttons set a loop gain and the effective
                 knee and timing are program-dependent; and a FET in its
                 triode region has a channel conductance that depends on
                 the drain voltage -- the signal -- which is where the
                 1176's even-harmonic grain under gain reduction comes
                 from. Attack 20 to 800 microseconds, release 50 to
                 1100 ms, the four ratios and "all buttons in".
                 The loop is SOLVED each sample, not delayed. A digital
                 feedback compressor that feeds back last sample's output
                 has a unit delay in a loop whose gain is 3 to 19, and at
                 a 20 microsecond attack -- one sample -- it limit-cycles;
                 that is why software 1176s quietly lengthen the attack.
                 The output level is the fixed point of "what the
                 detector sees is what the attenuator made", a monotone
                 equation in |y| that bisection finds exactly, the same
                 move zero-delay feedback makes for a filter. Then the
                 FET's signal-dependent conductance makes the sample the
                 root of a quadratic, which has a closed form.

VcaCompressor    the dbx 160 and the SSL bus compressor: a VCA whose gain
                 is exactly exponential in its control voltage, so the
                 ratio is exactly the ratio and the element itself adds
                 nothing -- which is the point of a VCA and the reason
                 this one measures under -60 dB of distortion at 10 dB
                 of gain reduction where the FET measures -40. The dbx
                 detects true RMS through a single time constant (its
                 "program-dependent" feel is the RMS integrator); the
                 SSL detects peaks and offers the two-capacitor auto
                 release, fast then slow. OverEasy is a wide soft knee.

The detector and knee mathematics are Giannoulis, Massberg & Reiss, "Digital Dynamic Range Compressor Design -- A Tutorial and Analysis" (JAES 2012); the time constants and curves are the manufacturers' published specifications; the gain elements are the physics stated above. Every figure quoted is measured in the unit test.

Included by dsp.h.

Types 3

The LA-2A-style optical compressor: an electroluminescent panel lighting a photocell, with the cell's two-speed release that lengthens after longer compression (see the file comment for the physics and the published figures it reproduces).

One channel, per sample. Call setSampleRate() in prepare(), before any audio: the panel's and the cell's time constants are worked out there for the rate. The setters and process() then run on the audio thread, in the DSP's own process(). There is no ratio, attack or release to set: Peak Reduction (0..1) is how hard the panel is lit, Mode picks the Compress or the Limit curve, makeup is in dB and the sidechain emphasis is 0..1. computeGain() takes the detector separately and returns the gain, which is how a key input or a stereo link is done: one instance, one detector, the gain applied to both channels. reset() empties the cell's memory and lands the glides.

The 1176-style FET compressor: a feedback design whose loop is solved exactly each sample, with the FET's signal-dependent channel giving the even-harmonic grain under gain reduction (see the file comment).

One channel, per sample. Call setSampleRate() in prepare(); the setters and process() then run on the audio thread. As on the hardware there is no threshold: setInput() (dB) is how hard the cell is driven against a fixed one at -18 dB, and setOutput() (dB) is the makeup. Attack is clamped to 20..800 microseconds and release to 50..1100 ms; Ratio::AllButtons lowers the threshold by 8 dB and doubles the grain (0..0.5, default 0.2). No key input: a feedback compressor's detector hears its own output.

The VCA compressor of the dbx 160 and the SSL bus compressor: a gain element exactly exponential in its control voltage, so the ratio set is the ratio measured, with a true-RMS or a peak detector and the SSL's two-capacitor auto release (see the file comment).

One channel, per sample. Call setSampleRate() in prepare(); the setters and process() then run on the audio thread. Threshold, knee and makeup are in dB, the ratio is N for N:1 (at least 1), attack, release and the RMS time in ms. With the RMS detector (the default) attack and release smooth the gain after the RMS integrator; with Peak they time the detector. Auto release, with either, replaces the release with the two-capacitor curve. computeGain() takes the detector separately and returns the gain, for a key input or a stereo link. MultibandDynamics is built on this.

↑↓ to move↵ to openEvery public name in the headers, and every guide