No simple way to control delay time of delay object with poteniometer?

I just want to clarify for my own sanity, but is there no way of updating the delay time of the delay object with a potentiometer? Seems like such a simple thing but obviously i am misunderstanding how the object works or something. I have searched for info but not really come across anything about it. I tried using a mixer to blend between different delay taps with different delay times but that is pretty unsatisfactory.

Here is what i'm working on, very simple delay/bitcrush/filter effect but pretty useless if i can gain control over the delay time

Thanks for reading :)

Code:
#define LED 3
#include <Bounce.h>

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=82,344
AudioMixer4              mixer1;         //xy=162,96
AudioEffectBitcrusher    bitcrusher1;    //xy=255,27
AudioEffectDelay         delay1;         //xy=307,220
AudioAmplifier           amp1;           //xy=409,29
AudioMixer4              mixer2;         //xy=462,224
AudioFilterBiquad        biquad1;        //xy=535,37
AudioOutputI2S           i2s2;           //xy=746,214
AudioConnection          patchCord1(i2s1, 0, mixer1, 0);
AudioConnection          patchCord2(i2s1, 0, bitcrusher1, 0);
AudioConnection          patchCord3(i2s1, 0, mixer2, 1);
AudioConnection          patchCord4(mixer1, delay1);
AudioConnection          patchCord5(bitcrusher1, amp1);
AudioConnection          patchCord6(delay1, 0, mixer1, 1);
AudioConnection          patchCord7(delay1, 0, mixer2, 0);
AudioConnection          patchCord8(delay1, 1, mixer2, 2);
AudioConnection          patchCord9(amp1, biquad1);
AudioConnection          patchCord10(mixer2, 0, i2s2, 0);
AudioConnection          patchCord11(biquad1, 0, mixer1, 2);
AudioControlSGTL5000     sgtl5000_1;     //xy=767,328
// GUItool: end automatically generated code



/*
  Bounce footswitch = Bounce(0, 50);  // debounce the footswitch
  Bounce D1 = Bounce(1, 50);          // debounce the toggle switch
  Bounce D2 = Bounce(2, 50);          // "  "  "  "  "  "  "  "  "

  // this section includes the function to check the toggle position
  bool right;
  bool middle;
  bool left;
  void checkToggle () {               // this is our function to check toggle position...
  D1.update();  D2.update();          // check digital inputs connected to toggle (can delete I think)
  if (digitalRead(1) && !digitalRead(2))   {
    right = 1;  // toggle is right
    middle = 0;
    left = 0;
  }
  if (digitalRead(1) && digitalRead(2))  {
    right = 0;  // toggle is in the middle
    middle = 1;
    left = 0;
  }
  if (!digitalRead(1) && digitalRead(2))   {
    right = 0;  // toggle is left
    middle = 0;
    left = 1;
  }
  }
*/

byte bitdepth = 16;                 // used to set bit depth
int samplerate = 44100;             // used to set sample rate
float mix;                          // clean/delay mix
float mix1;                        // clean/delay mix
float feedback;                    // delay feedback
int bandpass;                      //bandpass cutoff frequency


void setup() {

  AudioMemory(400); // the "40" represents how much internal memory (in the Teensy, not the external RAM chip) is allotted for audio recording. It is measured in sample blocks, each providing 2.9ms of audio.
  sgtl5000_1.enable();    // this turns on the SGTL5000, which is the audio codec on the audio board
  sgtl5000_1.volume(1);   // this sets the output volume (it can be between 0 and 1)
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); // selects the audio input, we always use Line In
  analogReadResolution(12); // configure the pots to give 12 bit readings
  pinMode(0, INPUT_PULLUP); // internal pull-up resistor for footswitch
  pinMode(1, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(2, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(3, OUTPUT);       // pin 3 (the LED) is an output;
  Serial.begin(9600);       // initiate the serial monitor. USB is always 12 Mbit/sec
  sgtl5000_1.audioPostProcessorEnable();
  analogReadAveraging(32);

}


void loop() {


  //set up delay
  delay1.delay (0, 400);
  delay1.disable (1);
  delay1.disable (2);
  delay1.disable (3);
  delay1.disable (4);
  delay1.disable (5);
  delay1.disable (6);
  delay1.disable (7);



  feedback = (float) analogRead (A2) / 4095; // delay feedback

  mix = (float) analogRead (A0) / 2000; // wet/dry mix
  Serial.println (mix);
  mix1 = 1.0 - mix;

  amp1.gain(2);


  //Set mixer levels
  mixer1.gain (0, mix1); // clean gtr in level
  mixer1.gain (1, feedback);
  mixer1.gain (2, mix);

  mixer2.gain (0, 0.5);
  mixer2.gain (1, 0.5);


  // do bitcrushing
  bitdepth = (16);
  bitcrusher1.bits(bitdepth);   // set bit depth

  samplerate = (analogRead(A1) << 1) + 1000;        // samplerate pot ranges from 1000 to 9190
  bitcrusher1.sampleRate(samplerate);               // set sample rate


  bandpass = (analogRead(A3) << 1) + 1000;               // lpf pot ranges from 500 to 8240hz
  biquad1.setBandpass (0, bandpass, 2);
  biquad1.setBandpass (1, bandpass, 2);
  biquad1.setBandpass (2, bandpass, 2);
  biquad1.setBandpass (3, bandpass, 2);

}
 
Like you're already doing for the gain, just use an equation with the number from analogRead() to compute the delay you want. Then use delay1.delay(mynumber) to change the delay object to the new setting. You're already doing this for mixer gain. You can do the same for delay time or pretty much any other adjustable parameter.
 
However, you might want to move this from loop() to setup()

Code:
  delay1.disable (1);
  delay1.disable (2);
  delay1.disable (3);
  delay1.disable (4);
  delay1.disable (5);
  delay1.disable (6);
  delay1.disable (7);

Really no point of doing this over and over at extreme speed as loop() runs repetitively. Once at startup is all you need if you don't ever change these settings.
 
Thank you for the reply, i definitely tried that but it sounded completely awful, like garbled the output. I'll write it up and post it to make sure i'm not doing anything stupid.

Also thanks for the delay.disable tip, that makes sense
 
Well i can kind of hear the delay but the audio output is incredibly fuzzy and sounds like its its been bitcrushed (i know i'm using a bitcrusher but it's not that) The dry audio path seems unaffected, just the delay path. I can't see why that would be, seems like what i've just done is pretty straight forward?

Code:
#define LED 3
#include <Bounce.h>

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=82,344
AudioMixer4              mixer1;         //xy=162,96
AudioEffectBitcrusher    bitcrusher1;    //xy=255,27
AudioEffectDelay         delay1;         //xy=307,220
AudioAmplifier           amp1;           //xy=409,29
AudioMixer4              mixer2;         //xy=462,224
AudioFilterBiquad        biquad1;        //xy=535,37
AudioOutputI2S           i2s2;           //xy=746,214
AudioConnection          patchCord1(i2s1, 0, mixer1, 0);
AudioConnection          patchCord2(i2s1, 0, bitcrusher1, 0);
AudioConnection          patchCord3(i2s1, 0, mixer2, 1);
AudioConnection          patchCord4(mixer1, delay1);
AudioConnection          patchCord5(bitcrusher1, amp1);
AudioConnection          patchCord6(delay1, 0, mixer1, 1);
AudioConnection          patchCord7(delay1, 0, mixer2, 0);
AudioConnection          patchCord8(delay1, 1, mixer2, 2);
AudioConnection          patchCord9(amp1, biquad1);
AudioConnection          patchCord10(mixer2, 0, i2s2, 0);
AudioConnection          patchCord11(biquad1, 0, mixer1, 2);
AudioControlSGTL5000     sgtl5000_1;     //xy=767,328
// GUItool: end automatically generated code



/*
  Bounce footswitch = Bounce(0, 50);  // debounce the footswitch
  Bounce D1 = Bounce(1, 50);          // debounce the toggle switch
  Bounce D2 = Bounce(2, 50);          // "  "  "  "  "  "  "  "  "

  // this section includes the function to check the toggle position
  bool right;
  bool middle;
  bool left;
  void checkToggle () {               // this is our function to check toggle position...
  D1.update();  D2.update();          // check digital inputs connected to toggle (can delete I think)
  if (digitalRead(1) && !digitalRead(2))   {
    right = 1;  // toggle is right
    middle = 0;
    left = 0;
  }
  if (digitalRead(1) && digitalRead(2))  {
    right = 0;  // toggle is in the middle
    middle = 1;
    left = 0;
  }
  if (!digitalRead(1) && digitalRead(2))   {
    right = 0;  // toggle is left
    middle = 0;
    left = 1;
  }
  }
*/

byte bitdepth = 16;                 // used to set bit depth
int samplerate = 44100;             // used to set sample rate
float mix;                          // clean/delay mix
float mix1;                        // clean/delay mix
float feedback;                    // delay feedback
int bandpass;                      //bandpass cutoff frequency
int delaytime;


void setup() {

  AudioMemory(400); // the "40" represents how much internal memory (in the Teensy, not the external RAM chip) is allotted for audio recording. It is measured in sample blocks, each providing 2.9ms of audio.
  sgtl5000_1.enable();    // this turns on the SGTL5000, which is the audio codec on the audio board
  sgtl5000_1.volume(1);   // this sets the output volume (it can be between 0 and 1)
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); // selects the audio input, we always use Line In
  analogReadResolution(12); // configure the pots to give 12 bit readings
  pinMode(0, INPUT_PULLUP); // internal pull-up resistor for footswitch
  pinMode(1, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(2, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(3, OUTPUT);       // pin 3 (the LED) is an output;
  Serial.begin(9600);       // initiate the serial monitor. USB is always 12 Mbit/sec
  sgtl5000_1.audioPostProcessorEnable();
  analogReadAveraging(32);


  delay1.disable (1);
  delay1.disable (2);
  delay1.disable (3);
  delay1.disable (4);
  delay1.disable (5);
  delay1.disable (6);
  delay1.disable (7);
}


void loop() {

  delaytime = analogRead (A4) / 2;


  //set up delay
  delay1.delay (0, delaytime);


  feedback = (float) analogRead (A2) / 4095; // delay feedback

  mix = (float) analogRead (A0) / 2000; // wet/dry mix
  Serial.println (mix);
  mix1 = 1.0 - mix;

  amp1.gain(2);


  //Set mixer levels
  mixer1.gain (0, mix1); // clean gtr in level
  mixer1.gain (1, feedback);
  mixer1.gain (2, mix);

  mixer2.gain (0, 0.5);
  mixer2.gain (1, 0.5);


  // do bitcrushing
  bitdepth = (16);
  bitcrusher1.bits(bitdepth);   // set bit depth

  samplerate = (analogRead(A1) << 1) + 1000;        // samplerate pot ranges from 1000 to 9190
  bitcrusher1.sampleRate(samplerate);               // set sample rate


  bandpass = (analogRead(A3) << 1) + 1000;               // lpf pot ranges from 500 to 8240hz
  biquad1.setBandpass (0, bandpass, 2);
  biquad1.setBandpass (1, bandpass, 2);
  biquad1.setBandpass (2, bandpass, 2);
  biquad1.setBandpass (3, bandpass, 2);



}
 
A few things to note:
  • the delay time is a float, in milliseconds - obviously an Arduino-style analogRead() is never going to give you fine-tuning here, but potentially worth knowing
  • there's not much throttling the update speed of your loop(), so it's probably changing the delay time several times per audio update
  • probably the cause of your woes, the analogue inputs are pretty noisy, so given you're likely changing the delay on every update, the delay is going to be jittering about by several milliseconds, every 2.9ms. You should experiment with smoothing the raw analogue input, ideally so when you don't touch the pot, no change is made to the delay. Any change above one sample (0.022ms) will make some difference, though it might not be very audible
 
Surely must be what h4yn0nnym0u5e said, the delay time is updating very often. Try to use the ResponsiveAnalogRead library that lets you set a threshold that the potentiometer must move before getting a new reading, in that way you filter all the noise of the analog inputs and get much more stable readings.
 
Thanks for the replies, very helpful. I’ve been trying to use ResponsiveAnalogRead with a little bit of success. The pot seems to jump far too quickly through the range though, going from 70 to 1023 in the smallest turn. I think this has something to do with the resolution?
The serial monitor is showing the raw value ranging from around 70 to 4090ish, it’s smooth from around 1000 onwards but very quick before that. The ‘smoothed’ value jumps from 70 to 1023 really quickly.

Do i need to set the resolution of the ResponsiveAnalogRead?
This is from the ResponsiveAnalogRead GitHub page which i feel is maybe what i’m after but not sure how to implement:

Code:
void setAnalogResolution(int resolution)
. (https://github.com/dxinteractive/ResponsiveAnalogRead/blob/master/README.md)

Code:
#define LED 3
#include <Bounce.h>
#include <ResponsiveAnalogRead.h>

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=82,344
AudioMixer4              mixer1;         //xy=162,96
AudioEffectBitcrusher    bitcrusher1;    //xy=255,27
AudioEffectDelay         delay1;         //xy=307,220
AudioAmplifier           amp1;           //xy=409,29
AudioMixer4              mixer2;         //xy=462,224
AudioFilterBiquad        biquad1;        //xy=535,37
AudioOutputI2S           i2s2;           //xy=746,214
AudioConnection          patchCord1(i2s1, 0, mixer1, 0);
AudioConnection          patchCord2(i2s1, 0, bitcrusher1, 0);
AudioConnection          patchCord3(i2s1, 0, mixer2, 1);
AudioConnection          patchCord4(mixer1, delay1);
AudioConnection          patchCord5(bitcrusher1, amp1);
AudioConnection          patchCord6(delay1, 0, mixer1, 1);
AudioConnection          patchCord7(delay1, 0, mixer2, 0);
AudioConnection          patchCord8(delay1, 1, mixer2, 2);
AudioConnection          patchCord9(amp1, biquad1);
AudioConnection          patchCord10(mixer2, 0, i2s2, 0);
AudioConnection          patchCord11(biquad1, 0, mixer1, 2);
AudioControlSGTL5000     sgtl5000_1;     //xy=767,328
// GUItool: end automatically generated code



/*
  Bounce footswitch = Bounce(0, 50);  // debounce the footswitch
  Bounce D1 = Bounce(1, 50);          // debounce the toggle switch
  Bounce D2 = Bounce(2, 50);          // "  "  "  "  "  "  "  "  "

  // this section includes the function to check the toggle position
  bool right;
  bool middle;
  bool left;
  void checkToggle () {               // this is our function to check toggle position...
  D1.update();  D2.update();          // check digital inputs connected to toggle (can delete I think)
  if (digitalRead(1) && !digitalRead(2))   {
    right = 1;  // toggle is right
    middle = 0;
    left = 0;
  }
  if (digitalRead(1) && digitalRead(2))  {
    right = 0;  // toggle is in the middle
    middle = 1;
    left = 0;
  }
  if (!digitalRead(1) && digitalRead(2))   {
    right = 0;  // toggle is left
    middle = 0;
    left = 1;
  }
  }
*/

byte bitdepth = 16;                 // used to set bit depth
int samplerate = 44100;             // used to set sample rate
float mix;                          // clean/delay mix
float mix1;                        // clean/delay mix
float feedback;                    // delay feedback
int bandpass;                      //bandpass cutoff frequency
int delaytime;
const int delayPin = A4;

ResponsiveAnalogRead analog(delayPin, true);


void setup() {

  AudioMemory(400); // the "40" represents how much internal memory (in the Teensy, not the external RAM chip) is allotted for audio recording. It is measured in sample blocks, each providing 2.9ms of audio.
  sgtl5000_1.enable();    // this turns on the SGTL5000, which is the audio codec on the audio board
  sgtl5000_1.volume(1);   // this sets the output volume (it can be between 0 and 1)
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); // selects the audio input, we always use Line In
  analogReadResolution(12); // configure the pots to give 12 bit readings
  pinMode(0, INPUT_PULLUP); // internal pull-up resistor for footswitch
  pinMode(1, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(2, INPUT_PULLUP); // internal pull-up resistor for toggle
  pinMode(3, OUTPUT);       // pin 3 (the LED) is an output;
  Serial.begin(115200);       // initiate the serial monitor. USB is always 12 Mbit/sec
  sgtl5000_1.audioPostProcessorEnable();
  analogReadAveraging(32);


  delay1.disable (1);
  delay1.disable (2);
  delay1.disable (3);
  delay1.disable (4);
  delay1.disable (5);
  delay1.disable (6);
  delay1.disable (7);
}


void loop() {

  // update the ResponsiveAnalogRead object every loop
  analog.update();

  Serial.print(analog.getRawValue());
  Serial.print("\t");
  Serial.print(analog.getValue());

  // if the responsive value has change, print out 'changed'
  if (analog.hasChanged()) {
    Serial.print("\tchanged");
  }

  Serial.println("");
  delay(20);

  delaytime = analog.getValue();

  //set up delay
  delay1.delay (0, delaytime);


  feedback = (float) analogRead (A2) / 4095; // delay feedback

  mix = (float) analogRead (A0) / 2000; // wet/dry mix
  Serial.println (mix);
  mix1 = 1.0 - mix;

  amp1.gain(2);


  //Set mixer levels
  mixer1.gain (0, mix1); // clean gtr in level
  mixer1.gain (1, feedback);
  mixer1.gain (2, mix);

  mixer2.gain (0, 0.5);
  mixer2.gain (1, 0.5);


  // do bitcrushing
  bitdepth = (16);
  bitcrusher1.bits(bitdepth);   // set bit depth

  samplerate = (analogRead(A1) << 1) + 1000;        // samplerate pot ranges from 1000 to 9190
  bitcrusher1.sampleRate(samplerate);               // set sample rate


  bandpass = (analogRead(A3) << 1) + 1000;               // lpf pot ranges from 500 to 8240hz
  biquad1.setBandpass (0, bandpass, 2);
  biquad1.setBandpass (1, bandpass, 2);
  biquad1.setBandpass (2, bandpass, 2);
  biquad1.setBandpass (3, bandpass, 2);



}


*EDIT*
In the set up, changing analogReadResolution from 12 to 10 and analogReadAveraging from 12 to 10 helps with the delay time range but it affects all the other pots in a negative way…I lose resolution of the feedback, bitcrush, and filter pot...

*EDIT 2*
Ahhh because i’m dividing feedback read by 4095 rather than 1023…sorry i’m learning on the fly here haha
 
Last edited:
Back
Top