I’m running into trouble with playing audio files. My project is structured as follows:
I have an.scd file which loads audio files into buffers and defines functions to generate patterns which use those buffers, e.g.
(
var buf1 = Buffer.readChannel("/file1.aif");
var buf2 = Buffer.readChanenl("/file2.aif");
~buf1Pattern = Pbind(\buf, buf1, ...);
~buf2Pattern = Pbind(\buf, buf2, ...);
)
I use those patterns in another .scd file which imports this file and plays the patterns. This happens in a single code block, which makes sure that with a single ctrl+enter keypress I can load and play the latest version of the patterns.
(
"./patterns.scd".load
~buf1Pattern.value.play;
)
The issue I’m seeing is that playing the pattern sometimes results in the error “Buffer UGen: no buffer data” and no audio output. The only way to fix this is to restart the server. This initially happened non-deterministically and quite infrequently, but as the number of buffers has increased (I have about 30 now) it’s gotten to the point where it’s completely deterministic and I can never play audio twice in a row without restarting the server.
I attempted to fix this by adding logic to wait for all the buffers to load using Buffer.readChannel
's action
callback, which ensures that I only start playing patterns once all the buffers are fully loaded. This alleviated the problem in that now the first play after starting the server is always successful, but it didn’t fix the issue for any of the subsequent plays. Here’s the polling logic I’m using, where ~onLoad
is the callback passed to Buffer.readChannel
. The .postln
are there to sanity check that we always start with 0 loaded buffers and end up with numberOfBuffers
loaded buffers.
loadedBuffers = 0;
~onLoad = { loadedBuffers = loadedBuffers + 1; };
~waitForBuffers = {
| action |
Routine({
while({ loadedBuffers < numberOfBuffers }, {
loadedBuffers.postln;
1.wait;
});
loadedBuffers.postln;
1.wait;
action.value;
}).play;
};
I’m 99% sure the issue has nothing to do with the file paths or the files themselves, as it’s non deterministic and restarting the server allows me to play the full pattern which uses all of my samples.
Does this have to do with reloading the buffers on each execution of my main code block? The reason I’m doing this is that when I make changes to the file defining the patterns, I need to re-import it to get the most up to date patterns. I could move buffer loading to a specific code block which I only execute once, but this would mean
a) polluting the global namespace with global variables for each buffer
b) having to execute two code blocks (one to load the buffers and one to play the patterns) every time I start a new session or restart the server