Chuck <=> Browser communication with OSC
17.06.17
As Whole-Play becomes more complex, the need to monitor various values of the composition has increased, and logging to a console is not particularly comfortable. Since I'm a web developer, I thought that creating a UI in the browser would be the best solution for me, so I set out to find a way to make Chuck talk to a browser. Here's my findings, using node.js and OSC.
I'm using two modules: socket.io (to use WebSockets) and osc-web (to provide OSC communication). The information can go from Chuck to the browser or viceversa, for this post I'll just illustrate the first scenario. Here's the step-by-step guide:
- Set up the node application
- Send OSC from Chuck
- Create the web page that will receive the OSC messages
Set up the node.js application
The first thing to do is to set up a a node.js application that will use WebSockets to listen to OSC messages.
- Install node.js
- Install the socket.io module. Simply typing
npm install socket.io
in the terminal will do it. - Install the osc-web module (instructions at https://github.com/automata/osc-web)
- Run the bridge from osc-web, which is located in the /osc-web folder created in the step before. In the terminal:
node bridge.js
.
Note that the bridge.js file in the distribution starts an OSC server for every browser window. I had to change that because I want multiple windows talking/listening to Whole-Play. Now my bridge.js looks like this (credits and big thanks to Joni):
var osc = require('node-osc'), io = require('socket.io').listen(8081); var oscServer, oscClient; oscServer = new osc.Server(3333, "127.0.0.1"); io.sockets.on('connection', function (socket) { socket.on("config", function (obj) { oscClient = new osc.Client(obj.client.host, obj.client.port); oscClient.send('/status', socket.sessionId + ' connected'); oscServer.on('message', function(msg, rinfo) { console.log(msg, rinfo); socket.emit("message", msg); }); }); socket.on("message", function (obj) { oscClient.send(obj); }); });
Now we have a node app running, which can send/listen to OSC messages.
Send OSC from Chuck
The code to send OSC from Chuck changed in version 1.3.4.0. The old classes OscRecv
and OscSend
still work, but it's recommended to use the new support classes OscOut
, OscIn
and OscMsg
. There are samples in the /examples folder of the Chuck installation. I'm only going to cover sending messages in this post, which is fairly simple:
OscOut out; // Prepare the connection out.dest("127.0.0.1", 3333); // choose the host/port that you want // Generate OSC message out.start(messageType); // a string with the message type // Add parameters out.add(myInt); out.add(myFloat); out.add(myString); // Send the message out.send();
Create the web page that will receive the OSC messages
To receive the OSC messages, we'll create an HTML page listening to OSC messages coming from a specific port. Here's the skeleton code:
...
... ...
The handler function receives the OSC message as a parameter, which is an array with all the info from the OSC message. This can then be used in any way you want to modify the web page (in the example I'm just printing the message type to a div).
What next?
You can also send messages from the web page to Chuck. The code in the web page is:
// for messages without arguments socket.emit('message', '/foobar');
// for messages with arguments socket.emit('message', { address: '/foobar', args: ["dummy", 13.1] });
And then Chuck would listen to OSC events:
OscIn oscIn; OscMsg oscMsg; 3334 => oscIn.port; // the port that the HTML page is emitting from, se above // create an address in the receiver oscIn.addAddress("/foobar,sf"); // 'sf' is the arguments: one string, one float //oscIn.listenAll(); // if you want to listen to all messages while (true) { oscIn => now; while (oscIn.recv(oscMsg)) { oscMsg.getString(0) => string type; oscMsg.getFloat(1) => float value; ... } }
Now imagination is the limit: initially I'm creating a graphical interface to show various parameters in Whole-Play (as the music unfolds), but there's endless possibilities about how to manipulate a web page from Chuck, can't wait to mess around with this new e-frienship. :)
0 comments