Hello
I am slowly converting old dirty patches from Max to SC and in FFT land, it is always a challenge. Now I know that @josh has made PV_BinDelay - and I use it to test this patch - it behaves like it should with the c external, but with pvcollect i still get artefacts (resonance and ring mod at the fft frame rate).
help?
~size = 2048;
~buf = Buffer.alloc(s,~size*100);
~del = Buffer.alloc(s, ~size / 2);
// x blocks of random delays
x = 5; ~del.sendCollection((x.collect{1.0.rand}.normalizeSum * (~size / 2.01) + 1).round(1).collect{|i|100.rand.dup(i)}.flat)
// look at them, woo
~del.plot
// play something pitchy
(
y = {arg buf;
var source = SinOsc.ar(Line.ar(220,440,10,doneAction: 2));
var fftbuf = LocalBuf(~size);
var chain = FFT(fftbuf, source, hop: 0.25, wintype: 1);
var chainB = PV_Copy(chain, LocalBuf(~size));
var cue = chain > -1;
var count = Stepper.kr(cue, max: 100);
FluidBufCompose.kr(fftbuf,destination: ~buf, destStartFrame: count * ~size, trig: cue);
chainB = chainB.pvcollect(~size, { |mag, phase, bin, index|
var fftindex = (bin*2);
var readhead = (count - BufRd.kr(1,~del,bin,0,0)).mod(100) * ~size;
var real = BufRd.kr(1,~buf, readhead + fftindex,0,0);
var imag = BufRd.kr(1,~buf, readhead + fftindex + 1,0,0);
[((real**2) + (imag**2)) ** 0.5, imag.atan2(real)];
}, frombin: 0, tobin: ~size/2+1, zeroothers: 0);
[source, IFFT(chainB,1)];
}.play
)
/// ringy
// same thing with Josh's sounds good - the C code (and my max patch and the patch above) do the same thing IIUC...
(
~fb = Buffer.alloc(s, ~size / 2);
y = {arg buf;
var source = SinOsc.ar(Line.ar(220,440,10,doneAction: 2));
var fftbuf = LocalBuf(~size);
var chain = FFT(fftbuf, source, hop: 0.25, wintype: 1);
chain = PV_BinDelay(chain, 1, ~delsec, ~fb, 0.25);
[source, IFFT(chain)];
}.play
)