# Move to specific locations of a sound file with Pdef

I would now like to apply what I learned in the post above, to an approach with patterns.

The goal: to move to specific locations of a sound file contained in a buffer, in sync with the clock (quant), but this time using a Pdef rather than Ndefs.

I use the same bases as in the solution of the post cited above:

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

//Set the tempo:
(
t = TempoClock.default.tempo = 110/60;
~rate_b = b.sampleRate;
~b = ~rate_b * t.tempo.reciprocal; //~b = 1 beat
)

(
SynthDef(\sound, {|gate=1, start=0, end=(b.numFrames-1), rate=1|
//// in the synth, '+' is analogous to 'or'
var trig = (Changed.kr(start) + Changed.kr(end)) > 0,
gate1 = ToggleFF.kr(trig),
gates = [gate1, 1.0 - gate1],
starts = Latch.kr(start, gates),
ends = Latch.kr(end, gates),
phasors = Phasor.ar(
trig:0,
rate:BufRateScale.kr(b)*rate,
start:starts,
end:ends
),
bufs = BufRd.ar(1, b, phase:phasors, loop:1),
egs = EnvGen.kr(
Env.asr(
attackTime:0.01,
sustainLevel:1,
releaseTime:0.01),
gate:gates,
doneAction:2),
sig = Mix(bufs * egs);
Out.ar(0, sig);
)

// The Pdef that plays \sound:
(
Pdef(\pat,
Pbind(\instrument, \sound,
\start, Pseq([~b*0, ~b*12],inf),
\end, Pseq([~b*2, ~b*14],inf),
\dur, 4,
\rate, 1,
\legato, 1
));
)
p = Pdef(\pat).play(quant:4);
p.stop;


The problem: It seems that there is not only one synth created by the Pdef, but one for each move in the buffer. Then, the synths created accumulate in stack until saturation.

What is going wrong? … and how to correct that?

Elode, have you tried removing the gate argument in your envelope? I’m not sure, but I wonder if the doneAction and gate together (in this case) might be counter productive.

@joesh : Thank you for the answer

But no, it does not change anything … any more than removing doneAction2.
And - as I understand it - gates are needed to produce the crossfade that avoid crunches.

Hi,

you took over the crossfading strategy provided by James here:

As he said:

But things are entirely different with Pbind: you’re producing a sequence of synths that can overlap by defining proper dur and legato values. So then the SynthDef can be much simpler.
You could, however also use Pmono (one monophonic synth), then again a crossfading strategy would have to be done within the SynthDef.
What’s the best way? Depends on your further plans and taste also. From my experience I guess it’s more comfortable to use Pbind (with Pdef or not).
Sorry, no time to provide an example right now, maybe someone can chime in.

1 Like

Thanks @dkmayer,
For Pbind and the creation of a synth at each event (sequence of synths), I think I understood (I hope ) .
So I simplified the SynthDef. I will do more thorough checks, but it seems that it works correctly, without cracks or pops:

(//The SynthDef with BufRd:
SynthDef(\sound, {|dur=1, gate=1, start=0, end=(b.numFrames-1), rate=1|
var sig, ptr, env; //ptr = pointer
env = EnvGen.kr(Env.asr(0.01, 1, 0.01, curve:-4), gate, doneAction:2);
//The parameter 'gate' and doneAction:2 seem necessary in this case:
//doneAction:2 avoids the stacking of synths. Correct?
ptr = Phasor.ar(rate:BufRateScale.kr(b)*rate, start:start, end:end);
sig = BufRd.ar(1, b, phase:ptr, loop:1);
Out.ar(0, Pan2.ar(sig)*env);