Fix Inverted Peaks Plugin

Hi all,

Further to this thread:

here is a plugin normally meant to fix inverted peaks in audio recordings, which can then be subsequently
processed with another plugin that ships with Audacity, called Clipfix.

The plugin is mostly based on Steve’s Updated Clipfix plugin. I added a slider to allow the tuning
of the max sample level difference, and a DC removal filter plus an antialiasing filter.
They can both (or individually) be de-activated, which is recommended for “normal” use.

Normal use:

The plugin would be used on audio that has inverted peaks due to clipping/crushing.
The single control slider (“Sample Max Delta”) can be left at the default of 0.5 for most applications.
For extreme cases, it may be worthwhile experimenting with different settings.
Best to de-activate both filters.

Other Uses:

It can also be applied to isolated drum tracks (and even electric guitars).
In this case, experiment with the “Sample Max Delta” slider for best effect.
Depending on it’s setting, it adds a bit of distortion which can make drums sound punchier (and more crunchy)
and when layered with the original drums, adds some body.

Same goes for electric guitars, a setting of around 0.1 - 0.3, tends to make the guitar sound a bit “brighter”.

For this kind of use, best to activate both filters.
Screen Shot 2021-10-08 at 9.50.15 PM.png
The Nyquist plugin (version 3), is attached below, for the updated version 4, scroll down the page.
For even older versions and how they came to be, please see the original thread, link at the top.

If you are unsure on how to install/use Nyquist plugins, please see Installing Nyquist Plug-ins

Feedback about your experiences and novel uses of this plugin are welcome.
Fix-Inverted-Peaks.ny (1.97 KB)

Congratulations. It does what it says :slight_smile:

A few points about the code:

;info

This header is now obsolete and ignored by Audacity (See: Missing features - Audacity Support)
Better to remove “;info” and just use a “;” as a normal code comment.


;maxlen 100000000

While this does prevent crashing if too much audio is selected, it’s not very user friendly as it just truncates the output without telling the user why or what has happened. It’s up to you as the plug-in developer to decide how you want to handle this, but it might be more user friendly to display an error message. For example, in the COND at the end, you could do something like:

(setf max-len 100000000)
(cond ((> len max-len) (print "Error.\nSelection too long"))
      ((and (= dcf 1) (= antialias 1))
      ...

or, a bit more informative:

(setf max-len 100000000)
(cond ((> len max-len)
        (setf *float-format* "%.3f")
        (let* ((secs (/ max-len *sound-srate*))
               (mins (truncate (/ secs 60))))
          (format nil "Error.\nSelection must be less than ~a mins ~a seconds."
                  mins (- secs (* 60 mins)))))
      ((and (= dcf 1) (= antialias 1))
       ...

Steve wrote:

Congratulations. It does what it says > :slight_smile:

Thank you Steve but you deserve the majority of the credit, as it’s mostly based on your code.
I just added some “fluff” around it.

Better to remove “;info” and just use a “;” as a normal code comment.

No problem, but will it keep compatibility with older versions that may still support it?
Although the plugin is based on version 4 of Nyquist syntax so I guess supporting older versions is out the window anyway.

While this does prevent crashing if too much audio is selected, it’s not very user friendly as it just truncates the output without telling the user why or what has happened.

OK, I wrongly assumed then that specifying a maximum, would not only limit it in code, but would also throw an error/warning
message that too much audio was selected.

Will make the changes and post an update shortly.
Thanks for the feedback.

As you say, very old versions of Audacity are out because they don’t support version 4 code.
I don’t recall exactly when the ;info header was dropped, but it was a long time ago (years).
There may have been a version or two that supported the ;info header and version 4 code, though it’s unlikely that many people will be using those versions (if they exist).

Always best to test assumptions :wink:

A bit off-topic, but maybe of interest:
Nyquist does not have a specific assert command, but it is easy to write something equivalent.

Example:
Pseudo code:

x = 1;
assert x > 0;
x++;
assert x > 1;

In Nyquist:

(setf x 1)
(unless (> x 0) (error "" x))
(incf x)
(unless (> x 1) (error "" x))

or to make it more obvious that it is just an assertion test, an ASSERT function could be defined:

(defun assert (predicate &optional (msg "") arg)
  (unless predicate
    (if arg
        (error msg arg)
        (error msg))))

which you could then use like this:

(setf x 1)
(assert (> x 0) "Assert failed" x)
(incf x)
(assert (> x 1) "Assert failed" x)

Updated Fix-Inverted-Peaks attached below.
It’s still limited to a selection of 100 million samples max, but throws a popup dialog when exceeded,
instead of just silently processing up to the limit only.

As for your assert idea Steve, very handy.
Is it on your audionyq.com site?

Fix-Inverted-Peaks.ny (Version 4):
Released under the “GNU General Public License v2.0 or later”
(License also stated in the plugin).
Fix-Inverted-Peaks.ny (2.43 KB)

Not yet, but it will be :wink:

Looks good to me.
You might like to add a license notice - I assume that you intend it to be open source (as you have published the source code publicly :wink:)
I generally recommend “GPL 2 or later” as that is compatible with Audacity’s current license and is future proofed by the “or later” (See: Frequently Asked Questions about the GNU GPL v2.0 - GNU Project - Free Software Foundation)

Using the ;copyright header will display the license in the plug-in’s “Manage button > About” dropdown.
There’s an example here (though use a semicolon rather than a “$”): https://github.com/audacity/audacity/blob/master/plug-ins/crossfadetracks.ny
The relevant parts:

;copyright "GNU General Public License v2.0 or later"

;; Released under terms of the GNU General Public License v2.0 or later:
;; http://www.gnu.org/licenses/old-licenses/gpl-2.0.html

Here’s another snippet for you to play with Paul

;; Invert peaks at threshold
(setf thresh 0.8)

(let ((top (sum (- thresh) (s-max *track* thresh)))
      (bottom (sum thresh (s-min *track* (- thresh)))))
  (sim *track*
       (clip (mult -1 ny:all top) (* 2 thresh))
       (clip (mult -1 ny:all bottom) (* 2 thresh))))

Ok, no worries will add the GPL 2 (or later) header.

That code snippet looks interesting, definitely trying it out later and let you know.

The exact opposite of fix-inverted-peaks. :smiley:

Actually it is very useful to test the “fix” plugin.
Bet you there will be more applications for it, gonna give it some more thought.

Took a 1KHz sine wave and…
1.png
Just look at the harmonics…


Then ran it through a notch filter (just to do more damage) 1 KHz and Q=15
3.png
Then ran fix-inverted-peaks plugin (default settings)…
4.png
Not shabby at all.
Still some harmonics left over, but a lot better.
BTW didn’t even run Clipfix and it made a big difference already.

Plugin above updated to “GNU General Public License v2.0 or later”.