3
$\begingroup$

I'm currently working on some reverb algorithm code for the Gamebody Advance to get a bit of that ambient feeling for the music instead of having plain dull sound. A few challanging restrictions are the low CPU speed of the GBA (~16 MHz ARM CPU) and the 4KiB of memory I have available for the reverb buffer @ 31536 Hz. Perhaps I could do the reverb at half the rate to save some memory. Goal is to keep the CPU budget for this under 5% and I'm well aware of this being a very eager goal. I've tried a few simple things like a simple feedback line but the results didn't turn out that great and sounded more like echo than actual reverb. However, I could get the ASM of this to work at about 2-3% CPU time.

So before trying to implement anything on hardware I wrote a little C++ application to try out a few algorithms and without the quirks of having no floats on the GBA. This is the core piece of code I've came up with:

// processing is done inplace on "buffer"
// samples ares stored L/R alternating
//
// reverbBuffer is a simple mono buffer
// buffer wraparound is already taken care of
//
// My reverb buffer positions are selected by being 'approximately' coprime
//
// NBPOS = 3 (number of taps on the buffer)

for (size_t i = 0; i < todo; i++) {
    float dryL = buffer[0];
    float dryR = buffer[1];
    float wetL = 0.f;
    float wetR = 0.f;
    for (int i = 0; i < NBPOS; i++) {
        wetL += coeffL[i] * reverbBuffer[bufferPos[i]];
        wetR += coeffR[i] * reverbBuffer[bufferPos[i]];
    }

    *buffer++ = dryL + wetMix * wetL;
    *buffer++ = dryR + wetMix * wetR;

    reverbBuffer[bufferPos[0]] = ((dryL + dryR) * 0.5f) * dryMix + ((wetL + wetR) * 0.5f);
    for (int i = 0; i < NBPOS; i++)
        bufferPos[i]++;
}

For testing I am using it on a few wave files @ 44.1kHz with an appropriately longer reverb buffer.

So, the results we're ... mixed. I've added some logic to create random values for the feedback coefficients (-1.0 to 1.0), the "dryMix" and "wetMix" variables (0.0 to 1.0). Depending on how lucky I either got terrible metallic oscillation or reasonably good results (still nothing I'd call perfect).

Is there any method of finding good coefficients for my feedback taps? Apart from bad sound I also had problems with instability and self oscillation. I don't have any professional DSP knowledge but I'd guess that the sum of the absolute values of all my coefficients should not exceed 1.0 (however this didn't seem to be always true for negative coefficients).

Also, if there is no way to calculate these coefficients with a lot of sense, is there at least a way of randomly generating these in a way they don't cause self oscillation?

PS: I've googled quite a bit about reverb and various things but I didn't find an algorithm which perfectly suits my case. Usually they are too basic (single tap feedback line) or they aren't fast enough (because I need something VERY FAST with low memory footprint).

$\endgroup$
  • $\begingroup$ Hi! What environment type do you want to simulate? $\endgroup$ – Fat32 Oct 7 '17 at 20:39
  • $\begingroup$ To be honest, I don't quite know what I'm looking for. I'm not familiar enough with all the different room types. I thought about something like a basic concert hall. However, I'm not quite sure if that's going to be even closely possible with the hard limitations on hardware I have. Something with a bigger room, longer decay but with an overall lower wet (reverb should not dominate the sound) I'm happy with approximate results as long as it doesn't sound like garbage. To give a reference, I was aiming at something like this: youtube.com/watch?v=t0UjNP1o7C0 $\endgroup$ – theIpatix Oct 7 '17 at 22:11
  • $\begingroup$ you need about a 1/4 seconds of echo. What was your audio sampling rate ? $\endgroup$ – Fat32 Oct 7 '17 at 22:15
  • $\begingroup$ The samplerate of my audio is 31536 Hz $\endgroup$ – theIpatix Oct 7 '17 at 22:22
  • $\begingroup$ Let's say approx. 32 kHz. A reverb impulse response of 250 ms duration would then have 8 kB of 8-bit sample storage. I guess this 's too much for you. You only have 4 kB ? $\endgroup$ – Fat32 Oct 7 '17 at 22:24
0
$\begingroup$

I don't know how to easily calculate stability criteria for your reverb topology, but it is easy to check if a set of delays and weights will give a stable filter (unless it is marginally stable or marginally unstable) by just calculating the impulse response and seeing if it blows up.

The easiest way to tune the reverb would be to use global optimization like differential evolution, where you actually try different delays and weights and optimize them against some cost function. The cost function could be such that it calculates the impulse response of the reverb and penalizes for instability, calculates the discrete Fourier transform (DFT) of the impulse response to get the frequency response, using fast Fourier transform (FFT), and rewards for something like spectral flatness.

It's a moderate amount of work if you are not familiar with those methods.

$\endgroup$
  • 1
    $\begingroup$ Thanks a lot for your input. I guess I'll need some time and motivation to set up a semiautomatic evaluation for the criteria you suggested and see if there is a good solution. $\endgroup$ – theIpatix Oct 9 '17 at 17:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.