10. Introduction to OSC
23 Jan 2018Overview
Open Sound Control, frequently referred to simply as OSC
, is a communication protocol for sending information across a computer network of some sort. OSC is an incredibly important component of SC, as SC is comprised of two separate applications (sc-synth
and sc-language
) that communicate with each other over OSC via your computer's internal network. Fortunately one can communicate via OSC
with any other computer on the same WIFI network provided we know that computer's IP Address. What follows is a brief example of sending a message from one computer to another followed by a quick sound making example.
OSCdef
Intro
To receive messages via OSC
one typically uses one of two UGens
in SC
: OSCdef
or OSCfunc
. Note that the structure in SC that we looked at extensively last week, the SynthDef
, has a similar ending to OSCdef
. In both cases def
is short for definition
and refers to the ability to reference the Synth
, or OSC
, objects by name. This naming feature is an important tool for our organizational purposes so I strongly urge you to focus on OSCdef
for all message receiving purposes over a network.
Format
OSCdef(\sine, { | msg, time, addr, recvPort|
msg.postln;
}, '/sin');
Above is the basic format for an OSCdef
. Note the following:
- Similar to a
SynthDef
, the first important piece of information we need to give to SC is the name of thisOSCdef
, which must be prepended with a\
. In this example the name, or definition on the server, of the OSCdef is\sine
- The name of the
OSCdef
is followed by a comma and then afunction block
(remember, anything between{...}
is a function and we often refer to a complete function as ablock
) which defines what this particularOSCdef
does when it receives a message. This structure still closely resembles the structure of aSynthDef
. - Next we define arguments between bars. The argument to focus on here is
msg
, the others you probably will not need to actively use. - Currently the only thing that happens in the function block is a
.postln
statement. In other words, all this OSCdef does currently is display whatever message it received in thepost
window. - Finally we have the
path
, a symbol that defines the label for this particular message. Here our OSCdef will only respond to messages that begin with'/sin'
. Note that thepath
contains both single quotes and a/
.
NetAddr
Format
~x = NetAddr([IPADDRESS], 57120);
~x.sendMsg('/sin', '/play');
In the above example I define a NetAddr, or a destination computer on the network, and then send a message to it. Note that the values in parens are both strings
prepended with a /
. As we have it above, the full message will be: /sin/play
.
Simple Network Communication
Get into groups of 2 for the next demos.
Demo 1: General Message Communication
// receives the message
OSCdef(\hello, { | msg, time, addr, recvPort|
msg.postln;
}, '/greeting');
// sends the message
~x = NetAddr([IP ADDRESS], 57120);
// try this one first
~x.sendMsg('/greeting', "hello");
// then try this one
~x.sendMsg('/greeting', '/hello');
// and finally this one (multiple times)
~x.sendMsg('/greeting', { rrand(20, 50).asFloat }.value);
Demo 2: Sound Control Over the Network
Receiver Example Code
// setup
s.boot;
// the example synth that will be controlled. note the standardized arguments: amp, freq, trig
SynthDef( \sin, { | amp = 0.0, freq = 440, out = 0, trig = 0 |
var env, sig, finalSig;
env = EnvGen.kr( Env.asr( 0.001, 0.9, 0.001 ), trig, doneAction: 0 );
sig = SinOsc.ar( freq, 0.0, amp );
finalSig = sig * env * 0.6;
Out.ar( out, Pan2.ar(finalSig) );
}).add;
// run the synth (note that the envelope is still set to 0 so we hear nothing
~x = Synth( \sin, [ \freq, 400, \amp, 0.5]);
// receive messages from another computer to change Synth at ~x
OSCdef(\sinResponder, { | msg |
msg.postln;
switch( msg[1],
'/play', {
"play sin".postln;
~x.set(\trig, 1);
},
'/run', {
~x = Synth( \sin, [ \freq, 400, \amp, 0.5]);
},
'/stop', {
"stop sin".postln;
~x.set(\trig, 0);
},
'/vol', {
"vol"++msg[2].postln;
~x.set(\amp, msg[2].asFloat );
});
}, '/sin');
Sender Example Code
s.boot;
/*
step 1: get the other computer's IP Address,
store it in a global variable (FYI these are
technically called Environment Variables in SC)
*/
~ip = "";
// pass the IP to a Net Address Object, store it to the variable ~x
~x = NetAddr(~ip, 57120);
// sending messages
~x.sendMsg('/sin', '/run');
// turn the other computer's sin on
~x.sendMsg('/sin', '/play');
// turn the other computer's sin off
~x.sendMsg('/sin', '/stop');
// change the other computer's sin's volume (try different numbers between 0.0 and 1.0)
~x.sendMsg('/sin', '/vol', 0.1 );