Skip to content

Farmer2K5/daisy-sdram-delaylines

Repository files navigation

DaisySP SDRAM DelayLine Extensions

This repo provides two SDRAM-backed delay line classes designed for long-delay and reverb applications on the Electrosmith Daisy Seed.

Both versions are derived from the original DaisySP DelayLine implementation (© 2019 Electrosmith, MIT License) and extend the design to support external SDRAM memory. The external-buffer design follows the ideas of Keith Shepherd (bkshepherd), adapted and extended for SDRAM integration.

⚠️ Work in Progress Disclaimer

This is an experimental project and a work in progress.

It was developed primarily for research and learning on the Daisy Seed, and while it has been tested on real hardware, no guarantees are made regarding the accuracy, stability, or sonic quality of its results.

This code should be viewed as a foundation for exploration — not a finished product. You are encouraged to modify, measure, and validate it for your own purposes, and to share improvements or findings with the community.


Files

File Description
sdram_alloc.h``sdram_alloc.cpp Lightweight bump allocator for SDRAM.
delayline_ext.h Delay line using an externally provided SDRAM buffer.
delayline_sdram.h Delay line that automatically allocates its buffer in SDRAM.

Example Usage

#include "daisy.h"
#include "sdram_alloc.h"
#include "delayline_ext.h"
#include "delayline_sdram.h"

using namespace daisysp;

DaisySeed hw;

// Allocate a float buffer in SDRAM
auto* buf = sdram_alloc_floats(48000);
// alternately, we could use DSY_SDRAM_BSS
// float DSY_SDRAM_BSS buf[48000];

// External SDRAM buffer version
DelayLineExt<float, 48000> delay_ext;

// Internal SDRAM buffer version
DelayLineSDRAM<float, 48000> delay_sdram;

void main(void)
{
    hw.Init();

    // reset the SDRAM buffer
    sdram_reset();

    // Initialize external buffer version by providing 
    // pointer to SDRAM buffer
    delay_ext.Init(buf);

    // Initialize internal SDRAM buffer version
    delay_sdram.Init();

    // ...

}

Notes

  • Call hw.Init()before any allocations.
  • If using sdram_alloc, call sdram_reset()before any allocations.

Performance

Four different SDRAM usage scenarios for delay buffers on the Daisy Seed, were minimally tested to quantify SRAM savings, SDRAM access overhead, and code complexity.

Test Scenarios

Scenario Description
No SDRAM Standard DaisySP DelayLine<T, N> using internal SRAM buffer.
Object in SDRAM Entire DelayLine object (including buffer) placed in SDRAM using DSY_SDRAM_BSS.
External SDRAM Buffer Modified DelayLine accepts an external buffer pointer (allocated via sdram_alloc() or DSY_SDRAM_BSS).
Internal SDRAM Buffer Modified DelayLine allocates its buffer internally using an SDRAM pool (sdram_alloc()).

All scenarios utlized single delay line of 48,000 samples (equal to one second at 48000Hz sample rate).

Benchmark Summary

Scenario SRAM Use SDRAM Use Avg CPU Load Relative Speed Key Takeaways
1️⃣ No SDRAM High (217 KB) 0 1.99 % 🟢 Fastest Fastest execution, but large SRAM footprint. Delay limited to a few ms.
2️⃣ Object in SDRAM ↓ to 25 KB 192 KB 2.19 % 🟡 ~10 % slower Huge SRAM savings; small CPU overhead from slower SDRAM access.
3️⃣ External Buffer ≈ 25 KB 192 KB 2.26 % 🟡 ~13 % slower Nearly identical to #2; flexible and reusable across modules.
4️⃣ Internal SDRAM Allocator ≈ 25 KB 192 KB 2.25 % 🟡 ~13 % slower Cleanest API; same perf as #3; automatic but less manual control.

Interpretation

Memory Efficiency

  • Moving the delay buffer to SDRAM cuts SRAM usage by ~190 KB (a ~5× reduction).
  • SDRAM load (~192 KB) is negligible as a fraction of 64 MB available.
  • Flash usage remains effectively constant across all builds.

CPU Overhead

  • SDRAM access adds only ~0.25 % absolute CPU load, or about 10–13 % relative increase over SRAM.
  • This is well within real-time constraints — typically imperceptible in audio workloads.
  • Variations between SDRAM scenarios are in measurement noise (<0.1 %).

Performance–Complexity Trade-Off

Scenario Complexity Control Recommended Use
No SDRAM 🟢 Minimal 🚫 None Short FX, modulation delays, or when SRAM budget is sufficient.
Object in SDRAM 🟢 Easy ⚠️ Per-object DSY_SDRAM_BSS Simple one-off long delays or reverbs.
External Buffer 🟡 Moderate 🟢 High Modular systems (multiple reverbs/delays sharing SDRAM pool).
Internal SDRAM Allocator 🟢 Easy 🟡 Medium General use; transparent SDRAM allocation without passing buffers.

Overall Conclusions

  • SDRAM latency penalty is small (~0.25 % CPU difference).

  • SRAM savings are huge — free up >85 % of local memory for code, filters, and working buffers.

  • Best general solution:

    • For production-ready modular code → Scenario 3 (External Buffer).

    • For drop-in simplicity → Scenario 4 (Internal SDRAM Allocator).

  • Avoid SDRAM entirely (Scenario 1) only when delay lengths are short and SRAM headroom is available.


License & Acknowledgments

Subject to the MIT License, you are free to use, modify, and redistribute this work, with attribution appreciated to the embedded DSP community.

None of this code is uniquely mine — it draws heavily on the shared knowledge of the Daisy, Teensy, ARM, and other DSP communities.
I am not a professional C++ developer, and this framework represents an ongoing learning effort built from their contributions.

Special thanks to the countless developers, forum members, and DSP enthusiasts whose posts, code snippets, and shared experiments continue to inspire.

About

Two SDRAM-backed delay line classes designed for long-delay and reverb applications on the Daisy Seed

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors