Can we talk about reverb?
  • The reverb node is pretty bizarre. It is ringing and metallic, not that such qualities are always bad but it's difficult to get a typical reverb sound out of it. What are the methods of DSP for creating reverb?

    I have taken a peek inside of Joe Orgren's "Fairly Serious Reverb" (best sounding reverb in audulus imho) and it is baffling. I see a matrix of all pass filters which are actually a pair of 1-pole hi-pass lo-pass and a delay. I would love to have a toe in the water of understanding where this is concerned.
    reverb comparison.audulus
    313K
  • In the Audio EQ Cookbook an alpass filter is described as having the following coefficients:

    APF: H(s) = (s^2 - s/Q + 1) / (s^2 + s/Q + 1)

    b0 = 1 - alpha
    b1 = -2*cos(w0)
    b2 = 1 + alpha
    a0 = 1 + alpha
    a1 = -2*cos(w0)
    a2 = 1 - alpha

    But there are only 5 inputs to the biquad filter node. Let's look at how it is implemented in the APF module included in the library:
    image

    Who made this module? While I appreciate the elegance of the single line, by moving the conversion to the 5 inputs to the side of the 6 coefficients we see a tangle of cords. Can this conversion be used on all the 6 coefficient filter recipes in the EQ cookbook?

    image
    Screen Shot 2017-10-13 at 12.42.56 PM.png
    1223 x 1022 - 167K
    Screen Shot 2017-10-13 at 12.45.01 PM.png
    1360 x 736 - 224K
  • For visualization, here is what an all pass filter does to a square wave.
    https://www.instagram.com/p/BaM3N84g1jk/?taken-by=robertsyrett
  • Very nice!

    Taylor says the reverb in the reverb node is from this: https://ccrma.stanford.edu/software/stk/
  • is that also where the APF filter came from?
  • Here is a plug-in inspired by a 1962 paper on using nested all pass filters in delay lines to emulate natural-sounding reverberation. There is an intriguing diagram that looks like it might be translatable into Audulus.

    https://valhalladsp.com/2009/05/30/schroeder-reverbs-the-forgotten-algorithm/
  • So I reached out to particle physicist Natascha Hedrich whose undergraduate thesis was on theoretical allpass filters and she provided me with a link to the 1962 paper by Manfred Schroeder about using allpass filters in reverb.

    http://charlesames.net/pdf/MRSchroeder/artificial-reverb.pdf

    I love the hand-drawn diagrams!
  • Some clarification regarding the bi-Quad node and the Audio EQ cookbook. Firstly the variable names for the co-efficients are reversed and the bi-quad node has been normalized by dividing everything by a0.
    Bi-quad node. Cookbook
    a1 b0/a0
    a2 b1/a0
    a3 b2/a0
    b1 a1/a0
    b2 a2/a0

    It took me a while to figure this out, but with the appropriate modifications the module can be used for all of the filters in the cookbook
  • @stschoen thanks for the assist with the math. After having read the 1962 paper by Manfred Schroeder, I have come away with the gist of why all pass filters are important for reverb: in order to get a sufficient number of echos to emulate natural acoustic spaces, you need 1000+ aperiodic delay lines and all pass filters allow you to just run feedback through a few delay lines without creating too much comb filter/flanging artifacts. The maths of how all this goes down are a bit fuzzy but it does explain the design of the "Fairly Serious Reverb" module, which is actually pretty close to the diagram shown in Schroeder's paper.
  • @RobertSyrett, both of the links you posted were interesting papers and should provide some opportunities for experimentation. I haven't looked into Joe Orgren's "Fairly Serious Reverb" module, although I've used it before. I love having the ability to read something like this and then go to Audulus and model it and see for myself. Hope we get a decent audio frequency scope node at some point.
  • I put together some of the examples in the Schroeder paper to see how they sounded. Nothing as lush as Joe Orgren's but perhaps more natural sounding. What do you think?
    Schoereder Reverbs.audulus
    556K
  • Well done! motion to turn the all pass reverberator into a uModule. It seems to be about as good as the "digiverb" module that Intellijel makes. True, it lacks the vastness of the fairly serious reverb, but it could still be very useful for some patches. I'm also impressed that it has no biquad node.
  • The all pass reverberator does really nicely in series and in parallel. I whipped up 9 of them after seeing the inside of the fairly serious reverb and it sounds really compelling. Even with the lack of the high and low damp and parameters that I have no clue about like detail and size you can get pretty beautiful results with just changing the gain and delay settings. I had some fun just assigning random values to them.
    Screen Shot 2017-10-16 at 5.46.21 AM.png
    840 x 803 - 172K
    9xallpass reverberator.audulus
    532K
  • I was also surprised by the lack of traditional filters. Schroeder seems to use the term reverberator and filter interchangeably, but If you think about it, a delay with a feedback loop will always be a filter of some sort. After all, the other filter nodes like the bi-quad and z-1 filters all involve a delay and feedback, the delays are just much shorter. Take the simple "comb" reverberator for example. For any frequency where the delayed signal is exactly out of phase with the source, the resulting output will be attenuated and wherever the two signals are in phase the output will be amplified, hence the "comb" effect. Schroeder realized that by adding in a portion of the undelayed signal and carefully adjusting the gains he could cancel out this effect and create an all-pass circuit. I haven't checked, but I would suspect that the phase response will be similar to your example. I understand the idea of the low pass filter in the feedback loop to simulate the shorter reverberation time of higher frequencies, but I'm not clear on the idea behind the low damp knob. Joe's reverb is beautifully constructed, but a bit overwhelming to try and reverse engineer. I think part of the richness comes from some type of chorus effect. (at least he has an LFO in there for something lol).
    BTW watch the feedback loop on the example with the all pass mixed with the direct signal. I first constructed it following his diagram and almost fried my speakers. He assumes the the all-pass is unity gain, whereas the module I constructed set at 0.7 has a positive overall gain. I inserted an attenuator in the loop to adjust for this but if you raise it the unit quickly becomes unstable.
  • It's true, what is a filter after all but another form of delay? I do think there is some refining to be done with the comb filter examples as they sound quite ringing to me, but the "allpass reverberator" is a very nearly ideal unit of reverb to build up from.

  • I agree regarding the comb reverberators. I built the example in Schroeder's paper with the four comb units followed by the two all pass units and I was disappointed with the results. I found it excessively resonant at any gain settings that provided a reasonable reverb time, particularly with an impulsive signal like the conga simulator. I much preferred the series all pass for overall sound. With a suitable choice of delay times and feedback gains, you can make something that sounds pretty good. In fact, in your example patch, I think I prefer it to the fairly serious reference. Less ambient background noise. I wish I understood the math well enough to re-create Schroeder's example mixing the direct sound with the reverberated sound using the same approach as the all pass unit. Simply mixing the dry and wet feeds suffers from the same comb filter issue as the simple reverberator. The mix of delayed and undulated sounds would result in selective phase cancellation. It would be interesting to see what (if any) audible difference it would make. Give the number of echoes in a practical reverb, it might not really make any significant difference.
  • BTW I really liked your demo patch. I'm really beginning to appreciate the subtle evolution that the Turing module can provide when it's set to a fairly low flip probability. I've been listening to the patch as I wrote the previous comment and it's generated some very compelling melodic lines which repeated just long enough to re-inforce the idea without becoming stale. Nice work!
  • @RobertSyrett, I was investigating why the all-pass reverb with mixing wasn't working the way I expected, so I was doing some gain measurements and discovered that the frequency response was far from flat. This puzzled me since this was supposed to be an all-pass filter. I checked and it looked like I had followed the diagram in the Schroeder paper. I noticed that Audulus had inserted a feedback delay just before the attenuator in the feedback loop. I was kind of surprised since there was already a delay, but I recalled that Joe's module had a feedback delay inserted just before the delay node. I wondered about it at the time, but I thought I would give it a try. As soon as I inserted the feedback delay node, the frequency response flattened out and the all-pass with mixing worked without oscillating. I modified all of the examples including the comb filters and also added a 9x9 of the modified unit to your patch for comparison. The old and new all-pass units definitely sound different as do the comb reverbs. In the case of the all-pass I think I like the modified design better, it seems to have increased the peaks in the comb units, although that is only judging by ear.
    Screen Shot 2017-10-17 at 12.57.46 PM.png
    3284 x 2550 - 436K
    Schoereder Reverbs V2.audulus
    839K
    9xallpass reverberator - modified.audulus
    624K
  • @biminiroad was saying that in instances where the feedback is happening at audio rates the unit delay node (z-1) would be preferable, but this sounds pretty good too!
  • I'm actually still not clear why a feedback delay is required at all since there is already a relatively long delay in the loop. I suspect that the algorithm that Taylor uses to determine the need for a feedback delay is not sophisticated enough to take into account existing delays other than the feedback delay node. By moving the delay to it's current location we keep the input signal and feedback in sync. In it's previous location the feedback was delayed with respect to the direct signal which would obviously mess up the relative phases. If I calculate things correctly the buffer at 44.1 kHz is about 3 milliseconds which, given the existing delay of 30-45 or more shouldn't make much difference vs. the z-1 node. I tried using the z-1 and couldn't hear any difference.
  • Yeah this is definitely an area where my ignorance shines. But it makes sense to use the dps version of the utility on the off chance that there may be some coloration once the computational load is greater.
  • Me too! Placing the feedback node in the proper location is still a black art for me. I understand the need but not the application. I probably wouldn't have tried it except I saw it in the Fairly Serious Reverb. It made a significant difference so obviously it's important, at least in this case.
  • @stschoen @robertsyrett - I kinda don't know either, but I just keep moving it around until it works. I fixed the min/max detector by moving the feedback delay. It was working OK where it was for LFOs, but would be terrible for audio rate stuff. If I thought about WHY it needs to be there, I could probably come up with an answer, but I mostly go "meh, it works" lol and move on. The Delta Change Detector did have an explanation that went step-by-step through why the feedback delay needed to be where it was.

    As for the feedback delay - there's that, and there's the single sample delay, which also acts like the feedback delay node.

    So in case it's the former, there needs to be a feedback delay because you can't process a number before you've computed it. Feedback is virtually instantaneous in analog electronics because electrons move at approximately the speed of light. To get anywhere close to this kind of feedback modelling you'd need a sample rate of like what a bajillion or something?

    Where you put the feedback delay can matter sometimes. It doesn't matter in the flip flop, but it does in the change detector module. If you parse out what's happening in each frame by following the feedback path, you'll start to understand when it does and doesn't matter and why. But in general, if it doesn't work, just put it somewhere else until it does. And if it doesn't work, then you probably have to rethink the way you built it.

    As for the z-1, its necessary only when the difference of -1 samples and -~300 samples makes a difference to what you're doing with the audio. So if you have a delay in the loop, there's no difference there, and you can use just the normal feedback delay.

    z-1 is necessary in cases of feedback like, for example, the VCA audio feedback path. If you don't have a z-1 in there, the gap from each processing frame is large enough that the feedback sounds like a delayed, almost resonant-phase cancelling signal. If they're just delayed 1 sample though, for (most) intents and purposes, they're basically right on top of one another.

    Another example of this is when you feedback an oscillator in an FM loop like:

    A->(FM)->B->(FM)->A

    There's a noticeable difference in how each sounds.

    This doesn't affect your reverb because the delay you put in is already greater than the ~300 sample buffer between each processing frame, so it's essentially like you've just turned up the delay time on the delay node a teensy bit more. Using the z-1 would make your delay a little shorter, but not really enough to be noticeable, as you...noticed lol. So basically yes it's a waste of processing to use a z-1 there.

    BTW thanks for all these patches, I'm going to get caught up on everything that's been happening on the forum tonight and tomorrow :) I'll make a separate post about the other stuff there.

    Hope this explains it all well!
  • For Christmas, can Audulus get a new reverb algorithm in the basic node?
    https://github.com/pichenettes/eurorack/blob/master/clouds/dsp/fx/reverb.h#L52
  • @robertsyrett theres a bunch of new stuff that will be added in 4 with some open source C++ library I forget which at the moment. But it does include a reverb. If VCV can have a Clouds dont see why we cant adapt it too.
  • Did some reading today on modeling a spring reverb. It sounds like it's not an easy problem to solve. I found several papers on various approaches to simulating it but nothing that was directly usable in Audulus. One paper suggested something like 100 all-pass filters in series and another's model took six minutes to calculate one second of reverb. Apparently the way sound travels down a helical spring is extremely complex. That might be why my Peavey solid-state guitar amp has a DSP to simulate that "tube" sound, but has a real spring reverb.
  • It's true. What if we made a sproing sound that was triggered by transients and stuck it in the 5x reverberator model though? IT's a little gimmicky but it could be a halloween costume for the reverb :)
  • Guess we need a sproing node :)
  • @stschoen - have you checked out how my spring reverb module works in the released version? It basically uses two modulated BPF nodes and is a very quick 'n' dirty way of getting spring without a whole lot of computational power.