My favourite FX is this FFT Delay

Hi everyone,

I thought I’d share one of my favourite FX with you. It’s basically a delay with some PV ugens in the feedback loop. You’ll need FbL, DFM1 & PV ugens installed.

I use this all the time and extensively on my recent release


(sorry shameless advertising :slight_smile: )

I think it works really well on musical sounds. Particularly if you need to add some spice to a simple oscillator.

Enjoy. x

// FFT Delay //
SynthDef("FFTDelay", {|in=8, out=0, inAmp=0.125, i_fft = 9, delayTime = 0.1, feed = 0.4, threshAbove = 0, threshBelow = 3, smooth = 0.5, smear=0, swapIn=0, pingPong=1, stretch = 0, freqHP=20, freqLP=20000, qHP = 0, qLP = 0, pan=0, noise= -2|
	var signalIn = In.ar(in, 2) * inAmp;
	var chain, signal, sigOut, ampAdj;
	var panPos   = pan * 2;
	var leftPos  = (panPos-1).clip(-1,1);
	var rightPos = (panPos+1).clip(-1,1);
	signalIn = [ LinSelectX.ar(swapIn, [signalIn[0],signalIn[1]]),
	             LinSelectX.ar(swapIn, [signalIn[1],signalIn[0]])];
	threshAbove = threshAbove ** 2;
	threshBelow = threshBelow ** 2;
	ampAdj      = 1 / ((threshBelow**0.8).clip(0.005,1.5));
	signal      = FbL({|feedback|
		chain  = FFT({ LocalBuf(2**i_fft) }!2, signalIn+(feedback.tanh*feed));
		chain  = PV_MagBelow (chain, threshBelow);
		chain  = PV_MagAbove (chain, threshAbove);
		chain  = PV_MagSmooth(chain, smooth);
		chain  = PV_MagSmear (chain, smear);
		chain  = PV_MagShift (chain, 2**stretch);
		sigOut = (IFFT(chain)*2);  // stereo
		noise  = 0.5 ** noise;
		sigOut = sigOut * ampAdj * noise;
		sigOut = DFM1.ar(sigOut,freqHP, qHP ,0.445,1,0);
		sigOut = DFM1.ar(sigOut,freqLP, qLP, 0.445,0,0);
		sigOut = sigOut / ampAdj / noise;
		[ LinSelectX.ar(pingPong, [sigOut[0],sigOut[1]]),
		  LinSelectX.ar(pingPong, [sigOut[1],sigOut[0]])];
	},1,delayTime.lag,2);
	signal = LinPan2.ar(signal[0], leftPos) + LinPan2.ar(signal[1], rightPos);
	Out.ar(out, signal * ampAdj);
},
metadata: ( specs: ( filtFreq:\freq, q:\unipolar, threshAbove:[0,4], threshBelow:[0,4], smear:[0,10,1,1], stretch:[-0.5,0.5],i_fft:[ 7, 13, \lin, 1, 10], freqHP:\freq ,freqLP:\freq, qHP:[0,1], qLP:[0,1], pan:[ -1, 1, \lin, 0, 0], noise:[-4,4,\lin,0,0]))).send;

SynthDef("PlayBuf", {| out = 0, bufnum = 0 |
	Out.ar(out, PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop:1) )
}).send;

b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav"); // remember to free the buffer later.

f = Synth("FFTDelay",[\in,4,\out,0,\i_fft,10]); // set fft size here 7-13
Synth("PlayBuf",[\out, 4, \bufnum, b]);
f.set(\delayTime, 0.0666);
f.set(\feed, 0.45);
f.set(\smooth, 0.93);
f.set(\smooth, 0.4);
f.set(\smear, 3);
f.set(\smear, 0);
f.set(\stretch, 0.1);
f.set(\stretch, -0.2);
f.set(\stretch, 0);
f.set(\threshAbove, 0.3);
f.set(\threshAbove, 0.7);
f.set(\threshAbove, 0);
f.set(\threshBelow, 1);
f.set(\threshBelow, 0.7);
f.set(\threshBelow, 3);
f.set(\freqLP, 6000);
f.set(\qLP, 0.25);
f.set(\freqHP, 200);
f.set(\qHP, 0.4);
f.set(\delayTime, 0.166);
f.set(\smooth, 0.8);
f.set(\pingPong, 0); // stereo
Synth("PlayBuf",[\out, 5, \bufnum, b]);
f.set(\pingPong, 0.5); // mono
f.set(\pingPong, 1); // ping pong
f.set(\swapIn,0.5); // input is mono
f.set(\swapIn,1); // swap L & R in
12 Likes

The combination of all these parameters is indeed unlocking quite a sonic universe!
(Note for those trying it out, you will need to install the Feedback quark.)