OSC
Open Sound Control

Protocolo de comunicación que permite que instrumentos electrónicos, computadoras, y dispositivos multimedia se comuniquen entre si en tiempo real sobre una red. El OSC está diseñado para trabajar sobre los sistemas de redes modernos como internet, o en redes locales usando TCP/IP, ethernet y redes inalámbricas. OSC utiliza puertos UDP para establecer conexiones entre aplicaciones y dispositivos. El mismo SuperCollider usa OSC para la comunicación servidor-cliente.

NetAddr(IP, puerto)
Dirección para identificar dispositivos conectados en una red

IP = Internet Protocol. El IP de la computadora a la que queremos enviar datos. Puede ser la misma computadora desde 	donde se estan enviando. Es un número de cuatro cifras separadas por puntos (e.g. 192.164.0.100) que sirve para identificar a cada 	dispositivo en red. Se escribe como string, asi que hay que ponerlo entre comillas. Para mandar datos internamente se usa un ip de regreso : "127.0.0.1" 

puerto = El puerto UDP al que queremos enviar los mensajes. SuperCollider trabaja con el puerto 57120.

Con el método .sendMsg podemos enviar mensajes a esta dirección. La sintaxis es asi: sendMsg(commandName, mensaje1, mensaje2, ...)

Ejemplo : 

e=NetAddr("192.168.9.100", 57120)
e.sendMsg("/conejos", "Blas", "Bugsbunny", "Frank")

OSCresponder(NetAddr, commandName, acción)
Responde con acciones determinadas al recibir un commandName específico de un NetAddr específico.

addr = El NetAddr de donde se quiere recibir. Si queremos recibir de donde sea escribimos nil.

commandName = Un String que sirve como identificador en la distribución de los datos. Se escribe dentro de comillas " " y precedido por una diagonal /. Ejemplo: "/uno".

acción = Una función en donde se especifican las acciones que el OSCresponder llevará acabo al recibir mensajes. Sus argumentos son: 		time, theResponder, message y addr. El argumento message es un array siendo el primer elemento el commandName y el segundo el 		mensaje. Es por eso que normalmente evaluaremos el argumento asi: message[1].

Al declarar un OSCresponder es necesario añadir el método .add al final para que se active. Para desactivarlo recurrimos al método .remove.

Ejemplo 1

Creamos un NetAddr y lo asignamos a una variable. Aqui usaremos n. Primero crearemos una conexión interna por lo que usaremos el IP "127.0.01" y el puerto 57120. Después creamos un OSCresponder y lo asignamos a otra variable, en este caso o. Le pedimos al OSCresponder que reciba del NetAddr n que es el que acabamos de crear. Despues le indicamos que reciba datos identificados con el commandName "/colores". Por último definimos la acción como una función de la manera que ya conocemos: entre llaves y declarando sus argumentos. Al final del OSCresponder escribimos el argumento .add. Podemos comenzar a enviar mensajes a nuestro NetAddr que esta identificado con la variable n con el método .sendMsg. En los argumentos escribimos el commandName al que queremos enviar y desoués el mensaje. Si queremos que el OSCresponder deje de responder le enviamos el método .remove. Podemos tener varios OSCresponder con distintos commandNames, solo hay que identificar el commandName cuando se envíe el mensaje al NetAddr.

n=NetAddr("127.0.0.1", 57120)  //  El IP de regreso y el puerto asignado a SuperCollider.

o=OSCresponder(n, "/colores", {|timepo, responder, mensaje, direccion| [timepo, responder, mensaje, direccion].postln}).add

n.sendMsg("/colores", "rojo")

o.remove

p=OSCresponder(n, "/texturas", {|timepo, responder, mensaje, direccion| mensaje[1].postln}).add

n.sendMsg("/texturas", "terso")

o.add

n.sendMsg("/colores", "amarillo")

Si se desea establecer comunicación via internet hay que conocer el IP externo de nuestro router en casa o donde estemos. Para esto se hace una cosa que se llama Port Forwarding. Cuando tenemos un router que nos conecta a internet éste crea una red local que distribuye el servicio entre las computadoras que tengamos y les asigna un IP local. Con este IP local no podemos comunicarnos via internet. Necesitamos el IP esxterno que es con el que el router se identifica en el mundo exterior. Existen varias páginas de internet que ofrecen el servicio de PortForwarding. Una es www.portforward.com. Después de conocer nuestro IP externo es necesario abrir los puertos para superCollider (57120). Para esto es necesario configurar el router desde la página web de la empresa que lo fabrica. Ahi hay que indicar que "pinche" un agujero en le firewall para que deje pasar los datos. Este agujero es el puerto en cuestión.

Ejemplo 2

Podemos insertar un switch en la acción del OSCresponder tal y como lo hemos hacho con el Tdef, con el SCPopUpMenu y con el MIDIIn.

(
(
SynthDef(\juego2, {|freq2,freq, dur, amp, pan=0|
				var sig, env;
				sig=Pan2.ar(Saw.ar(Line.kr(freq2,freq, dur),amp),pan);//+SinOsc.ar(freq,0,amp/3),pan;
				env=EnvGen.kr(Env([0,1,1,0],[0,dur,0]),doneAction:2);
				Out.ar(0,sig.wrap2(0.24)*env*1);
				}).send(s);
				
);
/*
Synth(\juego2, [\freq, 10, \freq2, 6200, \dur, 0.1, \amp, 0.75])
*/
(
SynthDef(\explosion2, {|freq, dur, amp|
				var sig, env;
				sig=Pulse.ar(freq,0.5,amp);
				sig=LPF.ar(sig,Line.kr(10000,30))!2;
				env=EnvGen.kr(Env([0,1,1,0],[0.01,dur,0.5]),doneAction:2);
				Out.ar(0,sig*env*0.25);
				}).send(s);
				
);
/*
15.do{|i| Synth(\explosion2, [\freq, rrand(20,25)*(1+(i*0.1)), \dur, 0.15, \amp, 0.1575])}
*/

)

(
h=OSCresponder(nil, "/bermejo", {|a,b,c,d|
							c[1].postln;
							switch(c[1], 1, {Synth(\juego2, [\freq, 10, \freq2, 6200, \dur, 0.1, \amp, 0.75])},
									    2, {15.do{|i| Synth(\explosion2, [\freq, rrand(20,25)*(1+(i*0.1)), \dur, 0.15, \amp, 2])}}
								)
							}).add
)

n.sendMsg("/bermejo", 1)
n.sendMsg("/bermejo", 2)

Ejemplo 3

Una aplicación muy util del OSC es la sincronía entre computadoras. Podemos hacer un Tdef maestro que corra en una computadora y que esta mande los pulsos via OSC a otras computadoras esclavas.

(
Tdef(\maestro, {
			  inf.do{|i|
			  		n.sendMsg("/pulso", i);
			  		0.1.wait;
			  		}
			  })
)

(
var array1=[0,4,8,12,14], array2=Array.rand(5,0,15), array3=[7,9];
j=OSCresponder(nil, "/pulso", {|a,b,c|
						   if(array1.find([c[1]%16])!=nil, {Synth(\juego2, [\freq, 10000, \freq2, 6200, \dur, 0.05, \amp, 0.75])});
						   if(array2.find([c[1]%16])!=nil, {Synth(\juego2, [\freq, 100, \freq2, 600, \dur, 0.05, \amp, 0.75])});
						   if(array3.find([c[1]%16])!=nil, {5.do{|i| {Pulse.ar((i*2).midiratio*[60,62,64,66].choose.midicps,0.5,1/5)*Line.kr(1,0,0.4,doneAction:2)}.play}});
						   if(c[1]%4==0, {{var freq=[0,3,5,7,10].choose.midiratio*32.midicps;Pulse.ar(freq,0.5,1/2)+SinOsc.ar(freq)*Line.kr(1,0,0.4,doneAction:2)}.play});
						   }).add
)

l=Tdef(\maestro).play
l.stop