Beginner buffer instrument

I’m trying out a sample in a pattern. The pattern (or sample) gets delayed when I trigger it. It doesn’t seem to start at the exact beginning.

s.boot;
p = ProxySpace.new.push;

t = TempoClock(120/60).permanent_(true)
t.tempo_(1)


~pat.play;
~pat.fadeTime_(1)
~pat.quant_(1)

(
b = Buffer.read(s, );   //5 second drum loop

SynthDef(\samp, {|out=0, prate = 1.0, amp=0.1, pan=0, bufNum = 0, startPos = 0, trig = 1.0|
    var source, env;
    source = PlayBuf.ar(2, bufNum, prate, trig, startPos, doneAction: 2);
	env = Env.adsr(0.01, 2.1, 0.6, 1.8, amp).kr(Done.freeSelf, \gate.kr(1));
    Out.ar(out, Pan2.ar(source * env * amp, pan)*20);
}).add;
)
(
~pat=
Pbind(\instrument, \samp,
	\startPos, 0,
	\bufnum, 0,
    \dur, 3,
	\prate, 0.9,
	\amp, 0.1
	
)
)
(
~pat=
Pbind(\instrument, \samp,
	\startPos, 0,
	\bufnum, 0,
    \dur, 3,
	\prate, 0.9,
	\amp, 0.1
	
)

Delayed relative to what? If you mean that you get a delay between executing the code and hearing the result, that’s because the event stream player schedules all messages in advance based on the Server latency (see Server.latency). The default latency is rather high (200 ms).

You can, of course, decrease the latency. Note, however, that if the latency is too low you will get “late” messages and the relative timing between events will become less and less precise.

Thanks,
I’m not sure if the code produces the result I’m experiencing, which is essentially that the sample starts late on the first initialization and then triggering the next pattern it’s instant but not faded in.

Two things here. One is, as spacechild said, it’s impossible to achieve a completely instantaneous response. There is always latency in real-time audio on general purpose computers. SuperCollider patterns, by design, delay the audio to get consistent timing (“server timing” help file). This is probably part of what you’re hearing.

The second is that you’ve requested quant = 1, which means “do not start now; wait for the next whole beat” and then the latency applies on top of that.

If the expectation is, “I hit ctrl-enter and I wanted the sound to start within milliseconds after that,” the code as written will not do that. “Immediate response” and non-zero quant are mutually incompatible – you can have one or the other but not both. So I’d suggest to let go of the “late” concern (unless there’s some other aspect to it, which you haven’t specified yet).

Fadetime for patterns will work if you have fast events and a slow fade time. You have slow events (dur = 3) and a fast fade time (1).

A DAW style automation crossfade would be hard to implement in JITLib as it’s currently designed.

hjh

Thanks,
I hear you all on that. I’m still confused because the delay with the sample that I am experiencing is about 3 seconds.
So is it waiting one duration for the sample (quant). Each instrument separately waits it’s duration? I thought it was waiting to switch the whole pattern.
Here’s a better example of the delayed sample vs, a parallel Sythdef: .

s.boot;
p = ProxySpace.new.push;

t = TempoClock(120/60).permanent_(true)
t.tempo_(1)


~pat.play;
~pat.fadeTime_(1)
~pat.quant_(1)

(
b = Buffer.read(s, );  //5 second drum loop

SynthDef(\samp, {|out=0, prate = 1.0, amp=0.1, pan=0, bufNum = 0, startPos = 0|
    var source, env;
    source = PlayBuf.ar(2, bufNum, prate, startPos: startPos);
	env = Env.adsr(0.01, 2.1, 0.6, 1.8, amp).kr(Done.freeSelf, \gate.kr(1));
    Out.ar(out, Pan2.ar(source * env * amp, pan)*20);
}).add;


SynthDef(\b, {arg freq = 200, amp = 1.0, decay = 0.001;
	var sig = SinOsc.ar(freq)*AmpComp.kr(freq/2);
	sig = sig * EnvGen.kr(Env.perc(0.001, decay, amp), doneAction: 2);
	Out.ar(\out.ir(0),
		sig !2/6 * amp);
}).add;
)
(
~pat=
Ppar([
Pbind(\instrument, \samp,
	\startPos, 0,
	\bufnum, 0,
    \dur, 3,
	\prate, 0.9,
	\amp, 0.1
),
Pbind(\instrument, \b,
	  \freq, 440,
	  \dur, 0.5,
	  \amp, 0.5,
	  \decay, 0.2
)
],inf)
)

(
~pat=
Pbind(\instrument, \samp,
	\startPos, 0,
	\bufnum, 0,
    \dur, 3,
	\prate, 0.9,
	\amp, 0.1
)
)

Ah, I see now – you’re not allowing time for the buffer read to complete. The first synth is playing while the buffer is still being read, so the first synth is silent.

The Buffer help file should have information about asynchronous operations. The tl;dr is, don’t read a buffer and try to use it in the same block of code without fork-ing and s.sync.

hjh

Thanks.
The fade-in is somehow erasing the first Playbuf trigger in the first pattern. Not a huge deal as cross-fading patterns is kind of hit or miss.

Ah, you’re right, your buffer load is in a different block.

Pattern fades are implemented analogously to MIDI fades. The volume can change on the next event, but not in the middle of an event. I guess you’re expecting something like fader automation, but pattern fades don’t work that way. That’s what I meant when I said this usage isn’t really compatible with slow events and a fast fade time – they’ll be much less hit or miss if you reverse that (faster rhythm, slower fade).

hjh

That’s good to know, thank you!
A quick solution to this behavior I found is to start with Pbind \type, \rest, that you mentioned.
Then the next pattern with the sample starts instantly.