Example code for AudioEffectDelayExternal ?

blakeAlbion

Well-known member
I can't find a sample program for AudioEffectDelayExternal.
I soldered a chip onto my audio shield and I want to test it.

Specifically how do you initialize it?
In the forum I see the example:
Code:
AudioEffectDelayExternal   dly1(AUDIO_MEMORY_23LC1024, 720);
AudioEffectDelayExternal   dly2(AUDIO_MEMORY_23LC1024, 720);

Is there a post that has a more up-to-date sample?
I can see some work was done on this more recently.

I got it to compile but as as soon as the AudioEffectDelayExternal object is constructed things freeze.

Is it possible my chip is bad?

I am using the 23LC1024T,

Thanks,
Benjamin
 
Last edited:
you can test the external psram with the example
Sketch in the library . It will show if its detect and how much. I had solder issues and reflowed it and it read correctly after that
 
you can test the external psram with the example
Sketch in the library . It will show if its detect and how much. I had solder issues and reflowed it and it read correctly after that
? Does the sketch work with a Teensy 4.0 and a rev D board?
 
It should work, but probably hasn't been tested in years. Not much need for a chip like 23LC1024 now that we have so much RAM inside the main processor. The SPI communication has a lot of overhead compared to using the internal memory.
 
Here's a test sketch I've used in the past. It's doing slightly weird stuff for me at the moment (lots of background noise) but that could be hardware issues. It compiles and runs OK. What version of Teensyduino are you using?
C++:
#include "Arduino.h"
#include <Audio.h>

// One PSRAM 8MB chip is 95108.93ms of delay
// With a SPI bus of 31.41MHz, and 3 delay objects with 3, 3, and 1 tap, we
// need to do 3 writes and 7 reads of 128*2*8 = 2048 bits, so 20480 bits,
// which will take about 0.68ms. This happens every 2.9ms, so expect
// a CPU load of 22.4%. We get about 19%, so fairly close.
//
// 2024-02-06 - re-testing CPU use %
// Memory     Usage  Max
// PSRAM64 -> 42.6  42.8
// EXTMEM  ->  3.8   4.8
// HEAP    ->  0.86  0.97
//
// See also the benchmark comment in extmem.h

#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_23LC1024
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_PSRAM64
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_PSRAM64_X8
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_EXTMEM
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_HEAP

// GUItool: begin automatically generated code
AudioSynthWaveformModulated waveformMod;    //xy=303,301
AudioEffectFade          fader;          //xy=506,304
AudioEffectDelayExternal delayExt(AUDIO_DELAY_MEMORY,910.0f);       //xy=540,506
AudioEffectDelayExternal delayExt1(AUDIO_DELAY_MEMORY,560.0f);      //xy=559,757
AudioMixer4              mixer4;         //xy=834,329
AudioMixer4              mixer5;         //xy=841,574
AudioOutputI2S           i2s;            //xy=1041,264

AudioConnection          patchCord1(waveformMod, fader);
AudioConnection          patchCord2(fader, 0, mixer4, 0);
AudioConnection          patchCord3(delayExt, 0, mixer4, 1);
AudioConnection          patchCord4(delayExt, 1, mixer4, 2);
AudioConnection          patchCord5(delayExt, 1, mixer5, 0);
AudioConnection          patchCord6(delayExt, 2, mixer4, 3);
AudioConnection          patchCord7(delayExt1, 0, mixer5, 1);
AudioConnection          patchCord8(delayExt1, 1, mixer5, 2);
AudioConnection          patchCord9(delayExt1, 2, mixer5, 3);
AudioConnection          patchCord10(mixer4, 0, delayExt, 0);
AudioConnection          patchCord11(mixer4, 0, i2s, 1);
AudioConnection          patchCord12(mixer5, 0, delayExt1, 0);
AudioConnection          patchCord13(mixer5, 0, i2s, 0);

AudioControlSGTL5000     sgtl5000_1;     //xy=1041,311
// GUItool: end automatically generated code



elapsedMillis next;
void setup() {
  Serial.begin(115200);

  Serial.println("Starting audio...");
  AudioMemory(40);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.4);

  mixer4.gain(0,0.3f);
  mixer4.gain(1,0.05f);
  mixer4.gain(2,0.10f);
  mixer4.gain(3,0.51f);

  Serial.println("Set up delayExt object");
  delayExt.delay(0,300.0);
  delayExt.delay(1,700.0);
  delayExt.delay(2,900.0);
 
  mixer5.gain(0,0.1f);
  mixer5.gain(1,0.05f);
  mixer5.gain(2,0.10f);
  mixer5.gain(3,0.71f);

  Serial.println("Set up delayExt1 object");
  delayExt1.delay(0,69.0);
  delayExt1.delay(1,241.0);
  delayExt1.delay(2,547.0);
 
  waveformMod.begin(0.001f,1000.0f,WAVEFORM_SINE);
  fader.fadeOut(1.0);
  delay(5);
  waveformMod.amplitude(0.5f);
    
  next = 4900;
}


void loop() {
  if (next > 5000)
  {
    next = 0;   
    fader.fadeIn(2.0);
    delay(40);
    Serial.printf("Usage %.2f, max %.2f\n",AudioProcessorUsage(),AudioProcessorUsageMax());
    AudioProcessorUsageMaxReset();
    fader.fadeOut(2.0);   
  }
}
 
Thank you @Paul and @h4yn0nnym0u5e .
I also see some confusion about SPI and hardware. I am using a Rev D board.

Regarding using SPI memory, I'm trying to get more memory than I have on the Teensy 4.0. Max audio delay seems to be like 150ms if I have 2 delays for left and right? Is there a better way?
 
My improvements to the AudioEffectDelayExternal object, the PR for which oh so nearly got merged 3 years ago, allow use of PSRAM as delay memory, both on the audio adaptor and as EXTMEM (irrelevant for Teensy 4.0, of course), in addition to some rather exotic options like an 8-chip PSRAM adaptor.

A single 8MB PSRAM gives a total of 95s of mono delay. You can have as many of those as you need, within memory constraints and the fact that the SPI access is slow. The limiting factor is number of objects plus number of used output taps. A Teensy 4.1 with on-board PSRAM is way better for big multiple-delay projects.

Are you sure you’re using AudioEffectDelayExternal? AudioEffectDelay uses audio blocks and will give you very limited delay lengths, but even your 23LC1024 should allow a total delay of just under 1.5s.
 
I'm trying to get more memory than I have on the Teensy 4.0. Max audio delay seems to be like 150ms if I have 2 delays for left and right? I
Hi, the AudioEffectDelay sets max delay to 4.00s for teensy 4. If you have 2 for stereo a sensible limit would be 2sec although depending on what else you have using memory you could push this. Cheers Paul
 
I shouldn't have to ask this but does EXTMEM access the secondary onboard RAM area?
I have experimented with adding RAM chips to the Teensy 4.1 and used static_malloc.h with great success.
But this is for a Teensy 4.0 and I was hoping to get longer delays by adding the 23LC1024. Just a bass synth with a decent echo effect.
 
EXTMEM allocates from PSRAM soldered underneath the Teensy 4.1; if that runs out it silently allocates from DMAMEM (which may be what you mean by "the secondary onboard RAM area"). This is irrelevant to a Teensy 4.0, therefore, as noted in my post #7 - any attempt to use it will result in a compile-time failure.

I don't know what static_malloc.h is - not part of cores, anyway, and not usable for any variant of AudioEffectDelayExternal.

Your code from post #1 should work to create two delay objects where you can set taps which delay up to 720ms each. Note that you do still have to set the tap times by calling AudioEffectDelayExternal::delay(tap#,millis) as needed, so for your example something like dly1.delay(0,700.0f) to use nearly all the available delay time.

I don't know if you did any of that. Because you didn't post a complete, usable sketch...
 
Here's a test sketch I've used in the past. It's doing slightly weird stuff for me at the moment (lots of background noise) but that could be hardware issues. It compiles and runs OK. What version of Teensyduino are you using?
C++:
#include "Arduino.h"
#include <Audio.h>

// One PSRAM 8MB chip is 95108.93ms of delay
// With a SPI bus of 31.41MHz, and 3 delay objects with 3, 3, and 1 tap, we
// need to do 3 writes and 7 reads of 128*2*8 = 2048 bits, so 20480 bits,
// which will take about 0.68ms. This happens every 2.9ms, so expect
// a CPU load of 22.4%. We get about 19%, so fairly close.
//
// 2024-02-06 - re-testing CPU use %
// Memory     Usage  Max
// PSRAM64 -> 42.6  42.8
// EXTMEM  ->  3.8   4.8
// HEAP    ->  0.86  0.97
//
// See also the benchmark comment in extmem.h

#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_23LC1024
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_PSRAM64
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_PSRAM64_X8
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_EXTMEM
//#define AUDIO_DELAY_MEMORY AUDIO_MEMORY_HEAP

// GUItool: begin automatically generated code
AudioSynthWaveformModulated waveformMod;    //xy=303,301
AudioEffectFade          fader;          //xy=506,304
AudioEffectDelayExternal delayExt(AUDIO_DELAY_MEMORY,910.0f);       //xy=540,506
AudioEffectDelayExternal delayExt1(AUDIO_DELAY_MEMORY,560.0f);      //xy=559,757
AudioMixer4              mixer4;         //xy=834,329
AudioMixer4              mixer5;         //xy=841,574
AudioOutputI2S           i2s;            //xy=1041,264

AudioConnection          patchCord1(waveformMod, fader);
AudioConnection          patchCord2(fader, 0, mixer4, 0);
AudioConnection          patchCord3(delayExt, 0, mixer4, 1);
AudioConnection          patchCord4(delayExt, 1, mixer4, 2);
AudioConnection          patchCord5(delayExt, 1, mixer5, 0);
AudioConnection          patchCord6(delayExt, 2, mixer4, 3);
AudioConnection          patchCord7(delayExt1, 0, mixer5, 1);
AudioConnection          patchCord8(delayExt1, 1, mixer5, 2);
AudioConnection          patchCord9(delayExt1, 2, mixer5, 3);
AudioConnection          patchCord10(mixer4, 0, delayExt, 0);
AudioConnection          patchCord11(mixer4, 0, i2s, 1);
AudioConnection          patchCord12(mixer5, 0, delayExt1, 0);
AudioConnection          patchCord13(mixer5, 0, i2s, 0);

AudioControlSGTL5000     sgtl5000_1;     //xy=1041,311
// GUItool: end automatically generated code



elapsedMillis next;
void setup() {
  Serial.begin(115200);

  Serial.println("Starting audio...");
  AudioMemory(40);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.4);

  mixer4.gain(0,0.3f);
  mixer4.gain(1,0.05f);
  mixer4.gain(2,0.10f);
  mixer4.gain(3,0.51f);

  Serial.println("Set up delayExt object");
  delayExt.delay(0,300.0);
  delayExt.delay(1,700.0);
  delayExt.delay(2,900.0);
 
  mixer5.gain(0,0.1f);
  mixer5.gain(1,0.05f);
  mixer5.gain(2,0.10f);
  mixer5.gain(3,0.71f);

  Serial.println("Set up delayExt1 object");
  delayExt1.delay(0,69.0);
  delayExt1.delay(1,241.0);
  delayExt1.delay(2,547.0);
 
  waveformMod.begin(0.001f,1000.0f,WAVEFORM_SINE);
  fader.fadeOut(1.0);
  delay(5);
  waveformMod.amplitude(0.5f);
   
  next = 4900;
}


void loop() {
  if (next > 5000)
  {
    next = 0;  
    fader.fadeIn(2.0);
    delay(40);
    Serial.printf("Usage %.2f, max %.2f\n",AudioProcessorUsage(),AudioProcessorUsageMax());
    AudioProcessorUsageMaxReset();
    fader.fadeOut(2.0);  
  }
}
I tried this sketch and it compiles but crashes in every configuration including heap. Loop gets through maybe 15 cycles.
 
What then is the relationship between AudioMemory() and AudioEffectDelay()? Does AudioMemory() eat into the max delay time? How do i calculate that?
Thanks
 
I tried this sketch and it compiles but crashes in every configuration including heap
That’s odd, I’ll have to check it doesn’t depend on some library modification that only I have. Shouldn’t, but you never know…
What then is the relationship between AudioMemory() and AudioEffectDelay()? Does AudioMemory() eat into the max delay time? How do i calculate that?
AudioEffectDelay uses blocks you allocated using AudioMemory(). There is a somewhat undocumented limit of 896 blocks on Teensy 4.x, so the 4s limit mentioned in post #8 is academic…

Each block is 128 samples, so 896 blocks at 44.1kHz works out to 128x896/44100=2.6s. You obviously can’t use all your blocks for delay memory, some are needed for I/O, but that’s a rough guide. For two audio delays the limit depends on how you use them, as blocks are allocated dynamically (unlike AudioEffectDelayExternal which uses a separate allocation fixed at compile time). So you could have one 2s and one 0.6s delay.
 
EXTMEM allocates from PSRAM soldered underneath the Teensy 4.1; if that runs out it silently allocates from DMAMEM (which may be what you mean by "the secondary onboard RAM area"). This is irrelevant to a Teensy 4.0, therefore, as noted in my post #7 - any attempt to use it will result in a compile-time failure.

I don't know what static_malloc.h is - not part of cores, anyway, and not usable for any variant of AudioEffectDelayExternal.

Your code from post #1 should work to create two delay objects where you can set taps which delay up to 720ms each. Note that you do still have to set the tap times by calling AudioEffectDelayExternal::delay(tap#,millis) as needed, so for your example something like dly1.delay(0,700.0f) to use nearly all the available delay time.

I don't know if you did any of that. Because you didn't post a complete, usable sketch...
To be clear I have only used test code on this thread. The project I am working on has too much code to test this one feature. So I am literally pasting in test sketches indiscriminately. I am using the latest Teensyduino….Am I? I will check.
I’m also using Gemini but it is hung up on spi pins and won’t let it go.
 
In my experience, if you start getting hung up on a single issue it's often well worth the effort to back out of your main project and make a small example to understand and sort that one small area. If after that it still doesn't work in your main code, then there's an unforeseen interaction which you need to investigate.

The latest is Teensyduino 1.60 - I tend to be using a nasty hybrid with all sorts of off-brand bleeding-edge improvements, which could mean the same code works here but not for you. I'd be a bit surprised in this case, though.
 
@PaulStoffregen After adjusting the sketch esthetically, I agree with you, the onboard memory on the Teensy 4.0 is decent for an echo effect, in stereo. (psychedelic pingpong is in full effect)
I am not working with humpback whale songs, where I need a 35 second delay. This sounds nice!
 
Yes, It's version 1.60.0. I love nasty hybrids, but is there a more stable version for audio projects?
Teensyduino 1.60 and its bundled Audio library should be as stable as it comes. It does not support the use of PSRAM as delay memory, either on a Teensy 4.1 as EXTMEM or on the audio adaptor. It does support the fairly ancient 23LC1024 on the audio adaptor, and has done for years; if that’s causing problems then they’re either hardware or your code.
 
Back
Top