Looping audio without overlapping with Pbind

hello,
a question that is really basic but is creating a lot of headaches for me. I have a very simple SynthDef:



    SynthDef(\buf, {
        arg out = 0, bufnum;
        var sig,env;
		env = Env(
			levels:[0,1,1,0],
			times:[1,1,0.5],
			curve:-7
	).ar(2);
	
        sig = PlayBuf.ar(1, bufnum,\rate.ir(1), loop: 1);
	sig = Pan2.ar(sig,\pos.ir(0.0));
        Out.ar(out, sig);
    }).add;

I want to make a buffered audio that lasts 16.068020833333, play in a Pbind in its entirety without overlapping the repetitions in each repetition, that is to say, that the loop starts immediately after the previous repetition is finished without losing the tempo. How would this be possible?

Have you had a look at the Pattern helpfile, ‘Recording Event Patterns’? I have no experience using these methods myself but maybe a good place to start.

Hi, I have no problem playing my audios, in particular I have two Synthdef, one for mono files and one for stereo. What I would like to know is how to handle the audios hosted in buffers and have absolute control over them, specifically two things: play in loop inside a Pbind and that the playback before the repetition is exact to the duration of the audio, I have tried to adjust both the envelope (I used an Env.linen), as the Pbind’s \dur. The problem is that it ends up superimposing each time one playback over another.
Another thing I would like to control is to play the audio with silent space between each playback. I don’t know if I explain myself well.

You’ve specified a one second attack and half-second release. Without crossfading, the signal will audibly lose volume.

s.boot;

(
SynthDef(\bufseg1, { |out, gate = 1, bufnum, startSec, rate = 1, amp = 0.1, pan = 0|
	var sig = PlayBuf.ar(
		1, bufnum,
		rate * BufRateScale.kr(bufnum),
		startPos: startSec * BufSampleRate.kr(bufnum)
	);
	var eg = EnvGen.ar(Env.asr(0.005, 1, 0.005, \lin), gate, doneAction: 2);
	Out.ar(out, Pan2.ar(sig * (eg * amp), pan))
}).add;
)

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

(
p = Pbind(
	\instrument, \bufseg1,
	\bufnum, b,
	\startSec, Pwhite(0, b.duration * 0.6, inf),
	\rate, 1,
	\dur, Pexprand(0.2, 0.9, inf),
	\legato, 1
).play;
)

p.stop;

This should give you an overlap of 10 ms, undetectable to the ear (but I think necessary – I do not agree with audio splicing without any crossfade at all – a very short crossfade is correct).

hjh

Hi, I have tried synthdef, but I can’t do what I want to do. The question is, is it possible to totally control the playback of an audio, that is to say to have total control, like managing the duration (imagine, the audio lasts 5’‘, so that it plays those 5’’ and it plays again without overlapping any fragment of the audio). And also, if possible, make the audio play in short fragments, i.e. play intermittently during the session. Or on the contrary, instead of using a Pbind or Pdef , use functions with tasks (Tdef, Ndef, etc)… it is not so easy from my ignorance to master these aspects. :sleepy:

James’s code will do exactly what you ask, if in the Pbind you give a startSec of 0 and a dur of b.duration

if you want it to play intermittently, you could add a field that gives a probability for the event to be a Rest:

// 70% chance of being a rest
\dummy, Pwrand([Rest(), 1], [0.7, 0.3].normalizeSum, inf),

One thing to be aware of is that the server clock and the language clock is never in perfect sync, so any looping buffer on the server will not loop around at ecactly the same time as the pbind restarts given that they are set to the same duration, e.g. a bufferdur of 2 seconds and a pbind looping after 2 seconds. The discrepancy is likely very small, but still something to consider, especially since you seem to be wanting extremely precise sync.

I just tested this, removing the envelope to see the signal discontinuity at the loop point. I find exactly one zero sample between the end of the previous loop and the beginning of the next one – I think this is negligible on the scale of a several second buffer

But if you let it run for 20 minutes it might be a different story…not sure, but from previous experiments I found the clock drift to be a real concern when running for a while. Probably not an issue if you spawn a new synth at each loop, like James’ code, but could be if you were reusing the same synth node over time. Anyways, as you said probably not a concern in this example, but I have often had small unpleasant surprises due to clock drift.

Ah yes you don’t want to count on a pbind to stay in sync with a separately looping synth, for example. But if the pbind is scheduling the synths it should stay in sync

Note that if you try to use that code in a Pdef and/or Pbind while changing parameters (\dur, etc…), you will end up with audio overlaps. The use case I’m talking about here is live coding. Audio playback and possible overlaps will also be highly dependant on tempo (and other factors most likely).

I have opened a topic with a similar question a few weeks ago and was unable to find a robust and versatile solution to looping audio samples easily. I suppose that @twistin is searching for something similar to Octatrack capabilities when it comes to mangling audio samples (stretching, slicing, etc).

Hello;
Finally James’ script did what he wanted. I just had to remove the Pxrand from the duration. And everything worked fine. Thank you all very much for your help.