«Basic Feedback Delay Network SynthDef» by michaeldzjap
on 18 Jul'19 18:40 inExample of a basic feedback delay network or FDN of order 8. Requires the MathLib quark. Use the scale argument to increase / decrease the delay time and the coef argument to control the decay time. Smaller scale values produce resonating sounds, larger scale values more reverb tail like sounds. Be careful with small scale values in combination with small coef values (hence the tanh).
For a theoretical reference see: https://ccrma.stanford.edu/~jos/cfdn/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
// Construct a circulant feedback matrix using the given eigenvalues ( // 1 - The eigenvalues of the feedback coefficient matrix d = [ -1, Polar(1, -3pi / 4), Polar(1, -pi / 2), Polar(1, -pi / 6), 1, Polar(1, pi / 6), Polar(1, pi / 2), Polar(1, 3pi / 4) ]; // 2 - Compute the feedback matrix from the given eigenvalues n = d.size; a = (Matrix.newIDFT(n) * Matrix.withFlatArray(n, 1, d)).real.flat / sqrt(n); ) ( s.waitForBoot({ var primePowerDelays = { arg delays; (delays collect: { |delay, i| var prime = i.nthPrime; prime ** ((log(delay) / log(prime)) + 0.5).floor; }).asInteger / s.sampleRate; }; var delayLengths = { arg n, dmin, dmax; var nm1 = n - 1; var d = dmin * ((dmax / dmin) ** ((0..nm1) / nm1)); (d * s.sampleRate).round(1.0).asInteger; }; SynthDef(\sine, { arg out, freq = 440, amp = 0.5, trigFreq = 1; Out.ar(out, Decay.ar(Impulse.ar(trigFreq), 0.2, SinOsc.ar(freq, 0, amp))) }).add; SynthDef(\fdn, { arg in, out, scale = 1.0, coef = 0.5; var a, x, w, fb, delT; fb = LocalIn.ar(n); a = \a.kr(0 ! n); delT = \delT.kr(primePowerDelays.(delayLengths.(n, 0.03, 0.06))); x = In.ar(in); w = a.size collect: { arg i; DelayN.ar(a.rotate(i).inject(x, { |input, coef| coef * fb[i] + input }), 1, (delT[i] * scale - ControlDur.ir).fold(0.0, 1.0)) }; LocalOut.ar(LeakDC.ar(OnePole.ar(w, coef))); Out.ar(out, w.sum.tanh ! 2) }).add; { s.scope(2) }.defer }); ) ( s.makeBundle(nil, { x = Synth(\sine, [\out, 10, \trigFreq, 0.25, \amp, 0.1], 1, \addToHead); y = Synth(\fdn, [\in, 10, \out, 0, \a, a, \scale, 1, \coef, 0.5], 1, \addToTail); }); )
reception
very cool!
there's a grainy/clicky sound with louder inputs that I'd love to figure out how to avoid though... wonder where to fiddle...