Looking to understand DelayLine

Hi

I have been asked to make a thing that delays a continuous input for 20 seconds (as in it is continuously delayed). So what is being played doesn’t come out of the speaker until 20 seconds later. I was going to try the daisy to do this. I’m looking at the stereo delay example in Arduino and I’m trying to work out what does what.
Is there documentation for this beyond the examples? Can anyone recommend somewhere I can learn more about the classes in DaisyDuino? I couldn’t find any explanation of delayLine.

Some questions
When I set up the delayLine do I need to make the float more than 24000? Is that the buffer size or is 24000 just a default?

and does hw.num_channels just know how many output channels are on the seed? Is the hw for hardware?

Thanks for any help. any tips will be super appreciated. Sorry I don’t have more information. I have had a look and tried to understand but just need to understand a bit more

here’s the code I’m playing with

// Title: StereoDelay
// Description: Applies stereo delay to input signal
// Hardware: Daisy Seed
// Author: Stephen Hensley

#include "DaisyDuino.h"

DaisyHardware hw;

size_t num_channels;

// two DelayLine of 24000 floats.
DelayLine<float, 24000> del_left, del_right;

void MyCallback(float **in, float **out, size_t size) {
  for (size_t i = 0; i < size; i++) {
    float dry_left, dry_right, wet_left, wet_right;

    // Read Dry from I/O
    dry_left = in[0][i];
    dry_right = in[1][i];

    // Read Wet from Delay Lines
    wet_left = del_left.Read();
    wet_right = del_right.Read();
//
//    // Write to Delay with some feedback
//    del_left.Write((wet_left * 0.5) + dry_left);
//    del_right.Write((wet_right * 0.5) + dry_right);

    // Mix Dry and Wet and send to I/O
    out[0][i] = wet_left;
    out[1][i] = wet_right;
  }
}

void setup() {
  float samplerate;
  // Initialize for Daisy pod at 48kHz
  hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
  num_channels = hw.num_channels;

  // Init Delay Lines
  del_left.Init();
  del_right.Init();

  // Set Delay Times in Samples
  del_left.SetDelay(480000.0f);
  del_right.SetDelay(48000.0f);

  // Start Audio
  DAISY.begin(MyCallback);
}

void loop() {}

Replying to this in case it’s useful to anyone else. I’m playing around with the code more and I’m getting a delay with no effect now which is what I am looking for. However, I can’t get the length of the delay to go more than a second and I’m putting in a number that I think should make it more like 10 seconds…

// Title: StereoDelay
// Description: Applies stereo delay to input signal
// Hardware: Daisy Seed
// Author: Stephen Hensley

#include "DaisyDuino.h"

DaisyHardware hw;

size_t num_channels;

// two DelayLine of 24000 floats.
DelayLine<float, 24000> del_left, del_right;

void MyCallback(float **in, float **out, size_t size) {
  for (size_t i = 0; i < size; i++) {
    float dry_left, dry_right, wet_left, wet_right;

    // Read Dry from I/O
    dry_left = in[0][i];
    dry_right = in[1][i];

    // Read Wet from Delay Lines
    wet_left = del_left.Read();
    wet_right = del_right.Read();

    // Write to Delay with some feedback
    del_left.Write(dry_left);
    del_right.Write(dry_right);

    // Mix Dry and Wet and send to I/O
    out[0][i] = wet_left;
    out[1][i] = wet_right;
  }
}

void setup() {
  float samplerate;
  // Initialize for Daisy pod at 48kHz
  hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
  num_channels = hw.num_channels;

  // Init Delay Lines
  del_left.Init();
  del_right.Init();

  // Set Delay Times in Samples
  del_left.SetDelay(4800000.0f);
  del_right.SetDelay(4800000.0f);

  // Start Audio
  DAISY.begin(MyCallback);
}

void loop() {}

Hi,

For a 20 second delay you’ll be needing a bigger DelayLine.

With a sample rate of 48k, you’ll need 48k * 20 = 960000 samples per DelayLine.

That works out as something near 4MB of DelayLine - so you’re going to have to put it in the SDRAM.
I’m not entirely sure how it works in DaisyDuino - but if you take a look at the pod/MultiEffect/MultiEffect.cpp from the DaisyExamples repo you’ll see how that’s done.

You’ll want something like:

static DelayLine<float, 960000> DSY_SDRAM_BSS del_left;
static DelayLine<float, 960000> DSY_SDRAM_BSS del_right;

EDIT: Looks like there is a DaisyDuino version of the MultiEffect patch here Arduino/libraries/DaisyDuino/examples/Pod/MultiEffect/MultiEffect.ino. Looking at this example I think the above code should work.

Cheers

2 Likes

Awesome!! thanks for that.

So my understanding is that I can think of a delay line like a physical connection where the sound I send to it will be delayed and I can do various things with that. I’ve got my code working now!
Here it is for reference (ok so it’s messy rn as I’ve just commented out all the right channel - I didn’t need stereo)

// Title: StereoDelay
// Description: Applies stereo delay to input signal
// Hardware: Daisy Seed
// Author: Stephen Hensley

#include "DaisyDuino.h"
#define MAX_DELAY  (48000 * 20)

DaisyHardware hw;

size_t num_channels;

// two DelayLine of 24000 floats.
//DelayLine<float, 24000> del_left, del_right;
DelayLine<float, MAX_DELAY> DSY_SDRAM_BSS my_delayed_sound;

void MyCallback(float **in, float **out, size_t size) {
  for (size_t i = 0; i < size; i++) {
//    float dry_left, dry_right, wet_left, wet_right;
    float dry_left, wet_left;

    // Read Dry from I/O
    dry_left = in[0][i];
//    dry_right = in[1][i];

    // Read Wet from Delay Lines
    wet_left = my_delayed_sound.Read();
//    wet_right = del_right.Read();

    // Write to Delay with some feedback
    my_delayed_sound.Write(dry_left);
//    del_right.Write(dry_right);

    // Mix Dry and Wet and send to I/O
    out[0][i] = wet_left;
//    out[1][i] = wet_right;
  }
}

void setup() {
  float samplerate;
  // Initialize for Daisy pod at 48kHz
  hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K);
  num_channels = hw.num_channels;

  // Init Delay Lines
  my_delayed_sound.Init();
//  del_right.Init();

  // Set Delay Times in Samples
  my_delayed_sound.SetDelay(960000.0f);
//  del_right.SetDelay(4800000.0f);

  // Start Audio
  DAISY.begin(MyCallback);
}

void loop() {}
1 Like

Cool!

I find it helpful to think of it as an area in memory where you can keep things. How long you can keep things depends on how many slots you have to put them in. I believe the underlying implementation is very similar to a circular buffer and your delay time depends on how far apart you can put your read and write pointers.

Cheers

1 Like