poly~ with JS object slows down interface

steve_j's icon

Mods not sure which forum to put this in. Please move elsewhere if appropriate.

Hi all,

i have a weird issue with the poly~ object.

Am calculating some vector angles and distances in a JS object (inside the poly~ sub patch) where it slows the main interface and objects lack responsiveness.

Gating the stream to the JS object reduces this (though not entirely), however it works fine if a version of the poly~ sub patch is open. It also doesn't seem to have issues if the v-sync is disabled.

It doesn't seem to affect the render side of things but is proving a bit of a headache.

Have attached a patch, sub patch and js script demonstrating the issue if anyone can try reproduce it? Or can shed any light on the issue/suggest solutions?

polyIssue.maxpat
Max Patch

polySubPatch.maxpat
Max Patch

jsVectorMath.js
js 0.81 KB

Thanks

Iain Duncan's icon

This is "expected behaviour". The JS object runs in the UI thread, so send it a big chunk of work, and UI activity will bog down. You could break the work up into pieces, or if you can manage with an asynchronous architecture you could switch to Node and have the work done in a separate process with a callback when its done, but other than that, I think you're going to be stuck with it.

steve_j's icon

Hi Ian, thanks for the reply. Makes sense regarding running in the UI thread, what im not sure about is the issue being resolved by opening an instance of the poly subpatch, does this start up a new UI thread for work in the poly object?

In all honesty the script in the JS object is simple enough to easily do with the expr object, so might be a better route, but would still like to get my head around whats going on here.

Thanks again

Iain Duncan's icon

That I don't know, I haven't experimented with running it in poly~. But I'd be interested to find out if anyone else knows!

Iain Duncan's icon

The expr object will definitely run much faster though!

11OLSEN's icon

@IAIN DUNCAN or someone else: can you post an example of using node to create a separate thread for heavy calculations? Would this work to process a buffer~ with js without blocking the main thread?

Iain Duncan's icon

Node scripts run in an entirely different process, so you wouldn't have to do anything to get the calculations out of the Max threads, but I'm not sure how you would get the buffer data to the node script, I've not done that before. You can't just use the regular JS buffer functions as those are only for running inside Max process space. Anyone else know?

11OLSEN's icon

Ok, I understand. I have not played around with node, yet. Maybe it's possible to pass and return buffer data as a float array to a node script? I was just hoping we can finally spawn threads without writing externals. Especially in M4L I don't want to freeze Live if a device does some number-crunching.

Iain Duncan's icon

It would certainly be possible, it just might be really big. What kind of work is it? Another approach, perhaps overkill, is to cook up something that breaks the work up over time, essentially making the equivalent of a thread that yields. One could do this in s4m or js by doing some amount of samples and then setting a clock to pick it back up and repeat after a delay of some ms. I have found this makes a huge difference in my code because audio calculations are so uneven in load that if you defer work over some (not necessarily even big) number of time slices, lots of performance issues disappear. That way you wouldn't have to reach for something like Node where you lose many of your Max integration functions.

Norman Freund's icon

I have a similar problem. I am using the poly~ object for a synthesiser. Initially I handled the polyphony outside of poly~, sending all inputs through the second inlet of poly~ and did some of the number crunching for midi to pitch conversion in a java script object -- every thing went fine.

Then I switched to getting poly~ to do the polyphonic voice allocation by sending the same data through the first inlet of poly~ (but sent as a midinote message), internally using the thispoly~ for voice allocation -- this is where the same java script code caused timing issues, incorrect calculations, calculations done in wrong order -- in short a total freaking mess!

So poly~ and the js object really don't like each other. The whole reason I was using js, was because the calculation intent and code revision was just easier than a spaghetti of cables.

Roman Thilenius's icon

i would not use javascript for anything DSP or sequencing.

LSka's icon

Since you're dealing with Jitter matrices, you can replace js with jit.gen

Iain Duncan's icon

Well anything coming from JS is going to be in the main/UI thread, so I would not be surprised that it causes issues going into the poly space and then being used for sequencing.

I did recently successfully drive some poly objects from Scheme for Max in case that's something you want to try.