AFAICS you need three sync
calls.
In general terms, when do you need sync
?
- The operation(s) are asynchronous – such as buffer reading, where the language sends a command to the server to start reading, but the language doesn’t automatically halt this thread until the command finishes.
- AND the next operation depends on information that is available only when the previous one finished.
So let’s say A = reading the IR signal, B = allocating the IR spectrum buffer, C = preparePartConv, D = freeing the IR signal buffer.
To do B, you need to know the size of the IR buffer. You don’t know the size until after the server finishes reading and sends the statistics back to the language. So, you must sync
before B.
To do C, you need the IR spectrum buffer to be fully allocated. This is also asynchronous. So, (IMO) better to sync
before C. (Note below about this.)
To do D, you have to be sure the IR signal buffer is no longer needed, which is only true after preparePartConv
has fully completed. So… yep… sync
before D.
(
~fftSize = 1024;
fork {
// A
~irbuffer = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav",
startFrame: 140000, numFrames: -1);
s.sync;
// B
~irspectrum = Buffer.alloc(s, PartConv.calcBufSize(~fftSize, ~irbuffer), 1);
s.sync;
// C
~irspectrum.preparePartConv(~irbuffer, ~fftSize);
s.sync;
// D
~irbuffer.free;
// *now* you're ready
};
)
If you do it that way, then… everything in PartConv is deterministic, so the result should be consistent. If you’re taking shortcuts by omitting sync
, then it becomes much harder to guarantee a correct result every time. E.g., this should always sound the same:
(
a = { |fftSize = 1024, irbufnum|
var freq = MouseX.kr(2, 440, 1);
var sig = Impulse.ar(freq);
sig = PartConv.ar(sig, fftSize, irbufnum);
(sig * 0.1).dup
}.play(args: [irbufnum: ~irspectrum]);
)
a.release;
I note that the help file leaves out sync
between B and C – this might actually work because they’re both “sequenced commands” in the server, queued up and executed in order. My opinion is that it’s better not to leave it to chance – I would sync
it anyway. I wouldn’t leave out the other ones.
(Wouldn’t all of this sync
ing slow it down a lot if you’re preparing multiple channels? The channels aren’t interdependent. So you could read as many IR time domain buffers as needed, sync once, then allocate the spectrum buffers all at once, sync, multiple preparePartConv calls, sync, and free. There is no need to complete the entire process for one channel before moving to the next channel.)
hjh