OSC Connections

Connecting processes: Open Sound Control

What is Open Sound Control (OSC)?

Figure: Wright, M., & Freed, A. (1997). Open SoundControl: A New Protocol for Communicating with Sound Synthesizers. https://doi.org/10.1007/BF02702378

How to configure processes for exchanging data via OSC

SuperCollider: Send OSC

// Some code
~processing = NetAddr.new("127.0.0.1", 12000);  
// Create a network address object ~processing, targeting a program 
// on localhost ("127.0.0.1") at port 12000. This is used to send messages 
// to other processes that listen on this address and port.

~pitchsize;  
// Declare a global variable ~pitchsize, which will store a random pitch value later.

(  

{
  var sig;  
  // Declare a local variable sig that will store the sound signal.

  ~pitchsize = exprand(100,1000);  
  // Assign ~pitchsize a randomly chosen value between 100 and 1000,
  // with an exponential distribution (more smaller values).

  //sig = SinOsc.ar(exprand(50,1000)!2);  
  // (Commented out) Generates a stereo sine wave with randomly chosen frequencies 
  // between 50 and 1000 Hz (using exprand again), but this line is not active.

  sig = SinOsc.ar(~pitchsize!2);  
  // Generate a stereo sine wave using the value of ~pitchsize for the frequency 
  // for both left and right channels (!2 creates an array of 2 identical channels).

  sig = sig * XLine.kr(0.5, 0.001, 1, doneAction:2);  
  // Multiply the sine wave signal by a decreasing envelope created with XLine.kr.
  // The envelope starts at 0.5 and fades to 0.001 over 1 second, and when finished, 
  // doneAction:2 will stop the sound automatically.

}.play;  
// Play the function, generating the sound and running the above code.

~processing.sendMsg('/size', 50000/~pitchsize);  
// Send a message to the external program, 
// with the OSC address "/size" and a value calculated by dividing 50000 by ~pitchsize.

~processing.sendMsg('/color', ~pitchsize);  
// Send another message to the external program, 
// with the OSC address "/color" and the value of ~pitchsize.

)

SuperCollider: Receive OSC

s.boot;
OSCdef.new(\oscrec, {  
// Define a new OSC listener named \oscrec. 
// This listener will respond to incoming OSC messages.

    arg msg, time, addr, port;  
    // Declare the arguments for the OSC message. 
    // 'msg' is the incoming OSC message (an array of data), 
    // 'time' is the time the message was received, 
    // 'addr' is the address it was sent from, 
    // and 'port' is the network port it arrived on.

    post('Received message: ');  
    // Print the text 'Received message: ' to the SuperCollider console.

    msg[0].postln;  
    // Print the first element of the 'msg' array to the console, 
    // which is typically the OSC address (e.g., '/ping').

    post('Value: ');  
    // Print the text 'Value: ' to the console.

    msg[1].postln;  
    // Print the second element of the 'msg' array, which is the actual data or value 
    // sent in the OSC message (e.g., a number or string).

}, '/ping');  
// Set the OSC listener to trigger when a message with the OSC address '/ping' is received.

Processing: Receiving OSC

Installing the oscP5 library via the library manager. Documentation of the library can be found at →https://sojamo.de/libraries/oscP5/

import oscP5.*;
import netP5.*;

// Import the oscP5 and netP5 libraries, which are needed for sending and receiving OSC (Open Sound Control) messages.

OscP5 oscP5;  
// Declare an instance of the OscP5 class to handle OSC communication (receiving messages).

NetAddress myRemoteLocation;  
// Declare a NetAddress variable, which stores the remote address (IP and port) for sending OSC messages.

float r = 100;  
// Declare a float variable 'r' to represent the radius of the ellipse (circle). It starts at 100.

color c;  
// Declare a color variable 'c' to store the color of the ellipse.

void setup() {
  size(600, 400);  
  // Set the size of the window to 600x400 pixels.

  oscP5 = new OscP5(this, 12000);  
  // Initialize oscP5 to listen for incoming OSC messages on port 12000.

  myRemoteLocation = new NetAddress("127.0.0.1", 12000);  
  // Set the remote address to "127.0.0.1" (localhost), using port 12000.
  // This is used if you want to send messages, but in this example, we are focused on receiving.

  colorMode(HSB);  
  // Set the color mode to HSB (Hue, Saturation, Brightness) for easy color manipulation.

  c = color(0, 150, 255);  
  // Initialize the color 'c' to a specific HSB value.

  noStroke();  
  // Disable the outline (stroke) for shapes.
}

void draw() {
  background(255);  
  // Set the background to white for each frame.

  fill(c);  
  // Set the fill color to the current value of 'c' (the color of the ellipse).

  ellipse(width / 2, height / 2, r, r);  
  // Draw an ellipse in the center of the window (width/2, height/2) with a radius of 'r'.
}

void oscEvent(OscMessage theOscMessage) {
  // This function is automatically called when an OSC message is received.
  // 'theOscMessage' contains the data from the received message.

  if(theOscMessage.checkAddrPattern("/color") == true) {
    // Check if the OSC message has the address pattern "/color".
    // If true, execute the code inside the block.

    c = color(random(255), 150, 255);  
    // Change the ellipse color randomly using the HSB color mode (random hue, fixed saturation, and brightness).
  }

  if(theOscMessage.checkAddrPattern("/size") == true) {
    r = theOscMessage.get(0).floatValue();  
    // Set the radius 'r' to the first value in the OSC message (this value is expected to be a float).
  }
}

Processing: Sending OSC

In this example we use the library ›controlP5‹ (https://www.sojamo.de/libraries/controlP5/) for the GUI

import controlP5.*;  
// Import the ControlP5 library, which is used to create user interface elements like buttons.

import oscP5.*;  
// Import the oscP5 library, which is used for sending and receiving OSC (Open Sound Control) messages.

import netP5.*;  
// Import the netP5 library, which works alongside oscP5 for networking features like addressing and sending messages.

ControlP5 cp5;  
// Declare a ControlP5 object to manage user interface components (like buttons).

OscP5 oscP5;  
// Declare an OscP5 object to handle OSC communication (sending and receiving messages).

NetAddress myRemoteLocation;  
// Declare a NetAddress object to store the remote address (IP and port) of where OSC messages will be sent.

void setup() {
  size(300, 300);  
  // Set the size of the window to 300x300 pixels.

  oscP5 = new OscP5(this, 12000);  
  // Initialize the oscP5 object to listen for incoming OSC messages on port 12000.

  myRemoteLocation = new NetAddress("127.0.0.1", 57120);  
  // Set the remote address to localhost (127.0.0.1) and port 57120, where OSC messages will be sent.

  cp5 = new ControlP5(this);  
  // Initialize the ControlP5 object to create user interface elements.

  cp5.addButton("Ping").setValue(0).setPosition(100, 100).setSize(100, 100);  
  // Create a button labeled "Ping" using ControlP5, position it at (100, 100), and set its size to 100x100 pixels.
  // When clicked, it triggers the `Ping()` function.
}

void draw() {
  background(255);  
  // Set the background color to white on every frame.
}

public void Ping(int theValue) {
  // This function is triggered when the "Ping" button is pressed.

  OscMessage thirdMessage = new OscMessage("/ping");  
  // Create a new OSC message with the address "/ping".
  
  thirdMessage.add("text");  
  // Add the string "text" to the OSC message as data.

  oscP5.send(thirdMessage, myRemoteLocation);  
  // Send the OSC message to the remote location defined by 'myRemoteLocation' (localhost on port 57120).
}

void keyPressed() {
  // This function is triggered whenever a key is pressed on the keyboard.

  switch(key) {
    case 'a':  
    // If the 'a' key is pressed:

      OscMessage firstMessage = new OscMessage("/pitch");  
      // Create a new OSC message with the address "/pitch".

      firstMessage.add(random(110, 880));  
      // Add a random pitch value between 110 and 880 to the message.
      
      oscP5.send(firstMessage, myRemoteLocation);  
      // Send the OSC message to the remote location.
      break;

    case 'b':  
    // If the 'b' key is pressed:

      OscMessage secondMessage = new OscMessage("/color");  
      // Create a new OSC message with the address "/color".

      secondMessage.add("text");  
      // Add the string "text" to the message.

      oscP5.send(secondMessage, myRemoteLocation);  
      // Send the OSC message to the remote location.
      break;

    case 'c':  
    // If the 'c' key is pressed:

      println("ping");  
      // Print "ping" to the console.
      
      OscMessage thirdMessage = new OscMessage("/ping");  
      // Create a new OSC message with the address "/ping".

      thirdMessage.add("text");  
      // Add the string "text" to the message.

      oscP5.send(thirdMessage, myRemoteLocation);  
      // Send the OSC message to the remote location.
      break;
  }     
}

TouchDesigner: Send OSC

TouchDesigner: Receive OSC

PureData: Send OSC

PureData: Receive OSC

Last updated