Update of Buffer instances

Hi,

In order to create a SynthDef according to the number of channels of a Buffer (mono or stereo), I would like to test the numChannels argument and compile the rest of my code at the same time.

However, as described in the Buffer help, You cannot rely on the buffer’s instance variables being instantly updated, as there is a small amount of latency involved. action will be evaluated upon receipt of the reply to the query.

So a first option would be to write the rest of the code (that requires updated Buffers) in action . Here is an example :

(
p = Platform.resourceDir +/+ "sounds/a11wlk01.wav";
b = Buffer.read(s,p,action: {
	arg buffer;
// after update :
	("numChannels is actually :" + buffer.numChannels).postln;
});
// before update :
("numChannels is :" + b.numChannels).postln;
)

I also thought of using a temporisation Routine including the rest of the code :

(
p = Platform.resourceDir +/+ "sounds/a11wlk01.wav";
b = Buffer.read(s,p);
// before update :
("numChannels is :" + b.numChannels).postln;

Routine({ 
	1.wait;
// after update :
	("numChannels is actually :" + b.numChannels).postln;
}).play;
)

But for both options, this implies to include all interlinked objects refering to Buffers in the encapsulated code. Is there another way to handle this latency of buffer instanciation ?

mic

The easiest way to pause a Routine until buffer loading and other asynchronous server actions are finished is Server’s sync method, e.g.

// 'fork' implicitly plays a Routine
// the Routine is necessary to pause and resume
fork {
    ... load one, or several buffers...
    s.sync;  // wait until ALL pending asynchronous commands are finished
    SynthDef(... depends on buffer info...);
};

Then you don’t need multiple nested action functions.

hjh

Thanks,

Indeed, this is more optimised and it answers my question. However, I have the feeling that I am missing something here :

//structure of the code : 

... patterns and synths using SynthDef depending on buffer ...

fork {
    ... load one, or several buffers...
    s.sync;  // wait until ALL pending asynchronous commands are finished
    SynthDef(... depends on buffer info...);
};

I am surprised that I don’t received an error message saying that the SynthDef that I am referring to outside of the fork is not defined, as I would expect SC to execute the code outside of the fork without waiting for the server s.sync.

mic

I would write the code to express the dependencies clearly.

  • Buffer loading first.

  • SynthDefs depend on buffer loading so they come after loading.

  • Patterns depend on buffers and SynthDefs so they come after both.

Writing stuff at the top of the code that depends on things you haven’t done yet strikes me as a fragile design. I’d avoid that.

hjh

Yes, it’s certainly more logic and stable in this way, thanks.

mic