loadCollection issues within and OSCdef

Hi all,

I am trying to copy the data I am receiving from OSC to a buffer. I’ m doing this from whithin the OSCdef. I was doing it like this:

(
var accData = 0.dup(6);
var accbuf = Buffer.alloc(s, 6);

OSCdef(\accMob,{
	arg msg;
	//msg.postln;
	xdataMa = msg[1].linlin(-10, 10, 0, 1);
	ydataMa = msg[2].linlin(-10, 10, 0, 1);
	zdataMa = msg[3].linlin(-10, 10, 0, 1);
	accData[0] = xdataMa;
	accData[1] = ydataMa;
	accData[2] = zdataMa;
	accbuf.loadCollection(accData);
}, '/accxyz', recvPort: 57120);
)

I was getting the error described in this post: Temp-file throws ‘Forma not recognised’ error. Despite of the error, the code still worked. To get rid of the error I realized that I have to create a temporal “copy” or an instance of the buffer, which I reckon is kept in the temp folder. So, the code becomes as following:

(
var accData = 0.dup(6);
var accbuf = Buffer.alloc(s, 6);

OSCdef(\accMob,{
	arg msg;
	//msg.postln;
	xdataMa = msg[1].linlin(-10, 10, 0, 1);
	ydataMa = msg[2].linlin(-10, 10, 0, 1);
	zdataMa = msg[3].linlin(-10, 10, 0, 1);
	accData[0] = xdataMa;
	accData[1] = ydataMa;
	accData[2] = zdataMa;
	accbuf = Buffer.loadCollection(s, accData);
}, '/accxyz', recvPort: 57120);
)

Apparently there were no errors. However, 10 seconds after executing the code, I got the following error:

The preceding error dump is for ERROR: No more buffer numbers -- free some buffers before allocating more.

Everything stop working. I increased the number os busses in the server: s.options.numBuffers_(10000);, which only delay the error. I reckon the memory of the server must be filled because it is creating temporal Buffers at the rate of the OSCdef. How can I free “temporal” Buffers? Perhaps I’m missing something basic. How could I get this working properly?, How does the copy of data from an array to a buffer function?, thanks

pd. I realized that there is access to the Cached Buffers. However there is no method to erase the ones that has been already used, they can be accessed just by number, not by name and they are removed from the cache when the Buffer is freed.

Since you’ve only got 3 data points you could use setn

b.setn(*msg[1..3].linlin(-10, 10, 0.0, 1.0)).

Hi,

thanks for the answer. The problem is that I have others patchs that have way more than 3 data points, I mean like 1500. Basically, I realized of the error with this one that is using less data.

Hey,
it seems that your solution works also with more data. Thanks!!!

Here, you’ve already allocated a buffer. So there is no need for the OSCdef to allocate new ones.

It’s perhaps a subtle point, but, be aware of the difference between class and instance methods. Buffer’s class methods make new buffers (with perhaps a few exceptions). If you want to reuse an existing buffer for new data, this is what the instance methods are for. So writing Buffer.loadCollection is already contrary to your intention.

In the help search page, there’s:

loadCollection (2 matches)
* Buffer - Client-side representation of a buffer on a server [Classes]
- Buffer - Client-side representation of a buffer on a server [Classes]

The * one is the class method, not what you want here. The - one has “.loadCollection(collection, startFrame: 0, action)” – there’s no server argument, because the existing buffer already has a server (another clue as to the different purpose).

Btw loadCollection uses temporary audio files on disk for transfer, which is slow (but works for large collections, like 100000 samples). Accelerometer data are probably pretty high-rate; I would avoid loadCollection for this use.

hjh

Thanks a lot for the explanation. It is very useful. Originally, I was using the instance form, that is b.loadCollection(array);, however, I was getting the error File temp could not be opened: Format not recognised. @Jordan solution works great with data of around 1500 elements. I do not think I will get bigger than that.

Hm, based on a quick look at the class def, the filename shouldn’t be just “temp.”

My guess, then, is, if it’s doing very rapid reads and writes on the same filename “temp,” and the data rate is high, then a new incoming message is overwriting the file at the same time the server is trying to read it.

AFAICS each filename is supposed to include a hash, which would be a different filename on successive attempts, but you’re not seeing that (which I can’t explain).

In any case, if setn works, that’s better for high data rates.

hjh

Sorry, my bad, the name wasn’t just temp. I was AFK, so I wrote it from memory. Indeed, the message included a hash, and it was different every attempt.

Anyway, back in the computer I tried again buffer.loadCollection(array); and get the following warning WARNING: Failed to write data, which seems because the data rate. Anyway, it seems that setn works good using high data rates (Accelerometer) and also with large amount of data with lower rate (OF).

p

Last point, for setn, the amount of data is limited by the max size of a UDP packet, which may vary depending on the environment (OS, network etc). In general, it should be fine to send 1500 floats this way, but 15000 would be less likely to work, and 150000, pretty much no.

Glad you’ve got it running!

hjh