Interaction Design WikiSystems Engineering

OSC

The "Open Sound Control" protocol is specifically designed to control multimedia installations in a local area network or over the internet. OSC was original designed to for the data to transported local and over the internet via UDP, but it some software is setup to use OSC over alternative communication protocols. 

Due to its popularity, OSC is often the easiest way to get two or more applications, computers or devices to talk to each other.   

Tools

Processing Examples 

If values are to be passed from Processing to other applications (e.g. Max MSP) or if values from these programs are to be received in Processing, we can use the Processing Library oscP5 (http://www.sojamo.de/libraries/oscP5/ ). This must also be downloaded and then placed in the library folder of Processing.

In order to send values to another computer via OSC, we must first import the library:

import oscP5.*; // oscP5 Library import
import netP5.*; // netP5 Library import
 
OscP5 oscP5; // Define osc object
NetAddress remoteLocation; //  Define goal address

In the next step we initialise the library and set the target address:

void setup() {
  oscP5 = new OscP5(this, 12000); // Start the library and wait for incoming messages on port 12000
  remoteLocation = new NetAddress("172.31.224.73", 12000); // The IP address and port of the recipient
}

Now all we have to do is create messages and send them to the destination address:

void mousePressed() {
  OscMessage msg = new OscMessage("/test"); // new message "/test" as Adresse pattern
  msg.add(123); // send a simple value
  oscP5.send(msg, remoteLocation);  // Send the message 
}

To receive messages we can add the following code:

void oscEvent(OscMessage msg) {
  println("### new message");
  println("AddrPattern: " + msg.addrPattern()); // Output of the address pattern
  println("TypeTag: " + msg.typetag()); // Output of the  Type-Tag
 
  // Adresse pattern test
  if(msg.addrPattern().equals("/test")) {
	// Output the number sent
    println(msg.get(0).intValue());
  }
}


P5js Examples 

Currently it's not possible to use UDP communication from javascript running in the browser. However, we can use websockets. 

First download the OSC browser library and added it script import to the document head in your index.html.

  <script language="javascript" type="text/javascript" src="../osc.min.js"></script>

In your p5j sketch, add the following code: 

const port = 8025;
const osc = new OSC();

setup() {
// setup OSC receiver
  osc.on('/text', msg => {
    handleMessage(msg);
  }
  );

  try {
    osc.open({
      port:
        port
    }
    );
  }
  catch (e) {
    console.log("Could not connect: " + e);
  }
}


function handleMessage(msg) {
 console.log((msg.args[0]); // print the 1st message item out to console
 console.log((msg.args[1]); // print the 2nd message item out to console
}


Arduino 

OSC can also be used on Arduino. Just make sure you're wifi (or ethernet) connected Arduino device is on the same network as your receiver/sender application. This example is complatable with the Arduino Uno Wifi, and the MKR1010 IOT. 

#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include <OSCMessage.h>
 
// WiFi stuff
const char* ssid = "Your Router";
const char* pwd = "Your password";
 
WiFiUDP Udp;                 // instance of UDP library
const int remotePort = 8000; // port to which you want to send
 
//fill in the IP address you want to send to:
char remoteAddress[] = "10.0.1.3";  // you will need to enter the IP address of the router here.
 
 
void setup() {
  Serial.begin(9600);
  //   while you're not connected to a WiFi AP,
  while ( WiFi.status() != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println (ssid);           // print the network name (SSID)
    WiFi.begin(ssid, pwd);   // try to connect
    delay(2000);
  }
 
  // When you're connected, print out the device's network status:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  Udp.begin(remotePort);
}
 
void loop() {
    int sensor = analogRead(A0);
    //the message wants an OSC address as first argument
    OSCMessage msg("/sensor/");
    msg.add(sensor);  
    Udp.beginPacket(remoteAddress, remotePort);
    msg.send(Udp); // send the bytes to the SLIP stream
    Udp.endPacket(); // mark the end of the OSC Packet
    msg.empty(); // free space occupied by message
    delay(100);
}