Dereverb

Hello,
I would like to share this Dereverb plugin (created in Audacity 2.4.2, tested also on 3.2). Basically, this is a multi-band gate with an option to fine-tune the threshold and the reverb reduction for every frequency band. The gate thresholds are automatically “guessed” based on the rms of the respective frequency bands. Combination of the guessed thresholds creates a precise reverb profile. This eliminates manual tweaking. The profile can be fine-tuned by (overall) Sensitivity plus by Threshold Offset for every frequency band separately if needed.

In most cases, it should be enough to control the plugin with Sensitivity and Reverb Reduction. Additionally, try to enable Expert mode and to adjust Release, High-mid and Low-mid Reduction.

Any feedback is welcomed!

Thank you!

Attention: The plug-in processes only MONO signal. It does not work for stereo signal.

When you download and test this plug-in, please post your feedback (positive or negative) or a suggestion to this thread. You can also send me an email: jozefhalaga@gmail.com. This is important for the further development.
Dereverb.ny (5.58 KB)
(NEW version n.7; uploaded October 12, 2022)
What is new: Few minor improvements.

Older versions:
Dereverb.ny (5.54 KB)
(Version n.6; uploaded October 10, 2022)
What is new: Limit for selection is raised up to 2 hours and 25 minutes (for 48000Hz).
Dereverb.ny (5.66 KB)
(Version n.5; uploaded October 7, 2022)
Dereverb.ny
(6.43 KiB) Downloaded 294 times
(Version n.4; uploaded August 16, 2022)
Dereverb_v3.png
(Search strings: remove echo, reduce echo, remove an echo, reduce room echo, reduce reverb, reduce room reverb, remove reverberation)

1 Like

I haven’t fully tested the plugin, but I see some non-standard syntax.
(Steve will be able to give you more pointers).

The header should not have $, but rather a single ;
Those are for effects shipped with Audacity and are used for language translation.
So everything from “$nyquist-plugin” to and including “$copyright”, should have a single leading ;

Same goes for the controls, a single ;

Thank you Paul. I will update the code accordingly to your advice.
Meantime, I am working on an update, but I got stuck.
I am improving precision by guessing the gate threshold based on the frequency band loudness. It looks very promising!

I am blocked with this - how to get RMS of a filtered sound? I separate a frequency band with high pass and low pass filer. It is stored in variable sig. I tried to get loudness by: (rms sig)
but it returns an error. This is working (get ‘selection ‘RMS), but I need to manipulate sound and then measure RMS.

Please help. Thank you!

If it’s a short sound (less than two million samples) you can do it like this (mono example):

(defun get-rms (sig)
  (let ((avg (snd-avg (mult sig sig) (truncate len) (truncate len) op-average)))
    (linear-to-db (sqrt (snd-fetch avg)))))

(get-rms *track*)

Note that “len” is the length of the selection in samples. We “truncate” the value because SND-AVG requires an integer number of samples.

Thank you Steve. 2 mil. samples is less then 41,7 seconds when sampling rate is 48kHz. It is really a short sound. How can I measure rms of a longer sound please? Maybe couple of minutes.

How are you testing this, or how will you test it? Do you have a Standard Echo Speech? Find a clean room with a wooden floor…

… and record, say, the Catskill Farms 10 second speech.

That would be handy because the text is publicly posted.

https://www.kozco.com/tech/audacity/TestClip/Record_A_Clip.html

That might be a little advanced. Set up to record and clap your hands once, like when someone records their YouTube performance with separate sound and needs a sync point

Koz

That’s a bit more tricky to do accurately.

Basically you need to loop through the audio with SND-AVG with a step size and block size of less than 2 million. That will create a new sound in which each sample represents the average of each block. You then find the average of the new sound.

See also: Nyquist Functions

@Steve, thank you very much for that piece of code that measure rms. This is very helpful! I would not be able to put it all together (I am still trying to understand it… :unamused:). But as expected, the precision is on the higher level now. And I am very happy about it.

I have updated the first message in this thread, so it is easy for other users to download the latest version.

LIMITATION: The plugin works for the selection up to 41 second, because of that 2 mil. samples limitation. Steve, you told me to loop through the audio, so I can get rms of a longer selection. I really want do my best to learn more on how to do programming in Nyquist. But still my knowledge is very limited. I am just at the beginning, trying to understand the basics. So I want to ask you if you can help me please also with this.

@Koz, I am not sure if I understand the second part of your message (so sorry for that). But what can I say is that for this initial development I am using three totally different real samples that contains room echo. Every sample has also different characteristics (fq profile), different echo (recorded in different environments) and different quality. My goal is to make an easy-to-use tool that removes room echo/reverb. I compare the results with Izotope RX 4 Advanced Dereverb module (why? Because it was recommended few years ago as a good dereverbation tool. Also the reason is that it does not use advanced algorithms with AI - I know that I cannot come any close to that level). I will try to record some samples for you later. Thank you for your help, too!

This can calculate the RMS for very long (mono) audio.

I’ve separated out the calculation for choosing an appropriate block (“step”) size into it’s own function. If you are working with very long audio selections (hours), then you may want to try and optimise the BEST-STEP-SIZE function, but as written it should work for any size up to many hours of audio with good precision.

(defun get-rms (sig ln)
  ;; Return RMS of mono sound.
  (let ((sigsq (mult sig sig)))
    (setf step (best-step-size ln))
    (setf ms (snd-avg sigsq step step op-average))
    (setf sigsq nil) ;memory optimisation.
    ;; Use SND-AVG rather than S-AVG for compatibility with
    ;; Audacity versions < 3.0.
    (when (> (snd-length ms 2) 1)
      (setf step (snd-length ms ny:all))
      (setf ms (snd-avg ms step step op-average)))
    (linear-to-db (sqrt (snd-fetch ms)))))


(defun best-step-size (ln)
  ;; Return a step size less than maxblock.
  ;; Optimisation Hints:
  ;; Large step requires less loops in LISP, so may be faster,
  ;; but greater difference between step size and final block length
  ;; decreases precision.
  (let ((maxblocklen 1000000))
    (if (> ln maxblocklen)
        (round (sqrt (float ln)))
        ln)))


(get-rms *track* (truncate len))

Thank you!!

I owe you a bottle of beer. No not bottle, a barrel of beer!!

The plugin attached in the first message was updated to the version 3.

  • it can process a longer selection now (all credit goes to Steve)
  • the lookahead setting was removed - this variable mirrors attack now. Let me know if you think we need this to revert back.
  • GUI string Reduction was replaced with Reverb Reduction to make it more clear for users
  • Reduction default value was changed from -20 to -16

I would be very thankful if someone can test this plugin and provide a feedback. Thank you!

Tried it on a short clip with quite a bit of reverb and unfortunately, could not find any suitable settings.
The plugin either did nothing or, completely distorted the audio depending on settings.

The GUI also displays odd characters under Linux (Debian 10) with Audacity Ver 2.2.2
I suspect it’s the bullet points you added.
The plugin also does not allow changing from the simple to expert modes, it’s stuck on simple.
Your syntax is incorrect in several places.


Nyquist shows the following with the debug button enabled:

Warning: cannot go back in time to 0, sound came from (FORCE-SRATE S%RATE (ABS-ENV (S-REST LOOKAHEAD)))

Dear Paul,
I really appreciate your help with testing and improving this plugin. Here are my comments:

Linux (Debian 10)

I did not tested this plugin under Linux or macOS. Thanks for helping with this. I have no idea if any plugin should work on all platforms. Are there some differences? I do not know.

Audacity Ver 2.2.2

This plugin was developed under Audacity 2.4.2. I can test it under older versions, but I prefer to focus on testing under the latest Audacity version.

GUI also displays odd characters

Wow, I would not expect to see such problem with Linux. Can you recommend another bullet character that Linux is able to show? Thank you.

does not allow changing from the simple to expert modes, it’s stuck on simple

I am afraid that this is because of some adjustments of the code. From the screenshot you provided, beside other GUI adjustments, I can see that there is a mistake in the choice control. Notice my screenshot - there is “Simple” mode. In your screenshot, there is “(Simple”. Something is wrong… This is not exact copy of my code, so I cannot say what is the problem, only if you attach your adjusted version and let me check it.

Nyquist shows the following with the debug button enabled:

Thank you for bringing this forward. I have also notice this warning. I do not know how to fix this. The plugin works, so for now I have ignored this. But I would appreciate if someone can shed a light on this.

@Steve, I have tested the selection limits and here are my findings:

  • maximum length of selection can be about 9 minutes and 30 seconds (48kHz, 32-bit)
  • if adding (SND-SET-MAX-AUDIO-MEM 2000000000), the max length is about 16 minutes and 30 seconds (48kHz, 32-bit)
  • probably this selection limit will vary from one machine to another

Is there something what we can do about it? Or this is the best what we can do? I mean it is good to have 9 minutes limit, it is definitely better than 41 seconds as it was at the beginning :slight_smile:

Finding suitable settings is certainly a problem.
The “Simple” mode is easy to use but the lack of frequency tuning seems to be basically just a gate (Noise Gate - Audacity Manual)
On the other hand, the “Expert” mode requires a lot of fiddling as we are basically running blind, so have to rely on “tweak, preview, tweak, preview …”.


Nyquist supports ASCII only. Recent versions of Audacity (2.4.2 or later if I recall correctly) should display UTF8 characters correctly when used in headers (the “;control” lines), but I’d recommend not relying on this. Best to stick with ASCII encoding (the plug-in uses a Unicode encoding scheme rather than plain ASCII text).

Note, there’s currently a bug that strips out any “&” characters from plug-in headers. This bug has been closed (not fixed) by the development team, so it is unlikely to be fixed any time soon (Missing "&" in Regular Interval Labels · Issue #3203 · audacity/audacity · GitHub). The workaround is to avoid using the “&” character.


You can use an asterisk (“*”) but it should be the ASCII encoded version (ASCII character 42, #2A hex https://www.asciitable.com/). Your plug-in uses the multi-byte Unicode character #E2 80 A2 Unicode Character 'BULLET' (U+2022)).


Unfortunately this is a limitation of the GUI that Audacity generates for Nyquist plug-ins. The GUIs are not “dynamic”. It is not currently possible for the plug-in to modify the appearance of the GUI on the fly, or even to “grey out” unused controls.
You can see the same limitation in the “Adjustable Fade” plug-in: Adjustable Fade - Audacity Manual


Perhaps you could post specific examples. It looks basically OK to me.

The two issues that I’ve spotted are:

  1. Unicode rather than plain ASCII
  2. Use of the “underscore” (“_”) function in a plug-in that does not have translations - this is harmless.


Note that’s a “warning” rather than an “error”. Ideally it should be corrected, but it’s non-fatal.
I’ve not checked, but it probably just requires wrapping a sound in (CUE ) so that Nyquist doesn’t try (and fail) to move the sound’s start time.

The RMS code that I posted here Dereverb - #9 by steve should be able to handle much longer sounds than that. I’ve not yet checked, but perhaps the code is retaining multiple copies of the audio in RAM. Also note that Audacity 2.4.2 on Windows is 32-bit, which means that it is limited to a maximum of 2 GB RAM.


The latest Audacity version is 3.1.2 (Audacity ® | Downloads).
Personally I still prefer the 2.4.2 version as it is more stable on Linux (I use Xubuntu), but Audacity 3.1.2 is available as 64-bit for Windows. Unfortunately even the 64-bit version is not yet entirely free of the old 32-bit limitations. We’re still waiting for this bug to be fully fixed: Nyquist effects overflow at > 2^31 samples · Issue #1607 · audacity/audacity · GitHub (one of the developers turned down the proposed fix which I submitted a couple of months ago.)

Hi Steve and butterfly,

As to the syntax, I downloaded the plugin from the first post (previous page).
The following line:

;control mode "Choose Mode" choice ("Simple" "Expert") 0

Should be:

;control mode "Choose Mode" choice "Simple, Expert" 0

When testing new plugins, I always prefer to enable the debug button:

;debugbutton true

In some plugins, I see enabled instead of true, both seem to work.

Lines 18 and 23 (blank lines included), don’t show up at all.

As to the functionality, I couldn’t get it to work.
My test clip is 1 minute in duration.

Unfortunately, with this kind of plugin, real time tweaking is really what is needed
as otherwise, it takes far too long.
@butterfly, perhaps you can post some suggested settings based on reverb examples.

I see that the plugin is mono only, this can be a limitation.
Perhaps consider testing for stereo audio with “arrayp” then applying the settings individually to the left and right
channels using “(aref track 0)” and “(aref track 1)”.
This has the added advantage that any slight reverb differences in the channels (due to distances of the mic placement)
will also be catered for, or at least the reverb reduced some what.

or 3.1.3. :wink:

You make some good points Paul. Expanding on them a little:

Yes.

If it were a plug-in that is shipped with Audacity it would be:

$control mode (_ "Choose Mode") choice (_  "Simple" "Expert") 0

The “$” at the start of the line is used when compiling Audacity’s translations, and the “" (underscore) function tells Audacity to look for a translation to substitute in place of the quoted text.
For 3rd party plug-ins, the “$” is treated like a “;”. That is, Nyquist treats everything after the character as a comment, and Audacity sees “$control” the same as “;control”. At run time, translations will not be found (because the 3rd party plug-in does not have translations compiled into Audacity), so the "
” function fails silently.


So do I.
The debug button has been disabled in most of the plug-ins that are shipped with Audacity, but only after they have been very thoroughly tested and have a successful track history in the wild.
It’s not an “error” to disable the debug button, though I would highly recommend leaving it enabled during development, testing, and field trials.


That’s because you’re using an old version of Audacity that pre-dates the “;control text” widget (See: Missing features - Audacity Support)


The docs: Missing features - Audacity Support


Or perhaps some semi-automated way to create appropriate settings? I’m thinking along the lines of the “noise profile” in the Noise Reduction effect.


That may be because your version of Audacity is so old. The earliest version that I’ve tried with it is 2.4.2.


When working on a new algorithm, I frequently start by coding for mono only. That’s generally sufficient for a proof of concept, and it avoids having to worry about possible complications of stereo processing until the algorithm is fully worked out.

Converting a mono effect to a stereo effect can often be done using the MULTICHAN-EXPAND macro.

Say that you have some code that works on mono audio only, and you want to apply it to stereo sound by applying to each channel independently (no interaction between the channels). You could wrap the code into a function:

(defun my-mono-effect (my-mono-sound)
  ... my mono effect code ...)

This will work as normal when called with TRACK as “my-mono-sound”, provided that TRACK is mono, but will fail if TRACK is stereo:

(my-mono-effect *track*)

To make it work with mono or stereo, we could use MULTICHAN-EXPAND like this:

(multichan-expand #'my-mono-effect *track*)

The macro calls the quoted function my-mono-effect, and if the other arguments are arrays, it passes the first element from the array (the left channel of track) to the function, then calls the function again with the next argument (the right channel).

Here’s a very simple example to illustrate how MULTICHAN-EXPAND works:

(defun test (val)
  (print val))

(setf my-array (vector "Hello" "World"))
(multichan-expand #'test my-array)

MULTICHAN-EXPAND first calls TEST and passes “Hello” as the argument, then calls TEST again with “World” as the argument.

See also: Missing features - Audacity Support

Oops, typo :blush: :smiley: