Reverb Dry/Wet Mix Issues

Hi There,

I’m trying to implement a very simple reverb using the Seed and have implemented ReverbSc in my code. I’m attempting to control the dry/wet mix of the reverb effect. However, when I implement a basic calculation, the reverb effect stutters a lot. It is most audible when the mix is turned mostly wet, and its a very periodic sounding stutter, almost like its overloaded the CPU.

#include "daisy_seed.h"
#include "daisysp.h"
#include <string.h>

using namespace daisy;
using namespace daisysp;

static DaisySeed              hardware;
static ReverbSc DSY_SDRAM_BSS verb;

bool  effect_state;
float reverb_value;
float vtime = 0.85f;
float vfreq = 20000.0f;
float wetCV;


static void AudioCallback(AudioHandle::InterleavingInputBuffer  in,
                          AudioHandle::InterleavingOutputBuffer out,
                          size_t                                size)
{
    // Check the effect state and set wetCV accordingly
    float wetCV;

    if(!effect_state)
    {
        wetCV = 0.0f; // No reverb
    }
    else
    {
        wetCV = reverb_value;
    }

    float dryl, dryr, wetl, wetr, sendl, sendr;

    for(size_t i = 0; i < size; i += 2)
    {
        // Apply gain to input
        dryl = in[i];
        dryr = in[i + 1];

        sendl = dryl * wetCV;
        sendr = dryr * wetCV;

        verb.Process(sendl, sendr, &wetl, &wetr);

        out[i]     = ((1.0f-wetCV)*dryl) + (wetCV*wetl);
        out[i + 1] = ((1.0f-wetCV)*dryr) + (wetCV*wetr);
    }
}

int main(void)
{
    float sample_rate;
    hardware.Configure();
    hardware.Init();
    hardware.SetAudioBlockSize(4);
    sample_rate = hardware.AudioSampleRate();

    //setup reverb
    verb.Init(sample_rate);
    verb.SetFeedback(vtime);
    verb.SetLpFreq(vfreq);

    // hardware.StartAudio(AudioCallback);
    hardware.StartAudio(AudioCallback);

    // Initialize UART
    UartHandler         uart;
    UartHandler::Config uart_config;
    uart_config.baudrate      = 9600; // Match baudrate with Pico
    uart_config.mode          = UartHandler::Config::Mode::TX_RX;
    uart_config.periph        = UartHandler::Config::Peripheral::USART_1;
    uart_config.parity        = UartHandler::Config::Parity::NONE;
    uart_config.wordlength    = UartHandler::Config::WordLength::BITS_8;
    uart_config.pin_config.tx = {DSY_GPIOB, 6}; // TX pin configuration
    uart_config.pin_config.rx = {DSY_GPIOB, 7}; // RX pin configuration

    uart.Init(uart_config);

    uint8_t rx_buffer[2];


    // Main loop
    while(true)
    {
        // Receive data from the Pico
        uart.BlockingReceive(rx_buffer, 2, 100);

        // Unpack received data
        effect_state = rx_buffer[0];
        reverb_value = rx_buffer[1] / 255.0f;
    }
}

Curiously, when I simply just add the wet on top of the dry, it sounds fine (although the intended effect is to not have any dry at 100% max). Any ideas what is causing this? The following code snippet makes the reverb sound fine (although is not the intended dry/wet effect).

        dryl = in[i];
        dryr = in[i + 1];

        sendl = dryl * wetCV;
        sendr = dryr * wetCV;

        verb.Process(sendl, sendr, &wetl, &wetr);

        out[i]     = dryl + wetl;
        out[i + 1] = dryr + wetr;

Hmm, that’s a bit unexpected, for sure!
How often are you sending a new Reverb value?
Maybe try just setting ‘reverb_value’ to a constant value, e.g. 0.666f, and don’t update it in the loop and see what happens?

1 Like

Thank you for the suggestion! I believe it was sending the reverb value too often. I’ve added this line and it has fixed the issue:

 // Main loop
    while(true)
    {
        // Receive data from the Pico
        uart.BlockingReceive(rx_buffer, 2, 100);

        // Unpack received data
        effect_state = rx_buffer[0];
        reverb_value = rx_buffer[1] / 255.0f;

        System::Delay(50);
    }