Daisy Seed loop() locks up in audio callback when processing ReverbSc in SDRAM

Can someone tell me what I’m doing wrong? I’m attempting to use ReverbSC in SDRAM and when I do it will not allow Loop() to process and the reverb sounds horrible. Can someone tell me if I’m missing something? Code can also be downloaded from here

/*
Name: ReverbTest.ino
Created: 11/30/2020 7:56:51 AM
Author: TGargasz
*/

#include “DaisyDuino.h”

DaisyHardware hw;

size_t num_channels;
unsigned long currentMillis; // To set period to poll knobs and switchs
unsigned long previousMillis = 0; // Last time knobs and switches were polled
const unsigned long interval = 250; // Interval at which to poll (milliseconds)

// ReverbSc verb; // This works
ReverbSc DSY_SDRAM_BSS verb; // This does not allow loop() to process and the reverb sounds terrible

void MyCallback(float** in, float** out, size_t size)
{
for (size_t i = 0; i < size; i++)
{
float out1, out2;
verb.Process(in[0][i], in[1][i], &out1, &out2);

    out[0][i] = out1;
    out[1][i] = out2;
}

}

void setup() {
pinMode(LED_BUILTIN, OUTPUT);

float sample_rate;
// Initialize for Daisy pod at 48kHz
hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
num_channels = hw.num_channels;
sample_rate = DAISY.get_samplerate();

verb.Init(sample_rate);
verb.SetFeedback(0.85f);
verb.SetLpFreq(18000.0f);

digitalWrite(LED_BUILTIN, HIGH); // Turn led on

DAISY.begin(MyCallback);

}

void loop()
{
currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
// save the last poll time
previousMillis = currentMillis;

    digitalWrite(LED_BUILTIN, !(digitalRead(LED_BUILTIN)));
    delay(20);
}

}

Is the SDRAM fast enough for ReverbSC? Maybe you should try to put only the delay buffer in SDRAM, not the whole class with all its members. And if this is not enough, there are probably some improvements to do to the current code when doing block processing to cache the delay line content. Indeed the cubic interpolation reads 4 neighbour samples, but likely 3 of them will be used again to compute the next output sample. So caching (N + 3 + some margin) samples in SRAM for each delay line before processing the block should make it run faster.

1 Like

@Firesledge, I’m not aware of any public members of ReverbSC that would be able to be relocated to SDRAM. I figured that if the Reverb in the Pod MultiEffects C++ example could run when configured to reside in SDRAM that it would also run in the Arduino environment now that the SDRAM has been made available. Is that not the case?

I don’t know, it was just an hypothesis. The behaviour you described looks like a CPU overload in the processing routine, so I was wondering if the SDRAM was fast enough.

The sound you describe does sound like audio underrunning (from too much time spent processing).

I have run the DaisySP version of ReverbSC in SDRAM without any noticeable issues. So it does sound like something to do with it running in Arduino.

I’ll take a look over the next day and chime back in when I know something definitive.

@Firesledge, I appreciate your responses and I agree with your diagnosis of CPU overload while executing verb.Process(). I’m hoping that it can be solved somehow.

@shensley, I created ReverbTest.ino that replicates the problem. Hopefully a tweak here or there will fix it. If not, I’ll need to find a way to port my code to VS2019 without using VisualGDB as my trial period has elapsed and my budget is too stringent to afford a copy.

Thanks for sharing the sketch! Definitely made it easier to test!

Alright! Figured out a (relatively painless) way to fix the issue you’re seeing.

Turns out with the current configuration, the section of memory for the DMA buffers is not set up, and therefore the DCache had to be disabled in order for audio to still work.
The buffers for the DMA must not be cached otherwise extra overhead for maintenance is involved.

For that reason we have a section marked in the linker for this, but that section is not yet in the STM32Duino build. In order to find these files you’ll have to navigate to (on windows):

C:\Users\<yourusername>\AppData\Local\Arduino15\packages\STM32\hardware\stm32\1.9.0\variants\DAISY_SEED\

The first file you’ll edit (or replace) is ldscript.ld

If you’re not seeing the AppData directory, it is likely because it is hidden by Windows. You can show it by going to View in explorer and checking the ‘Show hidden files’ button

So – as a temporary fix add the following to the linker script ldscript.ld (at line 190) :

.sram1_bss (NOLOAD) :
{
    . = ALIGN(4);
    _ssram1_bss = .;
    PROVIDE(__sram1_bss_start = _ssram1_bss);
    *(.sram1_bss)
    *(.sram1_bss*)
    . = ALIGN(4);
    _esram1_bss = .;
    PROVIDE(__sram1_bss_end = _esram1_bss);
} >RAM_D2

Additionally, you’ll need to modify one file in the DaisyDuino library. Arduino libraries can be found in C:\Users\<yourusername>\Documents\Arduino\libraries

Line 38 of DaisyDuino\src\DaisyDuino.cpp needs to be commented out, or deleted. (This line simply deactivates the d-cache, which is no longer necessary after the linker fix.

I’ll open a PR to add this section to the linker on the STM32Duino integration itself sometime this week, but until their next version I don’t think it’ll take effect through the Arduino IDE.


If anyone needs to do this on Mac/Linux the steps should be the same, but I’m not 100% sure where the alternate Arduino cores get installed off the top of my head.

In case you’d rather just replace the ldscript instead of edit it, here’s the modified version I have that (after the one line edit of DaisyDuino) sounds like what you’d expect.

Let me know if you have any hangups, and as mentioned I’ll try to get a more permanent fix in place ASAP.


As for the porting to VS2019, if you are interested in moving away from Arduino, I recommend checking out VS Code with the Cortex Debug extension. It’s totally free, cross platform, and we’ll be adding support for it to the existing DaisyExamples and creating tutorials for using it very soon.

2 Likes

Thank you very much for your rapid response! I will give it a go first thing in the morning as I am otherwise occupied for the rest of today. I’ll report my results back here.

I believe the link to the loader script in your message above is missing.

Right now I’m using VS2019 with VM Arduino extension and I like it alot. After the holidays I’ll give VS Code a shot.

1 Like

Ah, good catch! I went to drag it in, and forgot you can’t upload plain-text files.

Here’s a google drive link to the ldscript.ld I modified

This was painful to read :wink: When I’ve measured cache performance on Daisy, enabling DCache made patches run about x4 faster

1 Like

I know… honestly I had forgotten that we had it disabled in Arduino until this issue came up the other day. Certain memories benefit more than the others, but the SDRAM pretty much needs it to be usable for performative code.

1 Like

@shensley, I made the modifications as described above and it works like a charm! I thought I might have a problem with SPI timing (connected to ESP8266) but no issues at all. I put my entire audio chain in the mix (Tremolo, Echo, Distortion, Reverb, Flanger, and Bypass) all at once and they all work simultaneously and sound great! I’m hoping to sneak a DcBlock and Limiter in the chain somehow to tame the signal a bit while Daisy Chaining so many effects. I’m crossing my fingers that I won’t run into a wall of some sort. Thank you again for your help!

3 Likes

Fantastic! Glad that worked out! Can’t wait to see/hear a demo when you’ve got it all going!

1 Like

Here’s a Amp Demo using samples. It has 7 one minute loops of guitar samples that I found online. The first is dry and the rest demonstrate tremolo, distortion, flanger, echo, reverb, and finally a mix of effects. It was recorded with my cellphone and the amplifier was fed by a laptop’s headphone output and connected to a 4 inch communication speaker so the sound pressure was quite low and some background noises can readily be heard. I’m satisfied with all of the effects except distortion. The younger generation isn’t interested in any kind of sizzle fuzz of germanium times but strive for the muddy monster sounds of grunge. I prefer a tight crunch and I’m having a tuff time stretching my tastes.

1 Like

On my Mac, the path is:

/Users//Library/Arduino15/packages/STM32/hardware/stm32/1.9.0/variants/DAISY_SEED

Just an update on this thread – the PR for the linker change has gone through and is merged on the stm32duino Arduino Core. So as soon as they do their next release that will no longer require any manual intervention :smile:

3 Likes