MÓDULO 6: PURE DATA
Utilizaremos el objeto envelope y OSC para enviar información desde otro dispositivo a Pure Data
Envelope
¿Qué conceptos nuevos necesitaremos conocer?
¿Qué es un envelope o envolvente?
El envelope va a determinar la variación de los niveles de una señal a lo largo del tiempo. Para nosotros, va a ser una herramienta que nos permitirá dar forma/esculpir el sonido con el que estemos trabajando, desde su volumen a su frecuencia. En lo que a síntesis de sonido se refiere, el envelope es una curva que nos va a permitir controlar algún parámetro de una señal (Wilczek, 2022). Ya lo hemos utilizado anteriormente, pero de una manera muy sencilla cuando utilizamos el "line~" para suavizar los cambios de volumen en la "Practica 2: nuestro primer patch sonoro". En este caso utilizamos una sola rampa. ¿Os acordáis?
Figura 1. Tortuga deslizándose por una rampa.
Los envelopes se componen por varios segmentos y en cada segmento encontraremos una rampa diferente. Vamos ver el envelope ADSR, que es uno de los mas utilizados. Este envelope consiste en cuatro segmentos: A=attack, D=decay, S=sustain y R=release.
Figura 2. ADSR envelope
El Attack es el segmento en el que el valor aumenta desde el mínimo hasta el máximo que va a alcanzar el envelope. El Decay es el segmento en el que el envelope cae desde el pico máximo que se alcanza en el Attack, hasta un valor que se mantendrá constante en el segmento conocido como Sustain. El Realease es el último segmento del envelope en el cual el valor desciende a 0.
Por ejemplo, utilizaremos el ADSR para controlar la amplitud de una señal, en este caso estaremos dando forma al volumen de esta señal. Aqui teneis un ejemplo de ADSR modulando la amplitud:
En el video anterior podéis escuchar cómo cambia el sonido al modificar el tiempo de duración de cada segmento.
Ahora vamos a aprender como hacer envelopes en Pure Data
¿Qué elementos nuevos de Pure data necesitaremos conocer?
Delay
Este objeto nos va a permitir enviar un bang después de un tiempo de espera determinado. Digamos que nos va a permitir retener y retrasar el envío de un bang.
El tiempo que se retrase el bang lo configuraremos en el argumento del objeto o a traves del inlet derecho. A traves del inlet izquierdo también podemos configurar el tiempo e iniciar el delay, sin embargo cuando configuremos un tiempo a traves del inlet derecho el delay no empezara hasta recibir un bang en el inlet izquierdo Recordar lo que vimos en la lección "Elementos básicos" sobre la entra caliente de un objeto y las entradas frías. Por defecto la unidades son milisegundos, si queremos trabajar con otra unidad como por ejemplo segundos, tendremos que especificarlo en el mensaje que configura el tempo del delay. Si queremos detener el delay enviaremos un mensaje de stop.
Figura 3. patch delay-demo.pd
En la figura 3, el primer delay retrasara el bang medio segundo y el segundo delay 1 segundo. Tras mandar el mensaje configurando el tempo en segundos el tercer delay retrasará el bang medio segundo, si no enviamos ese mensaje configurando el tempo, el delay se retrasará medio milisegundo.
Delay + line
Como vimos anteriormente el objeto "line~" nos permite crear rampas. Crear una progresión lineal desde un valor a otro en un tiempo determinado. ¿Os acordáis? lo vimos en la "Practica 2: nuestro primer patch sonoro".
Figura 4. Tortuga deslizándose por una rampa.
Combinando "delay" y "line" vamos a poder combinar rampas para crear progresiones mas complejas, con diferentes direcciones. Por ejemplo ir de 1 a 0.5 en 500 milisegundos y al llegar a 0.5, ir a 0 en 800 milisegundos.
Figura 5. Combinación de varias rampas.
Vamos a ver cómo crear ahora un envelope ADSR con Attack, Decay, Sustain y Release en pure data, podéis abrir el patch line-ADSR.pd para probar su funcionamiento:
Figura 6. patch line-ADSR.pd
En la figura 4. vemos el patch line-ADSR.pd. Para comenzar el envelope activaremos el bang que se encuentra arriba. Este bang envía el primer mensaje y activa los dos delays. Cuando termina la primera rampa (el ataque) después de medio segundo (500 milisegundos) comienza la segunda rampa, como podéis ver el tiempo que dura la primera rampa y el tiempo del primer delay es el mismo para que justo en el momento en que termine la primera rampa comience la siguiente rampa, la segunda rampa que durara 700 milisegundos. Cuando termine la segunda rampa, habrán pasado 500+700=1200 milisegundos desde el comienzo del envelope. Si quisiéramos que la tercera rampa comenzara inmediatamente después de terminar la segunda configuraríamos el segundo delay con un tiempo de 1200 milisegundos, pero queremos que la señal se mantenga constante durante 3800 milisegundos, asi crearemos la sección de Sustain. Para esto configuraremos el segundo delay con un tiempo superior a 1200 en nuestro caso 1200+3800=5000 ya que 3800 es el tiempo que queremos que dure el sustain. Tras 5000 milisegundos el segundo delay envía el bang que enviará el mensaje con la tercera rampa al line~, comienza el release que en nuestro caso durara 1000 milisegundos.
Ejercicio 1: ¿Cuál es la duración total del envelope en el ejemplo anterior?
Ejercicio 2: crea un patch que genere un envelope con un ataque que vaya de 0.5 a 1 en 300 milisegundos, un decay que baje a 0.7 en 900 milisegundos. Un sustain de 2000 milisegundos y un decay que baje a 0 en 1100 milisegundos. ¿Cuál es la duración total del envelope que acabáis de construir?
Como habéis visto en el video de arriba, el tiempo que dura cada segmento es un parámetro clave para darle forma al sonido. Ahora, vamos a modificar el patch anterior para poder controlar el tiempo de cada segmento, y para ello vamos a introducir una utilidad de Pure data que nos va a permitir modificar el valor o los valores de un mensaje u objeto. Es el símbolo del dólar $.
$
Utilizaremos el símbolo $ para remplazar un valor numérico o un símbolo en un mensaje u objeto. Es una forma de crear una variable que podamos modificar dentro de un mensaje u objeto. Acompañaremos $ con el número que indica la posición del valor en el mensaje u objeto, en ente caso comenzamos a contar en el 1. Si tenemos un mensaje con dos valores, el primero será $1 y el segundo $2. El $1 y el $2 van a ser remplazados por los valores recibidos. Vamos a ver un ejemplo en el patch "variable-dollar-demo.pd":
Figura 7. patch variable-dollar-demo.pd
Si os acordáis habíamos visto que en programación se empieza a contar en el 0, entonces, ¿porque el primer valor variable cuando utilizamos $ lo nombramos con 1? Es poque el $0 tiene otra función, y lo utilizaremos para indicar que un objeto al cual le asignamos nosotros un nombre, como por ejemplo "tabwrite~", array, "send", "receive", ... funcionan e interaccionan solo con objetos del patch en el que se encuentra, es decir tiene un alcance local.
Esto que quiere decir y por qué nos va a ser util? Por ejemplo, teniendo dos patches abiertos con objetos "send" y "receive" nombrados con la misma etiqueta, "send go" y "receive go", lo que envíe el send del patch 1 va a llegar también al receive del patch 2, para evitar esto, colocaremos el $0 al comenzar el nombre de nuestra etiqueta: "send $0-go" y "receive $0-go", así, lo que envíe el "send $0-go" del patch 1 solo llegara al "receive $0-go"del patch 1. Como os podéis imaginar utilizaremos esto para objetos que no están conectados a traves de líneas, como el "tabwrite~" y la interfaz grafica array. En el siguiente capitulo veréis como esta utilizado en los patches.
Ahora que ya sabemos cómo introducir valores variables en mensaje, vamos a modificar el patch anterior para poder controlar el tiempo que dura el attack, el decay, el sustain y el release:
- La duración del primer delay va a ser la misma que la duración de la primera rampa (Attack).
- La duración del Decay sera la duración de la segunda rampa.
- La duración del segundo delay sera la suma de la duración del Attack más la duración del Decay más el tiempo de duración del Sustain.
- La duración del Release sera la duración de la tercera rampa
Recordar que en el objeto suma el inlet derecho actualiza el valor de uno de los sumandos, pero al actualizar ese valor no se emite el resultado por la salida. El objeto + va a enviar el resultado solo cuando reciba un valor o bang en el inlet izquierdo, por eso cuando actualizamos el valor del inlet derecho enviamos también un bang en el inlet izquierdo.
Figura 8. patch line-ADSR-tiempos-variables.pd
Vamos a ver ahora otra manera de construir estos envelopes en pure data utilizando el objeto "vline~".
vline~
Este objeto nos va a permitir construir envelopes combinando rampas de la misma forma que la combinación de delay y line~. De momento utilizaremos solo el inlet izquierdo para configurar los parámetros del vline~, que espera un mensaje con la información de las rampas que ha de realizar y cuando. La información de cada rampa estará separada por una coma, detrás de cada coma indicaremos el valor de destino, el tiempo que tardará en llegar al valor de destino y el tiempo que tardará esa rampa en comenzar desde que empieza el envelope. Si queremos configurar un valor inicial pondremos dicho valor al principio separado de una coma. El mensaje tendría la siguiente forma:
valor-inicial, valordestino-rampa1 tiempo-rampa1 delay-rampa1, valordestino-rampa-2 tiempo-rampa2 delay-rampa2
0, 1 500, 0.8 700 500
Rampa 1, Rampa 2
Para la primera rampa generalmente no pondremos delay porque al ser la primera comienza a la vez que se inicia el envelope. Y el delay de cada rampa es el tiempo desde que empieza el envelope hasta el momento en que queremos que commence esa rampa.
Vamos a ver ahora en el patch xxx como construir el mismo envelope que hicimos en el ejemplo de la figura 5, pero utilizando el objeto "vline~".
Figura 9. patch line-vline-ADSR.pd
Ejercicio 3: Construye el mismo envelope que hiciste en el ejercicio 1 utilizando el objeto vline~
Ejercicio 4: Modifica el patch en la Práctica 2, para ello, utiliza un envelope ADSR con el tiempo de decay variable que regule el volumen cada vez que se reproduzca una nota.
Figuras:
Figura 1. Tortuga deslizándose por una rampa. https://gifer.com/en/cih
Figura 2. ADSR envelope. https://thewolfsound.com/envelopes/
Figura 3. patch delay-demo.pd
Figura 4. Tortuga deslizándose por una rampa. https://gifer.com/en/cih
Figura 5. Combinación de varias rampas. https://giphy.com/gifs/southparkgifs-l0HluCIeReFkeWAQ8
Figura 5. patch line-ADSR.pd
Figura 6. patch variable-dollar-demo.pd
Figura 7. patch line-ADSR-tiempos-variables.pd
Figura 8. patch line-vline-ADSR.pd
Referencias:
Wilczek, J. (2022, Julio 3) Envelopes in Sound Synthesis: The Ultimate Guide. WolfSound. https://thewolfsound.com/envelopes/
Práctica 7: Kick drum y random
Una vez sabemos qué es y cómo utilizar un envelope, vamos a crear un sonido que imita el kick drum de una batería.
Crearemos una version sencilla con los elementos de Pure data que hemos aprendido hasta el momento. Vamos a utilizar dos envelopes, uno para el volumen y otro para la frecuencia. Recordar que hemos visto que era un envelope en la lección anterior.
Envelope que controla el volumen
Figura 1. patch Kick-drum-sencillo-paso-1.pd
Vamos a utilizar un oscilador y vamos a regular su volumen con un envelope utilizando el objeto "vline~". Los parámetros del "vline~" son los que nos van a permitir conseguir el efecto del kick-drum. En este caso nuestro envelope parte de 0.5 lo que va a generar un pequeño golpe, el Attack es muy rápido, va de 0.5 a 0.8 en 5 milisegundos. El Decay mucho más largo que en el attack baja de nuevo a 0.5 en 60 milisegundos. No tendremos Sustain e inmediatamente después del Decay comenzaremos con el Release, que sera la parte más larga de nuestro envelope, bajando a 0 en 400 milisegundos. A continuación veremos el contenido del mensaje que recibirá el "vline~" con los parámetros que configuran cada rampa de nuestro envelope, y una tabla en la que desgranaremos esos parámetros:
0.5, 0.8 5, 0.5 60 5, 0 400 65
Rampas | Valor inicial | Valor Final | Duración (milisegundos) | Delay. Tiempo desde el inicio del envelope, hasta el comienzo de esta Rampa (milisegundos) |
Attack | 0,5 | 0.8 | 5 | 0 |
Decay | 0.8 | 0.5 | 60 | 5 |
Sustain | - | - | - | - |
Release | 0.5 | 0 | 400 | 65 = 60 + 5 |
Ejercicio 5: Abrir el patch Kick-drum-sencillo-paso-1.pd y completar siguiendo las instrucciones que encontrareis a lo largo de la lección para crear un Kick drum. Al archivo que modifiquéis lo llamareis Kick-drum-sencillo-vuestronombre_vuestroapellido.pd
Cuando abráis el patch Kick-drum-sencillo-paso-1.pd, subir un poco el volumen, aseguraros de que el "osc~" está recibiendo un valor con el que vibrar (con activar el "osc~" os he ayudado un poquitito con el objeto "loadbang" que envía automáticamente un bang al abrir el patch). Ahora hacer click en el bang azul del patch. ¿Escucháis algo? ¿Veis cómo se dibuja la onda cada vez que enviáis el bang?
Recordar que, si no tenéis encendido el DSP, Pure Data no procesara señales y ni oiréis ni veréis nada
Cuando enviamos el bang para activar el envelope que controla el volumen, habréis podido comprobar que cada vez suena un poco diferente, al igual que el dibujo de la onda que veis en el array "$0-scope3", que cada vez se empieza a dibujar en un punto distinto. Esto pasa por que la fase de la onda cada vez que activamos el envelope es distinta.
Figura 2. Muchos aros girando con diferentes fases unos de otros.
¿Os acordáis de lo que es la fase? Lo vimos en la lección "Algo de teoría sobre las ondas". Para que suene siempre igual tendremos que inicializar la fase del oscilador cada vez que activemos el Kick drum, haremos esto a través del inlet derecho del oscilador. Podéis probar diferentes valores para la fase buscando el sonido que más os guste:
Figura 3. Añadimos un control de fase al oscilador del patch Kick-drum-sencillo-paso-1.pd
Envelope que controla la frecuencia
Hasta el momento la frecuencia del kick drum se mantiene constante desde el inicio al final del sonido del kick drum, en la figura 3 es de 71 Hz. Para continuar dándole forma al kick drum vamos a introducir un envelope que modifique la frecuencia, siendo mas aguda al principio que al final. En este caso nuestro envelope tendrá tres secciones, la primera un Attack que va de 6 a 2 en 2 milisegundos. La segunda un Sustain que dura 3 milisegundos y la ultima un Release que va de 2 a 0 en 460 milisegundos. En este caso nuestro envelope no tiene Decay.
6, 2 2, 0 460 5
Rampas | Valor inicial | Valor Final | Duración (milisegundos) | Delay. Tiempo desde el inicio del envelope, hasta el comienzo de esta Rampa (milisegundos) |
Attack | 6 | 2 | 2 | 0 |
Decay | - | - | - | |
Sustain | 2 | 2 | 3 = 5 - 2 | |
Release | 2 | 0 | 460 | 5 |
Vemos que la duración del Sustain viene determinada por la duración de la rampa anterior y el delay de la rampa siguiente.
Figura 4. Envelope que utilizaremos para controlar la frecuencia del "osc~" en el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd
En el envelope de la figura 4, tenemos una variación de valores que va de 6 a 0 en 465 milisegundos. Una frecuencia de 6 Hz es muy muy baja y ni la escucharemos ni nuestros altavoces serán capaces de reproducirla. Lo que vamos a hacer es elegir una frecuencia central en torno a la cual se produzca la variación que nuestro envelope controla. Vamos a mezclar esa frecuencia y la señal que genera nuestro envelope utilizando el objeto "*~". Si os fijáis también multiplicamos el resultado del envelope por sí mismo con otro objeto "*~" esto hara los cambios del envelope más pronunciados:
Figura 5. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos añadido el envelope que controla la frecuencia.
Como podéis comprobar, hemos hecho coincidir el tiempo de duración total del envelope que regula la frecuencia y el del envelope que regula el volumen, 465 milisegundos, si estos tiempos fueran distintos, la duración del kick drum vendría determinada por el envelop que controla el volumen.
Como podéis ver, multiplicamos nuestro envelope por el valor de la frecuencia central de nuestro kick drum. En el ejemplo de la figura 5, la frecuencia inicial del kick drum es de 6x45= 270, tras 2 milisegundos esa frecuencia baja y se mantiene 3 milisegundos en 2x45= 90 Hz y de ahí descenderá a 0 en 460 milisegundos.
¿Veis cómo como varia la frecuencia de nuestra onda con respecto al paso anterior en el cual la frecuencia era constante?
Figura 6. Comparación entre la onda con frecuencia de 71 Hz constante (izquierda) y la onda con frecuencia variable (derecha) regulada por un envelope.
Envelopes regulables
Ahora, vamos a hacer regulable una parte del envelope que controla la frecuencia, en concreto el valor inicial del envelope utilizando el símbolo $, esto va a afectar al golpe inicial del kick drum. Hemos visto el uso del símbolo $ en Envelope | Librería CATEDU ¿Qué notáis al variar ese valor?
Figura 7. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho modificable el envelope que controla la frecuencia.
Vamos a introducir ahora un nuevo elemento para controlar la escala de la frecuencia inicial de manera aleatoria. El objeto random.
random
Este objeto va a generar valores aleatorios en un rango determinado que comienza en 0. El número de valores desde el 0 que va a generar lo configuraremos en el argumento del random. Por ejemplo, si el argumento es 4, cada vez que reciba un bang enviara por su out put un 0, un 1, un 2 o un 3.
Figura 8. patch random-demo.pd primera parte
Si queremos que el rango comience en otro valor por ejemplo 17, sumaremos ese valor al resultado del random. De esta forma obtendremos valores aleatorios entre 17 y 20, 17 y 20 incluidos.
Figura 9. patch random-demo.pd segunda parte
Ejercicio 6: crea un patch utilizando el objeto random que genere valores pares entre 20 y 30. [20, 22, 24, 26, 28, 30]. A este patch lo llamareis random-ejercicio2_vuestronombre_vuestroapellido.pd
Ejercicio 7: Observa los valores impresos en la ventana de Pd procedentes del random de la figura 9. ¿Qué sucede cada vez que envías el mensaje de "seed 50" al random? Para visualizar mejor lo que sucede imprime también el mensaje de "seed 50" cada vez que lo envies al objeto random. ¿Y si mandas en mensaje "seed 4962"? Observa la secuencia de números que se genera. En un documento al que llamareis random-ejercicio3_vuestronombre_vuestroapellido colocar una captura de pantalla de lo que sucede y responder a las preguntas.
Ahora que ya conocemos el random, incluyámoslo en el control del envelope que regula la frecuencia de nuestro kick drum. El random va a controlar el valor de partida de ese envelope:
Figura 10. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho que un objeto random modifique el envelope que controla la frecuencia.
Ejercicio 8: Una vez lograste un patch como el de la figura 10, os toca experimentar, probar lo queráis con lo que hemos a prendido hasta ahora, buscar sonido que os parezcan interesantes, lo que queráis. El archivo que creéis para este ejercicio lo llamareis kick-drum-lab_vuestronombre_vuestroapellido.pd
¿Qué tenemos que entregar?
Los 4 ejercicios de la lección. Sube a la carpeta del Moodle de la Practica 7 los siguientes archivos:
- Ejercicio 5: patch practica7_Kick-drum-sencillo-vuestronombre_vuestroapellido.pd
- Ejercicio 6: patch practica7_random-ejercicio2_vuestronombre_vuestroapellido.pd
- Ejercicio 7: documento practica7_random-ejercicio3_vuestronombre_vuestroapellido
- Ejercicio 8: patch practica7_kick-drum-lab_vuestronombre_vuestroapellido.pd
Figuras:
Figura 1. patch Kick-drum-sencillo-paso-1.pd
Figura 2. Muchos aros girando con diferentes fases unos de otros. https://giphy.com/gifs/hooping-hula-perth-MwC8t7MaaR7kCr3FaN
Figura 3. Añadimos un control de fase al oscilador del patch Kick-drum-sencillo-paso-1.pd
Figura 4. Envelope que utilizaremos para controlar la frecuencia del "osc~" en el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd
Figura 5. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos añadido el envelope que controla la frecuencia.
Figura 6. Comparación entre la onda con frecuencia constante (izquierda) y la onda con frecuencia variable (derecha) regulada por un envelope.
Figura 7. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho modificable el envelope que controla la frecuencia.
Figura 8. patch random-demo.pd primera parte
Figura 9. patch random-demo.pd segunda parte
Figura 10. el patch que estamos modificando: Kick-drum-sencillo-paso-1.pd una vez hemos hecho que un objeto random modifique el envelope que controla la frecuencia.
Práctica 8: OSC. Open Sound Control
¿Qué es OSC?
Open Sound Control, abreviado OSC, es un protocolo de comunicación entre dispositivos (ordenadores, sintetizadores ...) que está optimizado para tecnologías conectadas en red (Hutchinson, 2022).
¿Y qué es un protocolo? Un protocolo es un lenguaje, un código que tanto emisor como receptor comprenden y nos va a servir para enviar datos estructurados que una vez recibidos podamos descifrar.
En este curso vamos a utilizar este protocolo para comunicar Pure data con otros programas y/o dispositivos. Esto nos va a permitir, por ejemplo, controlar Pure data desde el móvil. Para entender cómo funciona, primero vamos a utilizar un ejemplo muy sencillo que nos va a permitir controlar desde un móvil, tablet u otro programa del ordenador el Kick drum que hemos hecho en Práctica 7: Kick drum ... | Librería CATEDU . Vamos a utilizar una aplicación o app para ello. El ordenador y el movil que queramos utilizar para este ejercicio deberán de estar conectados a la misma red, por ejemplo ambos deben de estar conectados a la wifi de casa. Para asegurarnos de esto podemos apagar los datos de nuestro movil y solamente conectarlo a traves de la wifi.
Etiquetas y datos
¿Os acordáis de la diferencia entre datos e información que veíamos en Programación en genera... | Librería CATEDU? Vamos a ver como toma relevancia a la hora de enviar datos. Para que los datos que recibimos puedan ser interpretados como información tendremos que ponerlos en contexto y para ello vamos a utilizar etiquetas que nos indiquen el origen y contexto de cada dato.
Figura 1. El programa emisor poniéndole una etiqueta a un mensaje osc, para saber que contiene.
Los datos van a llegar por el mismo sitio y pueden ser diferentes como, por ejemplo, la hora de llagada y la hora de salida de un tren. Si solo recibimos la hora: "16:45" y nada mas no podremos saber si es la hora de salida o de llegada necesitaremos recibir un mensaje con otro dato que nos proporcione esa información: "salida 16:45". Ahora ya sabemos que la hora que hemos recibido es la de salida.
¡Vamos a ello! Comencemos por instalar y configurar la app en nuestro móvil o tablet:
Si no tienes un dispositivo Android más abajo te damos una alternativa para el ordenador y otros dispositivos.
Movil-Tablet
Android
Vamos a instalar la aplicación "OSCcontroller", podéis encontrarla en el siguiente enlace.
Una vez instalada, la abrimos y configuramos la IP de la red a través de la cual queremos enviar datos. ¿Qué es la IP? Una IP es la dirección que utilizan los dispositivos conectados a red para identificarse. En nuestro caso, vamos a tomar la IP local o privada.
¿Y cómo sabemos cual es nuestra IP? Podremos consultarlo en nuestro ordenador, accediendo a la configuración de red:
Figura 2. Consultar la IP local en Windows 10.
Esta IP es la que vamos a introducir en la app "OSCcontroller". Tambien vamos a configurar el puerto a través del cual nos vamos a comunicar, que sera el mismo que configuraremos en Pure data.
El puerto es el canal especifico en el que vamos a enviar los datos. Para este ejemplo utilizaremos el 8000, pero podéis utilizar otro puerto que tengáis libre. Nuestra IP puede cambiar así que, si vemos que no funciona, nos aseguraremos de que la IP de nuestra red coincide con la que configuramos en la app.
Figura 3. Configuración de IP, puerto, inicio de la conexión y acceso a los controles que enviaran los mensajes osc en la app OSCcontroller.
Una vez tengamos IP y puerto configurados pulsaremos Start para iniciar la conexión. El botón azul de control nos llevara a una ventana en la que encontraremos sliders, botones e interruptores y son los valores de estos controles los que se enviaran por osc.
¡Nuestro móvil o tablet ya está listo para enviar datos! Ahora vamos a configurar Pure data:
Configuremos Pure data
Para recibir esta comunicación a través de la red, vamos a utilizar el objeto "netreceive" de la siguiente manera:
Vamos a configurar el puerto de escucha en Pure data enviando un mensaje con el texto "listen" y el numero del puerto. Pondremos dos argumentos en el objeto "netreceive" para asegurar su correcto funcionamiento: "-u" y "-b".
Los datos recibidos por "netreceive" serán traducidos por el objeto "oscparse" a un language legible. Tras la traducción vamos a imprimir lo que estamos recibiendo.
¡Comencemos a enviar datos! Vamos a tocar los botones y sliders que vemos en la ventana de control del móvil:
Figura 4. ventana de los controles en la app OSCcontroller.
Figura 5. Pure data imprime los datos recibidos por osc y que se han enviado desde la app OSCcontroller.
Vamos a fijarnos en la interfaz del móvil en la figura 4. Tenemos 4 sliders en la parte izquierda, en la parte derecha superior tenemos tres interruptores y debajo de estos tres pulsadores. Cada uno de estos sliders, botones y pulsadores van a tener un código identificativo, una etiqueta que nos permitirá saber desde que objeto de control proviene la información recibida. Vamos a fijarnos ahora en las líneas impresas en la ventanita de Pd. En las primeras líneas podemos leer lo siguiente:
print: list oscControl slider4 0.16
Encontramos palabras y números separados por un espacio. Vamos a ver qué indican cada uno de estos grupos. Como bien sabeis el "print:" nos indica que esta linea que aparece en la ventanita son datos impresos desde un patch de pd utilizando el objeto print.
La palabra "list" nos indica que lo que se está imprimiendo es una lista de elementos.
La palabra "oscControl" es una etiqueta que identifica el emisor de estos datos, en nuestro caso es la app OSCcontrol. Podemos configurar el nombre de esta etiqueta en la app:
Figura 6. Marcado en rojo se muestra donde cambiar la etiqueta del emisor en la app "OSCcontroller".
La siguiente palabra es una etiqueta que nos va a indicar desde elemento de control se envían los datos. Que botón, interruptor o slider envía esos datos: slider1, slider2, slider3, slider4, toggle1 toggle2 toggle3, button1, button2 o button3.
print: list oscControl slider4 0.16
Tras esta etiqueta que indica desde que botón, interruptor o slider se envían esos datos, encontraremos un valor numérico que corresponde con el estado del botón, interruptor o slider. Este envío se va a realizar cuando cambie el estado del botón, interruptor o slider, por ejemplo, cuando pulsemos un botón o movamos un slider.
Como podéis ver en la figura 5, en la consola de Pd recibimos información de varios actuadores/elementos de control. El slider4 en la posición 0.16, el button1 y el button2 han sido pulsados, el toggle3 ha encendido y apagado, el toggle2 ha sido encendido y permanece encendido y finalmente el button3 y el button1 han sido pulsados.
Ejercico 9: Montad el sistema que acabamos de ver y haced pruebas con los actuadores y el print.
¿Funciona?
Figura 7. El paquete del slider4 de camino a Pure data cuando no enviamos el mensaje "listen 8000" al objeto "netreceive".
Una vez recibimos los datos en Pd tendremos que procesarlos un poco para poder utilizarlos para modificar parámetros en nuestro patch. Como hemos visto estamos recibiendo una lista con etiquetas y un valor numérico, vamos a desgranar y clasificar esa lista. Vamos a empezar por quitar la palabra "list" de nuestra lista de datos, utilizando el objeto "list trim"
Figura 8. Uso del objeto "list trim" para eliminar la palabra "list" de la lista en Pure data.
Ahora, vamos a ver cómo clasificar los datos en base a sus etiquetas con el objeto "route". Al tener solo datos enviados de desde el mismo origen, todas las listas contienen la palabra oscControl que hace referencia al origen de los datos. Si recibiéramos datos de dos fuentes distintas tendríamos una etiqueta diferente para identificar cada fuente, como en el siguiente ejemplo:
Figura 9. mensajes osc recibidos de dos emisores distintos en Pure data.
Para separar los datos de cada emisor, utilizaremos el objeto route cuyos argumentos serán el nombre de la etiqueta de cada emisor. En el ejemplo de las figuras 9 y 10, he utilizado dos aplicaciones distintas para enviar mensajes osc y mostraros como seria, pero vosotros de momento solo utilizareis OSCcontrol.
Figura 10. Uso del objeto "route" para clasificar los mensajes osc procedentes de dos emisores en Pure data. Fuente 1=oscControl, Fuente 2=multisense.
Por la primera salida del route, saldran las listas con la etiqueta oscControl, que es el primer argumento del "route"; por la segunda salida, las listas con la etiqueta multisense; y por la tercera salida, las listas que no contengan ninguna de las etiquetas anteriores. Como podéis observar, tras clasificar estas listas el route elimina la etiqueta de la lista, que era el primer elemento de la lista. La figura 10 era un ejemplo con dos fuentes, aunque en el ejercicio que estamos haciendo solo vamos a trabajar con una fuente, vamos a utilizar el route para quitar la etiqueta oscCcontrol.
Ahora vamos a clasificar los datos que vienen de cada botón utilizando el objeto route. Para los botones podemos ver en la lista que hemos impreso previamente que las etiquetas que utilizan son button1, button2 y button3. Utilizaremos esas etiquetas en el route.
Figura 11. Clasificación de los datos recibidos por osc en Pure data.
Vemos que al pulsar el botón 1 se envía un 1 a traves de la primera salida del route y al pulsar el botón 3 se envía un 1 a traves de la tercera salida del route. Al encender un toggle se envía un 1 y al apagarlo un 0. Los sliders envían un valor correspondiente a la posición del indicador en un rango de 0 a 1.
Ejercicio 10 : Una vez hemos conseguido enviar valores desde nuestro móvil a nuestro patch estamos listos para incluir estos controles en el kick drum que hemos hecho en la Práctica 7: Kick drum ... | Librería CATEDU. Vamos a utilizar los tres botones para controlar cada uno de los valores iniciales del envelope que regula la frecuencia del kick drum. Si os fijáis, en el patch que hicimos era un random el que controlaba los valores iniciales del envelope, ahora van a ser los botones de la app oscControl.
Ejercicio 11: Ahora que ya controlas el envelope de la frecuencia con los botones, intenta controlar la frecuencia general con el slider1 y el volumen con el slider2.
¿Y qué pasa con los que no tenéis un dispositivo Android?
Os vamos a dar una alternativa que es la aplicación TouchOSC. Esta aplicación está disponible para iphone y android pero en estos dispositivos es una aplicación de pago. La version de prueba de ordenador de esta aplicación es gratuita y podréis utilizarla para aprender a enviar mensajes osc desde otro programa a Pure Data.
Aunque utilicemos una aplicación distinta para enviar los mensajes de osc, estos funcionaran de la misma manera que en el ejemplo con Android. Pure Data nos llegaran listas con etiquetas y valores que tendremos que procesar.
Movil-Tablet-Ordenador
MacOSX
Vamos a descargar e instalar la última version para nuestro sistema operativo desde este link:
https://hexler.net/touchosc/bridge-releases
TouchOSC: Abrimos el ejemplo BeatMachine Mk2, en Help > Examples.
Salimos del modo de edición con Cmd + E
Configuración: En TouchOSC > Connections
Figura 12. programa "Touch OSC"
En la pestaña OSC configuramos en Host nuestra ipv4 y en Send Port: 8000
Figura 13. Configuración de IP y puerto en "Touch OSC".
Abrimos nuestro patch de Pure Data y hacemos click sobre listen 8000. Si no lo hacemos, Pure Data no recibirá información.
Una vez hayamos hecho click, podemos comenzar a girar los botones en TouchOSC y veremos cómo los valores se imprimen en la consola de Pure Data, como puedes ver en el siguiente .gif:
Figura 14. "Touch OSC" enviando mensajes osc a Pure data.
Aqui encontrareis un video de como configurar el programa si tenéis alguna duda. La parte de la aplicación Protokol no es necesaria ya que solo visualiza esos mensajes: https://hexler.net/touchosc/manual/getting-started-osc
¿Qué tenemos que entregar?
El ejercicio 10 y 11. Sube a la carpeta del Moodle de la Practica 8:
- Ejercicio 10: Un video en el que se vea y escuche como desde otra aplicación se controla el kick drum en Pd. El video deberá llamarse: practica8-video_vuestronombre_vuestroapellido.
- Ejercicio 11: una captura de pantalla del patch y el patch que has creado. El patch deberá llamarse: practica8_vuestronombre_vuestroapellido.pd y la imagen practica8-imagen_vuestronombre_vuestroapellido.
Referencias:
Hutchinson, S. [Simon Hutchinson]. (2022, 7 febrero). Open Sound Control (OSC) in Pure Data Vanilla | Simon Hutchinson. [Video]. https://youtu.be/tJ2Kocl-2m4
Figuras:
Figura 1. El emisor poniéndole una etiqueta a un mensaje osc, para saber que contiene. https://giphy.com/gifs/GLSSpain-box-parcel-paquete-OKPtqN7dlflYcw8gPu
Figura 2. Consultar la IP local en Windows 10.
Figura 3. Configuración de IP, puerto, inicio de la conexión y acceso a los controles que enviaran los mensajes osc.
Figura 4. ventana de los controles en la app OSCcontroller.
Figura 5. Pure data imprime los datos recibidos por osc y que se han enviado desde la app OSCcontroller.
Figura 6. Marcado en rojo se muestra donde cambiar la etiqueta del emisor en la app "OSCcontroller".
Figura 7. El paquete del slider4 de camino a Pure data cuando no enviamos el mensaje "listen 8000" al objeto "netreceive". https://giphy.com/gifs/page-usps-XoPxquIwsYXpC
Figura 8. Uso del objeto "list trim" para eliminar la palabra "list" de la lista en Pure data.
Figura 9. mensajes osc recibidos de dos emisores distintos en Pure data.
Figura 10. Uso del objeto "route" para clasificar los mensajes osc procedentes de dos emisores en Pure data. Fuente 1=oscControl, Fuente 2=multisense.
Figura 11. Clasificación de los datos recibidos por osc en Pure data.
Figura 12. programa "Touch OSC"
Figura 13. Configuración de IP y puerto en "Touch OSC".
Figura 14. "Touch OSC" enviando mensajes osc a Pure data.
Subpatch
A medida que vamos conociendo más elementos de Pure data y creando programas más complejos, nuestros patches se llenan más y más de cajitas y líneas que cruzan de un lado a otro, dificultando la legibilidad de nuestro algoritmos.
Figura 1. Patch de Pure data, poco legible para el ojo humano.
Vamos a intentar evitar situaciones como la de la imagen anterior. Existen algunos objetos que nos van a ayudar a mantener orden y claridad en nuestros patches, algunos de ellos ya los conocemos. Son el send y el receive que vimos en la Practica 2: nuestro pr... | Librería CATEDU. El nuevo elemento que vamos a introducir hoy es el subpatch.
¿Y que es un subpatch? Un subpatch es un patch que vamos a crear dentro de nuestro patch principal de pure data y que nos va a permitir agrupar partes del programa para que nuestro algoritmo principal sea fácilmente visible y comprensible, para que nosotros o cualquier persona que lea nuestro programa pueda entender qué es lo que estamos haciendo rápidamente. Recordemos la metáfora de la receta del libro de cocina que veíamos en la página de Entorno | Librería CATEDU.
En el siguiente video veremos cómo crear un subpatch utilizando el objeto "pd"
Ejercicio 12: Tras crear el subpatch que ves en el video. añade dos subpatches más uno para el volumen y otro para la comunicación osc.
Figuras:
Figura 1. Patch de Pure data, poco legible para el ojo humano. https://patchstorage.com/shedding-hydrogen/