miércoles, 19 de septiembre de 2012

Código fuente y Memoria

Codigo fuente y memoria finales del proyecto.


Desarrollado sobre:

  • PureData 0.42.5
  • Arduino IDE 1.0


Contenido:
Carpeta board: archivos de diseño Eagle de la placa, así como las salidas CAM empleadas.
Carpeta presentación: presentación tentativa para la exposición final.
Carpeta Código:
  • Pure Data: archivos del software para puredata:
    • ArduinoSynth: programa principal (se abre la aplicación abriendo el archivo archivo ArduinoSynth).
    • Deprecated: patches no utilizados ya por el programa.
    • PreviousReleases: backups antiguas del programa.
    • Resources: recursos utilizados en la creación del sistema.
    • Tests: archivos de pruebas realizadas en el programa
  • Arduino:
    • ArduinoSynth: software para Arduino Mega, imnplementa la interfaz USB y cuatro visualizaciones.
    • Requiere el uso de las librerías MatrixController y ArduinoSynthComms incluidas.
    • Librerías MatrixController, ArduinoSynthComms y Tlc4940Mux modificada.
    • DummySender: sketch simple para enviar notas MIDI con un Arduino Duemilanove.



Última modificación 21 mayo 2012 (Entrega final de la asignatura).

Descarga
Memoria: http://www.mediafire.com/?o4a662cu076p35j
Fuentes: http://www.mediafire.com/?ll9le032yykb7gn

martes, 24 de julio de 2012

Compiling Pd-extended on armhf / armel (Raspberry PI) [builds inside]

This post describes how to build Pd-extended on Raspberry Pi, almost everything is based on the post http://log.liminastudio.com/writing/tutorials/how-to-build-pd-extended-on-the-raspberry-pi. All credits goes there.

The official debian build for Raspberry Pi has changed the arquitecture from armel to armhf, to speed up the system by using the hardware floating point unit, this should help Pd since it works with float variables.
This process has been tested with Raspbian 15-7-12.

To get the sources, check the Puredata official page, but, for some reason, it doesn't work for me in the nights, so you can always get it from sourceforge:
0.42.5 http://sourceforge.net/projects/pure-data/files/pd-extended/0.42.5/Pd-0.42.5-extended.tar.gz/download
If you want to use the latest 0.43.1 source, it will be downloaded using the rsync command in the Liminastudio post.

Compiling takes around 4-5 hours in my Raspberry Pi (overclocked around 900 Mhz).

Pd-extended 0.43.1

When build the 0.43.1 version, the steps are the same as the post by Liminastudio, just add the repository line " deb-src http://archive.raspbian.org/raspbian wheezy main contrib non-free rpi " in the step 2. and add "tcl-dev" in step 4.

Pd-extended 0.42.5

But compiling the previous 0.42.5 may be interesting due to its lighter working compared to the newest 0.43, but it requires some changes to avoid problems compiling.

First of all, I suffered from a gcc compiler bug which triggers assembler errors, with the default gcc-4.6 compiler in debian, I had use gcc-4.7, which was able to compile all the sources without errors.

To compile this version, follows the steps 1 to 4 in the Liminastudio post. Then, download the 0.42.5 sources from the link above, and extract in the current folder.

After that, we'll set the gcc-4.7 as the default:
First, install the gcc-4.7, with g++ and libstdc++6, also, we'll install dssi-dev and liblo-dev, because we'll need them (these package may be installed in the step 4 along with the build dependences).
sudo apt-get install gcc-4.7 g++-4.7 libstdc++6-4.7-dev dssi-dev
fftw2 libgfortran3 libmpich1.0gf tcl-dev tcl8.4-dev tk tk8.4-dev
The default compiler is still gcc-4.6, we'll set the alternatives to use 4.7:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.7 10
Compiling the 0.42.5 version is a little trickier, we have to correct some things in the source. First, the pidip package fails compiling, so we'll replace it with the latest version (don't know it if may break it, haven't tested, just lets pd-extended compile). Just remove the externals/pidip folder, and replace it with the pidip source that we can dowload using

sudo apt-get install cvs
xport CVSROOT=:pserver:anonymous@giss.tv:/home/cvs 
cvs co pidip 

Now we need to correct a file in the source , the file is GEM/src/Pixes/videoV4L.h. We'll replace the file with the one here http://pd-gem.svn.sourceforge.net/viewvc/pd-gem/branches/0.92/Gem/src/Pixes/videoV4L.h?view=markup&pathrev=3937 . If we don't do that, we'll get a file not found error (more info here http://ubuntuforums.org/showthread.php?t=1767292).

The last change is in the pdp external, the ---export-dynamic makes the compiler throw a parameter not recognized error, I've deleted from the affeted files, you should change the following files:
    externals/pdp/Makefile line 29
    externals/pdp/scaf/Makefile line 29
    externals/pdp/opengl/Makefile line 23

The source with all these changes is here: https://docs.google.com/open?id=0B_UT435wUJeTQ2hvNG1WcVhsbGM


Then follow the remaining steps from step 8, you have only to change the name of the package in the dpkg command.
In step 8, a parameter has to be removed from the Makefile, but, if we compille all at once, the makefile hasn't been created before compiling, so we'll modify externals/OSCx/configure (info). There, in line 4429, remove "-lpd", do that also in line 98 of externals/OSCx/configure.ac, this last one don't know if it's necesary, but it's better to be sure in a four hour process .

All these corrections are in the following file if you prefer to skip these changes:

If you prefer to install my builds, just follow the first four steps, download the package using wget and the address and install it with dpkg.

Builds armhf (Raspberry Pi), use with Raspbian or similar:

0.43.1 - 23-7-12: https://docs.google.com/file/d/0B_UT435wUJeTVTh3VEFIODNrOU0
0.42.5: https://docs.google.com/open?id=0B_UT435wUJeTRnp0RFZfR1lfa1k

Direct download - for wget for example

0.43.1 https://dl.dropbox.com/s/0r9muesthz5fghi/Pd-0.43.1-extended-20120723.deb
0.42.5 https://dl.dropbox.com/s/p9xh0ia0xbjrnux/Pd-0.42.5-extended.deb





viernes, 25 de mayo de 2012

Presentacion final: video

Video final presentado en la reunión de prácticas especiales de LSED.

Arduino Synth - Presentación final on Vimeo.

En el vídeo, ha sido complicado grabar bien los resultados de la matriz y los efectos, en vivo presenta mayor gama y brillo de colores, además de funcionar más suave.
Sistema completo Arduino Synth.

martes, 22 de mayo de 2012

Conclusiones y futuro del proyecto


Conclusiones

Al comenzar la asignatura de Sistemas Electrónicos Digitales, creímos conveniente realizar una práctica especial en lugar de la práctica básica de la asignatura para tener la oportunidad de, además de elegir y desarrollar nuestro propio trabajo, realizar las labores ligadas a la gestión de un proyecto como son el establecimiento de objetivos y la planificación temporal y de recursos, conservando la libertad de reorientar el proyecto en torno a los áreas que consideramos de mayor interés.

Uno de los objetivos marcados era la portabilidad del programa para distintos sistemas operativos en la parte del programa en el PC, la cual está prácticamente asegurada, ya que nuestro sistema se basa en el framework del sistema operativo a través de Pure Data, disponible para multitud de sistemas operativos.
Esto permite, además de funcionar en todos los principales sistemas operativos actuales, ser compatible con sistemas de terceros, tanto hardware como software: ya sean sintetizadores (software o hardware), fuentes de sonido y datos MIDI, DAWs, etc., y siempre realizando pocas o ninguna modificación a nuestro sistema. Una configuración tentativa de la parte PC podría ser GNU/Linux + Pure Data + Sintetizador software Timidity++, pero el programa actual puede funcionar perfectamente por ejemplo en MacOS/Windows + Pure Data + Logic/Ableton/Cubase...

Por último, debido a que todas las herramientas empleadas: Pure Data, Arduino, etc. son de licencias abiertas, el sistema puede funcionar completamente sobre software libre, lo cual reduce el coste de la plataforma al coste propio del hardware.

Tras tres meses de trabajo, hemos completado el desarrollo de una plataforma que conjuga tanto hardware como software. Ha requerido, aparte de todas las tareas de programación, la creación de protocolos de comunicación y patrones de comportamiento para asegurar que todas las partes del sistema funcionaran de forma correcta y coherente.

Futuro

Debido a que el proyecto es una elección propia debido a nuestro interés en la materia, hemos identificado algunos aspectos que tendrían interés para una realización más completa:

Apertura de código (opensource) Una de las ideas principales en el desarrollo era el uso de herramientas que permitan que el sistema sea abierto, y por ello, el paso natural tras la finalización del proyecto, es la liberación tanto de código software, como esquemáticos hardware. Aún queda por determinar bajo que licencia será, pero algunas candidatas son GPL o Creative Commons.
Plataforma embebida Tras una de las presentaciones de progreso, recibimos la sugerencia de convertir el sistema en una plataforma embebida, que no dependiera de un PC. Esta estructura fue considerada al principio, pero la desestimamos dada la alta complejidad del desarrollo de la parte de análisis y sonido, realizada aquí en PureData, sobre otra plataforma como puede ser un microcontrolador. Sin embargo, tenemos una idea tentativa a la hora de realizar un sistema embebido similar.

Recientemente ha salido a la luz una plataforma llamada Raspberry Pi, que integra un ordenador completo basado en ARM en una placa del tamaño de una tarjeta de crédito, y es de bajo coste (en torno a 35$). Una plataforma de ese estilo permitiría por ejemplo disponer de builds de Pure Data para plataformas ARM y agrupar el sistema completo en un único dispositivo, con la ventaja del menor coste y de un consumo energético y computacional mucho menor en comparación con el del proyecto realizado. La adaptación del sistema sería simple, ya que emplearía la misma estructura, y además, dado que esta plataforma dispone de pines de entrada/salida que permiten el acceso a una UART del propio procesador, se podría eliminar el túnel USB en las comunicaciones disminuyendo de forma drástica la latencia del sistema, factor crítico en un sistema orientado a música y sonido.

domingo, 20 de mayo de 2012

Memoria: recursos online

Vídeos de visualizaciones.
Pop Visualization




Vumeter




Audiorítmica






PCB

Tras acabar realizamos una placa PCB con el hardware empleado, el resultado es el siguiente:
Placa montada y funcionando.

Interfaz gráfica completa: Arduino Synth

Ya tenemos todos los elementos necesarios en nuestro programa y sólo queda aglutinarlos en una única interfaz integrada por todos los módulos mostrados hasta ahora. Para ello hemos diseñado una GUI escalable, fácil de usar y lo más intuitiva posible para poder utilizarla sin dificultades.
Arduino Synth - GUI 
En ella se pueden observar los distintos módulos del programa:
  • Módulo de comunicación con Arduino (arriba izquierda) Controla la comunicación con el microcontrolador, permite abrir y cerrar conexión con él, activar el Active Sensing y el parseado de instrucciones MIDI, y además activa y desactiva la computación de audio en el Pure Data. 
  • Módulo de visualización/comunicación con la Matriz LED (arriba centro) Se trata del módulo de comunicación explicado en el apartado anterior. 
  • Display de mensajes MIDI (arriba derecha) En este display se visualizan las instrucciones MIDI que llegan del Arduino, cuyos bytes han sido parseados para hacerlos inteligibles (gracias al módulo printMidi) 
  • Visualización de energías y audio final (debajo de los tres anteriores) Aquí se recoge todo el audio generado en el programa y se envía por el puerto de salida para ser reproducido por la salida de audio del sistema. Se presenta la señal por pantalla y se calcula la energía en 8 bandas de frecuencia, preparando los valores para ser enviados al módulo de comunicación con la matriz LED. 
  • Arpeggiator (debajo del anterior) Explicado en el apartado siguiente. 
  • Módulo de síntesis FM (abajo izquierda) Nuestro primer sintetizador polifónico. Con presets añadidos y reverberación. 
  • Reproductor de audio (abajo centro) Reproduce archivos de audio. Contiene controles estándar de reproducción, volumen, posición de la canción, control de velocidad de reproducción y reverb. 
  • Módulo de redirección MIDI para programas externos (abajo derecha) Redirige la información MIDI a un bus virtual del sistema para ser utilizada por otros programas.
Y para finalizar, el esquema de funcionamiento global del programa:

Arpeggiator: una mejora del software


Además de construir un sistema básico completamente funcional, hemos querido añadir una mejora a nuestro diseño para hacer de él un programa más sólido y añadir una herramienta muy útil a la hora de componer música y efectos especiales.


Un arpegiador es un dispositivo que captura las notas tocadas por un controlador MIDI y lanza secuencias de notas en función de las teclas pulsadas. Por ejemplo, si tocáramos un acorde el arpegiador podría separar las notas de ese acorde y tocarlas secuencialmente, una detrás de otra (arpegio). O lanzar rápidamente escalas a partir de esas notas para crear efectos de sonido. O crear sonidos “colchón” que se mantengan a lo largo de la canción sobre los que poder tocar otros instrumentos.



'as_arpeggiator'
En lugar de alimentar directamente a los sintetizadores desde el ArduinoModule, hacemos pasar el flujo de instrucciones MIDI por el Arpeggiator. Este módulo coge uno sólo de los canales MIDI y deja pasar al resto sin actuar sobre ellos. Utilizando las notas de ese canal, este módulo puede crear efectos como los que hemos mencionado antes, creando nuevas instrucciones MIDI que se envían al sintetizador asociado a dicho canal.


Posee una línea temporal, que se encarga de generar los nuevos mensajes MIDI a la velocidad deseada. En los paneles inferiores se puede modular la frecuencia y la intensidad de estas nuevas instrucciones, así como cambiar la velocidad a la que se generan y otras opciones mediante el resto de la interfaz.

Subsistema de visualización. Comunicación con la Matriz LED

Finalmente, ahora que tenemos toda la información MIDI y de audio (de energía de la señal) disponible, necesitamos transmitirle al Arduino las instrucciones necesarias para generar los patrones luminosos que deseemos en la matriz de LEDs. Utilizando el patch ‘as_ledMatrix’ tenemos una interfaz mediante la cual activamos diversas funciones que hemos incorporado en el microcontrolador:
  • ON/OFF Apagamos o encendemos la matriz de LEDs activando y desactivando este botón.
  • Selección de modo Con estos 4 pulsadores podemos elegir cualquiera de los distintos modos de visualización. Los cuatro están explicados en el apartado de hardware, y son: EQ (SpectrumVisualization, muestra la energía por bandas de la señal), AudioRhythm (AudioRhythmicVisualization, crea patrones de iluminación en función de la información MIDI entrante), Random (PopVisualization, enciende luces posicionadas aleatoriamente en la matriz en función del número de notas tocadas en un intervalo de tiempo), y Demo (ShowcaseVisualization, muestra una serie de imágenes de demostración).
  • Asignación de canales MIDI a canales de visualización En el lateral izquierdo del módulo se asignan los canales MIDI deseados a los 4 canales de iluminación que controlan la visualización audiorítmica. A su vez, pueden activarse y desactivarse independientemente.
Una vez encendida la matriz de LEDs mediante el correspondiente botón, se envían distintos tipos de datos a la matriz en función del modo de visualización activado. Los pulsadores de selección de modo mandan bytes de comando que activan en la matriz las respectivas visualizaciones, y una vez elegidas, se envían datos diferentes en función de la visualización activada.
  • Para la EQ, lo que se envían son los paquetes de 8 bytes que contienen la energía de cada una de las bandas + 1 byte con la energía total de la señal.
  • Para la AudioRhythm se envía la información de nota e intensidad de las instrucciones NoteON de los canales MIDI asignados a cada uno de los canales de iluminación.
  • Para la Random se envían números aleatorios entre 1 y 17 cuando llega un mensaje MIDI de NoteON
  • Para la Demo, no se envía nada.
Todos estos datos se mandan al microcontrolador formateados según el protocolo que hemos creado para poder establecer comunicación entre el Pure Data y el Arduino, y está explicado completamente aquí.

Recolección de audio y cálculo de energía de la señal


Ahora que ya hemos construido todos los módulos de generación de sonido, pasamos a operar con toda la información que tenemos disponible de las instrucciones MIDI y del audio generado para crear una serie de visualizaciones, las cuales serán posteriormente representadas en la matriz de LEDs.


En primer lugar, queremos coger todo el audio generado en el programa o en los sintetizadores externos y mezclarlo, sumar todos los canales. De esta forma ya tenemos en un sólo flujo de audio estéreo todos los sonidos producidos y podemos operar con él.
Para mostrar la energía por bandas de la señal introducimos la señal ya mezclada en el módulo de visualización de energías que se encuentra en el patch ‘as_energyDisplayPanel.pd’.


En este módulo se realizan 3 tareas diferentes:

  • Envío del audio final al DAC del ordenador Es en este módulo donde enviamos la suma de todos los canales de audio existentes en el programa a la salida de audio del Pure Data, que conectamos por defecto a la salida de audio del sistema.
  • Representación de la señal de audio Además, se dibuja en pantalla la señal de audio en el tiempo.
  • Visualización de la energía por bandas Por último, y empalmando con el envío de datos a la matriz LED, se calcula la energía de la señal en 16 bandas de frecuencia diferentes utilizando un banco de filtros paso banda.

En cuanto a la visualización de energía, se pasa la señal a través de 16 filtros paso banda de 2º orden centrados en 25, 40, 63, 100, 160, 250, 380, 550, 790, 1k, 1.6k, 2.5k, 4k, 6.3k, 10k, y 16kHz. Su ancho de banda se expresa en octavas respecto de la frecuencia central, siendo el valor 100 equivalente a una octava. Nuestros filtros están configurados con un valor de 20, es decir, 1/5 de octava.
8 primeros filtros
Para calcular la energía de la señal utilizamos el objeto ‘env~’, que devuelve la amplitud RMS de la misma en dB (tomando el valor 1 como 100 dB). Esta configurado para utilizar una ventana de 512 muestras y realizar el cálculo cada 256 muestras. A continuación, se realiza la media aritmética de cada pareja de filtros (se suman por parejas y se normaliza: (filtro 1 + filtro 2)/2, (filtro 3 + filtro 4)/2, etc.) y se obtienen 8 valores de energía a lo largo de casi todo el rango de frecuencias audible.


A estos valores se les aplica una función de transferencia con el objetivo de ajustar los diferentes valores a la cantidad de LEDs que deben encenderse en cada caso y se restringe su valor entre 0 y 199 (por especificación del protocolo que hemos diseñado para comunicarnos con el micro).


Los datos generados por los filtros se muestran por pantalla utilizando una serie de vúmetros individuales. Y, por último, una vez obtenidos, los 8 bytes que contienen esos valores se empaquetan en un mensaje y se envían cada 50 milisegundos al último módulo del programa, el subsistema de visualización. Este es el encargado de hacer llegar al Arduino toda la información que queremos ver en la matriz LED.

sábado, 19 de mayo de 2012

Visualizaciones: Rhythm


Como visualización más compleja, hemos realizado una visualización basada en los datos de notas MIDI, en función del instrumento, nota e intensidad de la nota. Esta permite seguir el ritmo de la música al reproducir gráficamente la melodía realizada.
Fuentes de datos
La visualización se basa en los datos que llegan de los canales de instrumentos de la visualización, que en el software para PureData se eligen de entre los canales de la melodía en reproducción. De cada instrumento, se emplean la frecuencia y la velocidad de la nota.
Visualización
Se representa una visualización dividida en zonas correspondientes a cada instrumento. En ella se distinguen tres zonas diferenciadas: fondo, central y extremos.
Construcción de la visualización
La zona de fondo se asocia a la batería, y llevará los golpes de esta, su brillo está atenuado para no interferir con el resto de canales al estar siempre en pantalla.
Sobre el fondo de la batería se pintan los otros dos canales, extremos y centro, los cuales, según la velocidad o intensidad de la nota, pintarán mayor o menor número de LEDs, pueden verse los niveles marcados con distintos colores en la imagen superior. El color estará modulado por la frecuencia de la nota, y la superposición de los tres conforma la imagen resultante.
Al igual que en las otras dos visualizaciones, se ha implementado un desvanecimiento con el tiempo, pero en esta, además, cuando llega una nueva nota de un canal y ya estaba en curso una representación de ese canal, se apaga la representación de ese canal durante cierto tiempo (20 ms), y entonces se representa la nueva.
En esta visualización cabe destacar que se ha implementado un buffer sobre el que se calcula la representación, y una vez terminada, se traslada al buffer de la librería gráfica, esta estructura en sistemas gráficos es conocida como gráficos doble buffered.
Respuesta
Esta visualización responde al análisis de las notas de la melodía, luego debe representar de forma aproximada el ritmo de la melodía.

Visualizaciones: Spectrum


Hemos implementado un vúmetro como visualización, aprovechando los colores según el nivel de energía.
Fuentes de datos
La visualización se basa en los datos de energía que llegan del software de PureData. Cada vez que llega una trama de energía, se visualiza.
Visualización
Se representa el vúmetro, con una banda de energía representada en cada fila, y los puntos asociados a valores de energía más altos, tienen un color más cercano al rojo, y los de menor energía, al azul, pasando por verde, de forma similar a la escala comentada en la visualización anterior.
Los LEDs encendidos se van desvaneciendo suavemente si en los siguientes instantes no se reciben energías que requieran encender dichos LEDs.
Respuesta
Esta visualización responde al análisis del audio final, luego es válida tanto para una fuente de notas MIDI como para la reproducción de sonido en el PC.

Visualización: showcase



Como prueba de procesado, se realizó una visualización de colores y efectos sobre la matriz, pero ésta es
cíclica, no depende de ningún dato externo.
  • Ejecuta cíclicamente los siguientes efectos:
  • Pulsos de luz, primero los tres primarios, después los tres secundarios, y por último,
  • con blanco.
  • Desplazamiento de colores: desplaza una sucesión de mezclas de colores por la
  • matriz.
  • Pixels alternos, con los tres colores primarios. Este modo se implementó para probar la
  • interferencia entre filas que se comentó anteriormente en el desarrollo.
  • Efecto de dentro hacia fuera: desplaza una sucesión de mezcla

Visualizaciones: PopVis


La primera visualización que se implementó se basaba en generar conjuntos de puntos periódicos en pantalla modulados por el número de notas tocadas en cierto tiempo.
Fuentes de datos
El software para PC, para cada nota que se procesa, manda un byte por el puerto serie al Arduino. El sistema Arduino cuenta el número de bytes recibidos. Cada vez que ocurre un refresco de la visualización, el hilo de la visualización se encarga de resetear dicho contador.
Visualización
Cada vez que es necesario un refresco, el hilo de la visualización accede al contador de los bytes recibidos, y genera en la pantalla un número de puntos proporcional al número de bytes recibidos, y su color, también es proporcional al número de bytes, ya que se ha realizado una escala de colores azul-verde-rojo, realizando degradados en ese rango.
Escala Azul-Verde-Rojo
La escala de color no puede ser proporcional de forma fija al número de notas tocadas, debido a cada melodía funcionaría en una parte distinta de la escala, de ahí que hayamos optado por una realimentación, contabilizando la media de bytes recibidos en los últimos 3 segundos, y con ese valor, se modula tanto el número de bytes como su color. Así, también se adapta a las distintas partes de una canción.
Respuesta
Esta visualización responde al número de notas tocadas por unidad de tiempo, no responde d forma pura al ritmo, sino a las variaciones de cadencia de notas.

Módulo Arduino, overview

Una vez completados los módulos del sistema Arduino, el funcionamiento de módulos del software es el siguiente:
Diagrama de flujo de funcionamiento del sistema Arduino.
Diagrama de archivos del sistema Arduino

viernes, 18 de mayo de 2012

Sintetizadores externos

La mayoría de DAWs (Digital Audio Workstations, programas de grabación y edición de audio) proporcionan al usuario la opción de comunicarse con otros programas mediante puertos virtuales, a través de los cuales intercambian información de audio e instrucciones MIDI para generar sonidos .
Por ello, hemos incluido la posibilidad de redirigir todos los mensajes que llegan del controlador MIDI a través del Arduino al puerto de salida del Pure Data para que esa información pueda ser utilizada por otros programas y el músico pueda utilizar los sintetizadores que él desee.
La redirección se realiza en dos pasos:
  • En primer lugar, se envían los mensajes MIDI generados por el controlador al puerto de salida MIDI del Pure Data. En este punto, el usuario debe tener configurado algún bus virtual MIDI (Como el bus IAC [Inter App Communication] en Mac OS, o MidiYoke en Windows) en su sistema operativo, y debe elegirlo en la configuración del Pure Data en su puerto de salida. A su vez, se debe tener configurado el programa externo para recibir MIDI del bus virtual, del que recibirá las instrucciones.
  • Además, contamos con la posibilidad de capturar el audio generado en el sintetizador externo y redirigirlo al Pure Data para operar con él. Al igual que con el MIDI, tenemos que contar con un bus virtual (en este caso de audio, como Soundflower, Jack, Virtual Audio Card, etc.):.Configuramos el puerto de salida del sintetizador para conectarlo con el bus, y elegimos también en Pure Data el mismo bus como puerto de entrada de audio.
Así, brindamos muchas más posibilidades para generar sonidos y conseguimos que el programa sea mucho más extensible y útil para el usuario.

Módulo de redirección de instrucciones conectado al sintetizador FM8 de Native Instruments



jueves, 17 de mayo de 2012

Arquitectura de visualizaciones


Una vez que tenemos realizado todo el sistema de control de la matriz y de comunicaciones, el siguiente paso es comenzar a implementar las visualizaciones.
Para ello, hemos definido un esquema simple de visualización, en cada iteración del bucle loop, se llama a un método llamado visualizaciónLoop (), este método es llamado continuamente. Este método se divide en dos partes de funcionamiento.
  • En la primera, se comprueba si es hora de un nuevo refresco de la visualización. Para ello se basa en el uptime del Arduino, que, por defecto, es devuelto por la función millis() en milisegundos, y que es contabilizado por el timer0, que está configurado para interrumpir cada milisegundo.
  • En la segunda, se encarga de procesar los datos recibidos por el sistema serie para representar el efecto adecuado en la matriz.

La forma en la que se integran estas dos funciones es la siguiente:
  • En cada llamada, primero se comprueba si es hora de un refresco de la matriz, si es así, se realiza.
  • A continuación, se comprueba si se ha recibido datos, a través de la flag de recepción que hemos instaurado.
Cada visualización tiene sus tiempos de refresco y toma los datos que requiera de recepción.

El esquema del funcionamiento del software de Arduino es el siguiente:
Diagrama de flujo de las visualizaciones

Recepción de datos para visualizaciones


Para recibir los datos necesarios para la visualización desde el ordenador, hemos implementado un sencillo protocolo para el puerto serie.
Este permite recibir tanto tramas como bytes de comando.
Los bytes de comando son los siguientes:
  • 205 – Activar visualización audiorítmica
  • 206 – Activar visualización de vúmetro
  • 207 – Activar visualización de puntos
  • 208 – Activar modo demo de la matriz.


Así mismo, es necesario que reciba tramas de datos con datos tanto de energía espectral como de notas tocadas por un instrumento. Para ello se definen las siguientes tramas:
  • Trama de energías: 200 + 8 bytes de energía (intervalo 1-100), uno por banda + byte de energía total
  • Tramas de instrumentos: hay cuatro canales, el primer byte será 201, 202, 203 o 204 según el canal 0 a 3, y los dos bytes siguientes serán la frecuencia de nota y la intensidad, en escala de 1 a 17, y 1 a 16 respectivamente.


Los canales de instrumentos comentados no son los canales de instrumentos de la norma MIDI, sino los que nosotros vamos a usar en la visualización.

Nuestra rutina de recepción se encarga de almacenar estos datos, y una vez que la trama en recepción se ha completado, activa una variable flag global para informar al hilo principal del programa. De igual forma, tenemos un contador de bytes recibidos, que es usado por la visualización PopVis.
El esquema del funcionamiento de la rutina de recepción es el siguiente:
Diagrama de flujo de la rutina de interrupción.

domingo, 13 de mayo de 2012

Más prestaciones: Reproductor de audio


Para dar un poco más de variedad a las prestaciones del software, decidimos incluir un reproductor de archivos de audio. Así damos al usuario la posibilidad de escuchar una melodía de acompañamiento mientras toca sobre ella con su controlador MIDI externo.


Este patch abre un archivo de audio (exclusivamente, no reproduce mp3) y guarda el contenido de los dos canales, izquierdo y derecho, en dos arrays, redimensionándolos adecuadamente hasta un tamaño máximo de 4000000 de muestras (4000000 muestras / 44100 muestras/sg = 91 segundos aproximadamente).


A continuación, los controles integrados en la interfaz gráfica de 'Play', 'Pause', 'Stop', y los cursores de velocidad de reproducción y de posición actual en la canción permiten controlar un puntero que va reproduciendo la señal a medida que recorre los dos arrays. También existe un control de volumen, así como la posibilidad de añadir reverberación a la señal de audio reproducida mediante una serie de parámetros configurables en la interfaz.
as_lecturaAudio: nuestro reproductor de música

miércoles, 9 de mayo de 2012

Unas cuantas pruebas: Matriz LED, otras síntesis y Wiimotes


Llegados a este punto, realizamos pruebas para comenzar a ver representaciones en la matriz de LEDs a partir de números enviados por el Pure Data. Conseguimos mandar mensajes al microcontrolador para realizar tareas sencillas (como activar una luz aleatoria en la matriz) y algo más complejas (calcular la media de notas por segundo y realizar una visualización acorde con ella).


Síntesis por tabla de ondas:
esquema de funcionamiento
Hemos comenzado ya a probar otros tipos de síntesis, como la síntesis por tabla de ondas o la síntesis basada en samples, que más adelante nos podrían permitir reproducir sonidos realistas de buena calidad de instrumentos acústicos.


Por último, también hemos conseguido conectar dispositivos como un mando de PS3 o un Wiimote a nuestro software para poder modelar sonidos con ellos y comenzar a hacer cosas algo más novedosas. Utilizamos un objeto existente en las librerías de PD llamado ‘hid’ el cual permite acceder a los datos que envían varios dispositivos de “interfaz humana” como un ratón, un joystick, o un mando.


Desgraciadamente, los acelerómetros del mando de PS3 y todos los controles del Wiimote no siguen la especificación y por tanto no pueden ser usados directamente. Existen drivers externos como GlovePie (Windows) y OSCulator (Mac OS) que se conectan a estos dispositivos y hacen de enlace con el Pure Data. OSCulator, por ejemplo, encapsula los datos en tramas UDP y los envía a un puerto virtual al que se puede acceder desde el programa. A pesar de poder contar con ellos, decidimos apartar un poco la idea ya que implementarlo de esa forma se sale de la concepción multi-plataforma en la que basamos nuestro proyecto.

sábado, 5 de mayo de 2012

Matriz RGB: esquemático del hardware

Hemos realizado el esquemático del hardware de la matriz RGB (para posteriormente hacer la PCB), el esquema de toda esta parte puede descargarse aquí.

Cuando tengamos la placa PCB diseñada, subiremos los archivos de Eagle.

miércoles, 2 de mayo de 2012

Interfaz gráfica de usuario 1: primera aproximación

Para hacer que todos los módulos que vamos a incluir en nuestro software confluyan de forma eficiente y que el músico pueda usar nuestro software más intuitivamente, necesitamos dotar a nuestro programa de una interfaz gráfica de usuario.
Interfaz de usuario de ArduinoSynth: primera aproximación
Pure Data es un lenguaje de programación potente que permite, además de procesar flujos de datos y de audio fácilmente, crear interfaces visuales con paneles, botones, sliders y demás controladores que modulan el comportamiento de los demás objetos del programa.
Además de la carátula del módulo sintetizador que ya trae el ‘polywavesynth’, diseñamos la base de una interfaz completa con los siguientes elementos:

  • Subsistema de comunicación con Arduino En él podemos abrir y cerrar comunicación con el puerto serie correspondiente, activar o desactivar la ejecución del módulo de Active Sensing, del parseado de tramas MIDI y de la computación de audio del Pure Data. En este módulo se encuentra todo el código de la puesta a punto del sistema MIDI (toda la comunicación con la placa).
  • MIDI Display Aquí se muestra el flujo de instrucciones MIDI según llegan al PC, cuyos bytes han sido parseados y se muestran de forma inteligible, utilizando una mejora del patch pd printMidi (explicado aquí) y redirigiendo los mensajes de la consola a la interfaz gráfica (Por ejemplo, al tocar un La bemol en el canal 1 veremos en la pantalla: [Channel 0] | | | NoteOn | | | Ab4 | | | 88 | | | ).
  • LED Matrix Dentro de este módulo se aloja el sistema encargado del análisis de las tramas y del envío de mensajes de control de la iluminación.
  • Módulos de síntesis En la zona inferior se dispone de un espacio para los módulos de síntesis que se deseen emplear. En las primeras pruebas colocamos 8 ‘polywavesynths’ para comprobar que podíamos reproducir varios instrumentos simultáneamente, pero podemos recolocarlos para dejar sitio a los demás módulos.

domingo, 29 de abril de 2012

Síntesis FM. Polifonía

Ahora que ya tenemos la capacidad de producir sonidos simples, lo primero que nos llama es la necesidad de proporcionar polifonía a nuestro sintetizador para poder tocar varias notas simultáneamente en nuestro controlador MIDI.


Comenzamos añadiendo el objeto ‘poly’ a nuestro sintetizador monofónico, consiguiendo reproducir señales sinusoidales de distinta frecuencia (en función de las teclas presionadas) a la vez. Sin embargo, seguía siendo un sonido musicalmente pobre, así que buscamos ayuda en la red y encontramos un trozo de código llamado ‘polywavesynth’, de libre distribución. 


Gracias a este módulo de síntesis FM conseguimos sonidos más interesantes para nuestro sintetizador modulando distintos tipos de señales. Posee un generador de envolvente, un filtro paso bajo con control de frecuencia de corte y resonancia, control de balance estéreo y posibilidad de implementar fácilmente un módulo para ruedas de ‘pitch bending’ (presentes en la gran mayoría de teclados controladores para modular la frecuencia del sonido).


'as_synthModule': módulo de síntesis FM
Además, hemos añadido soporte para pedales de sustain, imprescindibles para tocar pianos y muy útiles para otros tipos de instrumentos; hemos reconfigurado el módulo de Active Sensing para que funcione con nuestro nuevo sintetizador; y por último y muy importante, hemos implementado la opción de separar y routear los flujos de datos de los 16 canales MIDI virtuales para independizarlos y otorgar un sonido distinto a cada uno de los instrumentos asignados a cada canal.


La versión final del módulo incluye la opción de añadir reverb al sonido y contiene una lista de presets, así como un submódulo que permite guardar y cargar configuraciones de parámetros en el sintetizador. Además, el audio generado se envía por dos canales a un mixer en lugar de ser dirigido directamente al DAC. De esta forma, podemos recoger todos los canales de todos los módulos en un sólo lugar cuya suma será la que enviemos finalmente a la salida de audio.


De esta forma, y como hemos podido comprobar en las pruebas, creando varios módulos sintetizadores tenemos capacidad para reproducir canciones con diferentes sonidos de diferentes instrumentos que tocan al mismo tiempo.

sábado, 28 de abril de 2012

Librería gráfica: MatrixController

Durante todo el desarrollo, hemos ido creando funciones para abstraer el funcionamiento de los canales PWM de la matriz en pos de programar basado en pixeles y colores RGB. Hace poco, hemos cogido todos estas funciones y las hemos reunido en una librería de Arduino que es la que maneja directamente nuestra librería Tlc5940Mux modificada.

La librería se puede descargar aquí: MatrixController 1.0.

Esta librería se usas creando una instancia con  
MatrixController matrix;

Se inicializa con:
matrix.init(0);

Y dispone de una serie de métodos, bastante autodescriptivos, aunque están documentados en la propia librería:

matrix.setPixel(1,2,4095,4095,0);
Pone el tercel píxel de la segunda columna (1,2) a una mezcla de rojo y verde.

matrix.setRow(0,0,0,4095);
Pone la fila superior a azul.

Los rangos de fila y columna son de 0 a 8, y los de cada canal RGB de color de 0 a 4095 (12 bits por canal, color de 36 bits).

La lista de funciones completas es:
  • init
  • setPixel
  • setRow
  • setCol
  • setMatrix
  • getPixelR
  • getPixelG
  • getPixelB
  • shiftFila
  • shiftRowData
Requiere de escribir el código de la ISR en el propio sketch que la use, aunque este es el siguiente:
/** It's 0 if there is no multiplex operation taking place currently, and different if yes.
    If everything's fine, it shouldn't be neccesary...
    */

volatile uint8_t isShifting;
/** Stores the actual row that is being excitated in the RGB display.
    */
uint8_t shiftRow;
/** Excitates the desired row. The power stage is active low.
    \param row, The index of the row that should be activated. */
inline void setRow(int row) {
  PORTC = row;
}
/** Interrupt subrutine for Timer1, called after each PWM cycle.
    It switchs the row and shifts the new colour data.
    */
ISR(TIMER1_OVF_vect)
{
  if (!isShifting++) {
   
    digitalWrite(BLANK, HIGH);  // turn off the outputs. It's the first thing to avoid row interference
    __asm__("nop\n\t");  // small delay after sending the data before transfering it to the registers
    // set the registers
    digitalWrite(XLAT, HIGH);             
    __asm__("nop\n\t");      
    digitalWrite(XLAT, LOW);     
    __asm__("nop\n\t");  // delay before turning on the outputs
    setRow(shiftRow);          // set the new row
    digitalWrite(BLANK, LOW);      // turn on the outputs 
    if (++shiftRow == NUM_ROWS){  // update the row variable
      shiftRow = 0;
    }
    matrix.shiftRowData(shiftRow);  // shifts the data of the next row, it only will take place in the following row change
    isShifting = 0;
  }
}


Este código se encarga de realizar los cambios de fila.

Para comprender el funcionamiento y uso, ver el sketch de ejemplo incluido en la carpeta examples de la librería de Arduino.

martes, 24 de abril de 2012

Presentación Hito 2

El pasado viernes 20, realizamos la presentación del hito 2 ante el DIE y los autores de las demás prácticas innovadoras del curso.


La presentación mostrada se puede descargar aquí.


En ella hemos presentado una aproximación de visualización audiorítmica, así como los progresos comentados aquí y algunas pinceladas que están pendientes de publicarse. También hemos comentado el trabajo destinado al hito final.

La visualización mostrada es la siguiente:

En el video NO se corresponde con la música, en la presentación sí que se mostró comanda por una fuente MIDI.

Interfaces serie: librerías e interrupciones

AtMega 2560 (4xUSART).
El entorno Arduino implementa la comunicación serie a través de la libreria integrada Serial. Esta se encarga de manejar las interupciones de las USART/UART de Arduino, configurar el hardware y gestionar el flujo de datos.
Particularmente, maneja las interrupciones de dato recibido y de dato transmitido, añadiendo o recogiendo los datos de sendos bufferes circulares, de forma que un sketch de Arduino pueda mandar datos a la UART sin preocuparse de si la unidad tiene trabajo en ese momento o no.
Esto trae el inconveniente de la recepción de datos, se ha de consultar periódicamente en el programa si se han recibido datos nuevos.
La referencia de la librería se encuentra aqui.


Con nuestro sistema, hemos experimentado pérdida de tramas, es decir, algunos bytes que deberían ser redirigidos desde el puerto MIDI al PC se pierden. Esto ocurre particularmente a velocidades altas de notas usando varios canales o instrumentos a la vez.
Al basarse la librería Serial en bufferes, nos lleva a pensar que se pierden las tramas al llenarse el buffer de recepción antes de que nuestro programa los procese.

Para solucionarlo, hemos estado leyendo acerca de manejar la UART directamente, sin la librería de Arduino, y procesar nosotros mismos las interrupciones. En concreto, la mayoría de información la hemos obtenido de este post del foro de Arduino: Interrupt-driven USART reception: I'm stumped.

Usando parte del código allí posteado, y cambiando algunos datos, como los vectores de interrupcion USART0_RX_vect y USART1_RX_vect, hemos hecho la librería de comunicaciones para nuestro sistema.

Se puede descargar aqui.

Contiene tanto los archivos ArdSynthComm.h, ArdSynthComm.cpp y keywords.txt (resaltado de sintaxis del entorno Arduino), como un par de ejemplos de uso: USBecho y MIDIreplicator. En sendos ejemplos se describe su función.


jueves, 12 de abril de 2012

It's all about timing: correcciones en la matriz RGB

Matriz.
Con la matriz, ya habíamos comentado el problema de interferencia entre filas aqui.

Tras examinar exhaustivamente los cronogramas producidos por el micro, el problema consistía en proceso de cambio de fila. Este, al principio, seguía el siguiente esquema:
  • Cambio de fila
  • Envío de datos de la nueva fila
  • Activado de señal BLANK para resetear salidas y de señal XLAT para escribir los nuevos datos.
  • Desactivado de XLAT y BLANK.
El problema residía en que, durante el tiempo que tarda en enviarse los datos de la fila i+1, los colores de la fila i se estaban pintando en la fila i+1 ya que se había cambiado la fila al principio.

La primera opción es modificar la rutina de interrupción para que sigua el siguiente esquema:
  • Activado señal BLANK
  • Envío de datos de la nueva fila
  • Activado de señal XLAT
  • Cambio de fila
  • Desactivado de señal XLAT y BLANK
Esto elimina los problemas de filas, pero nos ha llevado a ver un problema de temporización.
Cronograma, con errores de temporiz.
Para explicarlo claramente, es mejor examinar el cronograma de la imagen (pinchar para ampliar).
  • En él, tenemos la señal GSCLK, generada por el Timer2, de forma continua, a 8 Mhz y que se encarga de incrementar los contadores.
  • El timer 1 interrumpe cada 4096 ciclos de GSCLK y se encarga de activar las señales BLANK, XLAT y transmitir por SPI, además de cambiar de fila.
  • Las salidas del TLC5940 funcionan cuando la señal BLANK está a nivel bajo, y mientras no se hayan recibido más de 4096 ciclos de GSCLK tras la última bajada de BLANK.
El problema viene dado por el tiempo que BLANK está a nivel alto, ya que, si se cambia de fila cada 4096 ciclos de GSCLK, y BLANK está a nivel alto cierto tiempo, resulta en ciclos de GSCLK que no se realizan ya que no da tiempo entre los pulsos de BLANK, reduciendo la gama cromática, y no representando los colores adecuadamente.

La solución más básica es aumentar el número de ciclos de GSCLK que pasan entre cada interrupción para el cambio de fila, de forma que quepan 4096 ciclos (512 microsegundos) entre cada pulso de BLANK. Para realizarlo de forma aproximada, hemos medido dicho tiempo con el osciloscopio, y ajustado el valor del registro de captura del Timer (ICR1) para que coincida.
Esto, evidentemente, conlleva una perdida en la velocidad de refresco, quedandose en 200 Hz (en vez de los 244 Hz originales), ya que se necesitan 1120 ciclos más de GSCLK para que todo cuadre.


Tras esta corrección, la parte de control de la matriz podría haber quedado así, pero encontramos una solución mejor para optimizar el refresco.
El chip TLC5940 admite recibir datos durante un ciclo de PWM, y solo escribe los valores cuando llega la señal XLAT, luego, podemos transmitir los valores de la nueva fila mientras se está iluminando la anterior.
Resulta el siguiente esquema:
  • Activar señal BLANK 
  • Activar señal XLAT
  • Cambio de fila
  • Desactivado de BLANK y XLAT, la matriz empieza a iluminarse
  • Envio de los datos de la siguiente fila.
Con esta técnica, la duración del pulos de BLANK es mucho menor. Ajustando la temporización de la forma comentada anteriormente, sólo necesitamos 170 ciclos extra de GSCLK, y el refresco se queda en 235 Hz.

Con esto, creemos finalizado el diseño de la parte de la matriz RGB, aunque posteriormente se podría implementar la lectura de la flag de error XERR, dot correction o lectura del registro de estado, pero no son imprescindibles para el proyecto.
Cuando acabemos la temporización del micro, intentaremos comproblar con un analizador lógico que toda la temporización funciona de forma adecuada.