h4yn0nnym0u5e
Well-known member
Hi folks
I've been tinkering with the AudioEffectDelayExternal object some more, and have added modulation inputs to it:
This is very much preliminary, I'm sure there are many ways to break it horribly, but I thought I'd let any brave souls out there have a crack at it and see if they like it. You can find the code at https://github.com/h4yn0nnym0u5e/Audio/tree/feature/delay-modulation.
As you can see, it adds a modulation input for each of the taps, and a control function setModDepth(tap,milliseconds). Say a tap has a basic delay of 20ms, if you set the modulation depth to 5ms then when the modulating signal reaches +1.0, the delay will be 25ms; when it's -1.0, the delay will be 15ms. Clearly it will be bad news if the size of the delay memory is less than 25ms...
Here's some demo code:
Currently it only does linear interpolation between samples, but it doesn't sound too bad to my ear. Perhaps someone who knows what they're doing can provide some rather more objective analysis...
As it's based on my existing modifications, it can be used with SPI RAM on the audio adaptor (both 23LC1024 and PSRAM), a couple of the multi-chip SPI memory boards, PSRAM on the Teensy 4.1, and heap memory. The repository has an updated Design Tool with the ability to place it on your design, and some documentation to get you going.
I've been tinkering with the AudioEffectDelayExternal object some more, and have added modulation inputs to it:
This is very much preliminary, I'm sure there are many ways to break it horribly, but I thought I'd let any brave souls out there have a crack at it and see if they like it. You can find the code at https://github.com/h4yn0nnym0u5e/Audio/tree/feature/delay-modulation.
As you can see, it adds a modulation input for each of the taps, and a control function setModDepth(tap,milliseconds). Say a tap has a basic delay of 20ms, if you set the modulation depth to 5ms then when the modulating signal reaches +1.0, the delay will be 25ms; when it's -1.0, the delay will be 15ms. Clearly it will be bad news if the size of the delay memory is less than 25ms...
Here's some demo code:
Code:
#include "Arduino.h"
#include <Audio.h>
// 1000ms delay is 44100 samples or 88200 bytes: fits Teensy 4.1 heap no problem
// GUItool: begin automatically generated code
AudioSynthWaveformModulated wav; //xy=282,236
AudioSynthWaveformModulated LFO1; //xy=295,395
AudioSynthWaveformModulated LFO2; //xy=300,433
AudioSynthWaveformModulated LFO3; //xy=304,473
AudioEffectDelayExternal delayExt(AUDIO_MEMORY_HEAP,1000.0f); //xy=483,429
AudioMixer4 mixerL; //xy=760,345
AudioMixer4 mixerR; //xy=767,444
AudioOutputI2S i2s; //xy=959,395
AudioConnection patchCord1(wav, 0, mixerR, 0);
AudioConnection patchCord2(wav, 0, delayExt, 0);
AudioConnection patchCord4(wav, 0, mixerL, 0);
AudioConnection patchCord5(LFO1, 0, delayExt, 1);
AudioConnection patchCord7(LFO2, 0, delayExt, 2);
AudioConnection patchCord8(LFO3, 0, delayExt, 3);
AudioConnection patchCord9(delayExt, 0, mixerR, 1);
AudioConnection patchCord11(delayExt, 0, mixerL, 1);
AudioConnection patchCord12(delayExt, 1, mixerR, 2);
AudioConnection patchCord13(delayExt, 1, mixerL, 2);
AudioConnection patchCord14(delayExt, 2, mixerR, 3);
AudioConnection patchCord15(delayExt, 2, mixerL, 3);
AudioConnection patchCord16(mixerL, 0, i2s, 0);
AudioConnection patchCord17(mixerR, 0, i2s, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=959,442
// GUItool: end automatically generated code
uint32_t next;
void setup()
{
// sgtl5000_1.setAddress(HIGH);
sgtl5000_1.enable();
sgtl5000_1.volume(0.1);
sgtl5000_1.lineOutLevel(14); // 2.98V pk-pk
Serial.begin(115200);
while (!Serial && millis() < 3000);
;
Serial.println("Starting audio...");
AudioMemory(40);
mixerL.gain(0,0.71f);
mixerL.gain(1,0.25f);
mixerL.gain(2,0.1f);
mixerL.gain(3,0.05f);
mixerR.gain(0,0.71f);
mixerR.gain(1,0.1f);
mixerR.gain(2,0.2f);
mixerR.gain(3,0.07f);
Serial.println("Set up delayExt object");
delayExt.delay(0,23.0f);
delayExt.delay(1,57.0f);
delayExt.delay(2,129.0f);
wav.begin(1.0f,220.0f,WAVEFORM_TRIANGLE);
// Set up modulation
LFO1.begin(1.0f,1.1f,WAVEFORM_SINE);
float md = delayExt.setModDepth(0,1.00015f); // close to this depth...
Serial.printf("delayExt modulation depth is %.5fms\n",md); // ...but not quite!
LFO2.begin(1.0f,0.7f,WAVEFORM_SINE);
delayExt.setModDepth(1,2.0f);
LFO3.begin(1.0f,0.2f,WAVEFORM_SINE);
delayExt.setModDepth(2,5.0f);
next = millis() + 5000;
}
int count;
void loop()
{
if (millis() > next)
{
next += 5000;
delay(10);
Serial.printf("Usage %.2f, max %.2f\n",AudioProcessorUsage(),AudioProcessorUsageMax());
AudioProcessorUsageMaxReset();
}
}
As it's based on my existing modifications, it can be used with SPI RAM on the audio adaptor (both 23LC1024 and PSRAM), a couple of the multi-chip SPI memory boards, PSRAM on the Teensy 4.1, and heap memory. The repository has an updated Design Tool with the ability to place it on your design, and some documentation to get you going.