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);}
}
Comments