Dynamic range limiter
System object™ performs brick-wall dynamic range limiting independently across each input
channel. Dynamic range limiting suppresses 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
System object specify the type of dynamic range limiting.
To perform dynamic range limiting:
limiterobject 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?
dRL = limiter creates a System object,
dRL, that performs brick-wall dynamic range limiting
independently across each input channel.
dRL = limiter( sets the
dRL = limiter(___,
sets each property
Name to the specified
Unspecified properties have default values.
dRL = limiter('AttackTime',0.01,'SampleRate',16000) creates
a System object,
dRL, with a 10 ms attack time and a sample rate of 16
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.
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 limiter 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.
T is the threshold in dB.
W is the knee width in dB.
AttackTime — Attack time (s)
0 (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 limiter gain to rise from 10% to 90% of its final value when the input goes above the threshold.
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 limiter gain to drop from 90% to 10% of its final value when the input goes below the threshold.
MakeUpGainMode — Make-up gain mode
'Property' (default) |
Make-up gain mode, specified as
'Auto'–– Make-up gain is applied at the output of the dynamic range limiter 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.
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 limiting. It is applied at the output of the dynamic range limiter.
To enable this property, set MakeUpGainMode to
SampleRate — Input sample rate (Hz)
44100 (default) | positive scalar
Input sample rate in Hz, specified as a positive scalar.
EnableSidechain — Enable sidechain input
false (default) |
Enable sidechain input, specified as
false. This property determines the number of available inputs on
The sidechain datatype and (frame) length must be the same as
The number of channels of the sidechain input must be equal to the number of
be equal to one. When the number of sidechain channels is one, the
computed based on this channel is applied to all channels of
When the number of sidechain channels is equal to the number of channels in
computed for each sidechain channel is applied to the corresponding channel of
audioIn — Audio input to limiter
Audio input to the limiter, specified as a matrix. The columns of the matrix are treated as independent audio channels.
audioOut — Audio output from limiter
Audio output from the limiter, returned as a matrix the same size as
gain — Gain applied by limiter (dB)
Gain applied by the limiter, returned as a matrix the same size as
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
|Visualize static characteristic of dynamic range controller|
|Return static characteristic of dynamic range controller|
|Create audio plugin class that implements functionality of System object|
|Tune object parameters while streaming|
|Configure MIDI connections between audio object and MIDI controller|
|Disconnect MIDI controls from audio object|
|Get MIDI connections of audio object|
functions map tunable properties of the
System object to user-facing parameters:
Limit Audio Signal
Use dynamic range limiting to suppress the volume of loud sounds.
Set up the
audioDeviceWriter System objects™.
frameLength = 1024; fileReader = dsp.AudioFileReader( ... 'Filename','RockDrums-44p1-stereo-11secs.mp3', ... 'SamplesPerFrame',frameLength); deviceWriter = audioDeviceWriter( ... 'SampleRate',fileReader.SampleRate);
Set up the
limiter to have a threshold of -15 dB, an attack time of 0.005 seconds, and a release time of 0.1 seconds. Set make-up gain to 0 dB (default). To specify this value, set the make-up gain mode to
'Property' but do not specify the
MakeUpGain property. Use the sample rate of your audio file reader.
dRL = limiter(-15, ... 'AttackTime',0.005, ... 'ReleaseTime',0.1, ... 'MakeUpGainMode','Property', ... 'SampleRate',fileReader.SampleRate);
Set up a time scope to visualize the original signal and the limited signal.
scope = timescope( ... 'SampleRate',fileReader.SampleRate, ... 'TimeSpanOverrunAction','Scroll', ... 'TimeSpanSource','property',... 'TimeSpan',1, ... 'BufferLength',44100*4, ... 'YLimits',[-1 1], ... 'ShowGrid',true, ... 'LayoutDimensions',[2,1], ... 'NumInputPorts',2, ... 'ShowLegend',true, ... 'Title',['Original vs. Limited Audio (top)' ... ' and Limiter Gain in dB (bottom)']);
Play the processed audio and visualize it on the scope.
while ~isDone(fileReader) x = fileReader(); [y,g] = dRL(x); deviceWriter(y); x1 = x(:,1); y1 = y(:,1); g1 = g(:,1); scope([x1,y1],g1); end release(fileReader) release(dRL) 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
limiter System object™ and a
compressor System object. Set the
ReleaseTime properties of both objects to zero. Create an
audioOscillator System object to generate a sinusoid with
Frequency set to
Amplitude set to
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)
Tune Limiter Parameters
dsp.AudioFileReader to read in audio frame-by-frame. Create a
audioDeviceWriter to write audio to your sound card. Create a
limiter to process the audio data.
frameLength = 1024; fileReader = dsp.AudioFileReader('RockDrums-44p1-stereo-11secs.mp3', ... 'SamplesPerFrame',frameLength); deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); dRL = limiter('SampleRate',fileReader.SampleRate);
parameterTuner to open a UI to tune parameters of the limiter while streaming.
In an audio stream loop:
Read in a frame of audio from the file.
Apply dynamic range limiting.
Write the frame of audio to your audio device for listening.
While streaming, tune parameters of the dynamic range limiter and listen to the effect.
while ~isDone(fileReader) audioIn = fileReader(); audioOut = dRL(audioIn); deviceWriter(audioOut); drawnow limitrate % required to update parameter end
As a best practice, release your objects once done.
release(deviceWriter) release(fileReader) release(dRL)
Sidechain Ducking with Limiter
Use the EnableSidechain input of a
limiter object to limit the amplitude level of a separate audio signal. The sidechain signal controls the dynamic range limiting of the input audio signal. When the sidechain signal exceeds the limiter Threshold, the limiter activates and limits the amplitude of the input signal. When the sidechain signal level falls below the threshold, the audio input returns to its original amplitude. For a detailed comparison of compression and dynamic range limiting, see Compare Dynamic Range Limiter and Compressor.
Prepare Audio Files
In this section, you resample and zero-pad a speech file to use as input to the
EnableSidechain property of your
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 limiting 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.
Construct Audio Objects
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
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)]);
limiter object. Use 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 limited almost immediately after the sidechain signal surpasses the limiter threshold. The slow release time ensures the limiting on the input audio lasts through any potential short silent regions in the sidechain signal.
iAmYourLimiter = limiter('EnableSidechain',true,... 'SampleRate',targetFs,... 'Threshold',-48,... 'AttackTime',0.01,... 'ReleaseTime',1.75);
audioDeviceWriter object to play the sidechain and input signals.
afw = audioDeviceWriter;
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','Original 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 = 'Dynamic Range Limited 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
limiter object. Playback your processed audio signals and display the audio data using a
The top panel of your
timescope displays the unprocessed input audio signal and the middle panel displays the sidechain audio signal. The bottom panel displays the limited 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 in the bottom panel decreases. Once the sidechain signal ends, the amplitude of the bottom panel returns to its original level.
while ~isDone(inputAudioAFR) inputAudioFrame = inputAudioAFR(); sideChainAudioFrame = sidechainAudioAFR(); limiterOutput = iAmYourLimiter(inputAudioFrame,sideChainAudioFrame); afw(sideChainAudioFrame+limiterOutput); scope(inputAudioFrame,sideChainAudioFrame,limiterOutput); end
Release your objects.
release(inputAudioAFR) release(sidechainAudioAFR) release(iAmYourLimiter) release(afw) release(scope)
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:
xdB[n] passes through the gain computer. The gain computer uses the static characteristic properties of the dynamic range limiter to brick-wall 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 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
gc[n] is smoothed using specified attack and release time:
The attack time coefficient, αA , is calculated as
The release time coefficient, αR , is calculated as
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
Calculate and Apply Make-up Gain
MakeUpGainMode is set to the default
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
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 limiter is given as
 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.
C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.
Usage notes and limitations:
System Objects in MATLAB Code Generation (MATLAB Coder)
Introduced in R2016a