Processing Practice #01 | OSC

Contents

  1. OSC
  2. Setup
  3. Receive
  4. Send
  5. Communication
    1. Processing <- iOS / Android App
    2. Processing <-> Processing

OSC

OSC is a protocol for communication developed by CNMAT(The Centre for New Music and Audio Technologies) in UC Barkley. As CNMAT says, the feature of OSC is following:

Open Sound Control (OSC) is a protocol for communication among computers, sound synthesizers, and other multimedia devices that is optimized for modern networking technology. Bringing the benefits of modern networking technology to the world of electronic musical instruments, OSC’s advantages include interoperability, accuracy, flexibility, and enhanced organization and documentation.

The protocol of OSC can be roughly divided into 2 parts. One is “Message” and second is “Arguments”. You can give title which indicates its property to sending data as “Message” and value to send as “Arguments”. The protocol of OSC is following:

/<OSC Message> <OSC Arguments 1><OSC Arguments 2>...

And mainly OSC is used with UDP/IP as transmission method. As this transmission methods are basically used for internet communication, you need to define IP address of receiver . You need to define a port number of your software and also input the port number of the software to send for UDP. The diagram bellow is the example of schematic of OSC communication network.

diagram_osc

Setup

Initializing OSC, you need to define port number for receiving and sending. And for sending, you need to point out the target IP address.

<OscP5 name> = new OscP5(this, <your port number>);
<NetAddress name> = new NetAddress(<IP address to send>,<target port number>);

Any number works with your port number.

//import libraries
import oscP5.*;
import netP5.*;

//declare objects for osc
OscP5 oscP5;
NetAddress myRemoteLocation;//target to send

void setup() {
  //initialization
  oscP5 = new OscP5(this, 12000);
  myRemoteLocation = new NetAddress("127.0.0.1", 12001);
}

Receive

To receive data, you need to define function for receiving named “oscEvent”. This function is special function and runs every time you receive data.

void oscEvent(OscMessage m) {
  //any code here
}

And you can get data from OscMessage object named in this case using following functions:

  • m.addrPattern()  –  get the title of message
  • m.typetag()  –  get information of message
  • m.addrPattern(<title>)  –  check if the message have <title> as OSCMessage
  • m.get(<index>).<data type>Value()  –  get certain data at <index> with <data type>

Send

Sending message, you need to declare OscMessage object and add message to send.
Declaration for OscMessage is following:

OscMessage <OscMessage name>  = new OscMessage("/<message title>")

And followings are function for sending messages:

  • <OscMessage name>.add(<data to send>) – add data (OSC arguments) to send to OscMessage
  • <OscMessage name>.clear() – delete all the data in OscMessage
  • <OscP5 name>.send(<OscMessage to send>, <NetAddress object for destination>)  –  send OscMessage to the NetAddress
OscMessage myMessage = new OscMessage("/test");
myMessage.add(123);
oscP5.send(myMessage, myRemoteLocation);

 Communication

Processing <- iOS / Android App

For the iOS / Android App, I used Control(OSC + MIDI). This app is available for iOS and Android.

Before making your phone to connect to Processing, your computer and phone need to be connected to the same wifi network. If you cannot prepare for it, you can use Tethering for Android or network sharing for iOS.

And also you need to configure software setting to tell your phone the location of your computer. Run the app and configure setting as following:

App menu -> Destinations -> "+"

And then fill your computers IP address to first text box and processing’s port number to second text box.

import oscP5.*;

OscP5 oscP5;
PVector p;

void setup() {
  size(400, 400);
  frameRate(25);
  oscP5 = new OscP5(this, 12000);
  p = new PVector(0,0);
}

void draw() {
  background(0);
  ellipse(p.x,p.y,10,10);
}

void oscEvent(OscMessage m) {
  print(" addrpattern: "+m.addrPattern());
  println(" typetag: "+m.typetag());
  p.x = m.get(0).floatValue()*width;
  p.y = m.get(1).floatValue()*height;
}

The code above is for MultiTounchXY in Control(OSC+MIDI).

Processing <-> Processing

import oscP5.*;
import netP5.*;

OscP5 osc;
NetAddress location;
PVector p;

void setup() {
  size(400, 400);
  frameRate(25);
  osc = new OscP5(this, 12000);
  location = new NetAddress("127.0.0.1", 12001);
  p = new PVector(0, 0);
}

void draw() {
  background(0);
  ellipse(p.x, p.y, 10, 10);
  OscMessage m = new OscMessage("/pos");
  m.add(mouseX);
  m.add(mouseY);
  osc.send(m, location);
}

void oscEvent(OscMessage m) {
  print(" addrpattern: "+m.addrPattern());
  println(" typetag: "+m.typetag());
  if (m.checkAddrPattern("/pos")==true) {
    p.x = m.get(0).intValue();
    p.y = m.get(1).intValue();
  }
}