How to communicate between Max and a Java applet

Edrick's icon

Hi all,

I have been searching the forums for hours now and can't find a topic specifically about this so I will create a new post for it. I apologize if this is covered somewhere else.

My question is, what method can I use to have Max communicate with another program specifically written in Java such as an applet? Don't worry, I'm not looking for a step-by-step guide to do this but I would like to know what to research to make this possible.

More specifically, I would like to be able to have data from a game written in java to communicate with Max so that this information controls the audio in the patch (what the data does to the audio is obviously up to me). What is the bridge that allows that data to flow from the java applet/game to max? Is it OSC? Serial ports?

Any advice would be greatly appreciated. Keywords and methods for me to research or topics dealing with java programming to look into would be awesome since it would help me use the right terminology in my searches.

Thank you.

andymule's icon

There are two (main) routes. You can make your game into a Max External doing stuff like this:
http://pcm.peabody.jhu.edu/~wright/stdmp/docs/WritingMaxExternalsInJava.pdf
and route your data directly into inlets for your applet.

If your program is quite complicated, it's probably better to use OSC and run the two independent of each other, although OSC into hardcode Java is a bit of a headache itself. You probably want to use "JavaOSC". It's hard to find good examples of that too. Here's something I just worked on right now. It stores all data in an OSC message prepended by "/poop" in a string called data

hope this helps. good luck.

public void run() {
        OSCPortIn receiver = null;
        try {
            receiver = new OSCPortIn(PORT);   //port is just int
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        OSCListener listener = new OSCListener() {
            public void acceptMessage(java.util.Date time, OSCMessage message) {
                Object[] args = message.getArguments(); //this is where you pull your data
                if (args.length!=0) {   //this stores all data in a continuous string
                    data = "";                //!! need to not lose data
                    int i = args.length;
                    while (i>0) {
                        data += args[args.length-i];
                        //System.out.println(data += args[args.length-i]);     //debug
                        i--;
                    }
                }
                gfx.hasData = true;    // a flag in my threaded program
            }
        };
        if (receiver != null) {   //this sets up the listener
            receiver.addListener("/poop", listener);
            receiver.startListening();
        }

    }
andymule's icon

that //!! need to not lose data part was a self note, you can ignore that entirely

Jan M's icon

You mentioned the data source is an applet. is it running inside a webbrowser remotely - or do you have it running on the same machine as max?

Jan

Edrick's icon

Thank you very much andymule. I will look into this. I was also told to look into all the mxj objects for this as well but.

The applet would be running on the same machine, Jan. I think the best route would be the OSC route for now since it's an applet developed by someone else. I'm just trying to find ways to grab data from it.

My whole idea is still at such an early stage it's hard for me to be specific. For now I just want to find ways for them to communicate and see what kind of data I can send between the two. After that I can then worry about how to use it.

andymule's icon

It's hard to find examples of this. The best learning tool for me was to look at the test examples in the source code. You might want to do the same.

Here's where my code is at, if it helps. I'm sure it's not the most elegant, but it works and it's fast and fine. ThefromNick.offer()
thing is for an ArrayBlockingQueue
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ArrayBlockingQueue.html
since I'm pretty (very) sure these things run as threads, so you'll want to mind your data management carefully, lest the wrath of thread-gods descend upon ye.

OSCPortIn receiver = null;
        try {
            receiver = new OSCPortIn(OSCPORTIN);
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        OSCListener listener1 = new OSCListener() {
            public void acceptMessage(java.util.Date time, OSCMessage message) {
                if (message.getAddress().equals("/freq")) {
                    ArrayList temp = new ArrayList();
                    Object[] args = message.getArguments();
                    int l = args.length;
                    for (int i = 0; i < l; i++) {
                        //System.out.println("nick: "+(float)args[i]);
                        temp.add((float) args[i]);
                    }
                    fromNick.offer(temp);
                }
                if (message.getAddress().equals("/torso")) {
                    ArrayList temp = new ArrayList();
                    Object[] args = message.getArguments();
                    int l = args.length;
                    for (int i = 0; i < l; i++) {
                        //System.out.println("torso: "+(float)args[i]);
                        temp.add((float) args[i]);
                    }
                    fromKinect.offer(temp);
                }
                if (message.getAddress().equals("/control")) {
                    try {
                        Object[] got = message.getArguments();
                        fromControl.put((String)got[0]);
                        System.out.println("got!: "+(String)got[0]);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };
        if (receiver != null) {
            receiver.addListener("/freq", listener1);
            receiver.addListener("/torso", listener1);
            receiver.addListener("/control", listener1);
            receiver.startListening();
        }