Full text
AN EUCLIDEAN SEQUENCER PLUGIN FOR DIGITAL AUDIO WORKSTATIONS UN PLUGIN DE SECUENCIADOR EUCLIDIANO PARA ESTACIONES DE TRABAJO DE AUDIO DIGITAL TRABAJO FIN DE GRADO CURSO 2021-2022 AUTORES DAVID BURGOS DÍAZ GONZALO COSTALES DE LEDESMA DIRECTOR MIGUEL GÓMEZ-ZAMALLOA GIL GRADO EN INGENIERÍA INFORMÁTICA FACULTAD DE INFORMÁTICA UNIVERSIDAD COMPLUTENSE DE MADRID
0
AN EUCLIDEAN SEQUENCER PLUGIN FOR DIGITAL AUDIO WORKSTATIONS UN PLUGIN DE SECUENCIADOR EUCLIDIANO PARA ESTACIONES DE TRABAJO DE AUDIO DIGITAL TRABAJO DE FIN DE GRADO EN INGENIERÍA INFORMÁTICA DEPARTAMENTO DE SISTEMAS INFORMÁTICOS Y COMPUTACIÓN AUTORES DAVID BURGOS DÍAZ GONZALO COSTALES DE LEDESMA DIRECTOR MIGUEL GÓMEZ-ZAMALLOA GIL CONVOCATORIA: Junio 2022 CALIFICACIÓN: GRADO EN INGENIERÍA INFORMÁTICA FACULTAD DE INFORMÁTICA UNIVERSIDAD COMPLUTENSE DE MADRID 17 DE MAYO DE 2022
2
3
4
Índice general Índice i 1. Introducción 3 1.1. Motivación..................................... 3 1.1.1. Unpocodehistoria............................ 3 1.1.2. Estaciones de Trabajo de Audio Digital . . . . . . . . . . . . . . . . . 4 1.1.3. Plugins................................... 5 1.2. Objetivos ..................................... 5 1.3. Plandetrabajo.................................. 7 2. Estado del arte 9 2.1. Origen de los ritmos euclidianos . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2. Estaciones de Trabajo de Audio Digital . . . . . . . . . . . . . . . . . . . . . 11 2.3. Plugins....................................... 13 2.4. Secuenciadores .................................. 15 3. Manual de uso del plugin 18 3.1. Instalación..................................... 18 3.2. Estructuradelplugin............................... 20 3.2.1. Representación gráfica de los ritmos . . . . . . . . . . . . . . . . . . . 20 3.2.2. Componentes individuales de cada ritmo . . . . . . . . . . . . . . . . 21 3.2.3. Otros componentes del plugin . . . . . . . . . . . . . . . . . . . . . . 22 3.3. Ejemplosdeuso.................................. 23 4. Implementación 26 4.1. Conceptosbásicos................................. 26 4.2. JUCE ....................................... 26 4.2.1. Projucer.................................. 27 4.2.2. Estructura de un plugin de audio en JUCE . . . . . . . . . . . . . . . 27 4.3. ClaseEuclideanRhythm ............................. 29 4.3.1. Atributos ................................. 29 4.3.2. Funciones ................................. 31 4.4. PluginEditor.................................... 32 4.4.1. Atributos ................................. 32 4.4.2. Funciones ................................. 32 4.5. PluginProcessor.................................. 34 4.5.1. Atributos ................................. 34 i
4.5.2. Funciones ................................. 35 5. Contribuciones al proyecto 37 5.1. DavidBurgosDíaz ................................ 37 5.2. Gonzalo Costales de Ledesma . . . . . . . . . . . . . . . . . . . . . . . . . . 41 6. Conclusiones y Trabajo futuro 44 6.1. Conclusiones.................................... 44 6.2. Trabajofuturo .................................. 45 7. Introduction 46 7.1. Motivation..................................... 46 7.1.1. Historicalcontext............................. 46 7.1.2. Digital Audio Workstations . . . . . . . . . . . . . . . . . . . . . . . 47 7.1.3. Plugins................................... 48 7.2. Objectives..................................... 48 7.3. WorkPlan..................................... 49 8. Conclusions and future work 51 8.1. Conclusions .................................... 51 8.2. Futurework.................................... 51 Bibliografía 53 ii
Resumen Un plugin de secuenciador euclidiano para estaciones de trabajo de audio digital La constancia en el desarrollo y la innovación en la informática desde que la conocemos ha supuesto a lo largo del tiempo una revolución en muchos sectores. En esta ocasión nos centraremos en el musical, ya que, echando la vista atrás varias decenas de años, para realizar una composición musical eran necesarios muchos medios e instrumentos que hacían de esta, una tarea a veces ardua y compleja que muy pocos podían llevar a cabo. Sin embargo, todo esto ha cambiado ya que hoy en día cualquier persona puede ser productor de música con el simple hecho de tener un ordenador a su alcance. Que esto sea posible se lo debemos a las DAWs, del inglés Digital Audio Workstations o estaciones de trabajo de audio digital. Una DAW es básicamente un programa o software que permite grabar, editar, procesar y mezclar múltiples pistas de audio, además de escribir música y hacerla sonar mediante instrumentos virtuales. A parte de la infinidad de funcionalidades por defecto, las DAWs pueden ser extendidas mediante plugins externos. Dentro de este gran abanico de plugins, cabe destacar por su relación con este proyecto, a los secuenciadores. La función de estos es la de secuenciar música, o en otras palabras, programar eventos musicales en el tiempo. Esto es posible haciendo uso de cierta información proporcionada por el usuario en forma de acordes, parmetros, etc.. u otros datos recogidos de la interfaz gráfica de usuario. El fin de este proyecto es desarrollar un plugin de secuenciador euclidiano, que está basado en los ritmos euclidianos, cuyos orígenes provienen, como más adelante se explica, del Algoritmo de Euclides. Resumidamente, usando el máximo común divisor logra colocar elementos en una secuencia de la manera más uniforme posible en una división de tiempo dada, estableciendo un número de pasos y de eventos que definen un patrón rítmico. De este modo, gracias a la función que realiza este plugin de generación de eventos musicales, si lo combinamos con otro de instrumento virtual, se estaría generando música de manera casi automática. Palabras clave audio digital, DAW, plugin, VST, MIDI, JUCE, ritmos euclidianos, secuenciador euclidiano
Una vez finalizada la construcción de este plugin, y entendido el manejo y creación de eventos MIDI, empezamos a desarrollar el proyecto final. Tras numerosas versiones a lo largo de este proceso de desarrollo se consiguieron implementar los componentes y funcionalidades básicos del plugin, destacando el controlador principal del ritmo, que permite al usuario mediante sliders rotativos seleccionar el número de pasos y eventos del mismo, y otros controles adicionales, desde el control de dirección del ritmo, hasta posibilidad de agrupar las notas en tresillos y notas con puntillo. Además, se invirtió una gran cantidad de tiempo a la interfaz debido a su gran complejidad que requiere de señales que la hagan cambiar en tiempo real a una gran velocidad. Finalmente, se implementaron las funcionalidades de guardar y cargar presets que dieran la posibilidad al usuario de almacenar las configuraciones y ritmos que desee para su posterior uso. 8
Capítulo 2 Estado del arte Para lograr entender lo útil e importante que puede ser un plugin de estas características dentro del campo de la producción musical debemos desarrollar una explicación del estado en el que se encuentran este tipo de generadores/efectos de MIDI. Para ello explicaremos un poco más en detalle las distintas herramientas que componen las DAWs, los tipos de plugins que hay y lo que es un secuenciador, pero antes, un poco de contexto. 2.1. Origen de los ritmos euclidianos En 2004, el informático Godfried Toussaint descubrió lo que eran los ritmos euclidianos en la música y la capacidad que tenían para generar casi todos los ritmos alrededor del globo, exceptuando la India. En 2005, este mismo profesor describió lo que eran estos ritmos en su paper "The Euclidean Algorithm Generates Traditional Musical Rhythms"9. En este paper, Toussaint aplica el algoritmo de Euclides del maximo común divisor de dos números, correspondientes al número de pasos de un ritmo, y al número de eventos o pulsos del mismo. El resultado obtenido son los números de pulsos y silencios de un ritmo, quedando los pulsos de un ritmo equidistantes entre sí. El algoritmo a continuación explicado es el cual el profesor desarrolló en el paper, directamente implementado con el algoritmo de Euclides2. Pensemos en que un ritmo se puede representar directamente como una cadena binaria de 1s y 0s, donde los 1s representan eventos o pulsos y los 0s representan silencios de manera que, se desean distribuir uniformemente k eventos en n pasos. Si por ejemplo tomamos n = 12 pasos yk = 4 eventos el ritmo euclidiano resultante sería E(4,12) = [1,0,0,1,0,0,1,0,0,1,0,0]. El problema viene cuando el máximo común divisor de n y de k no es uno de estos dos números, es decir, que entre todos los eventos no hay el mismo número de silencios (eventos no equidistantes). Tomemos un ejemplo donde el máximo común divisor de n y k sea 1 para explicar el algoritmo, como por ejemplo, n = 13 yk=5: 9
1. Empezaremos colocando los cinco 1s seguidos de los ocho 0s correspondientes: [1111100000000] 2. Ahora procedemos a colocar cada 0 detrás de un 1, obteniendo 5 secuencias de pares [10] y tres 0s restantes: [10] [10] [10] [10] [10] [0] [0] [0] 3. Lo siguiente será distribuir los tres 0s restantes de una manera similar, colocando cada [0] detrás de una secuencia [10]: [100] [100] [100] [10] [10] 4. A continuación repetiremos el mismo proceso tantas veces sea necesario hasta acabar con una sola secuencia resultante: [1001010010010] Cabe destacar que, al ser una secuencia cíclica, la secuencia obtenida puede ser rotada, de manera que obtendríamos permutaciones del mismo ritmo, desplazando simplemente los eventos por el ritmo: rot([1001010010010], 1) = [0100101001001] Podemos ver diferentes ritmos en función de la rotación, por ejemplo, con el ritmo E(7,12). Este ritmo sin ninguna rotación corresponde al Bembé (a), con 1 rotación a la derecha corresponde al ritmo de palmeo del oeste del continente africano (b), y con 2 unidades de rotación a la derecha al ritmo Tambú de Curaçao (c): Figura 2.1:Ejemplos de rotación del Bembé africano Para descubrir y conocer muchísimos otros ritmos euclidianos como el tresillo cubano E(3,8), la cumbia colombiana E(3,4) o la Bossa-Nova brasileña E(5,16) se recomienda leer el paper de Godfried Toussaint anteriormente mencionado. 10
Tras una puesta en contexto sobre la historia que tiene a sus espaldas el plugin desarrollado en este proyecto, hablemos un poco más en profundidad sobre las DAWs, ya que son las herramientas donde las usaremos, y sobre los plugins, para ver los tipos que hay y como funcionan. 2.2. Estaciones de Trabajo de Audio Digital A pesar de la compleja interfaz que muestra una DAW al iniciarse, comprendiendo el funcionamiento de los siguientes elementos fundamentales, tendremos la posibilidad de llevar a cabo una producción musical. Para esta explicación tomaremos REAPER como representante, teniendo en cuenta que la gran mayoría de cosas que se presentan en esta DAW son análogas en cualquier otra. 1. Línea de tiempo: Es el esqueleto de una DAW, debido que a lo largo de esta línea es donde se irán colocando los diferentes bloques de audio o MIDI. En el eje horizontal está representado el tiempo, separado en diferentes compases, y en el vertical se diferencian las filas o pistas que componen el proyecto. Figura 2.2:Línea de tiempo en REAPER 2. Panel de control: Esta parte de la DAW es el centro de control de nuestro proyecto, desde donde podemos iniciar, pausar o grabar una secuencia del mismo. Además también se encuentran las características principales de nuestro proyecto como el compás musical o los pulsos por minuto ente otros, que nos indican la velocidad de reproducción. Estas características se pueden ajustar en cualquier momento para adaptarse a las necesidades que se deseen. Figura 2.3:Panel de control en REAPER 3. Control individual de pista: Una vez seleccionada la pista deseada de la línea de tiempo, se mostrará su vista con el control individual, donde se le podrán aplicar efectos y todo tipo de modificaciones, además de silenciarla (pulsando la "M") o aislarla (pulsando la "S") entre otras cosas. 11
Debemos hacer especial hincapié en esta parte de las DAWs ya que es el componente desde el cual se controlan los efectos o plugins que usamos en cada pista. Como podemos observar en la Figura 2.4, en cada pista destaca el bloque FX o bloque de efectos; este es el encargado de administrar el manejo del plugin o plugins que hayamos decidido usar en la pista. En el bloque FX es donde añadiremos los plugins a modo de secuencia, es decir, uno conectado a la salida de otro. Una de las principales características que lo conforman es que, dichos efectos son aplicados en tiempo en real. Veamos esto con un sencillo ejemplo: Imaginemos que tenemos un teclado MIDI por el cual introduciremos la entrada (las notas que deseemos tocar). A esta entrada se le podría aplicar una cadena de efectos formada por un arpegiador, un instrumento virtual de piano y finalmente un reverberador. De esta manera por ejemplo si se pulsa un acorde de do mayor, sonaría un patrón melódico con las notas do-mi-sol en un piano y con una cierta reverberación, donde si se modifica cualquiera de esos efectos, la salida se vería modificada instantáneamente. Figura 2.4:Control individual de pista en REAPER 4. Editor MIDI: Este componente lo que nos ofrece es una interfaz gráfica mediante la cual podemos programar eventos MIDI en el tiempo o, si han sido previamente grabados por ejemplo con un teclado MIDI, nos ofrece también la capacidad de editarlos. MIDI, de las siglas inglesas Musical Instrument Digital Interface, es un protocolo basado en la representación y el transporte de eventos cuya información simbólica representa notas musicales; destacando entre otros parámetros la duración, notación musical o intensidad. Este estándar tecnológico es el usado por las DAWs para represntar dicha información y además, como más adelante veremos, puede ser interpretada 12
por otros dispositivos, programas, o instrumentos electrónicos para generar una salida de audio. Para crear dichos evento solamente debemos abrir el editor MIDI e introducir valores con el ratón u otros dispositivos como teclados MIDI. Además, gracias a estos editores MIDI, podremos editar las características de cada nota individualmente, de modo que la customización nos facilite alcanzar las preferencias deseadas. Figura 2.5:Control individual de pista en REAPER 5. Mezclador: Este componente nos facilita una vista general de todas las pistas donde tendremos la posibilidad de modificar parámetros en todas ellas al mismo tiempo, o solamente en las que deseemos, desde un punto de vista común a todas. Figura 2.6:Control individual de pista en REAPER 2.3. Plugins Como hemos comentado previamente, VST, de las siglas Virtual Studio Technology, es el estándar de desarrollo y conexión de plugins más usado a día de hoy alrededor de todo el mundo. Dicho esto, se conoce como plugin VST a todo aquel software cuyo fin es ampliar las funcionalidades que una estación de trabajo de audio digital ya tiene. Dos de sus principales ventajas son, la capacidad de utilización y funcionamiento en cualquier DAW (REAPER, Ableton, Logic, etc...) y la respuesta en tiempo real del mismo, es decir, que vemos la respuesta o el cambio que produce el plugin VST en la pista de forma instantanea. Destacan 13
3 tipos principales de plugins: 1. Efectos de audio: Este tipo de plugins desarrollan la función de, tomar una entrada de audio digital, procesarla o transformarla, y devolver ese audio digital modificado. Podemos destacar entre ellos el ecualizador, el compresor o el reverb. Figura 2.7:Esquema de un efecto de audio 2. Instrumentos virtuales (VSTi): A diferencia de los efectos de audio, estos plugins lo que reciben es información musical simbólica (eventos MIDI) y sintetizan audio a partir de ellos, logrando emular el sonido de instrumentos reales como sintetizadores, bajos, o pianos, sin la necesidad de gastarse grandes cantidades de dinero en ellos. Figura 2.8:Esquema de un instrumento virtual 3. Secuenciadores/generadores MIDI: Estos plugins son parecidos a los primeros que hemos visto, los efectos de audio, con la diferencia que en lugar de recibir audio digital, pueden recibir MIDI, o no hacerlo. Esto significa que tienen la capacidad de generar, procesar y/o transformar MIDI. Algunos ejemplos destacables son el arpegiador, el generador de acordes, el humanizador o, como en el caso del plugin que se desarrolla en este proyecto, el secuenciador, más concretamente, el secuenciador euclidiano. Como veremos en la siguiente sección, hay varios tipos de secuenciadores dentro de los plugins generadores/efectos de audio, destacando el convencional, muchas veces confundido 14
Figura 2.9:Esquema de un generador/efecto MIDI con la propia DAW, y el secuenciador euclidiano. Tras estudiar como funcionan, podremos entender los procesos que llevan a cabo estos plugins de programar y reproducir eventos musicales (MIDI) de una forma secuencial con el fin de componer y llevar un control sobre equipos de música electrónica (sintetizadores, cajas de ritmos, samplers, etc...). 2.4. Secuenciadores Tras haber definido lo que son los ritmos euclidianos, a continuación veremos como a día de hoy se pueden conseguir haciendo uso de secuenciadores. La funión principal de estas herramientas es la de programar y reproducir eventos musicales (MIDI) de una forma secuencial con el fin de componer y llevar un control sobre equipos de música electrónica (sintetizadores, cajas de ritmos, samplers, etc...). Estos secuenciadores MIDI permiten al usuario grabar y editar música sin la necesidad de una fuente de entrada de audio. Estos datos luego se reproducen en un instrumento MIDI o módulo de sonido. Con este método, el intérprete puede seleccionar un sonido de piano para un fragmento musical y luego decidir que el fragmento funcionaría mejor como un sonido de órgano. 1. Secuenciador estándar: En su definición más amplia, un secuenciador es un programa o máquina física que permite grabar, editar y reproducir eventos musicales, siendo MIDI la interfaz de control más común para ello. Debido a la amplia cantidad de máquinas y sofware que se recogen bajo este término, esta no suele ser la definición de secuenciador estándar, entendiendose normalmente por “secuenciador” al secuenciador de pasos. El término “secuenciador de pasos” recoge máquinas y software que permiten generar secuencias rítmicas dividiendo el ritmo en pasos del mismo tamaño. Para ello se suele usar la representación de rejilla (vease la figura 2.10). Esta consiste en una matriz de huecos del mismo tamaño que se pueden ir rellenando, siendo los huecos silencios, y los bloques rellenos pulsos sonoros. Habitualmente el eje horizontal representa el tiempo, mientras que el eje vertical varía, pudiendo representar, por ejemplo, distintos elementos de un kit de percusión, normalmente llamados drum ma15
chine(figura 2.11) o las notas de un teclado, en cuyo caso el secuenciador se conocería como piano roll (figura 2.12). Figura 2.10:Secuenciador Polymath Figura 2.11:OneMotion drum machine Figura 2.12:Secuenciador Stochas 2. Secuenciador euclidiano: Este tipo de secuenciador es una muy buena alternativa al clásico secuenciador por pasos anteriormente descrito. Cambia el paradigma de programar los eventos MIDI y sus propiedades en una línea temporal de un compás, por la creación de patrones rítmicos euclidianos. En la práctica esto es mucho más sencillo de cómo suena en la teoría ya que, lo único que hay que hacer es introducir el número de total de pasos del compás, y el número de eventos o pulsos que deseamos que tenga, y será el propio plugin el que cree el ritmo, donde los pulsos introducidos estarán distanciados unos de otros de la manera más uniforme posible. Además de estos dos parámetros es posible ajustar muchos más, como la rotación del ritmo que anteriormente ha sido nombrada, la nota MIDI que queremos que suene, 16
Figura 2.13:Euclidean sequencer PRO 2.1 - Alkman le dirección en la que queremos que se interprete el ritmo, la intensidad de la nota y otros parámetros muy interesantes. A lo largo de este trabajo se irá estudiando el funcionamiento y la lógica de este plugin con el fin de poder entenderlo y desarrollar, aplicando lo aprendido, nuestro propio plugin de secuenciador euclidiano. 17
2. Error - Seleccione Preset: Producido porque se está intentando cargar un preset sin antes haber sido seleccionado ninguno en la comboBox. El cuadro de diálogo indicará que se debe seleccionar un preset. Figura 3.12:Error. Seleccione preset para cargar 3. Error - Preset Inexistente: Producido porque se está intentando cargar un preset seleccionado en la comboBox que no existe en el sistema, es decir, que ese slot esta vacío. El cuadro de diálogo indicará más detalles. Figura 3.13:Error. El preset seleccionado no existe Guardar preset: En esta operación nos podemos encontrar con 2 escenarios posibles: 1. Guardado exitoso: Se produce cuando, tras seleccionar el preset deseado en la comboBox, se guarda el estado del plugin de manera correcta en la ubicación adecuada como se muestra en el cuadro de diálogo. Figura 3.14:Preset guardado con éxito 24
2. Error - Seleccione Preset: Producido porque se está intentando guardar un preset sin antes haber seleccionado el slot o hueco en la comboBox. El cuadro de diálogo indicará que se debe seleccionar un slot donde guardar el preset de los 8 posibles. Figura 3.15:Error. Seleccione slot donde guardar el preset 25
Capítulo 4 Implementación En este capítulo se tratarán los conceptos que conforman el algoritmo del secuenciador euclidiano, así como el software que ha sido empleado para desarrollar el plugin, y el código usado para implementar las distintas funcionalidades. Con el fin de tener un repositorio común donde todos los autores pudiésemos acceder para descargar y subir los archivos necesarios que se fueran desarrollando, y además llevar un claro control de versiones, el software escogido ha sido GitHub. En el siguiente repositorio se pueden encontrar todos los que forman el proyecto:5. 4.1. Conceptos básicos Al activar cualquiera de las distintas etapas del plugin, esta empezará a generar mensajes MIDI en función de los inputs que introduzca el usuario. La funcionalidad básica la forman dos parámetros: el número de pasos, que indica el total de notas que tiene un compás y los eventos, que indica de estos pasos, cuántos han de sonar y cuantos no (los pulsos del compás). El algoritmo distribuye las notas que suenan y las que no de manera automática, de acuerdo a la definición de ritmo euclidiano. 4.2. JUCE JUCE es un marco para el desarrollo de aplicaciones multiplataforma orientadas al audio y la música de código abierto y desarrollado en C++. Cuenta con una extensa colección de clases con funcionalidades enfocadas al procesamiento de audio, interfaz de usuario, gráficos y conversión a JSON/XML entre otras, sobresaliendo en el apartado de procesamiento de audio debido a la gran cantidad de funciones que tiene para ello. De todas las utilidades que tiene, la más interesante de cara a este trabajo es la de desarrollar plugins. Cuenta con soporte para crear plugins con todos los formatos estándar (VST, VST3, AU, AUv3, RTAS o AAX), siendo VST3 el empleado para este proyecto, ya 26
que se trata de uno de los más eficientes en cuanto al consumo de CPU y es compatible con los principales sistemas operativos. Figura 4.1:Pequeño extracto del Class index con todas las funcionalidades de JUCE 4.2.1. Projucer Projucer es la herramienta de generación de proyectos de JUCE. Su utilidad principal recae en su capacidad de exportar proyectos de JUCE a un IDE, del inglés Entorno de Desarrollo Integrado. Una vez exportados los archivos y configuraciones del proyecto, Projucer genera de manera automática los archivos necesarios para que el proyecto se pueda compilar en la plataforma objetivo. Cuenta con compatibilidad para XCode, Visual Studio, Codeblocks y Linux Makefiles. 4.2.2. Estructura de un plugin de audio en JUCE Un plugin básico de JUCE cuenta con dos clases: PluginProcessor yPluginEditor. PluginProcessor es la clase que se encarga de procesar todos los mensajes MIDI que va a ir generando el plugin. Cuenta con los siguientes métodos para ello: prepareToPlay(): este método se llama nada más arrancar el plugin, y en él se incializan todas las variables que sean necesarias para el funcionamiento del mismo. processBlock(): este método se llama en intervalos de pocos milisegundos y es el encargado de realizar la generaración y el procesamiento de eventos MIDI que se escriben en el buffer MIDI de salida, además de procesar también las señales de audio que le llegan al plugin y devolverlas en el buffer de salida de muestras de audio, es decir, 27
Figura 4.2:Comienzo de un nuevo proyecto en Projucer es la función principal de nuestro procesador. Fijándonos en la Figura 4.4 veamos un sencillo ejemplo donde esta función variará el volumen de la señal de audio que le llegue mediante un parámetro controlado por el usuario: Figura 4.3:Sencillo ejemplo del funcionamiento de processBlock Para este ejemplo solo tendremos en cuenta el parámetro de entrada buffer, que como hemos comentado, es el encargado de procesar las señales de audio digital. Como vemos al principio del algoritmo, lo primero que se hace es recoger información sobre el número de canales de salida y entrada a tener en cuenta. Tras esto, y a modo de buenas prácticas, ponemos el cociente de variación de volumen 28
rawVolume a un nivel adecuado por defecto, además de vaciar el buffer de salida asegurándonos así de que no haya señales residuales. A continuación, iteraremos sobre todos los canales de entrada que tenemos y lo que haremos será, para cada uno de ellos, iterar sobre todos los samples que componen la señal de dicho canal y multiplicar cada uno de estos samples por el cociente de variación de volumen rawVolume. Con esto lo que conseguimos es variar el volumen de cada señal que nos entra sample a sample por cada canal. Por último, cabe destacar que en este caso, el valor rawVolume iría ligado a algún componente del PluginEditor encargado de recoger la entrada del usuario. PluginEditor es la clase encargada de mantener la interfaz del plugin, se encarga tanto de leer el input del usuario mediante los diferentes componentes (sliders rotativos, cajas de elección y botones), como de generar los gráficos de forma que se visualice el ritmo que se está generando. Para proporcionar y recibir información del procesador, esta clase cuenta con un campo de tipo PluginProcessor. Sus métodos esenciales son: paint(): este método se llama cada vez que es necesario redibujar alguna parte del plugin y se encarga de la generación de los gráficos del plugin. resized(): se llama cada vez que las dimensiones del plugin varían, y se encarga de la colocación de los distintos elementos que componen la interfaz. 4.3. Clase EuclideanRhythm A parte de la estructura principal que todo plugin de audio desarrollado en JUCE debe tener, en nuestro caso tenemos además una clase llamada EuclideanRhythm, cuya función es representar un ritmo euclidiano una vez es creado (como veremos a continuación) almacenando todos los parámetros necesarios para su correcto funcionamiento en forma de atributos, además de gran cantidad de funciones que permiten tanto al PluginProcessor como al PluginEditor interactuar con este pudiendo recibir información para saber en qué estado se encuentra y modificar parámetros del mismo, alterando sus características. 4.3.1. Atributos Entre muchos otros, los atributos más destacables por su importante relación tanto con la parte que procesa el plugin, como con la que mantiene su interfaz son: Steps,events yrotation: Estos valores enteros nos indican el número de pasos totales, eventos o pulsos, y rotación del ritmo respectivamente. Abarcan desde 0 a 32 excepto los steps, cuyo valor mínimo es 1. 29
EuclideanRhythm: Esta secuencia de 1s y 0s es la utilizada para almacenar el ritmo donde los 1s marcan los eventos y los 0s los silencios. Direction,reverse ypingPong: Se encargan, mediante valores booleanos, de indicar el sentido hacia el cuál el ritmo es interpretado. Direction =true indicará que el ritmo va en sentido horario, hasta que bien se ponga reverse =true, donde hará que el sentido se invierta, o bien pingPong tome el valor de true con lo que el ritmo, cada vez que llegue a su primer step, invertirá su sentido. NoteNumber,velocity: Encargados de, por medio de valores enteros, indicar el valor de las notas MIDI del ritmo y la intensidad de las mismas (valores de 0-127 donde 0 sería intensidad nula o silencio). FigureStep ygate:FigureStep es un float que, conectado a una comboBox del PluginEditor, nos da la posibilidad de elegir las figuras musicales de los pasos del ritmo (redondas - 1, blancas - 1/2, negras 1/4, etc...). Por otra parte, gate es un entero que nos permite decidir que porcentaje de esa figura (en tiempo) queremos que suene. Oscila entre un 0 y un 400 %, donde 0% sería un silencio, y un 100%, el tiempo correspondiente a la figura elegida. Triplets ydottedNotes: Estos dos booleanos nos dan la posibilidad de hacer que las notas de nuestro ritmo se conviertan en tresillos o en notas con puntillo. Además de estos parámetros que podemos modificar directamente interactuando con distintos componentes de la interfaz, cabe destacar, por su utilidad e importancia a la hora de hacer el procesamiento, los siguientes atributos: Index,bpm,sampleRate: El valor entero index nos indica la posición de la nota (el paso) del atributo euclideanRhythm anteriormente mencionado que se está procesando. El bpm y el sampleRate por su parte son valores recogidos de la DAW que nos indican la cantidad de pasos por minuto, o velocidad de reproducción el proyecto. Por otra parte el sampleRate nos indica la frecuencia de muestreo del mismo, es decir, el número de muestras por unidad de tiempo que se toman de una señal, normalmente 44100Hz (44100 muestras de la señal en 1s). stepDuration ytimeStep: Estos enteros representan respectivamente, la duración de un step en número de samples y el tiempo en número de samples que lleva procesándose ese step. (mismos dos parámetros respectivamente para las notas, noteDuration ytimeNote, que dependiendo del valor de gate coincidirán o no) NumSamplesPerBar ycurrentSamplerPerBar: Mediante dos enteros, expresan el número total de samples que tiene el ritmo, y el número del sample que acabamos de procesar, lo que nos sirve para ver por qué parte del ritmo vamos. 30
notesDurationMap: Por último, pero no menos importante, tenemos este mapa de <int, int>donde el primer valor identifica una nota MIDI y el segundo el número de samples que lleva sonando. Esto nos ayuda a mantener las notas MIDI sonando o no, de manera que cuando es el turno de un evento o pulso, se mandará el evento MIDI noteOn de la nota correspondiente al buffer MIDI de salida y se añadirá a este mapa. Esta parará de sonar cuando su segundo valor, el correspondiente al número de samples que lleva sonando, llegue al máximo (timeNote alcance el valor de noteDuration), mandando un evento MIDI noteOff al buffer MIDI de salida. 4.3.2. Funciones Tras haber destacado los atributos fundamentales de esta clase, comentaremos las dos funciones más importantes que, juntos con todos los getters ysetters que la componen, hacen que la clase EuclideanRhythm tenga una funcionalidad óptima: set_euclideanRhythm(int steps, int events): Esta función es la encargada de, en función en número de steps y events que reciba, producir la secuencia de 1s y 0s que conforman nuestro ritmo (atributo euclideanRhythm). Además, dependiendo del atributo rotation, se le aplicará una rotación u otra (por defecto este valor es 0, a no ser que el usuario lo haya modificado desde la interfaz). Figura 4.4:Función set_euclideanRhythm(int steps, int events) Esto es posible, tal y como vemos en la Figura 4.4, gracias a dos funciones auxiliares que dividen este proceso en dos etapas: •calculateRhythm(steps, events): Esta primera etapa del proceso consiste en obtener el ritmo euclidiano representado como una secuencia de 1s y 0s, donde los 1s (pulsos del ritmo) quedarán tan equidistantes como sea posible. Para conseguirlo, en lugar de usar el algoritmo que Godfried Toussaint desarrolló en su paper con este cometido, y que en capítulos previos ha sido explicado, hemos decidido usar el algoritmo de Bresenham 1, el cual permite obtener los mismos objetivos pero, desde nuestro punto de vista, con una implementación más sencilla. •rotateRight(this->_rotation): La segunda etapa, tras haber obtenido la secuencia de 1s y 0s que representan el ritmo euclidano, consiste en aplicarle el número de rotaciones que sea pertinente, tomando como parámetro de entrada el valor del atributo rotation de la propia clase (nótese que, si es 0, la secuencia de 1s y 0s quedaría igual). 31
convertBPMToTime(): Esta función es también fundamental ya que es la que obtiene, desde los bpm y el sampleRate del proyecto, la duración en samples de los steps y de las notas (la duración en samples de las notas también depende del gate como hemos comentado antes): stepDuration =60 ∗sampleRate ∗figureStep bpm . noteDuration =60 ∗sampleRate ∗(figureStep ∗gate 100 ) bpm . 4.4. PluginEditor Como ya se ha descrito anteriormente, esta es la clase encargada de mantener la interfaz, manejando el control de la misma y controlando lo que se está mostrando por pantalla. 4.4.1. Atributos Los atributos esenciales para el funcionamiento de esta clase son los siguientes: audioProcessor: Este atributo es una referencia al PluginProcessor. De este modo se tiene una manera rápida y eficiente de acceso a los atributos y funciones del PluginProcessor, que, como vamos a ver, ha creado a este objeto PluginEditor. Buttons, sliders ycomboBoxes: Contienen la lógica de los botones, sliders y demás elementos de la interfaz con los que el usuario puede interactuar. Los elementos que son particulares para cada una de las etapas del secuenciador, como por ejemplo el número de pasos o de eventos, están mantenidos en un mapa, con una entrada para cada una de las cuatro etapas del secuenciador, obteniendo así un código más limpio y fácilmente escalable. Attachments: Por cada elemento de lode recien nombrados que corresponden a una etapa (o ritmo) del secuenciador, existe su Attachments correspondiente. La función de los Attachment es la de ligar cada elemento de la interfaz con un parámetro de la estructura AudioProcessorValueTreeState. Esta estructura mantiene el estado completo del plugin en todo momento, y es útil tanto para almacenar configuraciones de parámetros, como para pasar valores al PluginProcessor. 4.4.2. Funciones A continuacion se van a describir las funciones más relevantes que conforman el PluginEditor: 32
EuclideanSequencerAudioProcessorEditor(EuclideanSequencerAudioProcessor&): Este es el constructor de la clase. En él se crean todos los mapas que alojarán a botones, sliders ycomboBoxes que van a conformar la interfaz. Además, también se ligan a sus respectivos Attachments y una vez inicializados con los valores correspondientes según su función. paint(juce::Graphics& g) ypaintRhythm(juce::Graphics& g, int seqID, float innerCircleProp): El fin de esta función es el de pintar la representación gráfica de los ritmos que haya activos. Tiene un bucle en el que, por cada etapa del secuenciador (máximo 4), coge uno de los mutex para que no haya corrupciones en memoria u otros errores, y tiene el correspondiente, llama a la función paintRhythm. Dicha función es la que realmente se encarga de representar gráficamente los ritmos, en función de los pasos, eventos y demás parámetros que conforman cada ritmo. Tras esta función el mutex queda liberado para que no hayas bloqueos en el plugin. Figura 4.5:Función paint(juce::Graphics& g)) setXParams: Este grupo de funciones son las encargadas de inicializar los distintos elemtentos interactivos de la interfaz. Por ejemplo, setNoteNumberComboBoxParams es la función dar los valores iniciales de las ComboBoxes que determinan la nota que suena en cada ritmo. resized(): Esta función es la encargada de establecer las posiciones de los distintos elementos que componen la interfaz. buttonClicked() ycomboBoxChanged(): Son los listeners de los distintos botones ycomboBoxes. Tras reconocer cual ha sido el elemento con el que se ha interactuado, se encargan de hacer los cambios o llamar a la función apropiada de PluginProcessor. disableComponents(int id) yenableComponents(int id): Activan y desactivan los componentes de cada etapa del secuenciador. El parámetro id indica de qué etapa se trata de las 4 que hay. 33
Después de haber estado investigando y estudiando cada uno de manera individual, empezar a trabajar de manera conjunta fue fácil ya que los conocimientos que teníamos, además de las ideas para el plugin, eran similares, de manera que lo que no sabía uno lo sabía el otro, y sino, siempre conseguíamos investigar un poco y acabar solucionando el problema que nos surgiera. Como ya he dicho, el desarrollo del plugin fue casi en su totalidad de manera síncrona, es decir, que las sesiones de trabajo que empleábamos para desarrollar el plugin eran simultáneas. Ya fuera de forma presencial, o trabajando cada uno de manera remota (estando en videollamada y haciendo uso de editores de código compartidos), los avances que el trabajo fue teniendo se debieron a que ambos estábamos involucrados en ellos. A continuación comentaré de manera más explícita cuáles fueron las aportaciones al trabajo en las que yo contribuí: Algoritmo de creación de ritmos euclidianos: Basándome en el anteriormente mencionado Aloritmo de Bresenham1, desarrollé un algoritmo que dándole el número de pasos totales y de eventos del ritmo, devuelve una cadena de 1s y 0s donde los 1s, correspondientes al número de eventos, están repartidos de la manera más uniforme posible. Steps slider yEvents slider: Creación y asociación de dos controladores a los parámetros steps yevents. Algoritmo principal: Desarrollo del algoritmo principal de processBlock que itera sobre cada paso del ritmo y crea y maneja los eventos MIDI de forma correcta. Rotation slider yNoteNumber comboBox: Creación y asociación de dos controladores a los parámetros rotation ynoteNumber. NoteDuration comboBox: Creación y asociación del controlador al parámetro noteDuration. Multi etapa: Diseño e implementación del modo multi etapa del plugin (máximo 4 etapas). Velocity slider: Creación y asociación del controlador al parámetro velocity. Limpieza y optimización de código: Limpieza y optimización de todo el código del proyecto para un óptimo escalado. On/Off buttons: Implementación de un botón de On/Off por cada etapa, que crea o destruye el ritmo correspondiente. Reverse mode: Implementación del botón Reverse, encargado de invertir la dirección del ritmo (hacer que se procese en sentido anti-horario). 40
Ping-Pong mode: Implementación del botón Ping-Pong, encargado de hacer que la dirección del ritmo pase a modo ping-pong (cambie de sentido cada vez que llega al principio/final del compás). Re-sync button: Implementación del botón Re-sync, encargado de sincronizar todos los ritmos haciéndolos empezar a todos de nuevo el compás. Diseño e implementación de la interfaz: Diseño e implementación de la representación gráfica de los ritmos del plugin. Triplets button yDotted button: Implementaciónes de las funcionalidades de tresillo y notas con putillo haciendo uso de dos botones. Reconocimiento y extinción de error añadiendo concurrencia: Extinción de un error que saltaba al corromperse el heap porque el PluginEditor accedía a partes de memoria que no debía. Esto era debido a modificaciones en ese instante de la memoria por el PluginProcessor. Éxito en la corrección haciendo uso de un mutex en el instante óptimo. Guardar/Cargar estado: Implementación del cargado y guardado de presets mediante un par de botones y una comboBox. Extinción de errores: Extinción de múltiples crashes que se producían al dejar de visualizar (minimizar) y luego volver a hacer visible el plugin en una DAW. Versión final del plugin: Retoques finales en el plugin y revisión de código. 5.2. Gonzalo Costales de Ledesma Previo al comienzo de este trabajo mis conocimientos sobre el procesamiento de audio eran escasos. Si bien sabía manejar DAWs, plugins y conocía el protocolo MIDI, mi conocimiento sobre como se implementaban estos era nulo. Como ya ha comentado mi compañero David, nuestra manera de abordar este proyecto consistió en consultar de manera asidua la documentación de JUCE, realizar los tutoriales propuestos en su web y ver videos de Youtube. En concreto, el ejemplo que más me sirvió para este trabajo fue el del arpegiador simple, que ilustra de manera muy simple la generación y procesamiento de mensajes MIDI. Fue a partir de este ejemplo como empezamos a conceptualizar y programar el bloque de procesamiento de nuestro plugin. El desarrollo del secuenciador se realizó en su gran mayoría de manera conjunta con David, como ya ha explicado previamente, por lo que es difícil separar las tareas entre los dos. A continuación voy a explicar más en profundidad las tareas que se realizaron y distinguir mi parte en ellas, en la medida de los posible: Algoritmo principal: Esta es la función básica del algoritmo y es, sin lugar a dudas, la tarea que más tiempo conllevó, ocupando alrededor de 12 horas, todas ellas 41
trabajadas con David. De atribuirme algo específicamente de esta etapa, sería la idea de la representación interna del secuenciador, basándome en la idea de representar el ritmo como una circunferencia y mantener una aguja que apunta al tiempo actual, así como las fórmulas para mantener la posición de esta aguja en caso de que cambiase el compás. NoteDuration comboBox: Creación y asociación del controlador al parámetro noteDuration. Se programó enteramente de manera conjunta junto a David. Llegamos juntos a la conclusión de que era necesario un mapa para mantener todas las notas que estuvieran sonando a la vez (en el caso de que la duración de cada nota fuera superior al tiempo que se tarda en laanzar la siguiente nota) por lo que en esta parte es imposible separar las participaciones de cada uno. Multi etapa: Diseño e implementación del modo multi etapa del plugin (máximo 4 etapas). Esta parte fue sencilla de implementar, simplemente fue necesario crear cuatro objetos donde antes había solo uno. La programación se realizó de manera conjunta, así que esta parte tampoco se puede separar. Velocity slider: Creación y asociación del controlador al parámetro, al igual que el caso anterior, fue sencillo y se programo de manera conjunta. velocity. Limpieza y optimización de código: Limpieza y optimización de todo el código del proyecto para un óptimo escalado. En esta parte se agruparon todos los elementos de cada etapa en mapas de cuatro elementos(uno por cada etapa), además de implementar un código de nombrado para los ids de cada elemento (por ejemplo el id del slider de steps de la etapa 1 sería “STEP_SLIDER_1”). Se realizó en su enteridad de manera conjunta. Triplets button yDotted button: Implementaciónes de las funcionalidades de tresillo y notas con putillo haciendo uso de dos botones. La idea de la implementación fue mía y la programación conjunta. Reconocimiento y extinción de error añadiendo concurrencia: Extinción de un error que saltaba al corromperse el heap porque el PluginEditor accedía a partes de memoria que no debía. Esto era debido a modificaciones en ese instante de la memoria por el PluginProcessor. Éxito en la corrección haciendo uso de un mutex en el instante óptimo. Realizado de manera conjunta mientras haciamos el debug de la interfaz. Selector de canal MIDI: Implementación del botón del selector de canal MIDI para poder mandar distintas instancias a distintos instrumentos. Impelmentación mía, pero David ayudó en el debug. Guardar/Cargar estado: Implementación del cargado y guardado de presets mediante un par de botones y una comboBox. Realizamos la investigación de amnera conjunta y programamos una parte, si bien la mayoría de la implementación fue labor de David. 42
Extinción de errores: Extinción de múltiples crashes que se producían al dejar de visualizar (minimizar) y luego volver a hacer visible el plugin en una DAW. Realizado de manera conjunta. Versión final del plugin: Retoques finales en el plugin y revisión de código. Realizado de manera conjunta. 43
Capítulo 6 Conclusiones y Trabajo futuro 6.1. Conclusiones Este proyecto, como bien sabemos, ha consistido en el diseño e implementación de un secuenciador euclidiano, finalizando con un plugin que ha cumplido los objetivos iniciales y ofrece la funcionalidad esperada. Además. cuenta con una interfaz gráfica de usuario que permite a los usuarios generar hasta cuatro ritmos euclidianos simultáneos de forma sencilla e intuitiva. Además de su función básica, se han desarrollado numerosas funcionalidades adicionales que le dan mayor versatilidad a la hora de generar ritmos. Con la función de rotación es posible obtener cualquier ritmo euclidiano posible. La capacidad de hacer ritmos utilizando tresillos o notas con puntillo da otra capa de posibilidades interesantes a los ritmos generados. Poder seleccionar la nota, implica que el propio plugin es capaz de generar eventos MIDI sin necesidad de un teclado ni ningún tipo de controlador. Otra característica destacable es la capacidad de guardar y cargar presets, lo que hace que sea muy cómodo volver a trabajar con ritmos que se han generado con anterioridad, y poder experimentar con ellos, sin temer que no puedas volver a recuperar ese ritmo inicial. Respecto al proceso de desarrollo del plugin, los miembros del equipo podemos afirmar que ha sido un reto debido a que nunca habíamos trabajado con JUCE, ni nos habíamos enfrentado al procesamiento audio/MIDI o a la generación de una interfaz gráfica de usuario como esta. A pesar de que ha sido difícil, hemos disfrutado aprendiendo cómo funciona el procesamiento de audio digital, las DAWs y todas las tecnologías que hemos empleado en el desarrollo de este plugin. Resumiendo, ha sido un proceso muy enriquecedor y gratificante. 44
6.2. Trabajo futuro Partiendo del hecho de que el plugin ha cumplido con los objetivos iniciales esperados, algunas otras características y funcionalidades que podrían ser interesantes de implementar en el futuro para amplían aún más su funcionalidad son: En primer lugar, sería interesante la posibilidad de implementar un arpegiador para cada ritmo. Esto extendería la capacidad de elegir la nota que suena en cada secuenciador, con la posibilidad de poder elegir varias notas, ya sean acordes, escalas o cualquier combinación de notas que el usuario desee, de modo que el ritmo itere sobre la lista resultante de notas en cada paso de la secuencia, proporcionando una personalización melódica a los ritmos. Otra característica interesante sería la de implementar diferentes vistas para la interfaz gráfica, de modo que el usuario pueda cambiar y usar la que más cómoda le parezca según sus preferencias. Dos posibles ideas que se han considerado son: una opción donde la representación de los ritmos está separada, y no representados todo ellos concéntricamente como ahora sucede, y otro diseño con los ritmos desplegados en una recta, yendo esta representación más acorde con los secuenciadores estándar. Nuestra última idea relacionada con el trabajo futuro consiste en desplegar este plugin y todas sus funcionalidades en un dispositivo físico. Esto permitiría, entre otros usos múltiples, el brindar al usuario la oportunidad de realizar shows en vivo utilizando esta increíble herramienta, cambiando la típica mesa de DJ por este dispositivo y abandonando la vía convencional. 45
Capítulo 7 Introduction 7.1. Motivation 7.1.1. Historical context After many ideas throughout the late XIX century and the entire XX century about musical creation with the use of technologies, finally in the 1980s this concept became into a real practice with the launch of digital synthesizers by Yamaha, specifically, the DX series. The popularity of these instruments capable of producing sounds using purely digital circuits was such that, the Yamaha DX7, reached a number of sales that place it today as one of the best-selling synthesizers in the history. Figura 7.1:Yamaha DX7 In this transition era from analog to digital, it is worth highlighting some events such as: The release of the CD or compact disc in 1982, by Sony and Philips together after several individual prototypes, which changed the way music is shared by introducing the ability to store and play digital audio. 46
In 1985 the launch of Commodore Amiga, a personal computer with a very affordable price and great multimedia capabilities that boosted music production using technology. The development and presentation of MIDI (Musical Instrument Digital Interface), a technological standard that describes a protocol, a digital interface and connectors that make it possible to transport and store symbolic musical information, or musical events (commonly called MIDI events) between computers, musical instruments and hardware. 7.1.2. Digital Audio Workstations Nowadays, music production and digital audio are going through their best moment, since anyone with not an advanced knowledge can develop more than respectable musical projects without no requirements of a professional music studio or large investments of money. This is largely due to the so-called Digital Audio Workstations or DAWs (Digital Audio Workstations), digital audio recording, editing and production systems composed of software tools (plugins, virtual instruments, etc ...) and hardware (microphones, monitors, etc ..). During the second half of the XX century, DAWs were composed entirely of hardware components (with exclusive software dedicated to it) since the computers limitations of the time were remarkable. When these limitations of data storage and processing were reduced, DAWs evolved to a point where everything that was needed to produce digital audio, that easily fullfilled a studio and was quite expensive, became basically a software tool. This tool can be used on conventional computers and even mobile devices requiring nothing more than an interface so the user can input audio and MIDI events into the device obtaining a playable audio output on other devices. These complex software are used from the most basic users to the best studios around the world due to three main reasons: Multi-track environment: It offers the ability to work with multiple tracks independently. Large extension: It provides us with an extensive project duration, easily exceeding 5 hours, or even more, depending on the sample rate we are working with. Default quality tools included: DAWs come equipped with software such as synthesizers or samplers among others, and with audio effects such as equalizers, compressors, reverbs, etc. In addition, to the default set of tools we can add an infinity of virtual instruments, effects and plugins that everybody can easily acquire. 47
Figura 7.2:REAPER’s graphical user interface 7.1.3. Plugins As we have previously mentioned, DAWs come with a set of default tools where which you can also add an infinity of extra functionalities thanks to different extensions among which are the VST plugins. VST, from the acronym Virtual Studio Technology11, is a standard developed by the German company Steinberg whose purpose is to offer the possibility of developing and connecting effect plugins and audio synthesizers with DAWs. Apart from VST, there are other standards such as AU (Apple) or AAX (Avid Audio), however, VST is the most used of all. In the next chapter we will go deeper talking about both the structure of DAWs, as well as the three large groups of plugins that are used in them: audio effects (whose function is to transform audio), virtual instruments (which generate audio interpreting MIDI events) and MIDI sequencers or generators (which assist in the work of sequencing or programming musical events). 7.2. Objectives With this project the main objective we want to cover is to create a MIDI generator that allows the user to test a paradigm you are not used to when it comes to creating and configuring rhythms. The implementation of this generator as a plugin with the VST standard brings accessibility for any user and versatility of being able to use it on your favorite digital audio workstation. In addition, the following secondary objectives are proposed: Show a professional interface, at the same time that is friendly and easy to understand by the user, without having to read large manuals. 48
Offer the possibility of creating rhythms with up to four of them at the same time. This means that in the same instance of the plugin, you can produce four different rhythmic patterns simultaneously. Allow you to connect the output of the plugin to the MIDI channel of the digital audio workstation you want, connecting the desired instrument to sound in each instance. Offer a comfortable control panel where the user can configure as desired the different parameters of the rhythm they want to obtain. Possibility to synchronize all the rhythms that are playing at a given moment so that their patterns start again from the beginning. This will allow the user to have control over the synchronization without having to stop and resume the rhythms all the time. Offer the functionality of saving and loading presets to the user, so that plugin configurations and rhythms parameters can be loaded and saved at the time you want. To conclude, and speaking of our personal learning, the objectives we propose are the following ones: Develop a good work structure and a good organization that facilitate the learning and collaborating processes, where synchronization and communication with the other member of the team is optimal so that the performance is the best. Learn how to use and deal with new tools and software such as the JUCE framework, so that the progress of the project and the development of our ideas and objectives are way easier. Face problems and situations that we have not faced during our learning in the career, and being able to solve them by researching and acquiring new knowledge that will very possibly be useful to us in the future. 7.3. Work Plan Once the objectives of the project have been established and having described the motivations of the same, it is time to describe the process that we have followed to carry out the project with the fulfillment of these mentioned objectives. The first steps of this work were to investigate the origin of the Euclidean sequencer, which led us to understand how Euclidean rhythms emerged, and how, nowadays, they are present around the whole world. After understanding these, the next step was to develop an algorithm that was capable of producing these rhythms, providing it as input the number of steps of the rhythm, and the number of events that it had so that it distributed them evenly creating the relevant rhythm. 49