Live granulation requires recording to a looping buffer first, then running GrainBuf on the buffer with a trailing pointer
To granulate a live microphone signal with GrainBuf, a multi-Synth architecture is needed: (1) a mic Synth reads SoundIn and writes to an audio bus; (2) a ptr Synth generates a Phasor ramp from 0 to BufFrames and writes to another bus; (3) a rec Synth reads both and uses BufWr to continuously record the mic into the buffer using the ramp as a frame index — creating a circular buffer that overwrites old samples; (4) a grain Synth reads GrainBuf using a delayed/lagging copy of the pointer for grain position. The grain pointer must stay behind the record head to avoid reading a discontinuity (the buffer wrap point), which causes audible clicks.
Examples
b = Buffer.alloc(s, s.sampleRate * 5, 1); ~micBus = Bus.audio(s, 1); ~ptrBus = Bus.audio(s, 1); SynthDef(\ptr, { arg buf=0; Out.ar(~ptrBus, Phasor.ar(0, BufRateScale.kr(buf), 0, BufFrames.kr(buf))) }).add; SynthDef(\rec, { BufWr.ar(In.ar(~micBus), b, In.ar(~ptrBus)) }).add;
Assessment
Why must the GrainBuf pos pointer be behind the record pointer in a live granulation system? What happens if a grain extends past the record head?