Max CRISIS: I'll pay 2000$ for a non-buggy, more stable version of Max.
I'm having a Max crisis. I'm angry. Every fucking time i put any patch i did into a poly~, it ends up with entire days of nightmares of bugs and strange behaviors before i figure out - in case i do - which way i can make things work. Every week of work i have strange behaviours needing hours/days of work before figuring out that it was just one of thoses underdocumented strange unlinear max weirdness. Or my Max 6.1.6 is crashing/not responding/audio-blocking-needing-restart all the time. Either because i'm going over the cpu for few seconds, or just because i'm guilty of using huge patches.
But if Max is mostly for making very small gliky patches for avant-garde parties, then i don't know what i'm doing here.
I just lost 2 DAYS of work of 2 PEOPLE (Me and a developer that i pay) trying to figure out why we had clicks all over the place each time we open a second voice in a big poly~…
...Until we realized tonight that it's JUST BECAUSE 'parallel' poly~ got buggy since Max 6!...
(See other topic: https://cycling74.com/forums/clicks-and-crazy-behavious-using-upsampling-and-parallel-in-poly/ ) But it's not the end, we still have buggy behaviours in some cases, that are not happening when the patch is not inside a poly~, having no idea what's going on...
Not to mention that the last 3 month working on my project with 2 other developers have been spent on redesigning the whole structure of it... Just because it's somehow impossible to know from java (mxj) when an abstraction inside a bpatcher containing mxj's has really finished lo load. (Problem that we only understood the dimension after the whole patch got really big) And we still have Big issues of java/C bridge efficiency, mostly because we can't directly connect to a [receive] max object from an mxj like it's possible to do from a C external.
I already spent 100000 Euros on the most ambitious and inspiring project and i'm gonna soon look for new C/java/(max?) developers to join us… ...but i'm bored to loose my money on the buggy/closed software that max is. Maybe I'm just at the wrong place. Maybe I should forget about Max and go 100% C for our complex project, we would need A LOT of work to do/maintain the UI and the sound synthesis, but maybe we would save more time stopping to try to connect awkwardly little unstable pieces of max, msp, jitter, java and C together.
Doing research in musical acoustics, experimenting musical instruments, all being about real-time sound, images and gestures interfaces, Max seemed to be the tool to develop my project since 11 years I'm using it. But Maybe it's just too unstable to built the heavy research tool we are designing.
So when Cycling will decide to double its team to make a non-buggy, stable, more logical version of max, and with all the details of the every objects correctly documented, then i really don't paying that 'Gold Version of Max' 2000 $ if you want. Really. It will save us a lot of time. Time is money.
Thank you,
Cheers,
Alexandre
Impossible to comment on the specifics of what you're saying - although I do have some opinions on Max 6 stability - but I thought I might let you know that it is, indeed, possible to communicate directly to a [receive] object from within mxj. Try the MaxSystem.sendMessageToBoundObject() method.
From the javadoc:
public static boolean sendMessageToBoundObject(java.lang.String sym_name,
java.lang.String msg,
Atom[] args)
This method provides and easy way for mxj objects to communicate with other max objects or libraries written in C by passing messages. Objects must be bound to the s_thing of a global symbol generated via a call to gensym. Messages cannot be declared as A_CANT since typedmess is used for the dispatching. Returns true on success, false otherwise. IN C:
void main(void)
{
...blah
addmess((method)my_obj_setstate, "setstate", A_GIMME, 0)
..blah
}
t_my_obj *x;
blah blah...
gensym("__my_special_lib__")->s_thing = (t_object *)x;
IN JAVA:
private static final String LIBNAME = "__my_special_lib__";
private static final int STATE_INIT = 0;
private static final int STATE_ACTIVE = 1;
blah blah..
public void setBackendState()
{
Atom[] args = new Atom[1];
args[0]= Atom.newAtom(STATE_INIT);
boolean res = MaxSystem.sendMessageToBoundObject(LIBNAME,"setstate",args);
...
}
Args can be null if message takes no arguments.
Parameters:
sym_name - the symbol to which the object is bound
msg - the message to pass
args - arguments to pass with the message
Returns:
true if message was sent successfully.
Software comes with bugs. They get fixed when users report them. You don't wanna know how many I reported. Even the hugest companies can't deliver 100% bug free programs. That's just the nature of it.
If you wanna be in full control, not having to wait for C74 to fix things, than yes, you should develop your own tools from the ground up (though you might still encounter compiler bugs...). As you already stated, that opens up a whole new can of worms when you're not a hardcore coding ninja. But for large projects with sufficient funding and expertise it can make sense.
That being said, I do develop sizable applications with Max that go well beyond your average MSP synth or cam tracking patch. It's got its quirks and I need to find my workarounds from time to time, but it works for me.
Btw, how many developer hours does $2000 cover? I'm afraid not very much compared to the hours that go into developing a massive tool like Max.
but I thought I might let you know that it is, indeed, possible to communicate directly to a [receive] object from within mxj. Try the MaxSystem.sendMessageToBoundObject() method.
This method does work as you describe, but it is not useful if you have to send many messages frequently are are concerned about performance (it will be much slower than some of the overloaded outlet(…)
methods).
In general, any of the methods that send stuff across the JNI as Java Atom
will be slow as you are sending references to Java objects that require another cross of the JNI barrier to inspect these objects for their values. Also, compared to sending a message followed by an array out an outlet, this method passes an extra string as the name of the bound object and this—or really any strings you send across the JNI—must be converted to a symbol with a call to gensym(C74_CONST char *s)
(this function is not very fast). So if performance is concerned, the combination of sending an array of Atom
across the JNI and an extra symbol to generate makes this method not an option compared to using an overloaded outlet(…)
method.