Universitat Oberta de Catalunya

Introducción al protocolo de comunicación Open Sound Control.

Introducción

A menudo cuando queremos desarrollar un proyecto determinado, en función de su complejidad, nos es necesario utilizar distintas herramientas especializadas para ciertos procesos.

Estas herramientas pueden ser tanto software, ejecutables propios o piezas electrónicas de hardware programadas con intencionalidades diversas.

En el terreno de las instalaciones interactivas multimedia, podemos encontrar muchos softwares concretos para trabajar con contenido gráfico y de sonido y, asimismo, dispositivos de hardware para capturar o reproducir imágenes y sonidos, así como para controlar motores o un montaje de luces, por ejemplo.

Autor: Sergi Lario. Diagrama de dispositivos performance distribuida Ultraorbism de Marcel·lí Antúnez.

Entre estos softwares, algunos se centran mayoritariamente en tratar sonido (SuperCollider, CSound, Ableton Live, Reaper…), otros exclusivamente en tratar gráficos (Modul8, Resolume…), mientras que otros engloban ambas funciones (Pure Data, Max/MSP, VDMX, Cinema 4D, Blender, Unity, Unreal…).

En algunas ocasiones necesitaremos utilizar más de un software a la vez para sacar el máximo provecho y rendimiento de cada una de las aplicaciones. En estos casos nos hará falta establecer cierta comunicación entre las aplicaciones y dispositivos para sincronizar procesos.

Los dispositivos externos como cámaras, micrófonos, impresoras, rúteres, joysticks, proyectores… están programados con un firmware que determinan su funcionamiento. Muchos de ellos facilitan la comunicación externa con otros dispositivos mediante un protocolo de mensajes.

Actualmente encontramos protocolos de comunicación propios de los fabricantes, así como otros que siguen estándares que han ido ganando adeptos con el transcurso del tiempo.

Entre los canales de comunicación o los medios físicos más utilizados encontramos los cables puerto serie (RS-232), I2C, SPI, USB, DMX, HDMI o Ethernet y los sin hilos Bluetooth, wifi u ondas de radio.

Protocolos de comunicación

Los protocolos de comunicación son estándares técnicos que establecen especificaciones sobre métodos, procesos y prácticas para implementar el intercambio de mensajes entre aplicaciones, hardware o ambas.

Básicamente definen el formato o nomenclatura de los mensajes que deben intercambiarse, cómo interpretarlos y cómo identificar emisor y receptores de la comunicación. Algunos de ellos tratan el reconocimiento de que la información ha sido recibida correctamente, para poder reaccionar en caso contrario, mientras otros lo ignoran.

Dentro del terreno de las instalaciones interactivas encontramos el uso de distintos protocolos de comunicación útiles para poder sincronizar entre sí aplicaciones software y hardware.

Aunque se trate de un convenio de mensajes, existen protocolos orientados y basados en la comunicación por red IP y otros por transacciones específicas de paquetes de bytes directamente. El hecho de poder trabajar en red entre dispositivos nos permite distribuir los recursos y también facilita la instalación física de los aparatos según convenga.

Entre los protocolos más utilizados en sistemas audiovisuales destacan MIDI, Art-Net, SNMP, los webSockets y OSC.

MIDI

Uno de los protocolos más utilizados históricamente y todavía en la actualidad es el MIDI (Musical Instrument Digital Interface). La mayoría de los fabricantes de instrumentos electrónicos, sobre todo musicales, implementan su propio controlador MIDI y ofrecen la modificación de su configuración en tiempo real.

Aun siendo ideado para transportar datos sobre cables DIN de 5 pines, actualmente existen especificaciones para USB, FireWire y Bluetooth.

Lo encontramos implementado en controladores o instrumentos como teclados, guitarras, pads, mesas de control de audio o de vídeo, etc.

Creative Sound Blaster Live! 1024 soundcard side view (connectors). Brtkr [CC BY-SA 3.0].(https://bit.ly/2pwDUqV)], from Wikimedia Commons.
Example of Standard MIDI Keyboard. Can be plugged into your computer. Drawn by my own. Cachsten [GFDL (https://bit.ly/1fd019p) or CC BY 3.0 (https://bit.ly/1cDjNzd)], from Wikimedia Commons.

Art-Net

Art-Net es una implementación del estándar digital DMX512-A sobre red IP que utiliza el protocolo de comunicación UDP (User Datagram Protocol). Permite la configuración de distintos universos compuestos por nodos distribuidos en red y cuenta con un sistema de suscripción entre ellos para establecer comunicación.

Se utiliza mayoritariamente en sistemas de iluminación, como controladores de tiras de ledes RGB, y también para sistemas de sonido.

Autor: Sergi Lario. ETHRNET / DMX512 Interface OPENDMX ETHERNET by ENTTEC.
Autor: Sergi Lario. ETHRNET / DMX512 Interface DMX512 DECODER by ENTTEC.

SNMP

Simple Network Management Protocol permite el control de distintos aparatos distribuidos conectados a la red. Cada aparato dispone de una configuración en forma de árbol ordenado que determina sus propiedades y valores actuales.

Frecuentemente se utiliza para monitorizar y configurar diferentes equipos electrónicos como televisores, cámaras, proyectores, controladores de vídeo y sonido, etc.

Snmp architecture. An.bellizzi [CC BY-SA 4.0 (https://bit.ly/2ryhTgk)], from Wikimedia Commons.

WebSocket

Los WebSockets, también por red IP utilizando el protocolo TCP (Transmission Control Protocol), facilitan la transferencia de datos de forma bidireccional entre un servidor y diversos clientes.

Mientras SNMP ofrece un grupo reducido de funcionalidades, los WebSockets son más abiertos, en el sentido de que nos permiten idear una lógica de datos más compleja.

La mayoría de los navegadores web actuales soportan este protocolo, y también puede implementarse en software partiendo de un servidor web. Este queda a la espera de peticiones para establecer un hilo de comunicación para cada cliente.

Los servidores web de código libre más populares son Apache HTTP Server, NGINX, Apache Tomcat, Node.js y Lighttpd.

El abanico de usos que ofrece es inmenso, nos permite construir tanto un sistema de chat en línea como un sistema de traducción de mensajes entre un protocolo y otro.

Diagram showing the basic topology of a Local Area Network.

OSC: Open Sound Control

Open Sound Control es un protocolo abierto que define un formato de mensajes que facilita la comunicación entre dispositivos capacitados para recibir o enviar datos por medio de la red, como ordenadores, sintetizadores de sonido y otros controladores multimedia.

Su objetivo es acercar los beneficios de la tecnología de las redes al mundo de los instrumentos electrónicos, aportando un sistema de comunicación flexible, preciso y que permita la interoperabilidad entre distintos dispositivos.

OSC proporciona todo el potencial necesario para el control en tiempo real de sonido y otros tipos de procesamiento de datos.

Actualmente existe un número amplio de implementaciones de OSC, incluyendo entornos de procesamiento de sonido y datos en tiempo real, herramientas web interactivas, sintetizadores de software, lenguajes de programación y dispositivos físicos para medir sensores o controlar actuadores.

La web http://opensoundcontrol.org concentra todo tipo de recursos sobre el protocolo, desde su especificación hasta distintas implementaciones para su uso en diferentes áreas de aplicación.

OSC es fruto de la investigación realizada en el Center for New Music and Audio Technologies (CNMAT).

Escenrario genérico: mensajes, servidores y clientes OSC

A grandes rasgos, OSC se basa en un formato de mensajes que nos permite encapsular la información con valores determinados como argumentos.

Cada mensaje se compone de un literal en forma de URL y una serie opcional de argumentos separados por espacios que son valores. Por ejemplo, si queremos controlar un reproductor de vídeo podemos pensar en mensajes del estilo:

/video/stop
/video/play “/home/floss/Videos/myvideo.ogg”
/video/pause 1
/video/pause 0
/video/setFrame 33
/video/setAtSecond 126.7
/video/rgbTint 255 0 255
/video/playVolumeLoop “/home/floss/Videos/myvideo.ogg” 0.75 “palindrom”

El formato de los mensajes OSC es tan abierto que nos permite idearlos y formularlos a nuestro gusto.

Para poder recibir e interpretar estos mensajes es necesario generar una aplicación llamada servidor OSC. Esta se ofrece para escuchar mensajes OSC, dada su propia dirección IP en la red y un número de puerto, y se encarga de gestionar la comunicación entre las distintas conexiones entrantes.

Para enviar mensajes es necesario generar un cliente OSC. Este, inicialmente, se conecta a una dirección IP y el puerto correspondiente a un servidor OSC. Mientras no se cierre esta conexión, el cliente puede enviar los mensajes que desee. En caso de que el servidor no esté disponible, no será posible realizar la conexión, para lo cual será necesario activar el servidor antes.

El procedimiento habitual es, en primera instancia, iniciar el servidor OSC, pedir la conexión y enviar datos desde el cliente, y cerrar la conexión cuando sea pertinente. En la parte del servidor, a medida que entran los mensajes, se descifran las rutas y agrupan los valores para poder determinar su intención.

En caso de querer que la comunicación sea bidireccional entre dos o más aplicaciones, y así permitir que puedan tanto recibir como enviar mensajes, estas deberán contener un servidor y un cliente trabajando a la vez.

Características generales

Entre las características más relevantes de OSC destacan:

  • Estructura de mensajes dinámica y abierta, parecida a las URL, como por ejemplo /luces/color 255 0 255
  • Transferencia de valores numéricos de alta resolución como argumentos
  • Lenguaje de coincidencia de patrones para especificar múltiples contenidos en un solo mensaje
  • Alta resolución para definir unidades de tiempo
  • Empaquetado de mensajes para ser ejecutados simultáneamente
  • Sistema de consulta para encontrar dinámicamente las capacidades de un servidor OSC y su documentación

Áreas de aplicación

Al ser un protocolo basado en comunicación por la red, el abanico de aplicaciones posibles es amplio, por ejemplo:

  • Instrumentos electrónicos basados en sensores o capacitadores gestuales.

    Para la interacción humana con sensores que detectan actividades físicas como el movimiento, la aceleración, la presión, el desplazamiento, la flexión, las pulsaciones de teclas, el cierre de un interruptor, etc.

  • Mapeo de datos entre aplicaciones o instrumentos.

Para sincronizar y establecer comportamientos causa-efecto entre distintos dispositivos, sin la necesidad de un actor humano.

  • Sistema de control centralizado y compartido entre diferentes actores.

    Para la interacción en tiempo real de múltiples actores sobre una interfaz compartida. Sigue el llamado modelo cliente-servidor de la mayoría de las aplicaciones web.

  • Interfaces web.

Para establecer comunicación y transferir datos desde y hacia una página web.

  • Realizaciones en redes de área local (LAN).

Se compone de un conjunto de dispositivos, frecuentemente computadores independientes, conectados a una red de área local. Cada uno de estos tiene la finalidad de controlar ciertos parámetros del resto de los dispositivos.

  • Realizaciones en redes de largo alcance (WAN).

Para la interacción entre actores dispuestos en distintas ubicaciones físicas (telepresencia).

  • Realidad virtual.

Para la comunicación entre múltiples sensores de realidad virtual, como intérpretes gestuales sobre un mundo virtual compartido.

  • Conversión de formatos de datos.

Convertir un protocolo de datos específico a OSC, dada su facilidad de transmisión por la red y la flexibilidad de formular los mensajes.

Implementaciones destacadas

La web http://opensoundcontrol.org/implementations lista distintas implementaciones de OSC para, entre otros, hardware, aplicaciones software de usuario y también en forma de bibliotecas de lenguajes de programación.

Entre las bibliotecas encontramos implementaciones para lenguajes de programación genéricos, como C, Python o Java, y otras más específicas según el software como:

Processing oscP5
openFramewoks ofxOsc
Csound OSC
Pure Data OSC
SuperCollider OSC

Entre los softwares también podemos hallar secuenciadores OSC como IanniX e interfaces de control remoto como touchOSC.

Generalmente los secuenciadores nos permiten definir y controlar distintas líneas de tiempo compuestas por una serie de eventos asignados a un tiempo determinado. Como si se tratara de una partitura musical, las notas equivaldrían a los mensajes que queremos disparar en un momento preciso. Así, por ejemplo, podemos definir una secuencia lineal de acciones, un metrónomo o una rampa de valores decreciente con aceleración para hacer un fade out.

Autor: Sergi Lario. Comunication between Pure Data and Iannix through osc with a MOTU audio card and a joystick bahia.

Las interfaces de control remoto nos permiten interactuar con aquellos artefactos, cuyos mensajes OSC necesarios para su funcionamiento conocemos. Normalmente se asocian a objetos gráficos como botones (trigger, toogle), barras de desplazamiento (sliders), cajas de texto, pads x/y, etc. Así, podemos asignar un mensaje OSC determinado a cada widget, de manera que cuando sea activado lo envíe por la red.

En la parte de hardware, Arduino también dispone de una implementación oscuino. De este modo, podemos controlar placas Arduino de forma remota y recibir los datos que pueda proporcionarnos.

Sintaxis

Internamente todos los datos que trata el protocolo OSC se componen a partir de los siguientes tipos de datos atómicos:

  • Números enteros int32 (32bit integer).
  • OSCtimetag. Etiqueta de tiempo fijo de 64bit.
  • Números decimales float32 (32bit número de coma flotante).
  • OSCstring. Una secuencia de caracteres ASCII no nulos seguidos por un carácter nulo, seguido por 0, 1, 2 o 3 caracteres nulos adicionales para conseguir un total de bits múltiplo de 32.
  • OSCblob. Una colección de datos iniciada por un int32 que indica su longitud, seguida por muchos bytes de datos arbitrarios, seguida por 0, 1, 2 o 3 ceros adicionales hasta llegar a un total de bits múltiplo de 32.

Paquetes OSC

Son la unidad de transmisión de datos y representa el contenido completo del mensaje. La aplicación cliente OSC confecciona y envía estos paquetes, mientras la aplicación servidor los recibe y los interpreta.

Los contenidos de un paquete OSC pueden ser un mensaje OSC o bien un conjunto de mensajes OSC empaquetados llamado bundle.

Mensajes OSC

Los mensajes OSC utilizan un patrón de direccionamiento iniciado por el carácter de la barra «/» y una serie opcional de uno o más valores como argumentos.

Cada uno de estos valores de los argumentos pueden ser de tipo entero, real, un OSCstring o un OSCblob.

De esta manera podemos idear mensajes, como, por ejemplo:

/audio/off
/audio/pause 1
/audio/pause 0
/audio/volume 0.75
/audio/play “/home/floss/Music/mysound.ogg”
/audio/playVolumeLoop “/home/floss/Videos/mysound.ogg” 0.75 “palindrom”

De forma transparente, las aplicaciones OSC componen internamente los mensajes a partir del patrón de direccionamiento, que es un OSCstring iniciado con «/».

Le sigue una etiqueta que determina los tipos de datos de los argumentos, que es un OSCstring iniciado con «,» y los caracteres: i, f, s o b, para identificar respectivamente si son int32, float32, OSCstring u OSCblob.

Acaba con una serie de 0 o más argumentos OSC (en binario).

Bundles OSC

Los bundles permiten enviar un conjunto de mensajes OSC al mismo tiempo.

Internamente se componen por el OSCstring «#bundle» seguido por un OSCtimetag y, después, por 0 o más mensajes OSC o bundles.

La etiqueta (tag) de tiempo indica cuándo debe iniciarse la ejecución de los mensajes o bundles que lo forman.

Semántica

Espacio de direcciones OSC y direcciones OSC

Los servidores OSC contienen un conjunto de métodos que permiten corresponder los mensajes recibidos a puntos de control determinados para producir el efecto deseado.

El espacio de direcciones OSC es la estructura de árbol que indica los posibles métodos.

La dirección de un método OSC se define por la ruta iniciada en la raíz hasta el nodo final, como si se tratara de una URL.

Ejecución de mensajes OSC y patrones de coincidencia

Siguiendo el sistema de las URL, en el servidor se formulan los patrones de coincidencia para determinar si a los mensajes entrantes les corresponde algún método. Esto sucede cuando:

• la dirección OSC y el patrón de direcciones OSC tienen el mismo número de partes (subcadenas entre las barras « y la parte final después de la última barra), y

• cada una de las partes del patrón coincide con la parte correspondiente de dirección.

Esto sucede cuando se corresponden carácter a carácter, pero también dispone de expresiones regulares, para poder definir mensajes dinámicos, con las reglas siguientes:

? se corresponde a cualquier carácter

* a una secuencia de 0 o más caracteres

[abcd] cualquier carácter especificado

[a-z] cualquier carácter alfanumérico comprendido entre los especificados

[!abcd] no contiene ninguno de estos caracteres

{foo,bar} a una de las cadenas especificadas

Por ejemplo, podemos idear un patrón de coincidencia como /foo/??/bar/*c/ que indicaría que entre las partes «foo» y «bar» debe haber únicamente dos caracteres alfanuméricos cualesquiera y que la parte final debe acabar con el carácter «c».

Temporalización y etiquetas de tiempo OSC

Cuando el servidor recibe un paquete que contiene solo un mensaje OSC, invoca el método correspondiente de forma inmediata. En caso de recibir un bundle, la etiqueta de tiempo determina cuándo debe invocarse el primer método y los consecutivos en el mismo orden de su envío.

Ejemplos cliente y servidor en Processing

La librería oscP5 para Processing facilita generar tanto clientes como servidores OSC y manipular mensajes y bundles de manera sencilla. Al estar ambas basadas en el lenguaje de programación Java, podemos utilizarlas sobre las diferentes plataformas de sistemas operativos más comunes.

El siguiente ejemplo es un simple cliente OSC que envía las posiciones x y del cursor cuando se mantiene pulsado el botón izquierdo del ratón sobre la pantalla, mostrando su representación de puntos visualmente.

import oscP5.*;
import netP5.*;

OscP5 oscP5;
NetAddress myRemoteLocation;
void setup() {
  size(400,400);  
  oscP5 = new OscP5(this,9999);  
  myRemoteLocation = new NetAddress(“127.0.0.1”,12000);
  background(64);
}
void draw() {  
  if(mousePressed) ellipse(mouseX,mouseY, 2, 1);
}
void mouseDragged() {  
  OscMessage myMessage = new OscMessage(“/pos”);  
  myMessage.add(mouseX);
  myMessage.add(mouseY);
  oscP5.send(myMessage, myRemoteLocation);
  println(“send /pos ” + mouseX + ” ” + mouseY);

A su vez, la aplicación servidor OSC siguiente queda a la espera de estos datos y representa también los puntos recibidos en la salida gráfica.

import oscP5.*;
OscP5 oscP5;
int firstValue, secondValue;
void setup() {
  size(400,400);  
  oscP5 = new OscP5(this,12000);
  firstValue = secondValue = -1;
  background(127);
}
void draw() {
  ellipse(firstValue,secondValue, 2, 1);  
}
void oscEvent(OscMessage theOscMessage) {  
   if(theOscMessage.checkAddrPattern(“/pos”)==true) {             
   if(theOscMessage.checkTypetag(“ii”)) {  
   firstValue = theOscMessage.get(0).intValue();
   secondValue = theOscMessage.get(1).intValue();  
   print(“### received an osc message /pos with typetag ii.”);
   println(” values: “+firstValue+”, “+secondValue);  
   return;
}
  }  
  print(“### received an osc message.”);
  print(” addrpattern: “+theOscMessage.addrPattern());
  println(” typetag: “+theOscMessage.typetag());
}

Al estar las dos aplicaciones en la misma máquina, se ha utilizado la dirección IP 127.0.0.1, que hace referencia a la propia máquina. Si nos interesara enviar los mensajes a todos los computadores de una red a la vez, podemos reemplazar el último valor de nuestra IP por un 255, como, por ejemplo: 198.168.1.255.

Conclusiones

Durante los últimos años el protocolo OSC ha sido agregado a la mayoría de las aplicaciones y dispositivos de control de datos en tiempo real y se han generado distintas implementaciones en forma de librería gracias a su versatilidad, apertura y extensibilidad.

Por un lado, OSC permite idear nuestro propio espacio de direcciones de manera semántica y comprensiva, como pasar múltiples datos de una sola tacada. También nos permite distribuir físicamente distintos dispositivos conectados por red y, así, también sus tareas.

Por estas razones, encontramos su uso, asimismo, en el llamado internet de las cosas (IoT por su sigla en inglés), que se basa en la interacción y el intercambio de datos entre los dispositivos de una red en diferentes terrenos como la domótica o la monitorización para estudios metropolitanos.  

A su vez, puede sernos útil para realizar sistemas de automatización de procesos como secuenciadores y también para centralizar y mapear datos entre distintos protocolos de comunicación.

Documentación:

Acerca del autor

Sergi Lario es desarrollador de software, experimentador visual, ingeniero de informática de sistemas y técnico de desarrollo de aplicaciones informáticas. Durante los últimos años ha realizado y colaborado en distintos proyectos como instalaciones interactivas para las artes escénicas, juegos de realidad aumentada y espectáculos audiovisuales, entre otros. Ha participado en diferentes convenciones de entornos de trabajo (frameworks) y conducido distintos talleres de programación: Pure Data, OpenFrameworks, Processing, Python y Open Sound Control... Utiliza herramientas libres tanto para la confección de aplicaciones como para un uso cotidiano. Actualmente dirige su propio estudio de ingeniería de software, Sofiethic, es cofundador y CIO en Broomx Technologies y, también, profesor colaborador en la Universitat Oberta de Catalunya en el Laboratorio de Programación Creativa, transversal a distintas materias del grado de Multimedia.

Deja un comentario