Imagine you have a buffer that is continuously being writting to and read from. In my example i read the buffer in a loop backwards. For visual aid i made a beautiful image in paint.
Imagine a buffer that is circular with a playinghead moving counterclockwise and the recordinghead moving clockwise. If they have the same speed and both start on top, then they would meet twice every cycle, once on top and once on the bottom.
When the heads meet id like to have some kind of crossfade. My attempt is as follows:
Once the heads are at a distance d from eachother, i try to crossfade from the playheads current position to one frame behind the recordinghead. Once the heads are closer then distance d there is a trigger, to trigger this crossfade. I thought that this way you crossfade over the collision and there would be no clicks. However there are still clicks.
({
var buffer, sig, trigger, recHead, playHead, startPos, d = 1000;
//with a modulating frequency of 1 there are no clicks
//because the buffer contents effectively dont change
sig = SinOsc.ar(440 + SinOsc.ar(1.5, mul: 100))*0.1;
buffer = Buffer.alloc(s, 44100);
recHead = Phasor.ar(0, 1, 0, 44100);
//we pretend PlayBufCF uses this playHead
playHead = Phasor.ar(0, -1, 44100 - 1, -1);
BufWr.ar(sig, buffer, recHead, 0);
//|playHead - recHead| < d || |playHead - recHead| > (44100 - d)
//second part of if statement is when
//the playHead and recHead are on opposite sides of the 0 frame
trigger = ((playHead - recHead).abs < d + ((playHead - recHead).abs > (44100 - d))) > 0;
//bufwr for reference
//with a modulating frequency of 1 there are also no clicks with BufRd
//BufRd.ar(1, buffer, playHead, 0);
//trying out different lagtimes, but it doesnt change much
PlayBufCF.ar(1, buffer, -1, trigger, recHead - 1, loop:1, lag:MouseX.kr(0.1,1).poll);
}.play)
I know that in my example the “real” playhead jumps a few frames ahead every trigger, so the trigger gets more and more behind. So i’d need to update the playhead and then update the trigger retroactively with this new playhead, however i have no idea how i should do that.
Has anyone solved this problem before and if so how did you implement a smooth transition when recordinghead and playhead cross?