Learn Arduino Gutiar Effect with me. Project 3 - Reverb

Next, let’s check out a simple reverb effect. Unlike the distortion, this actually calls a separate module built into the library to process the signal. This will be the building block that will allow you to access all the other effects that are built in. Some of these effects are Delay, AutoWah, Filter, Phasor, and many more. Cool!

#include "DaisyDuino.h"

DaisyHardware hw;

ReverbSc verb;

void AudioCallback(float *in, float *out, size_t size) {

  float dry, wet, intensity, sendDry;

  intensity = 0.7f;
  verb.SetFeedback(.8f);
  verb.SetLpFreq(10000.0f);

  for (size_t i = 0; i < size; i ++) {
   
    dry = in[i];
    sendDry = dry * intensity;
    verb.Process(sendDry, 0, &wet, 0);   
    out[i] = (dry +  wet) * 2;
 
  }
}
void setup() {

  hw = DAISY.init(DAISY_PETAL, AUDIO_SR_48K);
  verb.Init(DAISY.AudioSampleRate());
  DAISY.begin(AudioCallback);
}
void loop() {

}
ReverbSc verb;

The first thing you’ll notice is we are now defining an object ‘verb’ that refers to the ReverbSc class.

verb.Init(DAISY.AudioSampleRate());

We initialize the Daisy and then we’ll need to initialize the reverb with the current Audio Sample Rate, which is 48k as defined. After that, let’s start up our Daisy using an AudioCallback function.

float dry, wet, intensity, sendDry;

Now we’re going to define some variables. ‘dry’ is going to be the input signal, it will not be manipulated. ‘wet’ is going to be the processed reverb signal, stripped of the clean guitar signal. ‘intensity’ will be how loud the reverb is and ‘sendDry’ will be what we send to get processed.

intensity = 0.7f;
verb.SetFeedback(.8f);
verb.SetLpFreq(10000.0f);

As mentioned, ‘intensity’ will be how loud we want the reverb portion of the signal. Would recommend keeping it under 1. The next line, we’re going to set the Feedback of the reverb. This basically means how long a note will oscillate for. It processes on a logarithmic scale from 0-1. You likely won’t hear much, or any, reverb under 0.5. When you get close to 1, the reverb never fades (sounds neat, though). ‘verb.SetLpFreq(10000.0f)’ is going to be our Low Pass Filter Frequency. The higher the number, the ‘crisper’ the reverb will sound.

dry = in[i];
sendDry = dry * intensity;
verb.Process(sendDry, 0, &wet, 0);   

You should know what the first two lines here mean by now. We’re just setting the variable ‘dry’ as the input signal and then multiplying it by our reverb intensity. The third line is where the magic happens. ‘verb.Process(sendDry, 0, &wet, 0);’ It’s going to send the ‘sendDry’ variable to get processed, and then store the processed audio back into the ‘wet’ variable. As mentioned in my first post, documentation is hard to come by. If you dig deep in the github, you can find all the modules listed. DaisyDuino/src/utility/DaisySP/modules at master · electro-smith/DaisyDuino · GitHub If we open up the reverbsc.h and scroll down to line 49, we can see it takes two inputs, processes, and spits out two outputs. So multiple channels could be ‘verb.Process(sendLeft, sendRight, &receiveLeft, &receiveRight);’ Since we’re only dealing with one channel , I just replaced the ‘right’ channel with 0’s.

out[i] = (dry +  wet) * 2;

So now we have our ‘wet’ processed reverb signal and we need to output it. If we just do ‘out[i] = wet;’ we’re only going to the reverberated portion of the signal. We need to mix it back with our original dry signal by doing a ‘out[i] = (dry + wet)’. I thought the output volume was too low so I multiplied it by two like the first example. I guess I can increase the input gain on the Terrarium PCB but they don’t provide a schematic and I’m not smart enough to figure it out.

Anyhow, now we have a sick sounding reverb. I’m quite impressed with the quality. Try playing around with the Feedback, LP filter freq, and intensity values. If you’re really motivated, try mixing the reverb with the distortion.

I hope someone out there got something out of these posts. If anyone found value in these, or if I need any corrections, please leave a comment and I can fix them or make more.

2 Likes

Hey again! This is the output of my test of this reverb code (link). Notice no hiss. What is going on? Did the code raise the noise floor of the previous distortion patch?

Spectrum plot from Audacity of the whole sample this time.

I think it is great that you are doing this series and I am sure a lot of people will benefit.

Would it not be better to move these two lines from the AudioCallback to after the verb.Init() call in the setup()?

1 Like

Good catch. It would certainly be better to move those two lines to the setup function after the verb.Init().

For anyone who would like to know why: The AudioCallback function runs every time it gets a sample of audio, in this case, 48k times per second. It takes an amount of processing power and time to SetFeedback and SetLpFreq. In a more complicated program, this could induce unwanted and noticeable latency. If we move those two lines to the setup function, it only runs once.

2 Likes

It runs once per audio block, by default block size is set to 48 samples to run every millisecond when SR = 48kHz.

2 Likes