Forums > MaxMSP

Java, JavaScript or C


Mar 19 2013 | 4:47 pm

Hey,
which language would u suggest for programming externals for max/msp?
i’m using Java for the moment but there seem to be serious CPU problems with Java externals within max.
i’d especially like to programme my own externals for using the kinect.

thanx
P

Mar 19 2013 | 5:38 pm

C!!!
– no, seriously, JavaScript is easier… but if you can write some Java then you’ll have no problem with learning C, the Max API is somewhat trickier but if you have performance problems you’ll see the difference!

my 2 cents…
aa

Mar 19 2013 | 5:43 pm

okidoko…thanx a lot…that’s what i heard, too. C is the solution, C it will be ;-)


Lee
Mar 19 2013 | 6:45 pm

it really depends on what you want to do, if you need raw cpu power then C or Java, the call into Java is more expensive that a call into C, but the externals don’t have to be compiled for mac and windows as they run in the JVM… then again, Javascript can directly script gui elements without having to break into MAX, but won’t run as fast as C/Java (tho over time the js interpreters get smarter and faster….)

Mar 19 2013 | 7:00 pm

Hmm, i have a friend who had very, very big CPU problems with a JAVA external he programmed and used in his patcher.
he had crackles in the sound and the patcher crashed regularly – he removed the JAVA stuff and everything works fine.
so he really recommends C….


Lee
Mar 20 2013 | 2:06 am

I use java externals regularly and have no issues, but I don’t do anything audio intensive… Did he try sending his patch to c74 to see if they could identify any issues?

Mar 20 2013 | 10:49 am

Java is pretty fast if you aren’t passing too much stuff over the Java/native boundary (i.e. between Java and Max). If you’re happy having a JVM installed then you can also use Python, Clojure or Ruby.

Javascript doesn’t run in the scheduler, making it (IMHO) only really usable for UI, interaction and housekeeping. If you’re happy with that, then you can also look into ClojureScript (which compiles into optimised Javascript), or CoffeeScript.

Mar 20 2013 | 11:18 am

Your posts seem a bit like when you already had the answer in your mind and just needed some confirmation ;-)

Seriously, it really depends on what you’re doing. The obvious answer is C; however, there are scenarios when, actually, C wouldn’t be the fastest solution IMHO. For example, if you need to achieve something that has a highly optimized third-party solution in Java AND you don’t need to pass too frequently data between Max and MXJ, then you might end up with a more CPU-efficient (hence, faster) solution by using an optimized library in Java compared to the case when you try to build the stuff in C on your own. Development time and maintenance might also affect your decision, since a simple Javascript code for a simple task is much easier to maintain than the code of an external in Java (which IMHO is still easier to maintain than the code of an external in C, but that’s perhaps depending on your coding style and/or development tools as well). This last point is something that you won’t really consider when you create the external, but you’ll just hate yourself when you have to touch the code in, let’s say, two years from now, and you won’t even remember where to start with it…

HTH,
Ádám

Mar 20 2013 | 11:27 am

BTW, my personal experience with Java in Max is that, unless you do some very specific task, there are no serious differences in CPU consumption compared to externals that achieve the same task in C (note that I mentioned ‘achieving the same task’ and not ‘using the same coding solutions’). If there are, that’s usually the symptom of bad design rather than an overall problem with Java. Indeed, to make something efficient, you need to optimize it, and by this I mean, as a first step, that when you design your external you should avoid things that would slow it down unnecessarily. In other words, if the task can be achieved in more than one way (which is usually the situation in complex situations when it is worth to build an external instead of using built-in objects), you should always choose the solution that best suits the actual language and environment.

Mar 22 2013 | 12:32 pm

I didn’t know that — so if I’m sending MIDI data around (in overdrive mode, say) and one of the objects is a js object that processes that MIDI data, that’s going to have a significant impact on real-time performance (other than the actual CPU cycles to process javascript functions)?

—Javascript doesn’t run in the scheduler

Mar 22 2013 | 1:45 pm

Correct.


Lee
Mar 22 2013 | 5:04 pm

Hi Nick, I use js object to talk to live.remote~ objects with no (apparent) issue. seems that this is something i need to be thinking about from your post?

Mar 22 2013 | 5:08 pm

So how are things scheduled in this case? Does the entire event sequence get moved off of the high priority thread at the point when a js object is encountered?

It sounds like I may need to replace a few of my javascript objects with C externals

Mar 22 2013 | 5:32 pm

Correct – calls entering js/jsui get deferred to low priority.

For better timing accuracy you could look at something Java-based, although then you have the overhead of spinning up a JVM and sending stuff across the JNI boundary. I’ve sequenced with JVM-hosted languages without serious problems.


Lee
Mar 22 2013 | 6:03 pm

I’ve never had problems running in js or java either – I guess overall if it isn’t affecting the high priority stuff that is going on then the only cost is extra cpu cycles of crossing the boundaries – this may become more apparent on lower spec machines, buy maybe as the js/java execution environments get better over time this becomes less of an issue… from conversations i’ve had with c74 guys, the gap between the overall performance of js and java is getting smaller over time….

Mar 22 2013 | 7:46 pm

Apart from real-time stuff, this would explain some very anomalous behavior I’ve experienced for several years with my system, some of which I’ve reported on the forums, related to how does one know when a VST has finished loading.

It turns out that I am using a Javascript based dictionary for persistance and so I have a few objects that are used to load VSTs and configure their parameters. When I first built this and tried to play notes as soon as it seemed VSTs were loaded, I had many problems and so had to introduce several seconds of artificial delay.

If that javascript object is causing the entire loading process to be defered, such that regular event processing continues immediately, that would completely explain the problem.

It would also explain why it seemed to take longer to load a VST in my environment than if I just load one raw in a simple patcher.

This is VERY useful info.


Lee
Mar 23 2013 | 3:05 am

I’d be very surprised if that was due to js… If we put this into perspective, whether we’re in the high priority thread or the lower priority thread, we’re still going to be running millions of ops per second… I’m not sure having to put a several second delay into your patch is due to running in js….

Mar 23 2013 | 4:35 am

It’s not about speed or number of cycles/second.
Deferring the execution changes the order of execution. That can break stuff.

Consider for example the following patcher running in overdrive. The js object simply adds 1 to the incoming inlet and sends out the result. For the very first MIDI event, I would expect (and want) the output (in the max window) to be 3 but in fact I will get 1 because the js object is deferred and so the right inlet of the [+] is still 0


-- Pasted Max Patch, click to expand. --

Mar 23 2013 | 11:27 am

"The first thing to note is that at the time of this writing the Javascript implementation is single threaded and will only execute at low priority. For timing sensitive events the js and jsui objects should not be used for this reason."

Quoted from this article

http://cycling74.com/2004/09/09/event-priority-in-max-scheduler-vs-queue/

Unfortunately such essential info is not mentioned in the standard documentation.

Mar 23 2013 | 12:35 pm

well, actually you can set
immediate = 1
in your javascript code. this will allow your methods to run in the scheduler. not everything can be made immediate (no scripting, no UI iirc) but as long as it’s just plain computation you should have no problems.

hth
aa

Mar 23 2013 | 12:40 pm
Mar 23 2013 | 12:45 pm

… but in the Max6 doc is stated
Note: Immediate mode has been deprecated as of Max version 6.0.

… ok, forget about that! and then, frankly, C is soooo much better… ;)


Lee
Mar 23 2013 | 1:03 pm

I would definitely go C or Java if possible, unfortunately I’m doing m4l stuff so need js to talk to the LOM…..


Lee
Mar 24 2013 | 5:37 am

dhjdhjdhj, i see your point… you could always defer the input in this case – midi is control rate, not audio rate after all….

Mar 24 2013 | 11:49 am

But I think if you defer the midi input, scheduling at control rate (1 ms) is not applied anymore which may result in unpredictable latency.

Mar 24 2013 | 12:02 pm

Defering MIDI processing is not an option. MIDI event processing has to be done in real time otherwise the results will be very sloppy.

The solution (for me) will be to rewrite my javascript routines as C (or C++) externals.


Lee
Mar 24 2013 | 1:32 pm

yup…

would like to know what issued caused c74 to drop the ability of running js in the high pri thread…..

Mar 24 2013 | 1:42 pm

HI !

@Lee
It might be due to dynamic memory allocation , garbage collection that might introduce some memory leaks as JS might be clearing itself slower , but thats just a dirty guess


Lee
Mar 24 2013 | 1:49 pm

yeah, i would think something along those lines, would be interesting to know exactly what tho….

Mar 24 2013 | 2:46 pm

The Javascript engine doesn’t support multithreading. (It’s not an issue with garbage collection; there are many GC’d languages which multithread happily; in fact, it often helps to run the garbage collector in its own thread.)

Mar 24 2013 | 2:48 pm

Have a look at Rhino (the JS engine for the JVM); this might run JS code at high priority.


Lee
Mar 25 2013 | 3:42 am

which js engine is currently used? I read somewhere it was SpiderMonkey… are you saying that it is Rhino or just to take a look at Rhino?

Mar 25 2013 | 9:47 pm

Rhino is the pure-Java Javascript engine in Java 6. It seems to support multithreading:

https://developer.mozilla.org/en-US/docs/Rhino/Scopes_and_Contexts

It might therefore work at high priority (as well as in the UI thread).

Mar 25 2013 | 10:00 pm

I’ve been experimenting with the "immediate" stuff in Max 5.1.9 and it completely solves the issues for which I had used artificial delays and defers as hacks.
However, even though I’m not able to switch over to Max 6, I’ve made sure so far that all my patchers do work in 6. If I start using "immediate", I’ll break that migration path.
Is there something different I have to do to get the high priority behavior with Max 6 and Rhino? If so then I’ll just isolate my changes as much as possible.


Lee
Mar 26 2013 | 1:48 am

Can someone from c74 pls shed some light on this and also why the behaviour was changed between 5 and 6 – seems like a bit of a backwards step…

Mar 26 2013 | 12:49 pm

Rhino as engine in Max would be awesome. This would enable us to use the Max 4 Live API within Java too (same for all the other JS APIs in Max). This would allow some really cool coding.

Mar 26 2013 | 2:59 pm

I doubt it. The native Javascript will have been extended specifically with C linkage for the LiveAPI (as for patcher access, Dict, Sketch, MGraphics and so on). Rhino would only have access to anything that the JVM has access to.


Lee
Mar 26 2013 | 11:52 pm

Also, if calling js caused a crossing from max into java it would make it more expensive to call…

Feb 29 2016 | 3:28 pm

DHJ wrote:

>>
Apart from real-time stuff, this would explain some very anomalous behavior I’ve experienced for several years with my system, some of which I’ve reported on the forums, related to how does one know when a VST has finished loading.
<<

I’m getting a little annoyed that every time I discover something not working as I expect in MAX, either you’ve had the same problem 2 years earlier, and nothing as been done in the interim to improve it– or worse yet, your workaround has been deprecated.

Let me understand: If I want midi processing in high priority in max7 via scripting, my only option is writing my own C or C++ externals? Any scripting based on the JVM ( i,e.Java, Ruby) will introduce latency in the MIDI path?

Such horrible news. I hate doing MIDI processing with max objects, and have been so much happier with JS. But I am having exactly the same problems with loading VSTs, and apparently I can look forward to problems with my MIDI processing as well.

Starting to feel like I have wasted a lot of time and $$ with Max. Should have spent that time learning C++, and Juce.

Viewing 39 posts - 1 through 39 (of 39 total)

Forums > MaxMSP