compressor
Dynamic range compressor
Description
The compressor
System object™ performs dynamic range compression independently across each input channel.
Dynamic range compression attenuates the volume of loud sounds that cross a given threshold.
It uses specified attack and release times to achieve a smooth applied gain curve. Properties
of the compressor
System object specify the type of dynamic range compression.
To perform dynamic range compression:
Create the
compressor
object and set its properties.Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects?
Creation
Syntax
Description
dRC = compressor
creates a System object, dRC
, that performs dynamic range compression
independently across each input channel over time.
dRC = compressor(
sets the
Threshold
property to thresholdValue
)thresholdValue
.
dRC = compressor(
sets the Ratio property
to thresholdValue
,ratioValue
)ratioValue
.
dRC = compressor(___,
sets each property Name,Value
)Name
to the specified Value
.
Unspecified properties have default values.
Example: dRC = compressor('AttackTime',0.01,'SampleRate',16000)
creates a System object, dRC
, with a 10 ms attack time operating at a 16 kHz
sample rate.
Properties
Unless otherwise indicated, properties are nontunable, which means you cannot change their
values after calling the object. Objects lock when you call them, and the
release
function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, see System Design in MATLAB Using System Objects.
Threshold
— Operation threshold (dB)
–10
(default) | real scalar
Operation threshold in dB, specified as a real scalar.
Operation threshold is the level above which gain is applied to the input signal.
Tunable: Yes
Data Types: single
| double
Ratio
— Compression ratio
5
(default) | real scalar
Compression ratio, specified as a real scalar greater than or equal to 1.
Compression ratio is the input/output ratio for signals that overshoot the operation threshold.
Assuming a hard knee characteristic and a steady-state input such that
x[n] dB > Threshold
, the
compression ratio is defined as .
R is the compression ratio.
x[n] is the input signal in dB.
y[n] is the output signal in dB.
T is the threshold in dB.
Tunable: Yes
Data Types: single
| double
KneeWidth
— Knee width (dB)
0
(default) | real scalar
Knee width in dB, specified as a real scalar greater than or equal to 0.
Knee width is the transition area in the compression characteristic.
For soft knee characteristics, the transition area is defined by the relation
for the range .
y is the output level in dB.
x is the input level in dB.
R is the compression ratio.
T is the threshold in dB.
W is the knee width in dB.
Tunable: Yes
Data Types: single
| double
AttackTime
— Attack time (s)
0.05
(default) | real scalar
Attack time in seconds, specified as a real scalar greater than or equal to 0.
Attack time is the time it takes the compressor gain to rise from 10% to 90% of its final value when the input goes above the threshold.
Tunable: Yes
Data Types: single
| double
ReleaseTime
— Release time (s)
0.2
(default) | real scalar
Release time in seconds, specified as a real scalar greater than or equal to 0.
Release time is the time it takes the compressor gain to drop from 90% to 10% of its final value when the input goes below the threshold.
Tunable: Yes
Data Types: single
| double
MakeUpGainMode
— Make-up gain mode
'Property'
(default) | 'Auto'
Make-up gain mode, specified as 'Auto'
or
'Property'
.
'Auto'
–– Make-up gain is applied at the output of the dynamic range compressor such that a steady-state 0 dB input has a 0 dB output.'Property'
–– Make-up gain is set to the value specified in the MakeUpGain property.
Tunable: No
Data Types: char
| string
MakeUpGain
— Make-up gain (dB)
0
(default) | real scalar
Make-up gain in dB, specified as a real scalar.
Make-up gain compensates for gain lost during compression. It is applied at the output of the dynamic range compressor.
Tunable: Yes
Dependencies
To enable this property, set MakeUpGainMode to 'Property'
.
Data Types: single
| double
SampleRate
— Input sample rate (Hz)
44100
(default) | positive scalar
Input sample rate in Hz, specified as a positive scalar.
Tunable: Yes
Data Types: single
| double
EnableSidechain
— Enable sidechain input
false
(default) | true
Enable sidechain input, specified as true
or
false
. This property determines the number of available inputs on
the compressor
object.
The sidechain datatype and (frame) length must be the same as audioIn
.
The number of channels of the sidechain input must be equal to the number of
channels of audioIn
or
be equal to one. When the number of sidechain channels is one, the gain
computed based on this channel is applied to all channels of audioIn
.
When the number of sidechain channels is equal to the number of channels in audioIn
, the
gain
computed for each sidechain channel is applied to the corresponding channel of audioIn
.
Tunable: No
Usage
Description
Input Arguments
audioIn
— Audio input to compressor
matrix
Audio input to the compressor, specified as a matrix. The columns of the matrix are treated as independent audio channels.
Data Types: single
| double
Output Arguments
audioOut
— Audio output from compressor
matrix
Audio output from the compressor, returned as a matrix the same size as
audioIn
.
Data Types: single
| double
gain
— Gain applied by compressor (dB)
matrix
Gain applied by compressor, returned as a matrix the same size as
audioIn
.
Data Types: single
| double
Object Functions
To use an object function, specify the
System object as the first input argument. For
example, to release system resources of a System object named obj
, use
this syntax:
release(obj)
Specific to compressor
visualize | Visualize static characteristic of dynamic range controller |
staticCharacteristic | Return static characteristic of dynamic range controller |
createAudioPluginClass | Create audio plugin class that implements functionality of System object |
parameterTuner | Tune object parameters while streaming |
MIDI
configureMIDI | Configure MIDI connections between audio object and MIDI controller |
disconnectMIDI | Disconnect MIDI controls from audio object |
getMIDIConnections | Get MIDI connections of audio object |
The createAudioPluginClass
and configureMIDI
functions map tunable properties of the compressor
System object to user-facing parameters:
Property | Range | Mapping | Unit |
---|---|---|---|
Threshold | [–50, 0] | linear | dB |
Ratio | [1, 50] | linear | none |
KneeWidth | [0, 20] | linear | dB |
AttackTime | [0, 4] | linear | seconds |
ReleaseTime | [0, 4] | linear | seconds |
MakeUpGain (available when you set
MakeUpGainMode to 'Property' ) | [–10, 24] | linear | dB |
Examples
Compress Audio Signal
Use dynamic range compression to attenuate the volume of loud sounds.
Set up the dsp.AudioFileReader
and audioDeviceWriter
System objects™.
frameLength = 1024; fileReader = dsp.AudioFileReader( ... 'Filename','RockDrums-44p1-stereo-11secs.mp3', ... 'SamplesPerFrame',frameLength); deviceWriter = audioDeviceWriter( ... 'SampleRate',fileReader.SampleRate);
Set up the compressor to have a threshold of -15 dB, a ratio of 7, and a knee width of 5 dB. Use the sample rate of your audio file reader.
dRC = compressor(-15,7, ... 'KneeWidth',5, ... 'SampleRate',fileReader.SampleRate);
Set up the scope to visualize the original audio signal, the compressed audio signal, and the applied compressor gain.
scope = timescope( ... 'SampleRate',fileReader.SampleRate, ... 'TimeSpanSource','Property','TimeSpan',1, ... 'BufferLength',44100*4, ... 'YLimits',[-1,1], ... 'TimeSpanOverrunAction','Scroll', ... 'ShowGrid',true, ... 'LayoutDimensions',[2,1], ... 'NumInputPorts',2, ... 'Title', ... ['Original vs. Compressed Audio (top)' ... ' and Compressor Gain in dB (bottom)']); scope.ActiveDisplay = 2; scope.YLimits = [-4,0]; scope.YLabel = 'Gain (dB)';
Play the processed audio and visualize it on the scope.
while ~isDone(fileReader) x = fileReader(); [y,g] = dRC(x); deviceWriter(y); scope([x(:,1),y(:,1)],g(:,1)) end release(dRC) release(deviceWriter) release(scope)
Compare Dynamic Range Limiter and Compressor
A dynamic range limiter is a special type of dynamic range compressor. In limiters, the level above an operational threshold is hard limited. In the simplest implementation of a limiter, the effect is equivalent to audio clipping. In compressors, the level above an operational threshold is lowered using a specified compression ratio. Using a compression ratio results in a smoother processed signal.
Compare Limiter and Compressor Applied to Sinusoid
Create a limiter
System object™ and a compressor
System object. Set the AttackTime
and ReleaseTime
properties of both objects to zero. Create an audioOscillator
System object to generate a sinusoid with Frequency
set to 5
and Amplitude
set to 0.1
.
dRL = limiter('AttackTime',0,'ReleaseTime',0); dRC = compressor('AttackTime',0,'ReleaseTime',0); osc = audioOscillator('Frequency',5,'Amplitude',0.1);
Create a time scope to visualize the generated sinusoid and the processed sinusoid.
scope = timescope( ... 'SampleRate',osc.SampleRate, ... 'TimeSpanSource','Property','TimeSpan',2, ... 'BufferLength',osc.SampleRate*4, ... 'TimeSpanOverrunAction','Scroll', ... 'ShowGrid',true, ... 'LayoutDimensions',[2 1], ... 'NumInputPorts',2); scope.ActiveDisplay = 1; scope.Title = 'Original Signal vs. Limited Signal'; scope.YLimits = [-1,1]; scope.ActiveDisplay = 2; scope.Title = 'Original Signal vs. Compressed Signal'; scope.YLimits = [-1,1];
In an audio stream loop, visualize the original sinusoid and the sinusoid processed by a limiter and a compressor. Increment the amplitude of the original sinusoid to illustrate the effect.
while osc.Amplitude < 0.75 x = osc(); xLimited = dRL(x); xCompressed = dRC(x); scope([x xLimited],[x xCompressed]); osc.Amplitude = osc.Amplitude + 0.0002; end release(scope)
release(dRL) release(dRC) release(osc)
Compare Limiter and Compressor Applied to Audio Signal
Compare the effect of dynamic range limiters and compressors on a drum track. Create a dsp.AudioFileReader
System object and a audioDeviceWriter
System object to read audio from a file and write to your audio output device. To emphasize the effect of dynamic range control, set the operational threshold of the limiter and compressor to -20 dB.
dRL.Threshold = -20; dRC.Threshold = -20; fileReader = dsp.AudioFileReader('FunkyDrums-44p1-stereo-25secs.mp3'); deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate);
Read successive frames from an audio file in a loop. Listen to and compare the effect of dynamic range limiting and dynamic range compression on an audio signal.
numFrames = 300;
fprintf('Now playing original signal...\n')
Now playing original signal...
for i = 1:numFrames x = fileReader(); deviceWriter(x); end reset(fileReader); fprintf('Now playing limited signal...\n')
Now playing limited signal...
for i = 1:numFrames x = fileReader(); xLimited = dRL(x); deviceWriter(xLimited); end reset(fileReader); fprintf('Now playing compressed signal...\n')
Now playing compressed signal...
for i = 1:numFrames x = fileReader(); xCompressed = dRC(x); deviceWriter(xCompressed); end release(fileReader) release(deviceWriter) release(dRC) release(dRL)
Diminish Plosives from Speech Signal
Plosives are consonant sounds resulting from a sudden release of airflow. They are most pronounced in words beginning with p, d, and g sounds. Plosives can be emphasized by the recording process and are often displeasurable to hear. In this example, you minimize the plosives of a speech signal by applying highpass filtering and low-band compression.
Create a dsp.AudioFileReader
object and a audioDeviceWriter
object to read an audio signal from a file and write an audio signal to a device. Play the unprocessed signal. Then release the file reader and device writer.
fileReader = dsp.AudioFileReader('audioPlosives.wav'); deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); while ~isDone(fileReader) audioIn = fileReader(); deviceWriter(audioIn); end release(deviceWriter) release(fileReader)
Design a highpass filter with a steep rolloff of all frequencies below 120 Hz. Use a dsp.SOSFilter
object to implement the highpass filter design. Create a crossover filter with one crossover at 250 Hz. The crossover filter enables you to separate the band of interest for processing. Create a dynamic range compressor to compress the dynamic range of plosive sounds. To apply no make-up gain, set the MakeUpGainMode
to "Property"
and use the default 0 dB MakeUpGain
property value. Create a time scope to visualize the processed and unprocessed audio signal.
[B,A] = designVarSlopeFilter(48,120/(fileReader.SampleRate/2),"hi",Orientation="row"); biquadFilter = dsp.SOSFilter(B,A); crossFilt = crossoverFilter( ... "SampleRate",fileReader.SampleRate, ... "NumCrossovers",1, ... "CrossoverFrequencies",250, ... "CrossoverSlopes",48); dRCompressor = compressor( ... "Threshold",-35, ... "Ratio",10, ... "KneeWidth",20, ... "AttackTime",1e-4, ... "ReleaseTime",3e-1, ... "MakeUpGainMode","Property", ... "SampleRate",fileReader.SampleRate); scope = timescope( ... "SampleRate",fileReader.SampleRate, ... "TimeSpanSource","property","TimeSpan",3, ... "BufferLength",fileReader.SampleRate*3*2, ... "YLimits",[-1 1], ... "ShowGrid",true, ... "ShowLegend",true, ... "ChannelNames",{'Original','Processed'});
In an audio stream loop:
Read in a frame of the audio file.
Apply highpass filtering using your biquad filter.
Split the audio signal into two bands.
Apply dynamic range compression to the lower band.
Remix the channels.
Write the processed audio signal to your audio device for listening.
Visualize the processed and unprocessed signals on a time scope.
As a best practice, release your objects once done.
while ~isDone(fileReader) audioIn = fileReader(); audioIn = biquadFilter(audioIn); [band1,band2] = crossFilt(audioIn); band1compressed = dRCompressor(band1); audioOut = band1compressed + band2; deviceWriter(audioOut); scope([audioIn audioOut]) end
As a best practice, release your objects once done.
release(deviceWriter) release(fileReader) release(crossFilt) release(dRCompressor) release(scope)
Tune Compressor Parameters
Create a dsp.AudioFileReader
to read in audio frame-by-frame. Create an audioDeviceWriter
to write audio to your sound card. Create a compressor
to process the audio data. Call visualize
to plot the static characteristic of the compressor
.
frameLength = 1024; fileReader = dsp.AudioFileReader('RockDrums-44p1-stereo-11secs.mp3', ... 'SamplesPerFrame',frameLength); deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); dRC = compressor('SampleRate',fileReader.SampleRate); visualize(dRC)
Create a timescope
to visualize the original and processed audio.
scope = timescope( ... 'SampleRate',fileReader.SampleRate, ... 'TimeSpanSource','property',... 'TimeSpan',1, ... 'BufferLength',fileReader.SampleRate*4, ... 'YLimits',[-1,1], ... 'TimeSpanOverrunAction','Scroll', ... 'ShowGrid',true, ... 'LayoutDimensions',[2,1], ... 'NumInputPorts',2, ... 'Title','Original vs. Compressed Audio (top) and Compressor Gain in dB (bottom)'); scope.ActiveDisplay = 2; scope.YLimits = [-4,0]; scope.YLabel = 'Gain (dB)';
Call parameterTuner
to open a UI to tune parameters of the compressor while streaming.
parameterTuner(dRC)
In an audio stream loop:
Read in a frame of audio from the file.
Apply dynamic range compression.
Write the frame of audio to your audio device for listening.
Visualize the original audio, the processed audio, and the gain applied.
While streaming, tune parameters of the dynamic range compressor and listen to the effect.
while ~isDone(fileReader) audioIn = fileReader(); [audioOut,g] = dRC(audioIn); deviceWriter(audioOut); scope([audioIn(:,1),audioOut(:,1)],g(:,1)); drawnow limitrate % required to update parameter end
As a best practice, release your objects once done.
release(deviceWriter) release(fileReader) release(dRC) release(scope)
Sidechain Ducking with Compressor
Use the EnableSidechain input of a compressor
object to reduce the amplitude level of a separate audio signal. The sidechain signal controls the compression on the input audio signal. When the sidechain signal exceeds the compressor Threshold, the compressor activates and decreases the amplitude of the input signal. When the sidechain signal level falls below the threshold, the audio input returns to its uncompressed amplitude.
Prepare Audio Files
In this section, you resample and zero-pad a speech file to use as input to the EnableSidechain
property of your compressor
object.
Read in an audio signal. Resample it to match the sample rate of the input audio signal (44.1 kHz).
targetFs = 44100;
[originalSpeech,originalFs] = audioread('Rainbow-16-8-mono-114secs.wav');
resampledSpeech = resample(originalSpeech,targetFs,originalFs);
Pad the beginning of the resampled signal with 10 seconds worth of zeros. This allows the input audio signal to be clearly heard before any compression is applied.
resampledSpeech = [zeros(10*targetFs,1);resampledSpeech];
Normalize the amplitude to avoid potential clipping.
resampledSpeech = resampledSpeech ./ max(resampledSpeech);
Write the resampled, zero-padded, and normalized sidechain signal to a file.
audiowrite('resampledSpeech.wav',resampledSpeech,targetFs);
Construct Audio Objects
Construct a dsp.AudioFileReader
object for the input and sidechain signals. Using the ReadRange property of the AudioFileReader
, select the second verse of the input signal and the first 26.5 seconds of the sidechain signal for playback. To allow the script to run indefinitely, change the playbackCount
variable from 1
to Inf
.
inputAudio = 'SoftGuitar-44p1_mono-10mins.ogg'; sidechainAudio = 'resampledSpeech.wav'; playbackCount = 1; inputAudioAFR = dsp.AudioFileReader(inputAudio,'PlayCount',playbackCount,'ReadRange',... [115*targetFs round(145.4*targetFs)]); sidechainAudioAFR = dsp.AudioFileReader(sidechainAudio,'PlayCount',playbackCount,... 'ReadRange',[1 round(26.5*targetFs)]);
Construct a compressor
object. Use a high Ratio, a fast AttackTime, and a moderately slow ReleaseTime. These settings are ideal for voice-over work. The fast attack time ensures that the input audio is compressed almost immediately after the sidechain signal surpasses the compressor threshold.
The slow release time ensures the compression on the input audio lasts through any potential short silent regions in the sidechain signal.
iAmYourCompressor = compressor('EnableSidechain',true,... 'SampleRate',targetFs,... 'Threshold',-40,... 'Ratio',8,... 'AttackTime',0.01,... 'ReleaseTime',1.5);
Construct an audioDeviceWriter
object to play the sidechain and input signals.
afw = audioDeviceWriter;
Construct a timescope
object to view the uncompressed input signal, the sidechain signal, as well as the compressed input signal.
scope = timescope('NumInputPorts',3,... 'SampleRate',targetFs,... 'TimeSpanSource','property',... 'TimeSpan',5,... 'TimeDisplayOffset',0,... 'LayoutDimensions',[3 1],... 'BufferLength',targetFs*15,... 'TimeSpanOverrunAction','Scroll',... 'YLimits',[-1 1],... 'ShowGrid',true,... 'Title','Uncompressed Input Audio - Guitar'); scope.ActiveDisplay = 2; scope.YLimits = [-1 1]; scope.Title = 'Sidechain Audio - Speech'; scope.ShowGrid = true; scope.ActiveDisplay = 3; scope.YLimits = [-1 1]; scope.ShowGrid = true; scope.Title = 'Compressed Input Audio - Guitar';
Create Audio Streaming Loop
Read in a frame of audio from your input and sidechain signals. Process your input and sidechain signals with your compressor
object. Playback your processed audio signals and display the audio data using a timescope
object.
The top panel of your timescope
displays the uncompressed input audio signal and the middle panel displays the sidechain audio signal. The bottom panel displays the compressed input audio signal. Notice the amplitudes of the signals in the top and bottom panels are identical until the sidechain signal begins. Once the sidechain signal activates, the amplitude of the signal in the bottom panel is compressed. Once the sidechain signal ends, the amplitude of the signal in the bottom panel begins to return to its uncompressed level.
while ~isDone(inputAudioAFR) inputAudioFrame = inputAudioAFR(); sideChainAudioFrame = sidechainAudioAFR(); compressorOutput = iAmYourCompressor(inputAudioFrame,sideChainAudioFrame); afw(sideChainAudioFrame+compressorOutput); scope(inputAudioFrame,sideChainAudioFrame,compressorOutput); end
Release your objects.
release(inputAudioAFR) release(sidechainAudioAFR) release(iAmYourCompressor) release(afw) release(scope)
Algorithms
The compressor
System object processes a signal frame by frame and element by element.
Convert Input Signal to dB
The N-point signal, x[n], is converted to decibels:
Gain Computer
xdB[n] passes through the gain computer. The gain computer uses the static characteristic properties of the dynamic range compressor to attenuate gain that is above the threshold.
If you specified a soft knee, the gain computer has the following static characteristic:
where T is the threshold, R is the ratio, and W is the knee width.
If you specified a hard knee, the gain computer has the following static characteristic:
The computed gain, gc[n], is calculated as
Gain Smoothing
gc[n] is smoothed using specified attack and release time properties:
The attack time coefficient, αA , is calculated as
The release time coefficient, αR , is calculated as
TA
is the attack time period, specified by the
AttackTime
property. TR
is the release time period, specified by the
ReleaseTime
property. Fs is the input sampling rate, specified by the
SampleRate
property.
Calculate and Apply Make-up Gain
If MakeUpGainMode
is set to the default 'Auto'
,
the make-up gain is calculated as the negative of the computed gain for a 0 dB input,
Given a steady-state input of 0 dB, this configuration achieves a
steady-state output of 0 dB. The make-up gain is determined by the
Threshold
, Ratio
, and
KneeWidth
properties. It does not depend on the input signal.
The make-up gain, M, is added to the smoothed gain, gs[n]:
Calculate and Apply Linear Gain
The calculated gain in dB, gm[n], is translated to a linear domain:
The output of the dynamic range compressor is given as
References
[1] Giannoulis, Dimitrios, Michael Massberg, and Joshua D. Reiss. "Digital Dynamic Range Compressor Design –– A Tutorial and Analysis." Journal of Audio Engineering Society. Vol. 60, Issue 6, 2012, pp. 399–408.
Extended Capabilities
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Usage notes and limitations:
System Objects in MATLAB Code Generation (MATLAB Coder)
Version History
Introduced in R2016a
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)