Basically, each FFT bin gets fitted with its own recirculating delay line, and the delay times and feedbacks are controlled by makegens. For example, if you randomize the delay times, you get wild repetitive, spectrally splintered patterns.
p-fields:
/* SPECTACLE - FFT-based delay processor
p0 = output start time
p1 = input start time
p2 = input duration
p3 = amplitude multiplier
p4 = ring-down duration
p5 = FFT length (power of 2, usually 1024)
p6 = window length (power of 2, usually FFT length * 2)
p7 = window type (0: Hamming; see below for others)
p8 = overlap - how much FFT windows overlap (any power of 2)
1: no overlap, 2: hopsize=FFTlen/2, 4: hopsize=FFTlen/4, etc.
2 or 4 is usually fine; 1 is fluttery; the higher the more CPU time
p9 = wet/dry mix (0: dry -> 1: wet) [optional, default is 1]
p10 = input channel [optional, default is 0]
p11 = percent to left channel [optional, default is .5]
The following function tables control amplitude.
Function table 1 is the input amplitude, spanning just the input
duration.
Function table 2 is the output amplitude, spanning the entire
note, including ring-down duration.
The following function tables control EQ, delay time, and delay feedback
for all the frequency bands of the FFT. Think of them as curves on a
graph with frequency on the x axis and amplitude, delay time or feedback
on the y axis.
Function table 3 is the EQ table (i.e., amplitude scaling of each band),
in dB (0 dB means no change, + dB boost, - dB cut).
Function table 4 is the delay time table.
Function table 5 is the delay feedback table. Values > 1 are dangerous!
NOTES:
p7 - window type:
0: Hamming, 1: Hanning, 2: Rectangle, 3: Triangle, 4: Blackman,
5: Kaiser
When in doubt, use Hamming.
p8 - overlap:
1: no overlap, 2: hopsize=FFTlen/2, 4: hopsize=FFTlen/4, etc.
2 or 4 is usually fine; 1 is fluttery; higher overlaps use more CPU.
Also possible to use negative powers of 2, e.g., .5, .25, .125, etc.
This leaves a gap between successive FFTs, creating ugly robotic
effects -- beware of clipping.
p9 - wet/dry mix:
This is pre-EQ.
*/
Sample scorefile:
rtsetparams(44100, 2)
load("SPECTACLE")
/* ftp://presto.music.virginia.edu/pub/rtcmix/snd/ah.snd */
rtinput("/Users/johgibso/snd/ah.snd")
inchan = 0
inskip = .2
indur = 2
ringdur = 15 /* play after indur elapses, while delay lines flush */
amp = 12
wetdry = 1 /* 100% wet */
fftlen = 1024 /* yielding 512 frequency bands */
winlen = fftlen * 2 /* the standard window length is twice FFT size */
overlap = 2 /* 2 hops per fftlen (4 per window) */
wintype = 0 /* use Hamming window */
/* input envelope (covering ) */
makegen(1, 18, 1000, 0,0, 1,1, 19,1, 20,0)
/* output envelope (covering + ) */
makegen(2, 4, 1000, 0,1,0, 1,1,-1, 2,0)
/* EQ curve: -90 dB at 0 Hz, ramping up to 0 dB at 300 Hz, etc. */
makegen(3, 18, 1000, 0,-90, 100,-90, 300,0, 8000,0, 22050,-90)
/* fixed delay times between .4 and 3, randomly spread across spectrum */
min = .4; max = 3
seed = 1
makegen(4, 20, 1000, 0, seed, min, max)
/* constant feedback of 80% for all freq. bands */
fb = .8
makegen(5, 18, 1000, 0,fb, 1,fb)
/* do it for the left chan! */
start = 0
SPECTACLE(start, inskip, indur, amp, ringdur, fftlen, winlen, wintype, overlap,
wetdry, inchan, pctleft=1)
/* shift delay table to make right channel sound different */
shiftgen(4, 500)
/* do it for the right chan! */
SPECTACLE(start, inskip, indur, amp, ringdur, fftlen, winlen, wintype, overlap,
wetdry, inchan, pctleft=0)