top of page

Glitch Delay

The glitch delay takes advantage of the technique of cross-fading between delay lines (to silence the click sounds when turning the delay time pot) to create something altogether diffrerent. This idea comes from my PT2399 glitch delay.

This effect has mono input and stereo outputs.


I've set up eight delay "taps" at different delay times using the same Delay object. At regular intervals - controlled by a pot and triggered by a timer [LINK] - one delay line fades out and another fades in, using eight fade objects.


This creates the effect of jumping forwards or backwards in time across the recorded audio.


The fades are then mixed together. The output of Mixer2 connects back to Mixer1 to create a feedback path. This is set to maximum when the footswitch is pressed.


The footswitch has two modes, latching and momentary, set by the toggle switch (still need a purpose for middle toggle position!).



The size knob (A0) sets the time between each potential crossfade.


The length of each crossfade is set by the smoothing knob (A1).


The value of the density knob (A2) is compared to a constantly re-randomised number whenever it's time for a crossfade. If the knob value is higher than this number, a "glitch" will occur and a crossfade happens. If not, nothing happens and we wait for the next potential crossfade.


A3 is a standard delay time knob, but the delay time will only change during the next crossfade.


#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=360,216
AudioEffectDelay         delayExt1;      //xy=473,513
AudioMixer4              mixer1;         //xy=598,217
AudioEffectFade          fade3; //xy=680,423
AudioEffectFade          fade2; //xy=682,366
AudioEffectFade          fade5; //xy=685,543
AudioEffectFade          fade1;          //xy=686,315
AudioEffectFade          fade6; //xy=686,591
AudioEffectFade          fade4; //xy=687,480
AudioEffectFade          fade7; //xy=690,643
AudioEffectFade          fade8; //xy=690,703
AudioMixer4              mixer2; //xy=873,369
AudioMixer4              mixer3; //xy=877,539
AudioOutputI2S           i2s2;           //xy=1153,424
AudioConnection          patchCord1(i2s1, 0, mixer1, 0);
AudioConnection          patchCord2(i2s1, 1, mixer1, 2);
AudioConnection          patchCord3(delayExt1, 0, fade1, 0);
AudioConnection          patchCord4(delayExt1, 1, fade2, 0);
AudioConnection          patchCord5(delayExt1, 2, fade3, 0);
AudioConnection          patchCord6(delayExt1, 3, fade4, 0);
AudioConnection          patchCord7(delayExt1, 4, fade5, 0);
AudioConnection          patchCord8(delayExt1, 5, fade6, 0);
AudioConnection          patchCord9(delayExt1, 6, fade7, 0);
AudioConnection          patchCord10(delayExt1, 7, fade8, 0);
AudioConnection          patchCord11(mixer1, delayExt1);
AudioConnection          patchCord12(fade3, 0, mixer2, 2);
AudioConnection          patchCord13(fade2, 0, mixer2, 1);
AudioConnection          patchCord14(fade5, 0, mixer3, 0);
AudioConnection          patchCord15(fade1, 0, mixer2, 0);
AudioConnection          patchCord16(fade6, 0, mixer3, 1);
AudioConnection          patchCord17(fade4, 0, mixer2, 3);
AudioConnection          patchCord18(fade7, 0, mixer3, 2);
AudioConnection          patchCord19(fade8, 0, mixer3, 3);
AudioConnection          patchCord20(mixer2, 0, mixer1, 1);
AudioConnection          patchCord21(mixer2, 0, i2s2, 0);
AudioConnection          patchCord22(mixer3, 0, i2s2, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=1092,696
// 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; middle = 0; left = 0;}    // toggle is right
if(digitalRead(1) && digitalRead(2))  {right = 0; middle = 1; left = 0;}      // toggle is in the middle
if(!digitalRead(1) && digitalRead(2))   {right = 0; middle = 0; left = 1;}    // toggle is left
}

void fadeout();
void fadein();

unsigned int glitchtime = 300;
unsigned int fadetime = 50;
unsigned int density = 50;
unsigned int delaytime = 1000;
unsigned long currentMillis = millis();
byte whichfade = 0;   // 0 is fade in fade1, fade out 2, fade out 3. etc...
byte lastfade = 1;
bool latchstate = 0;  // the state of the footswitch in latching mode. 0 = off, 1 = on

extern "C" uint32_t set_arm_clock(uint32_t frequency);

void setup() {

  set_arm_clock(46000000);
 
  AudioMemory(360); // 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;
  
  sgtl5000_1.adcHighPassFilterDisable();
  sgtl5000_1.audioPostProcessorEnable();
  
  // preliminary delay line fades
  fadeout();
  fadein();

  // input/feedback mixer 
  mixer1.gain(0, 1.5);
  mixer1.gain(1, 0);
  mixer1.gain(2, 1.5);

  // 8x mixer (1)
  mixer2.gain(0, 1);
  mixer2.gain(1, 1);
  mixer2.gain(2, 1);
  mixer2.gain(3, 1);
  // 8x mixer (2)
  mixer3.gain(0, 1);
  mixer3.gain(1, 1);
  mixer3.gain(2, 1);
  mixer3.gain(3, 1);
}

void loop() {
  
  if(millis() - currentMillis >= glitchtime)              //(count >= glitchtime);  // time to glitch
  {
    density = analogRead(A2);
    delaytime = (analogRead(A3) >> 3) + 400;
    if(density >= random(4095))
    {
      fadeout();

      lastfade = whichfade;
      while(whichfade == lastfade)
      {whichfade = random(4);}
      
      fadein();
    }
    currentMillis = millis();    
  }

  // rate of glitching
  glitchtime = (analogRead(A0) >> 3) + 80;  // 50 to 561

  // smoothing (length of fades)
  fadetime = glitchtime / (64 - (analogRead(A1) >>  6)) ; // 64 to  1

  // footswitch
  checkToggle();
  footswitch.update();
  if(right){                                                                                      // momentary mode
    if(!digitalRead(0)) {mixer1.gain(0,0); mixer1.gain(1,1); mixer1.gain(2,0); mixer1.gain(3,1); digitalWrite(LED,HIGH);}                                    // turn on feedback
    else{mixer1.gain(0,1); mixer1.gain(1,0);mixer1.gain(2,1); mixer1.gain(3,0);digitalWrite(LED,LOW);}                                                     // turn off feedback
  }
  else if(left) {                                                                                      // latching mode
   if(!latchstate && footswitch.fallingEdge()) {mixer1.gain(0,0); mixer1.gain(1,1);mixer1.gain(2,0); mixer1.gain(3,1);latchstate = 1; digitalWrite(LED,HIGH);}      // turn on feedback  --------------  remember gains (0.5 and 2) are compensating for wrong resistor!
   else if(latchstate && footswitch.fallingEdge()) {mixer1.gain(0,1); mixer1.gain(1,0);mixer1.gain(2,1); mixer1.gain(3,0);latchstate = 0; digitalWrite(LED,LOW);}    // turn off feedback
  }

}

// glitch functions
void fadeout ()
{
  if(whichfade == 0) {fade1.fadeOut(fadetime); delayExt1.delay(2, delaytime * .29); fade5.fadeOut(fadetime); delayExt1.delay(6, delaytime * .27);}
  if(whichfade == 1) {fade2.fadeOut(fadetime); delayExt1.delay(3, delaytime * .53); fade6.fadeOut(fadetime); delayExt1.delay(7, delaytime * .50);}   
  if(whichfade == 2) {fade3.fadeOut(fadetime); delayExt1.delay(0, delaytime * .74); fade7.fadeOut(fadetime); delayExt1.delay(4, delaytime * .77);}
  if(whichfade == 3) {fade4.fadeOut(fadetime); delayExt1.delay(1, delaytime * 1);   fade8.fadeOut(fadetime); delayExt1.delay(5, delaytime * 0.98);}
}

void fadein ()
{
  if(whichfade == 0) {fade1.fadeIn(fadetime); fade5.fadeIn(fadetime);}
  if(whichfade == 1) {fade2.fadeIn(fadetime); fade6.fadeIn(fadetime);}
  if(whichfade == 2) {fade3.fadeIn(fadetime); fade7.fadeIn(fadetime);}
  if(whichfade == 3) {fade4.fadeIn(fadetime); fade8.fadeIn(fadetime);}
}

Recent Posts
Search By Tags
Glowfly_Logo_RGB_inv.png
bottom of page