limiter

Dynamic range limiter

Description

The 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 limiter System object specify the type of dynamic range limiting.

To perform dynamic range limiting:

  1. Create the limiter object and set its properties.

  2. 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

Description

dRL = limiter creates a System object, dRL, that performs brick-wall dynamic range limiting independently across each input channel.

dRL = limiter(thresholdValue) sets the Threshold property to thresholdValue.

dRL = limiter(___,Name,Value) sets each property Name to the specified Value. Unspecified properties have default values.

Example: dRL = limiter('AttackTime',0.01,'SampleRate',16000) creates a System object, dRL, with a 10 ms attack time and a sample rate of 16 kHz.

Properties

expand all

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.

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

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

y=x(xT+W2)2(2×W)

for the range (2×|xT|)W.

  • 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.

Tunable: Yes

Data Types: single | double

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.

Tunable: Yes

Data Types: single | double

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.

Tunable: Yes

Data Types: single | double

Make-up gain mode, specified as 'Auto' or 'Property'.

  • '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.

Tunable: No

Data Types: char | string

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.

Tunable: Yes

Dependencies

To enable this property, set MakeUpGainMode to 'Property'.

Data Types: single | double

Input sample rate in Hz, specified as a positive scalar.

Tunable: Yes

Data Types: single | double

Usage

Description

example

audioOut = dRL(audioIn)performs dynamic range limiting on the input signal, audioIn, and returns the limited signal, audioOut. The type of dynamic range limiting is specified by the algorithm and properties of the limiter System object, dRL.

example

[audioOut,gain] = dRL(audioIn)also returns the applied gain, in dB, at each input sample.

Input Arguments

expand all

Audio input to the limiter, specified as a matrix. The columns of the matrix are treated as independent audio channels.

Data Types: single | double

Output Arguments

expand all

Audio output from the limiter, returned as a matrix the same size as audioIn.

Data Types: single | double

Gain applied by the limiter, 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)

expand all

visualizeVisualize static characteristic of dynamic range controller
createAudioPluginClassCreate audio plugin class that implements functionality of System object
parameterTunerTune object parameters while streaming
configureMIDIConfigure MIDI connections between audio object and MIDI controller
disconnectMIDIDisconnect MIDI controls from audio object
getMIDIConnectionsGet MIDI connections of audio object
cloneCreate duplicate System object
isLockedDetermine if System object is in use
releaseRelease resources and allow changes to System object property values and input characteristics
resetReset internal states of System object
stepRun System object algorithm

The createAudioPluginClass and configureMIDI functions map tunable properties of the limiter System object to user-facing parameters:

PropertyRangeMappingUnit
Threshold[–50, 0]lineardB
KneeWidth[0, 20]lineardB
AttackTime[0, 4]linearseconds
ReleaseTime[0, 4]linearseconds
MakeUpGain (available when you set MakeUpGainMode to 'Property')[–10, 24]lineardB

Examples

collapse all

Use dynamic range limiting to suppress 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 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)

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)

Create a 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);

Call parameterTuner to open a UI to tune parameters of the limiter while streaming.

parameterTuner(dRL)

In an audio stream loop:

  1. Read in a frame of audio from the file.

  2. Apply dynamic range limiting.

  3. 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)

Algorithms

expand all

The limiter System object processes a signal frame by frame and element by element.

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

Introduced in R2016a