Nyquist Reverb plugin

Based on the discussion of GVerb bugs (the GVerb plugin is distributed together with the Audacity Windows version) I remembered that some years ago I had wrapped Roger’s Reverb Example into an Audacity Nyquist plugin.

The Nyquist code of this Reverb plugin can be found in the download area of the German Audacity forum under:

Maybe we could improve this code and replace the ugly GVerb effect from the Audacity Windows version?

  • edgar

+1, but not just the Windows version. My vote is to replace GVerb in all versions of Audacity.

Unfortunately Nyquist plug-ins tend to run rather slowly on Linux, but that’s a price that I’d be happy to pay for a better and more user friendly reverb effect.

The main problem that I see with deciding on a suitable replacement is that there is a near infinite range of subtly different reverberation effects (KVRaudio.com lists 132 different reverb plug-ins ). I’m not sure how we will come to agreement about which “flavours” to include.

A Nyquist plug-in has the advantage that it is easy to maintain “in house”. Also Nyquist plug-ins are cross-platform compatible and there should be no associated licensing problems.

If it is agreed that a Nyquist reverb is a good way to go, then perhaps a good approach would be to look at the GUI and required features first, then write the code to fit.

Having spent 30 years in the IT industry, a large slice of that as a programmer, what you are suggesting would have been regarded as heresy in my day. Think of the user first, then design the product. Never! :smiley: :smiley:

Steve’s quotes are from the GVerb bug discussion, post 179350:

My plugin code from above is moro-or-less just a plugin header and a dry/wet mixer added to Roger’s code. I think of my plugin as pretty much crap, that’s why I wrote “maybe we can improve it”.

The Nyquist STK reverbs nrev, jcrev, and prcrev are based on CCRMA code from Physical Audio Signal Processing by Julius Smith. Many of the DSP primitives described there are already implemented in Nyquist, so it would be possible to de-mathify great parts the book into Nyquist code.

Edgar-rft says: Letting the user being involved in technical decisions is the fastest way to bring a project down to the lowest idiots level. This is not because the users are idiots, it’s just the math of the Least Common Multiple. The more numbers involved, the lower the LCM becomes.

The user’s opinion should not be ignored when designing the final plugin, otherwise you will be flooded with complaints. But clever technical decisions to make the final result usable are done faster (and often better) than starting user polls and counting votes. At least this is my experience.

The reason why I started a public discussion was that I would like to write an experimental plugin that allows to develop the final version via Nyquist code. If we really find a good solution (what is more difficult than it sounds) then we can think about a re-implementation in C, but not earlier.

More details still to come later …

  • edgar

Hmm … I’m sitting here meanwhile since more than ten hours, trying to translate Acoustic Modeling with Digital Delay and Artificial Reverberation from Physical Audio Signal Processing for Virtual Musical Instruments and Audio Effects to Nyquist code, but the more I try, the more the limitations of Nyquist become obvious to me:

  • The STK reverbs can only be adjusted in “delay” and “mix” parameters, what is nearly nothing, so I’m really seriously asking myself for what they shall bo good for.

  • The COMB filter and FEEDBACK-DELAY functions (which are internally one and the same function) can have no filter in their feedback path, so I can’t simulate air absorption or wall damping.

  • Nyquist can’t produce recusive sounds (you can’t use the sound output of a built-in SND-… function as input for the same function call), so feedback comb filters cannot be simulated by recursion.

  • Pseudo-recursive sounds can be simulated by using SETF on local sound variables in DO and DOTIMES loops, but this is horribly slow if good results are wanted because lots of iterations in slow Lisp are needed.

Currently I’m afraid that it was just simply too naive to think that Nyquist could be used to simulate a reasonably good quality reverb plugin.

I still haven’t given up, but it doesn’t looks really good anymore. :frowning:

  • edgar

Figure 3.3 shows a general schematic of a reverberator with separate implementations of early and late reverberation. The taps on the TDL may include lowpass filtering for simulation of air absorption.

While the late reverb logically begins when the early reflections end, as implemented in Fig.3.3, it may be more cost-effective in practice to feed the ``late reverb’’ unit from an earlier tap (or set of taps) from the TDL, thus overlapping them somewhat. This can help when the late reverberator needs time to build up to full density.


Using this approach, the “late reverberator” section can be added to multiple taps increasingly rolling off high frequencies with each tap. Although a crude model for absorption loss it can work quite well in practice. As relatively few “early reflections” are required the plug-in can still be reasonably efficient.

The best results that I’ve had have used DO loops with a large number of repeats, but as you say this is horribly slow. Using the Nyquist STK reverbs for the late reverberator section(s) and a (relatively) small number of early reflections is a much faster compromise that is still capable of better results than GVerb.

The tapped-delay (= early reflections) + late-reverb principle is the only way I know to produce a reverb effect with reasonable computing time. There are theoretically better statistical models, but they most often need several hours to compute and I never heard a convincingly “better” result.

But again I run into problems with the built-in Nyquist functions, because SND-TAPF and SND-TAPV only let me control the volume levels, but not the frequency rolloff, so the only way I know to make a frequency-dependent tapped delay would be something like this:

(defun tapped-delay (snd delay decay cutoff rolloff count)
  (do ((del delay  (+ del delay))    ; delay time
       (dec decay  (* dec decay))    ; volume level
       (cut cutoff (* cut rolloff))  ; lowpass frequency
       (i 0 (1+ i)))
      ((= i count) snd)
    (setf snd (sum snd (mult dec (at-abs del (cue (lp snd cut))))))))

(multichan-expand #'tapped-delay s 0.1 0.5 1000 0.9 10)

This gives a series of COUNT lowpass-filtered delays with decreasing CUTOFF frequeny. I think I do not need to explain that for realistic early relections you need several tapped delays in parallel, and the code from above still gives no stereo simulation.

For the late reverb it’s probably sufficient to produce some statistical reverb mud and then use a multiband equalizer (approx 5-10 channels) with slightly randomized decay envelopes, or maybe just simply one of the STK reverbs instead. This will be the next thing to investigate.

Question: Is there any easier or faster way known how to get a frequency-dependent tapped delay?

  • edgar

Not that I know of - that’s basically the same method that I have used.

Once some late reverb has been added a reasonably good reverb can be achieved with surprising few early reflections and the number of iterations is a major contribution to the speed. With your code example, reducing the number of loops from 10 to 5 gives around 50% increase in speed, but the difference in the sound produced is still quite small and after adding late reverb will probably not be noticeable.

If a lot of early reflections are required then a faster approximation is to use a small number of feedback delays.

(mult 0.3 (lp (feedback-delay s delay 0.1) 1000))
(mult 0.3 (lp (feedback-delay s delay 0.3) 700))
(mult 0.3 (lp (feedback-delay s delay 0.6) 400))

The plugin below is probably 99% what you can get out of a simple delay. It’s probably not sufficient to simulate the acoustics of the Carnegie Hall, but it already gives some nice early reflections and room simulations.

The late-reverb section is still completely missing. I had tried to use the Nyquist STK reverbs for the late-reverb but if played together with the sound from the delay code (same delay code as above), then the STK delays sound so sh*tty that there was no other way then to remove them.

The sliders are:

  • Room Size - the first delay (earliest reflection) in milliseconds
  • Intensity - the reverb decay in percent (that’s easier than 0.0 … 1.0)
  • Brignthness - the initial lowpass frequency of the earliest reflection in Hertz
  • Damping - the lowpass frequency decay in percent (same reason as above)
  • Density - the number of taps per delay
  • Diffusion - the number of delays per channel


  • Mega Cathedral - Turn all sliders except Damping to full right (maximum), turn only Damping to full left (minimum).
  • Extreme Ping-Pong Table Tennis - Turn Intensity, Brightness, and Density to full right (maximum), turn Room Size, Damping, and Diffusion to full left (minimum).

Things where I’m not sure if they are really good:

The left and right stereo channels use two completely independent delays with no cross-channel interaction. This may sound unnatural.

The default settings are a very low living-room simulation that I often need for speech that had been recorded in anechoic broadcast speaker chambers. These settings are probably pretty unrealistic for real-life usage. Feel free to change them.

I wanted to have an experimental test plugin where plugins with fixed presets can be derived from. There are many explanations in the plugin code. The plugin is not what I would call “user friendly”. Please feel free to fiddle around and nag as much as you can.
multi-tap-test.ny (4.15 KB)
The plugin appears in the Audacity Effect menu under the name “Multi-Tap Test…”

  • edgar

Some excessive headphone tests later I realized that using two independent delays for the stereo channels can result in disturbing stereo panning effects with long delay times, so here is the next version with a synchronized stereo delay.
multi-tap-test-2.ny (3.25 KB)
The plugin appears in the Audacity Effect menu under the name “Multi-Tap Test 2…”. Both versions can be installed side-by-side to compare the results, both plugins use the same settings as described above.

  • edgar

Not a problem with speakers, but with headphones the version 2 is noticeably more “natural” sounding provided that the source starts as true stereo (not 2 channel mono).

One minor issue at the moment (and I don’t know if there is a good solution) is that it takes a little while for the effect to “build up”.

The best solution is probably somewhere in the middle. Using two independent delays and make the taps go ping-pong between the channels, what probably approximates more to natural wall reflections.

The problem is just simple. If you have e.g. 100 milliseconds delay time (cathedral), then the signal at the tenth tap needs minimum 1 second to appear at all. With long delay times there also still is a very unregular reverb decay, that towards the end starts fluttering, what sounds really embarrising.

Probably the only solution to this is building a dense statistical reverb floor using e.g. the Nyquist feedback-delay, and mix it with a low volume from the beginning, and then also use this floor for the final reverb decay instead of the fluttering tap-delay sound. This is what I meant with “producing a realistic reverb sounds easier than it really is”.

A final problem is that the Tap-Delay-2 with high Density and Diffusion settings (that are necessary to produce a semi-realistic sound), I already need 30 seconds to apply the effect to a 20 second sound. Nobody would want to work with such a slow plugin. :frowning:

BTW: A not-so terribly math-overloaded explanation of the standard combfilter/allpass reverb:

Let’s see what happens later on…

  • edgar

Fortunately it is much quicker on Windows. On XP in Virtualbox with Audacity 2.0 it takes 34 seconds to process a 3 minute track (default plug-in settings).

Sorry I’ve not had time to contribute any code but now that I’m close to finishing the Sound Finder / Silence Finder improvements I may have a little more time.

Doesn’t matter … I do not think that we will have a real good reverb any time soon. First finish the xyz-Finder stuff, it makes not much sense to do thousand things simultaneosly. I just was bored, so I played a bit with Nyquist :smiley:

  • edgar

Productive playing :smiley: