OSC support in Max6

Thijs Koerselman's icon

First of all congratulations on Max6 and thank you for this major update!

I think it is silly that the first thing I had to do in order to work with Max6 was install some OSC externals. Isn't it about time that Max6 natively has an object with OSC-route functionality? From all the applications that support it I would expect Max to be on top really. And compared to a lot of the fancy stuff in Max6 it appears to be such a basic thing.

Maybe am I overlooking some recently added features that allow me to natively route OSC in Max6?

Spip's icon

+1

Same surprise here…

Liang's icon

+1

expecting new update :)

Rodrigo's icon

Is there a way to get OSC-route type routing using just vanilla objects? (a bunch of sprintf type objects?)

I've been trying to go 'external free' and [OSC-route] is holding on tight!

spectro's icon

[regexp] is likely a better alternative to [sprintf] for OSC style message parsing/routing. As for it covering other aspects/features of [OSC-route] I couldn't say without spending some time with them...

Rodrigo's icon

Sorry, that's what I meant. Actually, both of those fall under "mystery objects" for me as they both seem to do crazy voodoo stuff, but that's neither here or there.

The only thing I use OSC-route for is just like the vanilla route object, but that doesn't get freaked out by forward slashes.

This is 100% of what I use OSC-route for (and I'm sure I'm not the only one):

Max Patch
Copy patch and select New From Clipboard in Max.

spectro's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Well, I am far from a regexp expert (say that fast five times!) , but here is a quick hack. There are probably quite a few ways to skin this cat and here I have taken the easy way out by additionally stripping the last forward slash before sending to route.

Rodrigo's icon

That looks awesome....

Having a look through my (gigantic) main patch to make sure there's no OSC-route specific stuff, but I think I can just drop that in in place of all the rest. (only thing I've seen so far is long string messages, but those are only on the output going through a prepend and udpsend.

As the OP noted, it is weird that this isn't built into max (as in an OSC parsing object)

pid's icon

a guy called james drake wrote a javascript for that:

// oscroute.1.0
// James Drake
inlets = 2;
outlets = jsarguments.length;

var jsargs = arrayfromargs(jsarguments);

function anything() {
    var args = arrayfromargs(arguments);
    if(inlet == 0) {
        var matched = 0;
        for(i = 1; i < jsargs.length; i++) {
            if(messagename == jsargs[i]) {
                outlet(i-1, args);
                matched = 1;
            } else if(messagename.indexOf(jsargs[i]) == 0 && messagename.charAt(jsargs[i].length) == "/") {
                outlet(i-1, messagename.substring(jsargs[i].length), args);
                matched = 1;
            }
        }
        if(matched == 0) {
            outlet(jsargs.length-1, messagename, args);
        }
    } else if(inlet == 1) {
        for(i = 0; i 

Rodrigo's icon

That's quite elegant. Being JS based it's also cross platform and futureproof? (ie, should I use this or the regexp version posted above).

Rodrigo's icon

Ok, just discovered that the js solution sucks for timing stuff. I noticed that my OSC stuff was spurty/laggy, and it's a result of this js stuff. (If I replace everything with OSC-route, it doesn't lag behind).

Max Patch
Copy patch and select New From Clipboard in Max.

I tried using the regexp solution above, but found a situation where it doesn't work.

Stephane Morisse's icon

What does the (.+) do in the [regexp] ? I looked at [regexp] help and found this : ' + Preceding character occurs one or more times :
"ba+" matches "ba", "baa", "baaa", but not "b". '
This is even more confusing to me because in the help, there's also this about ( ) : ' Group characters : "Do(n't)?"matches "Do" or "Don't" '
And Max won my heart again with a nice quote from Pierre Desproges in the examples...

pdelges's icon

The . match any char (with the exception of special ones, like cr, space, etc.)
.+ will match a non-empty string, i.e. 1 or more characters (opposed to .* which will match 0 or more chars)

Parentheses will group the characters into a string (this is usefull if you want to substitute a string with another one, you can refer to the matched strings with the %1, %2 ... syntax) that will be sent thru regexp's second output.

For example, the stringWaabXbaaZaba
with this RE:W(.+)X(ba*)Z(.*)

wiill output on the 2nd outlet the list aab baa aba

Rodrigo's icon
Max Patch
Copy patch and select New From Clipboard in Max.

This might actually do the trick. It strips away all / and replaces it with " " so you can just use route for everything else (I'm gonna try implementing this today and see how it goes).

Pedro Santos's icon

Rodrigo, thinking a little more about that solution, the only situation where I guess it wouldn't work is if the OSC names had spaces already... for instance:
if instead of "/multi1/1 0" the message was "/multi 1/1 0", the route object would consider "multi" and "1" separate elements of the message..

It could be solved with the same method by FIRST substituting " " (spaces) with "_" (for instance) and THEN substituting the "/" with " ".

I usually use osc-route, so I don't know how it works performance-wise...

Pedro Santos's icon

Rodrigo, thinking a little more about that solution, the only situation where I guess it wouldn't work is if the OSC names had spaces already... for instance:
if instead of "/multi1/1 0" the message was "/multi 1/1 0", the route object would consider "multi" and "1" separate elements of the message..

It could be solved with the same method by FIRST substituting " " (spaces) with "_" (for instance) and THEN substituting the "/" with " ", or something like that.

I usually just use osc-route, so I don't know how it works performance-wise...

orange_glass's icon
Max Patch
Copy patch and select New From Clipboard in Max.

I've rolled a version of this which uses the same regex approach to adapt the stream to a list for use with the normal router object. Let me know what you think.

Rodrigo's icon

Ok, so I've been working with some more OSC stuff lately, and the solution I was using before (using [fromsymbol @separator /]) doesn't work when spaces are used. So I tried what Pedro said by replacing all spaces with another character and pulling that out at the end using regexp, but I can't get commas to pass through now (even if I do the \, thing).

Has anyone figured out a native object way to deal with regular ass OSC messages?

Max Patch
Copy patch and select New From Clipboard in Max.

Here is my old version and new version side by side, with different message types so you can see where they fail.

Rodrigo's icon
Max Patch
Copy patch and select New From Clipboard in Max.

Ok, this solution works for the three cases I have, but there surely has to be a more elegant native solution.