Audiobook mastering (In Development and Test)

Here’s my attempt at a “process” type of plug-in to automatically apply the three steps listed in the Audiobook Mastering version 4 thread.

A few notes:

  • I used highpass4 for the equalization step as that seems to give approximately the same rolloff as the “low rolloff for speech” EQ preset (about 24dB/octave).
  • I used code from the Limiter plug-in but removed some of the options that are not applicable to audiobook mastering to keep the interface simple and uncluttered.
  • This plug-in processes stereo channels independently, since I’m too concerned about processing stereo for audiobooks.

Any thoughts/suggestions/improvements? This is my first Audacity plug-in, so let me know if I messed anything up.
master-audiobook.ny (3.89 KB)

Did it work? Apply conventional tools according to the instructions and then run your code on the same sample.

It seems to be a race. Neil Darlow produced Macro code for using the existing tools in one step.

The only reason this isn’t a gift from the angels is one of the mastering tools, RMS Normalize doesn’t come natively with Audacity—yet. So the Macro isn’t stand-alone. Soooo close.

As we go.


This will need to hang until Steve (Senior Elf) gets back from holiday. He’s one of the humans who can speak code. The code includes proper name, time and date, so I’m happy.

I noticed “brick wall” mentioned in the code. Effect > Limiter: Soft is used intentionally in existing mastering because it can tame expressive, theatrical presentation and nobody (so far) can hear it working.

Also, I couldn’t follow the activity (no surprise there), but the steps have a very specific order. If you need the brick wall and other management, there’s a good chance your application order may be wrong.


First-pass sound test. Top to bottom: Classic Mastering, Master Audiobook, and the original voice performance.

Screen Shot 2019-09-19 at 19.20.13.png
Master Audiobook (in the middle) has significant wave distortion with non-symmetrical up/down overall bending and the first word has significant negative waveform compression missing in the positive.

Note the same passage with classic processing (on top) is clean and symmetrical like the original, and only if you’re paying strict attention do you find that the overall volume has been boosted very slightly and the fine tips of the peaks have been compressed to meet the ACX peak specification.

And I may know why. Classic Mastering intentionally creates distortion at the RMS Normalize step. It’s perfectly normal for the sound channel to overload and send peaks above 100% in order to get the RMS volume correct. But this doesn’t matter because Audacity works internally in 32-float format which doesn’t overload. The last step, Soft Limiter, gently pushes all those overloading peaks back into compliance with no harm done.

Because the formerly overloaded peaks have very low RMS/loudness, this peak correction makes little or no difference in the final outcome—except to pass ACX.

There is one more difference I noted. The high pass filter doesn’t have quite the moxie (technical term) that Low Rolloff does. It makes no difference in this particular case, but in the field, microphones can produce low frequency garbage that can be louder than the show. Also, many home microphones produce low pitch trash because, who’s going to know and after all, it’s expensive to fix and everybody looks at the price first.

We will know, because that kind of trash can keep you from passing ACX.

The top one is classic mastering, the bottom one is Master Audiobook.

Screen Shot 2019-09-19 at 19.42.28.png
Screen Shot 2019-09-19 at 19.42.55.png

This is a very well behaved sound test. Those distortions may get worse with a New User and a straight-out-of-the-box microphone.


Thanks for the feedback!

I did make sure the plug-in follows the steps in the proper order (equalize, RMS normalize, soft limit), as shown in the last handful of lines in the plug-in:

  (let* ((equalized (equalize sig))
         (normalized (norm equalized))
         (limited (softlimit normalized thresh hold)))

(Those are done in exactly the order as listed, top to bottom.)

The mention of “brick wall” is from limiter.ny (Steve Daulton’s Limiter plug-in). The “hardlimit” function is used by the “softlimit” function. To be honest, I don’t know exactly how it works, but the limiting step in my plug-in should be identical to the soft limiter in the Limiter plug-in because I’m using the exact same code. If you zoom in on the waveform that looks clipped on the bottom, you’ll probably see that it’s not actually clipped (the peaks just all line up).

I suspect all of these differences are from using a fourth-order Butterworth high-pass filter (the “highpass4” function) instead of an equalizer in the “equalize” step. I’ve noticed that it often changes the waveform differently (visually) than the equalizer. It sometimes pushes the wave form up or down more than the equalizer does, which then causes the top or bottom to look clipped after the soft limiting step runs. From what I’ve read just now, a Butterworth filter has nonlinear phase response, which likely explains the differences we see. I’ll look into changing the equalization/high-pass filtering step with something better (low or zero phase response). Hopefully that will fix both the waveform symmetry issue and the low-frequency trash issue.

the waveform that looks clipped on the bottom, you’ll probably see that it’s not actually clipped (the peaks just all line up)

I’m not shocked. That exactly what happens if the performance actually overloads, except it happens to both positive an negative peaks. Most important the Soft Limiter smooshes (technical term) the peaks in such a way that they sound fine.

The mention of “brick wall” is from limiter.ny

I believe you. This is me, not a programmer.

the “highpass4” function

I can believe that. If somebody forced me to describe the damage, I’d say the 0Hz to 2Hz “DC level” was wandering giving the apparent effect of overall waveform rising and falling.

Both Butterworth and Chebyshev are messy, just in different ways.

That rolloff has a history. It’s a close cousin to the rumble filter seen on sound mixers and in particular field mixers for exterior movie sound tracks. It’s a terrific compromise but you can still fake it out. If you have an announcing voice that goes down that low, “NBC Radio News on the Hour,” that might not be the filter for you.

This is the text version of the equalization effect. I think the name was the only thing that ever changed. It was designed as LF Rolloff… and got changed into Low Rolloff… for its debut.

Here’s a thing I wrote on the sister posting.


That’s the current curve. At a length of 4855, that green line is what it’s really doing.

Screen Shot 2019-09-20 at 13.20.59.png

If I recall correctly, that is there as a precaution against peaks that exceed 0 dB. Of course there shouldn’t be any peaks greater than 0 dB in the original audio, but if there are, then the “soft limiter” alone would do nasty “wrap around” things to them. The brick-wall limiter is used to ensure that can not occur.

It would be a good idea to test that.
Create a test signal, and duplicate it. To one copy, apply the effects one at a time. To the other copy apply your plug-in. If the results are not identical, you have a bug.

The Butterworth filter will, as you say, look different from the Equalization effect, due to differences in phase response, but that should not be a problem - the difference should not be audible. However, that flat bottom waveform looks suspicious.

If I recall correctly, that is there as a precaution against peaks that exceed 0 dB. Of course there shouldn’t be any peaks greater than 0 dB in the original audio, but if there are, then the “soft limiter” alone would do nasty “wrap around” things to them. The brick-wall limiter is used to ensure that can not occur.

Writing that down.

Since the Limiter is the third step and it follows RMS Normalize which can create intentional “overload”, how does it know the original show had clipping?


It doesn’t. However, if RMS Normalize creates more than occasional peaks slightly over 0 dB, then you have bigger problems to worry about.
If there is only an occasional peak, slightly over 0 dB, then hard limiting those peaks to 0 dB prior to soft limiting to around -3 dB will not be a problem.
Note that we are talking about hard / soft limiting, not “clipping”.

If there is only an occasional peak, slightly over 0 dB

I think you’re being a little optimistic there. If you have a thin, expressive woman’s voice recorded properly, you’re likely to get a lot more than occasional tips over 0. But yes, I get the one-two punch.

I can’t wait to find out which programming step or process is causing that waveform distortion. Is this where you find out that neat, orderly code writing is desirable?


I’ve verified that the soft limiter step is bit-for-bit identical to Steve’s Soft Limiter plug-in. ACX Check says Peak level is -inf dB on the difference signal.

The RMS Normalization step gives slightly different results from using the RMS Normalization plug-in manually. And I mean a verrry slight difference. (In one of my tests, the difference signal between RMS Normalize and my plug-in peaked at -82.2289 dB.) This is because the RMS Normalization plug-in uses a shortcut method to measure the RMS of the signal before amplifying it, which gives slightly inaccurate results that are nonetheless good enough for most purposes.

The only step that causes distortion in my plug-in is the high-pass filtering because of the Butterworth filter. It causes the relative phases of the various frequencies in the speech to become offset from each other, which can leads to higher peaks than in the original.

I don’t have a whole lot of experience with Nyquist. Steve, what’s your recommendation for doing high-pass filtering with a linear phase filter? I’ve found some Nyquist code that convolutes a section with a windowed sinc convolution kernel, but I haven’t had a chance to play with it yet.

From what I recall, it’s tricky, and slow. Audacity’s Equalization effect handles this much better, which leads me onto a suggestion; Rather than combining all of the effects in a Nyquist plug-in, why not combine them in a Macro? That would allow you to use the Equalization effect, except there’s a catch…

In Audacity 2.3.2 (and I think earlier versions too), there’s a bug in the Equalization effect that causes Audacity to crash if you open the Equalization effect from within the Macro Manager. To work around this bug, ensure that the correct Equalization setting is set before adding the effect to the Macro.

And you’ll be competing with this Macro.

Equalization:CurveName=“Low rolloff for speech” FilterLength=“5007” InterpolateLin=“0” InterpolationMethod=“B-spline”
RmsNormalize:mode=“Independently” target=“-20”
Limiter:gain-L=“0” gain-R=“0” hold=“10” makeup=“No” thresh=“-3.5” type=“SoftLimit”

Which appears to work just dandy except for one operational problem. RMS Normalize is not native to any Audacity version including, it seems, the upcoming 2.3.3. So it’s close but no cigar. Everybody’s looking for a simple, stand-alone mastering solution…which is why we have our hopes pinned on you.


I downloaded the macro and it appears in my macro list, but I cannot get it to “do anything”. I highlight a section, then Apply Macro, then click on ACX Mastering. But I do not see any changes. What am I doing wrong? I have version 2.3.2

It’s remotely possible your presentation didn’t need mastering. One of the suite’s design goals was to create as little sound damage as possible, so with the exception of the equalizer, if the tools aren’t needed, they just don’t do anything.

I would recommend applying the tools manually and watch what happens to the blue waves. UNDO back out to the original and see if the Macro does the same thing. Use a quiet reading (wave tips at about 50%) so you can see the tools work.

This is the quick notes on the process. If you get lost, go for the wiki page.

Screen Shot 2019-10-14 at 20.07.25.png
Have you ever used a Macro before?

Sorry that it has taken me so long to respond. Yes, I have played around with macros, with some good experiences. I started with the Bass Cut on the Filter Curve and modified it based upon my microphone, then added the Loudness Normalization, followed by the Soft Limiter and finishing with ACX Check. It seems to be pretty decent.
I’ve created a 2nd macro using Izotope RX7 DeClick and Mouth DeNoise, chased by Waves NS1.
I am getting a pretty quiet end product.

That flat bottom wave several messages up may be the kiss of death even if you can’t hear it. ACX is looking for processing errors and flat waves are a billboard that You Did Something That Might Be Evil.

Loudness Normalization

Have you noticed that there is an unintended feature in 2.4.2 Loudness Normalize where RMS and LUFS get crossed? The upcoming Audacity 3.0 doesn’t do that, so In my opinion 3.0 may be the first Audacity version that will survive a Mastering Macro clean and with zero damage.

One can only hope.