Sweeping through a Buffer in sync with Tempo

I’d recommend keeping the “phasor” that moves the playback position around on the server and just retriggering it from the client, so you’d keep the Sweep ugen and replace the Impulse that’s triggering it now with a control:

(
    b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");

    SynthDef(\kali, { |out=0, buf, t_trig, tempo=1, rate=1, scale=1, density=10, scatter=0, mul=1, add=0|
	Out.ar(out,
            Pan2.ar(
                BufGrain.ar(
                    trigger: Impulse.kr(density),
                    dur: 1/density * 2,
                    sndbuf: buf,
                    rate: rate,
                    pos: Sweep.kr(t_trig, tempo/(scale*4)) + PinkNoise.kr(mul:scatter),
                    mul: mul,
                    add: add,
                )
            )
        )
    }).add;
)

Then you’d create the Synth as before:

(
    a = Synth(\kali, [
	\buf, b,
	\rate, 1,
	\density, 10,
	\scatter, 0,
	\tempo, 1,
	\scale, 2,
	\rate, 1,
    ]);
)

There are several ways to set the \t_trig control from the client. One of the simplest would be a Routine:

(
    r = Routine.new({
        inf.do({
            a.set(\t_trig, 1);
            1.yield // interval in beats between triggers
        })
    }).play(quant: 1) // begin triggering on beat, play on TempoClock.default unless another Clock is specified
)

r.stop // stop retriggering

I hope that gives you enough to get started with. Two other quick notes:

  1. The name t_trig is a special form that creates a “trigger rate” Control. See the SynthDef helpfile for more information. As an alternative to declaring t_trig in the arg list, you can create a NamedControl directly in the body of the SynthDef function like this: \trig.tr. There’s a great explanation of why you might want to do this in this thread: NamedControl: a better way to write SynthDef arguments, but feel free to stick with whatever approach works for you.

  2. As I said above, there are many different ways of sending triggers (and of setting the other parameters of your Synth) from the client. If you want to use Events and Patterns to control this or any other Synth, you’ll need to watch out for certain reserved Symbols (including 'tempo' and 'scale'!) that have special properties in Events and can cause issues if you use them as control names in a SynthDef. These are listed in Event’s helpfile.