Peak Limiter / Expander

This “Peak Processor” effect can “squash” (compress) or “stretch” (expand) peaks above the set threshold level.

Negative ratios produce “soft clipping” of audio exceeding the threshold by non-linear (exponential) amplification (compression).
Positive ratio values expand the dynamics above the threshold, producing approximately the opposite effect.

In this version compression and expansion are not an exact reverse of each other so expanding previously compressed peaks will not restore an exact copy of the original (though it will be quite similar)

This version supports MONO TRACKS ONLY.

Version 0.2 beta Removed. See next post for updated version (1.0)

Current version of Soft Clipping Limiter: sclimiter.ny

This effect looked promising. The sound quality of the limiter is noticeably (and measurably) better than the “Broadcast Limiter II” as it does not suffer from aliasing distortion.

So here’s a new version that supports stereo tracks.
In this version, the expander is complimentary to the compressor so a positive (expand) setting will exactly cancel out an equivalent negative (compress) setting.

[peakprocess.ny version 1.0 removed. See next post for updated version.]

Obviously care needs to be taken with peak expansion to avoid clipping, but I noticed that excessive expansion can cause infinite or “not a number” (nan) sample values. This is not good.

This version prevents infinite and “nan” values. For expansion settings the output level is limited to 0 dB which I think is the neatest way to handle the issue.
peakprocess.ny (1.76 KB)

Yes, I’ve tried it and it’s really true!

Edgar (author of broadcast-limiter) says: Stomp the broadcast-limiter to the trash and use peakprocess instead!

The broadcast-limiter was a heavy compromise between sound quality and speed, I always wanted to find a way to compute a limiter function and then use it with snd-compose, but never succeeded. It looks as if snd-exp could be a working solution.

The peakprocess currently still runs slower than the broadcast-limiter but produces a much superior output sound quality. I will look at the code if I can make it run faster.

I currently have the problem that the slider limits seem to be not really useful. For example I have to type a compression value of approx. -1.000.000 (minus one million) into the text box of the “Ratio” slider to get a usable compression output for broadcast mastering.

As a replacement for the broadcast limiter there’s probably no need for the expander option?


I would imagine that most users would be looking to use the limiter for the purpose of “maximising loudness”.
With the broadcast-limiter, a threshold setting of 0.7 actually starts to soft clip at about 0.62 (-4.1 dBFS)

If “peakprocess” is run with a threshold of 0.623765 (equivalent to a threshold of 0.7 in broadcast-limiter) then the difference between how much they can be amplified is only about 0.2 dBFS (broadcast-limiter amplifies by 3.6 dB, peakprocess can be amplified by 3.4 dB). Given that increasing the “strength” further increases the harmonics with minimal increase in the headroom I wonder whether it is worth going much beyond -20.

If “peakprocess” is run with a threshold of 0.623765 and a compression setting of -30, the result is virtually identical to using broadcast-limiter with a threshold setting of 0.7 (but without the aliasing). I wouldn’t object to the “ratio” setting range being increased to -30, particularly if it was configured only as a limiter and not expander, so the range would be 0 to 30 (could be written as a 0 to 100 scale, then multiply by -10/3).

The (s-exp) function on its own takes as long as the broadcast-limiter, so unless there is a quicker way to calculate the exponential of each sample “peakprocess” is going to be slower than “broadcast-limiter”.

I may have saved you some time Edgar.
I’ve rewritten the main compressor function, ripped out most of the nonsense, and it’s a lot faster now.
A 10 minute track now processes in 28 seconds rather than the previous 35 seconds. In comparison broadcast-limiter takes 24 seconds for the same (mono) track, which is still faster, but at least it’s quite close now.

Still need to test it but looking good so far.

The broadcast-limiter is not a compressor. It’s a brickwall-limiter with a hard-wired compression ratio of 1:unlimited. The only difference to the Nyquist “clip” function (a real brickwall limiter) is that the broadcast-limiter has a built-in “knee” function, so there is a transition range of 1dB between linear amplification and “clip”. This transition is not smooth enough, that’s why the broadcast filter aliases. The broadcast-limiter “treshold” slider defines the middle of the “knee” transition.

To get a similar effect with peakprocess I need a compression ratio of nearly 1:unlimited (that’s why I need to type minus one million).

To use the peakprocess for broacast limiting (where the primary goal is maximum loudness without overdriving the transmission line) a second “peaklimiter” (or similar) plugin without the “expander” part and only one “threshold” slider can be easily created out of the existing peakprocess plugin (that would be my part to do), while the peakprocess plugin itself (including the expander) could then be left as-is.

The main reason why the peakprocess is slower than the broadcast-limiter is that with s-exp and s-log the positive and the negative halfwave need to be processed independently and therefore the sound needs the double time to compute. Maybe I find a way how to write snd-compose functions out of the s-log and s-exp math, then both halvwaves could be processed in one step. I see no other way to make the plugin run faster.

I have to admit that I’m not a really brilliant mathematician (that’s the main reason why I’m a technician and not an engineer), so this may take some days.

I saw this after I had written the stuff above. In case of doubt just attach the semi-finished plugin somewhere.

Wikipedia disagrees. Dynamic range compression - Wikipedia

Compression and limiting are not different in process but in degree and perceived effect. A limiter is a compressor with a high ratio and, generally, a fast attack time.

So in the case of “broadcast-limiter” the compression ratio is inf:1 and the attack/release times are zero and a “soft knee”.

In the UK at least, this would more usually be described as “soft clipping” rather than “limiting”. A “brick wall limiter” would generally describe an effect where the attack time is very short, just a few milliseconds, frequently with lookahead equal to the attack time. Typical values would probably be somewhere around 7 milliseconds attack time, and 30 milliseconds release and a hard knee threshold.

Here’s a close up of a sine wave that has been processed with the above settings. All tracks are displayed with “Waveform dB” as that shows the differences more clearly. One of the tracks has been processed with the broadcast limiter, the other with peakprocess followed by Amplify and Invert. The bottom track is a mix of the other two tracks.
In the peakprocess effect there is no change to the waveform below the threshold, so in relation to the broadcast limiter this would equate to the lower edge of the threshold knee, hence the need to set the threshold a little lower in peakprocess to achieve a similar result to the broadcast-limiter.

Edgar: > The broadcast-limiter is not a compressor.
Steve: > Wikipedia disagrees.

Yes, but where in the Wikipedia article is the broadcast-limiter mentioned?

What I meant is: a broadcast-limiter is a special case. A normal limiter can have an attack-time, an attack can produdue an overshoot, and an overshoot is intolerable on a radio/tv transmission line, where the output signal is used to drive the power transmitter. In reality there still is a clipper in the electric signal line before the power transmitter but if I pre-produce the sound for a radio or tv show I must push the volume level as loud as I can while simultaneously prevent overshoots by all means, what usually results in heavy peak clipping. Pushing the volume to the limit without producing overshoots is the main purpose of a broadcast limiter, therefore the “knee” (the transition between linear amplification and brutal clipping) must be as small as possible.

A broadcast signal is typically affected by heavy peak clipping. This is the main difference to e.g. CD mastering, which targets to hifi equipment. The goal of broadcast mastering is maximum volume, while the goal of CD mastering is maximum sound quality. The s/n ratio of a radio/tv transmission line is much worse than hifi equipment, so heavy compromises must be made. In the worst case of radio shortwave transmission you can feel happy if you have a s/n headroom of 20dB.

The rft-broadcast-limter as well as the peakprocess plugin strictly spoken both fall into the category of “waveshapers”. Both modify the amplitude by a fixed math formula without using an ADSR envelope like a compressor does. That’s why I still think that the peakprocess could be a good replacement for the broadcast-limiter.

Steve: > peakprocess doesn’t change to the waveform below the threshold

That’s another advantage of peakprocess over the broadcast-limiter where the “middle of the knee” threshold is based on a rough estimation instead of a precise math formula, so the overall volume change of the unmodified part of the signal is small but not exactly predictable.

Steve: > peakprocess with a threshold of 0.623765 and a compression -30 is equal to broadcast-limiter with a threshold of 0.7

If you use a more realistic broadcast threshold of 0.25 then you will instantly see and hear the difference. At the same time you will realize that there is a very different unterstanding of “tolerable distortion” between broadcast people and and musicians. :wink:

I still think the broadcast-limiter should be replaced or improved by the peakprocess code (that’s my job) but it’s probably best if we offer two plugins, one for broadcast people and one for musicians.

Intermediate message: I have the new broadast-limiter runnig, using a function-array and the nyquist “shape” function. Threhold, knee, and output level can be adjusted independently, and no aliasing anymore. It still needs some clean-up, more news later on…

Excellent description Edgar. As I fall into the “musician” category rather than the “broadcast people” category I found it very informative.

Even if “Broadcast Limiter II” is replaced, I hope that it does not disappear entirely. When I first started playing with Nyquist I found great educational value in figuring out how it worked.

I agree that two plug-ins would be useful “one for broadcast people and one for musicians”.

Sounds interesting.

Here’s a version of the “peak processor” without the expander.
I’ve called it “Soft Clipping Limiter”
This is version 0.1 (beta) as it could do with a bit of tidying up, but it’s quite a bit quicker than peakprocessor.ny and I’ve included a setting for make-up gain. With make-up gain selected, if the track has been normalised to 0 dB before applying the effect, the peak amplitude after processing will be 0 dB.

[Soft Clipping Limiter version 0.1 beta removed - see later post in this topic for latest version]

Here is the new “Broadcast Limiter IV” using the Nyquist “shape” function. Funny: the audio processing is done in one single Nyquist function.

The “shape” part is based on Roger’s Distortion Tutorial.

The explanation of the “knee” math in the “coord” function is still missing (I’ve ripped it out of an electronics schematic diagram), it’s basically a logarithmic fade using “db-to-linear” to convert a linear “percent” relationship into a logarithmic volume change. I would like to find out how this can be expressed via “exp” and “log”, so we could write peakprocess function tables to get fully compatible “compress” and “expand” back and forth transformations.
RFT-Limiter-IV.ny (1.86 KB)

I’ve not had chance to test the plug-in yet, but I’ve had a quick look at the code. Since you mentioned the (shape) function a couple of posts back it now seems a really obvious way to perform soft clipping (though I recall that the first time I read through Roger’s Distortion Tutorial it went straight over my head).

Something I’ve been thinking on, (but as yet got no evidence for or against); is a log/exp curve the best curve to use?
All clipping will produce harmonics at higher frequencies than the original waveform. “Soft” clipping will produce a series of harmonics that reduce in amplitude at higher frequencies than “hard” clipping does. Ideally I think we would both want the knee curve to be such that higher harmonics are as low as possible as eventually they will produce aliasing and “bad sound” that we want to avoid. Using the (shape) function it should be possible to tailor the curve shape to anything that we want.

Steve: > All clipping will produce harmonics at higher frequencies than the original waveform. “Soft” clipping will produce a series of harmonics that reduce in amplitude at higher frequencies than “hard” clipping does. Ideally I think we would both want the knee curve to be such that higher harmonics are as low as possible as eventually they will produce aliasing and “bad sound” that we want to avoid. Using the (shape) function it should be possible to tailor the curve shape to anything that we want.

That’s correct. According to my experience the “best” setting of the “knee” depends on many things. The audio signal (speech, music, slow, fast, loud, soft, classic, folk, opera, trash-metal), the dynamic range of the transmission line, and also the amount of backgrond noise in both, the audio signal as well as the transmission line. In many cases the audio signal must be pre-processed by a compressor, otherwise it gets distorted too much by the limiter.

Getting a “good” sound out of a compressed or limited audio signal is an art of its own.

The best setting of the “threshold” and “knee” is virtually unpredictable in advance, that’s why both must be adjustable, while the “output level” slider saves you an additional “amplify” step in the end.

Steve: > Is a log/exp curve the best curve to use?

The answer is definitely YES, because nearly everything in the audio world is based on exponentiation and logarithms, but with different bases. Decibels (volume) are based on log10 while pitch (notes and tuning) is based on log2. Nyquist provides the natural versions of “exp” and “log” (based on the Euler number) because these are the most universal ones, where all other bases can be derived from.

I’ve digged out my math books and in the attachment below is a Lisp file where all the Nyquist volume and pitch conversion functions (like “db-to-linear” and “step-to-hz”) are defined using XLISP’s “exp” and “log” functions. Use it as a cheat-sheet for your own functions.

ARGH: If I try to attach a lisp file I get a message “the extension .lsp is not allowed”. I always thought this is the “Nyquist” section of the forum and now I can’t even attach a Nyquist lisp file. What’s that for a nonsense?
logarithm.ny (4.13 KB)

Thanks for the cheat sheet, as long as I don’t loose it that’s likely to be a good time saver.

I notice that it says:
lin-to-db - same as Nyquist’s linear-to-db [but slower]
db-to-lin - same as Nyquist’s db-to-linear [but slower]

but it doesn’t appear to be any slower. Is there a reason why it should be slower?

Steve: > …it doesn’t appear to be any slower…

My fault. I thought that “db-to-linear” and “linear-to-db” are C-functions but grepping trough the Lisp files in the Audacity Nyquist folder I find:

; db = 20log(ratio)
; db = 20 ln(ratio)/ln(10)
; db/20 = ln(ratio)/ln(10)
; db ln(10)/20 = ln(ratio)
; e^(db ln(10)/20) = ratio
(setf ln10over20 (/ (log 10.0) 20))

(defun db-to-linear (x) 
  (cond ((numberp x)
         (exp (* ln10over20 x)))
        ((arrayp x)
         (let* ((len (length x))
                (result (make-array len)))
           (dotimes (i len)
             (setf (aref result i)
                   (snd-exp (snd-scale ln10over20 (aref x i)))))
         (snd-exp (snd-scale ln10over20 x)))))

(defun linear-to-db (x) 
  (cond ((numberp x)
         (/ (log (float x)) ln10over20))
        ((arrayp x)
         (let* ((len (length x))
                (result (make-array len)))
           (dotimes (i len)
             (setf (aref result i) 
                   (snd-scale (/ 1.0 ln10over20) (snd-log (aref x i)))))
         (snd-scale (/ 1.0 ln10over20) (snd-log x)))))

But there is a difference: the Nyquist “db-to-linear” and “linear-to-db” functions can also handle sounds, not only numbers.

When we first got the phpBB software it didn’t allow .ny either, but I’ve now added .lsp.

Well even Steve’s sounds distorted enough to my ears if I move the sliders far enough to left :slight_smile:. Would it be possible to have a “multiplier” control in Steve’s to mimic Broadcast Limiter, assuming the expander remains omitted? Or should we have more features in a separate broadcast limiter, like the exciter that was in V3?

That said, I think we do want a simple expander plug-in somewhere. A big use case is for recent “loudness wars” CDs, assuming anything can be done to improve them. I had some success with a few recent pop CDs using v1 of Steve’s plug-in which had the expander. Classical CDs may be another issue because there you may want to increase the volume differences between quite lengthy “quieter” and “louder” sections which should really be “quiet” and “loud”. Is some kind of “RMS expander” needed for this?

I know Steve you’ve mentioned an expander/noise gate might be a good addition to Audacity but I think there is a need for a really “simple” expander just like a really simple compressor.


I’ve completed my “Soft Clipping Limiter” (attached).

This version is specifically for soft clipping and not “expansion”, so now moving the “ratio” slider to the right makes the clipping “harder”.
It also has an option to apply “make-up gain”. If make-up gain is enabled (default) then a peak output of +/- 1 before applying the effect will be clipped down (soft clipping) then boosted back up to +/- 1 (make-up gain).

In music production soft clipping is usually only done to catch occasional brief transients rather than lopping the top off everything. Much more than that and it will be clearly (and usually unpleasantly) audible with this type of effect. Of course, some may want to use the effect “creatively” to deliberately cause distortion. Setting a low threshold and a soft “hardness” setting can be used as a finely controllable “fuzz” effect.

I think a simple but “conventional” expander would be more useful than a wave-shaping expander - that is, something that operates over multiple cycles rather than individual peaks. Unfortunately, in practice, attempting to re-expand soft-clipped waveforms usually sounds worse than doing nothing, but it should be possible to make a reasonably effective expander effect to partially reverse the effect of a a compressor. It is probably not possible to reverse a compressor effect exactly as there are too many unknowns. Even when all of the parameters are known (for example with the various Dolby and DBX noise reduction systems) it is still notoriously difficult to get the expansion to exactly match the compression.
sclimiter.ny (1.83 KB)