Software - adrihigu/Proyecto-afinador GitHub Wiki
Programación en Processing
Elegimos este entorno de programación debido a que posee herramientas ya implementadas y fáciles de aprender para realizar la interfaz de usuario. Además, gracias a su compatibilidad con Java, nos dio la oportunidad de desarrollar una buena solución para parte pesada del procesamiento de los datos sin tener que recurrir a la ejecución conjunta de otros programas de cálculo, tales como MatLab, para llevar a cabo esta tarea en tiempo real.
En primer lugar, la recepción serial de los datos provenientes del módulo DEMOQE fue manejada a partir una interrupción serial, que se dispara cada vez que el buffer de lectura está disponible. Como al iniciar el programa el primer byte que se lee puede no ser un encabezado, es necesario sincronizar la lectura del buffer antes de empezar a decodificar la data. Para ello, lee byte a byte hasta encontrar un encabezado, solo entonces pasa a estar sincronizado.
Luego, lee el tipo de encabezado que recibe: si lee 0xF1, asigna el tamaño del buffer a 3 bytes; si lee 0xF2, asigna 5 bytes al buffer y habilita la decodificación del canal 2 a la siguiente vuelta. Nótese que el canal 1 siempre se decodifica mientras haya sincronización. De este modo, al salir de la interrupción serial y al volver a entrar, se tienen al final del buffer de lectura el encabezado del siguiente bloque y se repite el proceso. En el caso en que el último byte leído resulta no ser un encabezado, pasa a estar desincronizado.
En la decodificación, se asigna el estado de los sensores digitales a variables booleanas, de modo que “true” denota que el pulsador está presionado y “false” sin presionar. Como los modos de operación del afinador se manejan mediante pulsadores, se han tomado los flancos de subida como indicadores de encendido y apagado de dichas funcionalidades, asignando allí el estado del sistema. En esta sección del código también se realizan las operaciones lógicas pertinentes para obtener los datos de los sensores analógicos decodificados, guardando en variables de tipo lista los valores para su posterior procesamiento.
La etapa de procesamiento está asociada a la detección de la frecuencia fundamental de la señal de audio proveniente del micrófono. Ante todo, damos crédito por la implementación del algoritmo de detección de tono a los desarrolladores de TarsosDPS, un conjunto de librerías implementadas en Java para procesamiento de audio en tiempo real (Ref 1). El algoritmo YIN en el que está basado se explica detalladamente en la referencia 2.
Dado que está hecho en Java con programación orientada a objetos, para hacer uso del algoritmo es necesario crear un objeto de la clase “PitchDetector” que implementa el método en cuestión. Dicha clase tiene como parámetros de inicialización la frecuencia de muestreo y la cantidad de muestras del arreglo de datos, en este caso 3640.89Hz y 512 muestras, respectivamente.
En la parte principal del programa, se procesan los datos solo cuando el buffer que contiene los valores del primer canal analógico alcanza el número de muestras especificadas. Luego, se llama al método “getPitch()” introduciendo como parámetro el arreglo de datos, devolviendo un objeto “PitchDetectionResult”. Este a su vez posee un método que devuelve la frecuencia captada en una variable float, que es guardada en una lista para su visualización en la interfaz de usuario. Finalmente, la lista con los valores de la señal del micrófono es borrada.
Figura 1. Interfaz de usuario en modo dinámico
Figura 2. Interfaz de usuario en modo estático
Figura 3. Interfaz de usuario en modo afinador de guitarra
Figura 4. Interfaz de usuario en modo afinador de violín
Los elementos más importantes de la interfaz de usuario (Figura 1) son:
El gráfico de barras verticales que se desplaza a medida que se detectan nuevos tonos. Cada rectángulo representa la altura musical del tono, donde el más reciente aparece a la derecha con su nombre y una barra horizontal a lo largo de la ventana.
La(s) barra(s) horizontales de referencia de acuerdo al modo de operación. En modo dinámico, hay sólo una barra en movimiento que se actualiza en tiempo real, mientras que en modo estático esta se mantiene constante mientras ocurre la detección de tono. El valor de la referencia se fija como el promedio de las medidas del segundo canal analógico con el fin de reducir los efectos del ruido sobre la señal potenciómetro. En modo afinador para guitarra o violín, se muestran simultáneamente los tonos de referencia asociados a la afinación de las cuerdas de cada instrumento. Estas son de color azul para diferenciarlas del tono captado, además, para estas el nombre de los tonos aparece a la derecha.
Por último, en la esquina superior derecha se tiene un mensaje que indica si se está por debajo, por encima o en la nota de referencia. A la izquierda, se indica el tono actual de la referencia y el detectado, así como el modo de operación y el mensaje “(PAUSA)” si se presiona la barra espaciadora o el cuarto pulsador del DEMOQE. Cuando el sistema está en pausa, no se ejecuta la detección del tono ni se actualiza la interfaz de usuario.