Server status yellow with certain Buffers and BufRd

Hello,
I am experiencing a weird behaviour with a BufRd SynthDef that is set with an Array of data in a Routine
the SynthDef has two signals with the same Buffer (for mixing purposes) I am aware that this is not the best way to mix the signals, but since I am not sure, if the problem originates here, I left it in.


SynthDef(\brForum, {
	arg buf=0, rate=1;
	var sig, sig2, ptr, ptr2, env;
	ptr = Phasor.ar(0, BufRateScale.kr(buf) * rate * \harm.kr(0).midiratio, 0, BufFrames.kr(buf)-1);
	ptr2 = Phasor.ar(0, BufRateScale.kr(buf), 0, BufFrames.kr(buf)-1);
    sig2 = BufRd.ar(1, buf, ptr2);
	env = Env.asr(\atk.ir(1),\sus.ir(1),\rls.ir(1)).kr(2, \gate.kr(1));
	sig = 2.collect({
		var lag = LFNoise1.kr(\lg1.kr(0)).bipolar(\lg2.kr(0.0));
		lag = lag * s.sampleRate;
		BufRd.ar(1, buf, ptr + lag, \lp.kr(1.0));
	}).sum ;
	sig = RLPF.ar(sig, \ffreq.kr(200), \rq.kr(0.5));
    sig2 = sig2 * env * \fade2.kr(0.1);
	sig = sig * env * \amp.kr(0.3) * \fade.kr(1);
    SendReply.kr(Impulse.kr(10), '/br', buf);
    sig = Mix.ar([sig, sig2]);
	Out.ar(\out.kr(0), sig);
}).add;

The problem occurs when playing this Routine, where I manipulate the Synth(\brForum) with some data.

buf1 = ‘https://drive.google.com/file/d/1r0sdTe90qmJJ811oKfjm2to81opjAXtO/view?usp=drive_link
buf2 = ‘https://drive.google.com/file/d/1XUfNz-Yt3S89--cU6ovskPVTLs0YLeys/view?usp=drive_link

var rout;
o = OSCdef(\br, { |msg| msg[3].postln}, '/br');
rout = r({
		var data, normalized, buf, buf1, buf2, syn;
		data = (0..300);
		normalized = data.normalize(80, 3000);
               buf1 = Buffer.read(s, path/buf1);
                buf2 = Buffer.read(s, path/buf2);
                buf = buf2;
		syn = Synth(\brForum, [\buf, buf, \fade, 0.7, \fade2, 0.3, \end, buf.numFrames-1]);
		normalized.do({
			|d, i|
                         "normalized data   %  at   %".format(d, i).postln;
			syn.set(\ffreq, d, \lg2, d.linexp(80, 3000, 0.03, 0.5), \harm, d.linlin(80,3000, 12, 36));
			0.05.wait;
			if(i >=( normalized.size-1), {"end of data, releasing synth %".format(syn); syn.release(2)});
		});
}).play

It works well for half a second and then the sound stops, and the SendReply.kr in the SynthDef stops sending data to the OSC Function. There is no error message, though.
When I Command . the server status turns yellow.
I am guessing it is something with the Buffer handling but I can’t figure out what. Strange thing is, it did work a couple of days ago.
Does someone have a clue?

thanks a lot.

It looks like it’s a combination of memory leak and an operator issue.

Buffer.read doesn’t just load data into a container. It allocates memory for a new Buffer object AND reads the data the path argument is pointing to. So you’re probably leaking memory in the routine.

The other more acute issue is here:

This should be (assuming path is a path string and the file name is “buf1” with no extension):

path +/+ "buf1"

Here, you’re asking for the variable path to be divided by buf1 which is null because nothing was assigned to it.

You can run it with memory leak, but you can’t divide var path by null.

As what @mjsyts said about the path of the buffer being nil. However, I don’t think the issue is leaking memory.

The messyness of the code obscures the issue here, which is server synchronisation — there was a big discussion about this recently…

var buf = Buffer.read(s, path/buf2); // you only use this buffer, no need for buf1
syn = Synth(\brForum, [
   \buf, buf,
   \fade, 0.7, 
   \fade2, 0.3, 
    \end, buf.numFrames - 1 /// uh-oh, buffer not loaded on server, this will be 0
]);

The solution is to call s.sync before you get the buffer’s number of frames.

It should look like this…

var buf = Buffer.read(s, someRealPath); 
s.sync;
syn = Synth(\brForum, [
   \buf, buf,
   \fade, 0.7, 
   \fade2, 0.3, 
    \end, buf.numFrames - 1 // now its good
]);

As an aside, I recently made a quark that makes this a little more obvious as you have to call await before you can use the buffer. The documentation isn’t done, so I wouldn’t suggest it be used just yet…
(GitHub - JordanHendersonMusic/Smart: A supercollider quark for async, promises, which will also provide new basic types.)

var rout = Routine({
	var buf = SmartBuffer.read("path/asdf", s).await();
	var syn = Synth(\brForum, [\buf, buf, \fade, 0.7, \fade2, 0.3, \end, buf.numFrames - 1]);
	
	(0..300).normalize(80, 3000).do({
		|d, i|
		syn.set(\ffreq, d, \lg2, d.linexp(80, 3000, 0.03, 0.5), \harm, d.linlin(80,3000, 12, 36));

		0.05.wait;
	});
	
	syn.release(2) // this can be moved down here
}).play

Thank you Jordan and mjsyts,
Sorry for the confusing code with the paths, I did in fact have valid paths there.
Weirdly enough, I don’t run into problems anymore, even without the s.sync.
I will add the s.sync though, thinking of it as a good practice. May a restart cleared up some stuff…

s.sync might or might not be needed depending on how fast the server can execute the command… Therefore it is always needed as you can’t rely on it.