Node exhaustion using buffers

I’m running out of nodes running simple patterns with a BufRd-based SynthDef. Help!

The synthdef:

SynthDef(\bufplay,{ arg buf,pan=0.0,amp=1.0,out;
  Out.ar(out,Pan2.ar(BufRd.ar(
		buf.numChannels,buf,
        Sweep.ar(0,BufSampleRate.kr(buf)),
		0),pan,amp))
}).add;

I have a datastructure with all the buffers loaded, here’s the pattern:

(
var k = ~r8.bufs["DRY_K1"], s = ~r8.bufs["WOOD_S1"];
play(Pbind(
	\instrument, \bufplay,
	\dur,0.125,
	\amp, Pseq([0.8,0.4],inf),
	\pan, Pseq([-1.0,0.0,1.0],inf),
	\buf, Pseq([k,k,s,k,k,k,s,s],inf)))
)

This creates hundreds of nodes and eventually dies with “too many nodes”.

I’m wondering why this is not an issue more often with Patterns? is there some voice-stealing magic going on?

Hi @spopejoy ! welcome to the forum…

one problem is that there is no cleanup in your SynthDef ie Synths are created but never killed.

There are lots of ways to solve this!

You could use Line as the index instead of Sweep - Line has a doneAction argument which you can set to 2 which will free the enclosing Synth when completed: see the help for Done for more details.

Another possibility is to use PlayBuf instead of BufRd because it has a doneAction argument as well.

If you want the pattern duration to be able to shut off your Synths before you reach the end of your buffers, your SynthDef would need an argument named gate which could control an EnvGen with doneAction set to clean up the synth.

Also a quick note - BufRd will loop through a buffer continually unless the “loop” argument is set to 0 so your pattern is just layering these looping playback over eachother which should eventually get pretty loud :wink:

2 Likes

@semiquaver thanks! PlayBuf with Done.freeSelf works beautifully (and is really way better than BufRd for this application in any case :+1: )

2 Likes