martes, 13 de julio de 2010

Prioridades...


Hace mucho tiempo que no pasaba por estos lares… pero tengo una explicación muy razonable: un nuevo proyecto profesional. Desde hace un mes dispongo de un tiempo limitado, y lo que es más importante, me resulta imposible lograr el nivel de concentración que requiere este proyecto.

Es algo parecido a la inspiración, para que las notas lleguen y fluyan desde ese medio que no controlamos y al que sólo podemos contactar en estados de gracia, necesitamos estar rodeados de cierta paz y armonía (con lo que sea) Lo mismo ocurre en la programación de este Environment.

Así que os pido disculpas a todos los que estáis pendientes, ya sea uno, diez o cien. Mi objetivo es acabarlo, así que no renuncio a ello. Lo que haya programado hasta la fecha ya es todo un logro, falta un tercio de la aplicación. Me gusta la palabra “aplazamiento”, posiblemente sea la más adecuada.

Hasta pronto, espero.

lunes, 17 de mayo de 2010

Control remoto


Antes de exponer las novedades del proyecto debo confesar que este blog ha batido un record muy especial: el de no tener ningún comentario acerca de lo que se expone. Como autor desconozco si se comprende el contenido expuesto, si interesa o incluso si puedo ayudar a mejorar la comprensión. Esto certifica la realidad: REQUIEM es una curiosidad de un loco que ha perdido el tiempo convirtiendo los objetos del Environment en un lenguaje de programación. Pues sí, este es el caso.

Hace días contacté con una de las eminencias del Environment a nivel internacional. El interés fue tanto como larga puede ser una frase de menos de veinte palabras. El Environment ya no interesa. Es una ventana más del poderoso engranaje de Logic, pero no una prestación estelar. Lejos quedan los días en los que uno se diseñaba el entorno virtual de su estudio. Posiblemente esto sea debido a que masivamente se usan los plug-ins de sintetizadores virtuales, y éstos ya cuentan con excelentes interfaces gráficos de usuario. El Environment tenía sentido en un mundo rodeado de hardware externo con pequeñas pantallas LCD. Todos los otros usos que podamos darle son mínimos: procesos musicales para música experimental, módulos para “humanizar” pasajes, secuenciadores… REQUIEM

Pero desde el primer día dejé claro que este proyecto se hacía realidad para demostrar la potencia REAL del Environment, así que mi única misión es que diseñarlo, acabarlo, crear su documentación y dejarlo ahí en el océano de la red: crear un producto acabado.


Remote Editor

Volvamos a las novedades de los últimos días en la programación de REQUIEM: el módulo de control remoto. Mientras se resuelven varios problemas surgidos acerca del diseño del modo Song, he decidido avanzar por otro nuevo flanco: que el usuario pueda controlar parámetros de REQUIEM con los controles físicos de su teclado de control MIDI (sliders y codificadores). De esta forma se podrán abrir y cerrar filtros, controlar panoramas y volúmenes, y en definitiva todos los parámetros de síntesis de los dispositivos de REQUIEM.

La ventana “Remote Editor” muestra 8 faders virtuales que actúan como control remoto. El usuario puede asignar cualquier controlador MIDI (del 0 a 127) para controlar remotamente estos faders que a su vez pueden estar asignados a sus respectivos destinos. Por ejemplo se podría asignar el primer fader para controlar el “Cutoff” del sintetizador 1 de REQUIEM, con un ancho de banda de 0 a 127 (o por ejemplo de 80 a 100 para un efecto más suave).


Cada uno de los 8 faders virtuales puede controlar remotamente 2 destinos: uno para los sintetizadores y otro para la caja de ritmos. Además he añadido la posibilidad de seleccionar el modo de operación. En el caso de tener un destino que ya está siendo modulado (por ejemplo por un LFO), podremos elegir sustituir esa modulación o controlar su ancho de banda. Esto se hace desde la casilla “Mode”, seleccionando “Override” o “Replace”.


Así pues cada fader cuenta con estos parámetros:

  • Source: Qué controlador MIDI (0 a 127) controlará remotamente el fader desde la entrada MIDI.
  • Range-Low: Valor mínimo al que responderá el fader.
  • Range-High: Valor máximo al que responderá el fader.
  • Synths: Qué parámetro de los sintetizadores controlará.
  • Drums: Qué parámetro de la caja de ritmos controlará.
  • Mode: Sustituye o modula la modulación existente.

He creado un banco con 128 memorias almacenables por el usuario de forma que cada fader virtual pueda cargar una de las 128 memorias. A eso le he dado del nombre de “Definitions” (Definiciones) Las definiciones pueden ser copiadas, pegadas y eliminadas.


Además hay otra función muy útil: “Learn”. Al pulsar este botón REQUIEM escuchará” la información de control recibida y automáticamente establecerá el parámetro “Source”. Así el usuario no tiene que reconfigurar nada en su teclado de control, simplemente pulsar el botón y mover el control. Al recibir esos datos REQUIEM usará el controlador recibido. Como la función “Learn” abre la puerta MIDI para poder “escuchar” la informaron entrante, he incluido un tiempo de operación de forma que si no se recibe nada el modo “Learn” se deshabilite. Esto evita que un usuario abandone esa ventana dejando la función “Learn” habilitada.

Por otro lado también es posible habilitar o deshabilitar la recepción de controles de volumen y panorama para cada dispositivo (sintetizadores y caja de ritmos) además de habilitar o deshabitar la recepción desde los faders virtuales. Estas opciones no son memorizables, no forman parte de las “Definitions”.

Ya está todo funcionando, tan sólo falta enlazar los destinos y la entrada MIDI real. Espero poder avanzar con el  Modo "Song", que es mi verdadero quebradero de cabeza.

 Esquema del flujo de la señal MIDI entrante a REQUIEM

domingo, 9 de mayo de 2010

Mapa de pantallas


He montado un pequeño diagrama de las pantallas principales de REQUIEM. Como verás hay pantallas en rojo vacías. Esto significa que o bien no existen (por ejemplo la pantalla “Preferences”) o bien que se está trabajando en las mismas (como el caso de “Song”)

En este diagrama no aparecen las pantallas que contendrán todo lo relativo a la detección de acordes (una función realmente “heavy” desarrollada en parte) y el mezclador (que ya existe en estado embrionario) Iré actualizando el mapa a medida que se completen las funciones restantes.

Creo que de esta forma se entienden mejor tanto la estructuración como las funcionalidades de REQUIEM. Debajo de la imagen hay un enlace para descargar una versión en alta resolución. 

martes, 4 de mayo de 2010

E-Code: Módulos Copy / Paste


El Environment en Logic 5.5 presenta un límite de poco más de 8000 objetos. Actualmente estoy bastante cerca de ese límite: sólo podré usar algo más de 1000 objetos adicionales. Una de las soluciones es “empaquetar” conjuntos de objetos creando Macros. Un objeto Macro puede contener casi un centenar de objetos pero sólo puede tener una entrada y una salida (y no puede contener objetos Alias, aunque aquí no representa problema alguno). Esto significa que todo lo que esa Macro debe procesar sólo puede hacerse en los objetos de la Macro. Soy consciente que la expresión “una Macro sólo puede tener una entrada y una salida” es confusa. No te preocupes, lo comprenderás al ver los gráficos inferiores. En el post E-Code Lección 1 – Área de trabajo encontrarás más detalles de las Macros.

El caso es que una de las funciones que más se repite en REQUIEM es el mecanismo de las funciones “Copy” y “Paste”. En REQUIEM podemos copiar y pegar Presets de sonidos, Presets de modulación, Phrases, Patterns, Pasos de canción, las llamadas “Scenes”, Presets de Edición, Kits de batería, parámetros de los LFOs y alguna cosa más. Todo eso son funciones que pueden empaquetarse como Macros y liberar más de 600 objetos que podré usar de nuevo, incrementando el cómputo de objetos disponibles.


El ejercicio de hoy es un buen ejemplo de la filosofía del E-Code: traducir una función esquematizada con flujos de datos a objetos Environment. En nuestro caso la función a “Environear” es un buffer de copia de datos, es decir, la parte mecánica de las funciones “Copy” y “Paste”.

Un buffer de copia es una función compuesta de una puerta de entrada, un almacén que guarda los datos capturados y una puerta de salida que permite enviar esos datos capturados al receptor. Cuando señalamos una frase en un procesador de textos y procedemos a la función “Copy”, todos los datos señalados son capturados y enviados a una memoria temporal en la que se guardan. Al proceder con la función “Paste” estos datos son disparados en la posición de pegado.

Imaginemos que queremos copiar un paquete de 8 parámetros (por ejemplo los parámetros de un LFO):
  1. Pulso “Copy”.
  2. Se abre la puerta del buffer de copia (la puerta de salida está cerrada)
  3. Se envía un disparo a los datos originales a copiar
  4. Los datos reciben el disparo y se introducen en el buffer de copia.
  5. Se cierra la puerta del buffer al recibir el último dato almacenado.
Ahora procedemos con la función “Paste”:
  1. Pulso “Paste”.
  2. Se abre la puerta de salida del buffer.
  3. Se cierra la puerta de entrada (reiterativo, por seguridad)
  4. Se disparan los datos almacenados.
  5. La puerta de salida se cierra al pasar por ella el último dato almacenado.
Expresado como flujo de datos el esquema es el siguiente:


Y convertido a código E-Code el resultado es este:

 


En verde puedes ver el cable que transfiere los datos a copiar al buffer “Copy / Paste”. Este cable sale de una Macro que almacena 128 memorias cada una con 6 parámetros distintos. Es un módulo de 128 Presets.

En azul puedes ver el recorrido de la señal al realizar la copia y en amarillo, lo mismo aplicado para la punción “Paste”. En rojo se representa la salida de datos. Soy consciente que viéndolo todo simultáneamente es imposible comprenderlo. Así que lo mejor es tratarlo por partes.


Función “Copy”

En primer lugar el usuario debería seleccionar el “Preset” del cual queremos copiar los datos.

Al pulsar el botón “Copy” se introduce un “program change” valor “1” en el Transformador “IN”. Este Transformador divide la señal en dos rutas dependiendo del evento recibido. Si el evento es un cambio de programa (como el que hemos enviado) envía dicho evento por el cable superior. El evento de “program change” sigue la ruta hasta llegar a un “Ornament”, un objeto gráfico que multiplica los eventos entrantes en tantas rutas como cables usemos en su salida. En este caso salen dos cables portando el “program change” inicial. Uno se introduce en el Transformador “copy” y el otro en el Transformador “paste”. En cada uno de estos se comprueba que la función sea la de copiar o pegar. Recuerda que el “program change” tiene un valor de "1" (es la definición de salida del objeto botón “copy”), así que la ruta de señal buena será la que continua desde el Transformador “copy”. El Transformador “paste” cortará la señal ya que únicamente dejará pasar los eventos de “program change” con valor “0” (enviados desde el botón “Paste”)

A partir de este punto las tareas se dividen en dos ya que el Transformador “copy” tiene dos cables de salida:

1- Por el cable superior sale el evento “program change” valor “1” que es retardado 2 ticks de señal, convirtiéndose en una señal de disparo en el Transformador etiquetado como “bang”. La señal de disparo pasa por el Transformador “OUT” hasta alcanzar el Transformador “bang Preset”. Este envía una señal al módulo de memorias “128 Preset Memory” para que dispare los 6 parámetros del “Preset” actual (el que el usuario vería en pantalla).

2- Un segundo evento “program change” valor “1” parte del Transformador “copy” por el segundo cable de forma simultánea al primer cable. Este segundo evento es introducido en un Transformador llamado “open” que abre la puerta de entrada “In” (conmutador de cables), permitiendo el paso de los parámetros a copiar. En este instante, cuando la puerta se abre, el proceso de este cable termina, ya no ocurre nada más en esa ruta de señal.



En el paso 1 he retardado la señal 2 ticks, ¿recuerdas? (justo después del Transformador “copy” que divide la señal inicial en dos rutas de señales). Bien, cuando el módulo de memoria “128 Preset Memory” envía sus 6 parámetros gracias a la señal de disparo recibida por “bang Preset”, éstos valores se introducen por el Transformador inicial “In”, y son enviados por su segundo cable ya que no son eventos tipo “program change”. Los 6 eventos siguen el cable encontrándose una puerta “In” abierta. Precisamente hemos retardado el disparo de estos 6 eventos con un retardo para que diera tiempo a que la puerta se abriese sin arriesgarnos a perder uno de los eventos copiados (posiblemente el primero).

Los eventos cruzan un filtro de entrada que se asegura que sólo se introduzcan 6 eventos y no más. Estos eventos se reparten según su definición en 6 faders que los almacenan. Estos 6 faders están cableados a una puerta de salida “Out” que está cerrada. El último fader, llamado “Mod 6” envía dos señales a los transformadores “close” inferiores que cierran tanto la puerta de entrada “In” (que se abrió al inicio del proceso) y la puerta “Out” que aunque ya esta cerrada, recibe el evento igualmente.

Fin del proceso, los datos han sido capturados y son almacenados en 6 faders. Pero no salen, sólo se enviarán al pulsar el botón “Paste”.

La función "Copy" en funcionamiento. Los datos capturados coinciden con los que se ven en el "Monitor" superior. El "Monitor" inferior no muestra datos pues la puerta de salida "Out" está cerrada


Función “Paste”

Ahora el usuario debería seleccionar el “Preset” en el que realizaremos la función de pegar.

Al pulsar el botón “Paste” se introduce un “program change” valor “0” en el Transformador “IN”. Este Transformador vuelve a dividir la señal en dos rutas dependiendo del evento recibido. Si el evento es un cambio de programa (como el que hemos enviado) envía dicho evento por el cable superior. El evento de “program change” sigue la ruta hasta llegar al objeto “Ornament” que multiplica la señal en dos rutas portando el “program change” valor “0” inicial. Como el Transformador “copy” espera recibir un “program change” valor “1” envía el evento por el segundo cable, yendo al Transformador “paste”. El Transformador “copy” cortará la señal ya que únicamente dejará pasar los eventos de “program change” con valor “1” (enviados desde el botón “Copy")

A partir de este punto las tareas se dividen en dos ya que el Transformador “paste” tiene dos cables de salida.

1- Por el cable superior sale el evento “program change” valor “0” que es retardado 2 ticks de señal, convirtiéndose en una señal de disparo en el Transformador etiquetado como “bang”. Este Transformador multiplica la señal por 6 y la envía a sendos objetos fader que contienen los datos almacenados. Los 6 eventos almacenados son enviados hacia la puerta de salida que debería estar abierta en al paso 2. Al enviar el último evento almacenado, llamado “Mod 6”, se envía un evento que cierra las puertas “In” y “Out”. El retardo de 2 ticks se impone para que el disparo se haga después de abrir la puerta de salida “Out”.

 
2- El segundo cable del Transformador “paste” abre la puerta “Out”. Los datos se envían de vuelta al Módulo de Memoria y se almacenan en el Preset actualmente seleccionado.

 La función "Paste" en funcionamiento. Los datos capturados son enviados (ver "Monitor" inferior). El "Monitor" superior muestra los nuevos datos introducidos en la memoria


Creando la Macro

Como el proceso funciona, quizás sea el momento de empaquetar todo el buffer de copia en forma de Macro. De esta forma, todos esos objetos contarán como uno sólo. Para ello es necesario comprobar la entrada de lo que será la Macro. El Transformador “IN” será usado como Macro mientras que el Transformador “OUT” será la salida.

Objetos usados como entrada (gráfico superior) y salida (inferior)

Al seleccionar todos los objetos que compondrán la Macro comprobamos que NO HAY NINGÚN CABLE que salga de esos objetos, todos nacen y mueren dentro de la Macro. La Macro sólo tendrá una única salida: el Transformador “OUT”.

 
Listo, ¡podemos crear la Macro!


NOTA: Este buffer de copia es ideal para copiar y pegar hasta 10 parámetros. En el caso de las “Phrases” (16 notas + 16 velocidades de pulsación + 16 duraciones de nota), es necesario otro mecanismo cuya conversión a Macro es mucho más sofisticada.

jueves, 29 de abril de 2010

Más allá de los 7 bits...


Las capacidades del Environment y sobretodo su concepción no dejan de sorprenderme. Me resulta increíble descubrir nuevas posibilidades y combinaciones de funciones. Y el último descubrimiento es sencillamente magistral: se pueden manejar valores mayores de 127 desde los objetos del Environment. Que Santa Inspiración Divina proteja a Gerhard Lengeling por tener esa increíble visión hace ya muchos años: ¡qué maravilla de programa!

Veamos el porqué de mi efusiva alegría (ojo, esto presupone ciertos conocimientos del protocolo MIDI). Cualquier evento MIDI de canal tiene un límite de valores que va de 0 a 127 (el 0 cuenta como valor), es decir, podemos cambiar valores en un rango de 128 valores distintos. Cuando subimos el volumen con un fader en el Environment se está enviando un evento de control MIDI de 3 bytes: el primero es el de estado (tipo de evento y canal MIDI por el que se transmite), el segundo indica el controlador MIDI que estamos enviando (en el ejemplo volumen, control número 7) y el tercer byte la cantidad que estamos enviando (por ejemplo subirlo hasta el máximo, 127). En el caso de un evento de nota, el primer byte sigue siendo el tipo de evento y el canal MIDI por el que se transmite, pero el segundo byte es el número de nota (de 0 a 127, esto es C-2 a G8) mientras que el tercer byte indica la fuerza con la que se ha pulsado dicha nota (de 0 a 127). Y seguimos… hay 128 cambios de programa en el protocolo MIDI (de 0 a 127), y la post-pulsación (aftertouch) envía valores de 0 a 127 al actuar (tanto el aftertouch de canal como el polifónico que es individual para cada tecla pulsada). ¡Estamos presos en el mundo de los 8 bits!, y además resulta que no se emplean realmente 8 bits, sino 7, por ello existe la limitación de 128 valores. Si se empleasen los 8 bits podríamos manejar 256 valores para cada evento.

El fader de la derecha envía hasta 16383 valores frente a los 127 valores estándar de un controlador MIDI. Observa el campo "Rango" cuyos límites son "0" y "127" (7 bits).

Pero…. Hay un evento de canal que envía valores de 14 bits (ojo que si dividimos 14 por 2 nos da 7, una cifra mágica que ha aparecido al final del párrafo anterior). La rueda de inflexión de tono o pitchbend es un control físico que incluyen los teclados MIDI que al moverse envía un evento MIDI de 3 bytes (como los controladores, notas y aftertouch polifónico). El primer byte es como siempre el tipo de evento y canal MIDI, pero el segundo y el tercero combinan sus valores dando lugar a un límite de 16384 valores (128 x 128). Así el segundo byte se llama LSB y el tercero MSB. Cuando el LSB alcanza su valor máximo de 127, el MSB suma una unidad y espera a que el valor LSB alcance de nuevo el máximo de 127 para subir otra unidad. Y así, combinando esos dos valores se logra dar una resolución de 14 bits que es necesaria para la rueda de modulación, de otra forma los saltos al mover la rueda serían perfectamente audibles (sólo contaría con 128 pasos frente a los más de 16000 que permite)

En este caso el campo "Rango" está definido como "0" y "16383" (14 bits). Además el campo "Filtrar" está configurado como "14 bits" algo IMPRESCINDIBLE.

Y otro “pero” todavía mejor… En el protocolo MIDI es posible usar dos eventos de control combinándolos a modo de MSB y LSB. Esto suele hacerse para “crear” un evento de cambio de banco de sonidos y lo emplean sintetizadores que tienen más de 128 memorias de sonidos. Si estos eventos son enviados en la misma posición de reloj junto con un cambio de programa, el sintetizador pertinente sabe qué banco de sonidos debe seleccionar y qué sonido en particular de ese banco se desea usar.

Valor mínimo a 14 bits: "0", enviado como LSB 0 (control 64) y MSB 0 (control 32)

Valor mínimo a 14 bits: "16383", enviado como LSB 127 y MSB 127.

Secuencia de cambio de valores: se han enviado los valores 124, 125, 126, 127, 128, 129 y 130. Observa cómo el MSB (control 32) del valor 128 cambia de "0" a "1" cuando su LSB (control 64) pasa de "127" a "0".


¿Qué tiene que ver todo esto con REQUIEM?

En el último post hablé de un posible sistema de automatización para REQUIEM. El sistema que estoy barajando implicaría poder grabar hasta 500 compases de automatización con una resolución de 1/32 eventos para cada compás. Y el problema surge en esto: si REQUIEM ofrece hasta 500 compases de automatización, ¿cómo voy a grabar y editarlos si los objetos del Environment sólo pueden emplear y visualizar de 0 a 127 valores? Basta comprobarlo creando un fader en el Environment. El campo “Rango” presenta un límite de 127 como valor máximo. Así pues el contador de compases del Modo Song (Canción) de REQUIEM sólo visualizará hasta el compás 127 (o 128 si usamos el valor 0 como valor funcional).

La forma “barata” de superar esa limitación es trabajar con bancos, por ejemplo tener 10 bancos de 128 compases cada uno. El usuario vería un nuevo dígito a la izquierda del número de compás, y el compás actual como un valor de 0 a 128. Sinceramente no me parece un modo “profesional” de presentar la información, por no decir que manejar y editar los compases puede ser muy arduo al tener que seleccionar siempre el banco de 128 compases en el que estamos operando.

Pero el problema es que el Environment sólo permite ver esos valores “de alta resolución”, pero no manejarlos. Un objeto Transformador sólo procesa valores de entre 0 y 127, y los meta-eventos del Environment sólo saben mover / procesar / disparar valores de entre 0 y 127. Así que… ¿para qué mostrar valores mayores de 127 si no podemos procesarlos?

Respuesta corta: MSB y LSB
Respuesta larga: Dividir ese valor de 14 bits en dos de 7 bits. ¿Hay algo en el Environment que pueda lograrlo?. Por supuesto, un fader definido para enviar valores de 14 bits.



Trataré de abordarlo en el próximo post…

jueves, 15 de abril de 2010

Automatízame un poco, por favor…

 
Hacía unos cuantos días que no me pasaba por este barrio. Confieso que a veces me cuesta “environear”, normalmente después de preguntarme para qué servirá semejante esfuerzo. Aún así, todavía no me he caído: sigo teniendo la esperanza de aunar todas las ideas acerca de REQUIEM y lograr terminarlo.

Hoy toca hablar de las automatizaciones, esto es, poder grabar y reproducir cambios en los controles del interface de usuario. Logic tiene un excelente sistema de automatizaciones, al igual que Cubase, Reason (en menor medida) y la mayoría de secuenciadores de audio y/o MIDI. ¿Y REQUIEM? (dejando a un lado sus potentes 6 LFOs)

Primero veamos en qué consiste un sistema de automatización: se trata de pistas especiales en las que podemos grabar cambios en los controles. Esos datos pueden grabarse de diversos modos: al tocar el fader deseado y moverlo, reemplazando datos existentes, incrementando o reduciendo la automatización existente, etc… La edición suele ser gráfica en forma de curvas o bien en forma de lista (como una lista de eventos). Técnicamente hablando es algo tan sencillo como ir grabando a cierta resolución los cambios en los controles.

¿Cómo se implementa todo esto en un environment para Logic? Lo primero a resolver es cómo grabar esos datos y a qué resolución hacerlo. Es decir, en un compás, ¿cuántos eventos de automatización podremos grabar?, ¿y durante cuantos compases? No valen las respuestas como “a la máxima resolución” y “durante infinitos compases”. REQUIEM es un environment y cuenta con serias limitaciones… 8000 objetos (en la versión 5.5 de Logic, desconozco cual es ese limite en la versión actual) y un ancho de banda de proceso muy reducido (no pretendas procesar 200 streams de datos a través de 200 objetos de forma simultánea…)

Usando el elemento clave en cuanto a construcción de memorias en E-Code, el objeto Transformador, podemos memorizar 128 eventos de automatización. Eso nos podría valer para una resolución de 1/128, es decir, 128 eventos en cada compás. Pero si quiero poder grabar durante 100 compases, deberé usar 100 Transformadores. ¡Y esto sólo para un control en pantalla, imagina si deseamos automatizar 10 controles!

Lógicamente este método no nos vale, hay que reducir la resolución interna. Usando una resolución de 1/32, es decir, 32 eventos de automatización por compás, podemos usar un Transformador para memorizar 4 compases (4 x 32 = 128). Y encadenando más Transformadores, podemos cubrir fácilmente 500 compases. En este caso necesitaríamos 125 objetos Transformadores. Esos Transformadores deberían ir conmutándose entre sí, por ejemplo, al llegar al compás 5 sería el segundo Transformador el que actuaría, al llegar al compás 9, sería el tercero y así sucesivamente. Y lo mejor… se podrían empaquetar esos 125 Transformadores en un par de objetos Macro, convirtiéndolos en ¡2 únicos objetos!

¿Qué podríamos automatizar en REQUIEM?

La idea es poder grabar y reproducir cualquier control de síntesis o control de estado (eso es sencillo), pero lo difícil es hacerlo con todos simultáneamente: harían falta cientos de Macros como la anteriormente citada. Creo que lo mejor es ofrecer varias pistas de automatización, y que sea el usuario el que indique qué control grabará en cada una de ellas. Inicialmente la idea es probar con 4 pistas de 500 compases cada una, con una resolución de 1/32. Esto puede verse limitado por “todas las otras tareas de REQUIEM”, es decir, las 9 pistas de ritmos, las 8 pistas solistas, los LFOs y el manejo del interface de usuario… es decir, ¡el famoso ancho de banda!

Si el rendimiento fuera óptimo, probaría con 8 pistas de automatización (duplicando lo anterior). Con 8 pistas ya es posible efectuar buenas mezclas y efectos de producción. Por otro lado, el sistema de automatización no podría tener edición gráfica, y en caso de tener edición numérica (en forma de lista), su programación sería terriblemente compleja (debería extraer los datos grabados en cada Transformador según la posición de reproducción de la canción). Además, funciones tipo “Copy”, “Paste” serían realmente imposibles de lograr… ¿Cómo copiar un rango de datos de automatización que se ha grabado al final de un Transformador continuando en el inicio del siguiente? Creo que para tratarse de un environment, el simple hecho de poder grabar y reproducir, enmudecer, escalar o reducir la automatización ya es un logro, así que con eso ya me daría por satisfecho.

Como siempre, el tiempo dirá…

domingo, 28 de marzo de 2010

Sentido del ritmo II


Después de duras negociaciones con mi pobre antiguo Pentium 4, finalmente he podido grabar un vídeo con sonido y capturarlo todo en el mismo ordenador. Por suerte el driver ASIO de la tarjeta empleada, una E-MU 1820, permite el envío de audio al driver multimedia desde las entradas ASIO o físicas simultáneamente.

Dejando a un lado cuestiones técnicas, aquí tienes a REQUIEM trabajando para ti. El vídeo muestra la creación de una ritmo sencillo (bombo y platos) usando los pulsadores virtuales (PADs) en pantalla. Espero que te guste.
 

viernes, 26 de marzo de 2010

Tecnología obsoleta


A diferencia de lo habitual, REQUIEM está siendo desarrollado usando un ordenador arcaico con unas prestaciones ridículas en cuanto a velocidad y potencia. Esto garantiza que el código pueda “volar” en las máquinas de última generación. Aunque REQUIEM no ataca directamente a la CPU del ordenador, sí recarga el rendimiento del motor MIDI y audio de Logic con la consecuente carga en el driver ASIO del ordenador. Si a mi me funciona significa que funcionará en cualquier ordenador moderno.

Este principio tan “bello y noble” tiene una consecuencia negativa: estoy haciendo malabarismos para lograr tener a REQUIEM en reproducción mientras se graba el audio generado se envía simultáneamente al driver multimedia de Windows para que la aplicación de grabación de video en pantalla pueda capturar tanto la imagen como el sonido. Mi pobre PC está sufriendo… (Debo decir que aunque es una máquina muy antigua está configurada para arrancar con el 97% de recursos libres) Este es el motivo por el que hasta ahora no he publicado un vídeo con sonido.

En cuanto a REQUIEM, el motor de la sección “Drums Device” ha sido modificado con los buffers de copia de pista y copia de todo el patrón entero (“Phrase” en el argot de REQUIEM, esto es, copiar las 8 pistas simultáneamente). Además he añadido una función muy simple pero altamente útil: “Copy to next”. Esta función realiza una operación “Copy” del instrumento de percusión seleccionado (pista seleccionada en el “Drums Device”) en la “Phrase” seleccionada y pega el contenido copiado en la siguiente “Phrase” en el mismo instrumento seleccionado. Esto permite transferir pistas al patrón siguiente al actual, pudiendo crear variaciones del patrón en grabación con una sencilla operación.

Pero además estoy implementado esta misma operación a escala “Phrase”, es decir, copiando los 8 instrumentos simultáneamente a la “Phrase” siguiente a la actual. Así, al tener tu ritmo programado, podrás copiarlo al siguiente patrón y realizar modificaciones en el mismo. Luego podrás encadenarlos formando un ritmo más complejo con más compases de duración.

También he modificado el aspecto gráfico del interface de usuario. Ahora es más compacto provocando una menor confusión gráfica al mostrar tantos controles en pantalla.


Modo grabación en el "Drums Device"

Espero poder ofrecer un vídeo con sonido en breve...

domingo, 14 de marzo de 2010

Sentido del ritmo I


Fue ayer cuando di con la solución. No estaba frente al ordenador, estaba conduciendo. La solución me encontró a mi, y no yo a ella.

No he mostrado nada acerca de la caja de ritmos de REQUIEM porque sufría un curioso bug. El interface de usuario del “Drums Device” muestra las notas de cada instrumento seleccionado. Si seleccionamos “SD 1” mostrar los acentos de la pista de la caja 1. Si luego pulsamos “BD 2” mostrará los acentos del segundo bombo, dependiendo del patrón seleccionado. Pero esto no ocurría hasta ahora. A veces se mostraba el contenido correcto pero sonaban patrones distintos. Habiendo repasado el código cientos de veces, decidí hace semanas avanzar por otros caminos programando otras áreas de REQUIEM. Y el código no estaba mal, estaba bien escrito, lo que fallaba era la ruta de ejecución.

Esquema del código. Parte musical, sin síntesis de sonidos.

Código E-Code del dispositivo de ritmos. Parte musical, sin síntesis de sonidos.
Cada instrumento de la caja de ritmos tiene su propio botón tipo On / Off para poder apagarlo si es necesario. Técnicamente, “apagar” significa que el procesado de los objetos deja de funcionar (se corta) pero que el contenido se sigue viendo. El “corte” era lo que estaba mal, pues al deshabilitar parte del proceso del instrumento apagado, éste no podía actualizarse una vez se ponía de nuevo en marcha. Y como consecuencia sonaba el contenido antiguo, el existente antes de pulsar el botón “Off”. De modo que una vez arreglado, me complace presentarte la caja de ritmos de REQUIEM:

 
¡Hasta la próxima!

miércoles, 10 de marzo de 2010

¡Vaya pedazo de código!


Imagina que estas componiendo tu canción y quieres copiar los compases 5, 6, 7 y 8, en los compases  15, 16, 17 y 18 (por poner un ejemplo) Esto tan sencillo se vuelve arduamente complejo en E-Code.

La sección “Song” de REQUIEM opera sobre objetos transformadores a modo de matrices de memoria. Esta técnica es empleada en cualquier parte “memorizable” de REQUIEM, sólo que en esta ocasión la estructura es distinta. En un único objeto transformador se almacenan los 128 patrones que se reproducen en cada uno de los 128 compases. Por ejemplo, el compás 1 reproduce el patrón 54, el compás 2 el 13, el compás 3 el 120, etc…

Lo interesante es ofrecer funciones tipo copiar / pegar de modo que el usuario pueda copiar una sección de compases sobre otra sección de compases de la misma duración. Así pues, técnicamente hay que copiar parte de los 128 datos almacenados en el transformador, pasarlos a otro transformador a modo de almacén temporal, reubicar el puntero de memoria del primer transformador (del que hemos copiado los datos), y disparar los datos almacenados en el segundo transformador escribiéndolos en la posición actual del primero. Los datos existentes de esa porción quedarán eliminados y sustituidos por los nuevos.

El código E-Code para esta operación lo puedes ver en el siguiente vídeo. Actualmente la ejecución de este código provoca un bug gráfico en mi Logic 5.5, así que habrá que descubrir qué funciona mal, teniendo en cuenta que el código en sí funciona y efectúa todo lo narrado.

jueves, 4 de marzo de 2010

Yo grabo, tú grabas, él graba…


El procedimiento de grabación de notas en REQUIEM ya está listo e integrado en el GUI. Este es el resumen de su operatividad.

Al pulsar el botón “Rec” ocurre lo siguiente:
  1. Cambios gráficos en el interface de usuario con nuevos controles y colores distintos.
  2. Apertura del buffer de escritura: las memorias son rellenadas con nuevos datos.
  3. Bloqueo del modo “Pattern”: Los patrones no son encadenados pero si es posible conmutar de uno a otro manualmente.
  4. Bloqueo del acceso al “Phrase Editor” (el editor de eventos de REQUIEM)
  5. El teclado virtual muestra las notas entrantes, no las salientes. Se abre el acceso de la entrada de MIDI externo.
  6.  El contador de compases cambia mostrando información del paso (“Step”) editado actualmente. Se crea una copia de la información de compás previa para poder ser reclamada al abandonar el modo de grabación, restaurando así el valor del contador de compases.
  7. El visualizador de pasos (“Steps”) se sitúa en el “Step 1” mostrando lo que haya grabado.
La grabación en REQUIEM es bastante versátil. Como método de introducción el usuario puede usar el teclado virtual en pantalla o su teclado MIDI. Independientemente del modo de grabación (paso a paso o a tiempo real), el usuario puede indicar si se capturará el tono de las notas entrantes, su velocidad de pulsación o su duración. Esto se indica con los botones de la esquina inferior derecha “Note”, “Vel” y “Len”.

 
Modo Play

 
Modo Rec
Modos de grabación

La grabación puede ser a tiempo real o paso a paso. El modo de grabación lo define el estado del botón “Realtime”. Al activar el botón “Realtime” el usuario podrá tocar en tiempo real (siguiendo la claqueta) y REQUIEM grabará las notas en las 16 posiciones de nota (“Steps”). Las notas introducidas aparecerán en el teclado virtual superior y en los indicadores centrales sobre el transporte.

En el modo paso a paso es el usuario quien indica el “Step” en el que se grabará la nota, velocidad y duración de nota. Para ello puede usar el fader “Step” y los botones “<” y “>” del transporte. El indicador central “Step” mostrará el paso actual y a su lado aparecerá la información grabada en dicho paso. Si se desea eliminar una nota se procederá con el botón “| Delete |” de la esquina inferior derecha.

En la grabación paso a paso es posible grabar en modo “Stop” o en “Play”. Si se inicia la reproducción REQUIEM reproducirá la información grabada junto con las nuevas notas introducidas en sus pertinentes posiciones. Además existe una útil función tipo “Auto-Step” que permite pasar al paso siguiente al introducir la nota, ahorrando la pulsación del botón “>” cada vez. Esta función se activa con el botón “>>” y no tiene efecto en modo a tiempo real (“Realtime”)

Por último existe el botón “Chain” que en teoría debe encadenar las frases, así si un usuario quiere grabar de un tirón las frases 1, 2, 3, 4 y 5 (por ejemplo) puede hacerlo pulsando ese botón. De momento no se ha implementado esta función.

En modo “Pattern” la grabación varía. En este modo el usuario puede encadenar hasta 5 frases (“Phrases”) indicando las repeticiones que efectúa cada una de las frases. Al pasar a modo grabación, al pulsar “PlayREQUIEM no encadenará los patrones, sino que el usuario deberá usar los botones “<” y “>” de la sección “Pattern” para conmutar entre las distintas frases que conforman el patrón. Para reproducir el patrón de forma normal basta con pulsar “Rec” para abandonar el modo grabación.

La función de grabación se deshabilita automáticamente si el usuario cambia al dispositivo de ritmos “Drum Device”. Aunque es posible ir cambiando de dispositivo “Lead” en plena grabación y grabar todos los patrones necesarios de cada dispositivo sin tener que abandonar el modo grabación, esto no es así en el caso del dispositivo de ritmos. Se hace necesario abandonar la grabación debido a requerimientos del motor de ritmos de REQUIEM. Dicho de otra forma, problemas de diseño que no sé si lograré superar.


Por último, en el “Phrase Editor” la grabación se deshabilita (al pulsar “Rec” no ocurre nada). Esto es necesario ya que el propio “Phrase Editor” abre su puerta dedicada a la introducción de datos. Si además habilitamos la grabación son dos las puertas abiertas y se gestionan dos buffers de datos. Es demasiada complejidad para algo evidente: ¿se puede introducir y editar información en el “Phrase Editor”?... ¡Entonces para qué habilitar el modo grabación!

El procedimiento de grabación debe ser el mismo en el dispositivo de ritmos, así la experiencia del usuario podrá aprovecharse al instante. Evidentemente hay algún cambio significativo, pero la disposición de los controles será la misma.

Buenas noches… y buena suerte

viernes, 26 de febrero de 2010

Ritmos grises


Hacía ya días que no escribía nada aunque el código no ha dejado de crecer y mejorar. Días grises en los que un divorciado de la música recuerda a su gran amor: aquello que no es ruido, la música. Me he emocionado bastante escuchando uno de mis LP preferidos (si es que esto hoy en día tiene aún sentido) He llegado a la conclusión de que quizás sea posible apartarse de ella, pero ella siempre acaba reclamándote.

Y concentrándonos en mi locura particular, que sólo sirve para certificar mis paranoias mentales dejando claro que no hay mejor forma de malgastar talento, veamos los avances de REQUIEM Environment. Ya he integrado la “caja de ritmos”, es decir, la sección “Drums” entera al interface de la aplicación. Desgraciadamente aun hay fallos en la reproducción de ritmos, ocasionalmente lo que suena no concuerda con lo que se está viendo, y debo descubrir cuándo ocurre el fallo. Viendo el trabajo realizado en esta sección, diría que está a un 50%.

Otra integración es el interface gráfico del modo “Song”, una lista de “Scenes” que van desfilando de derecha a izquierda. Es una virguería gráfica que aún debe someterse a varias pruebas de flujo de trabajo.

Pero además de todo esto he estado arreglando pequeños bugs en la sección “Lead”, los 8 sintetizadores. El modo grabación funciona de forma distinta a lo planificado: “el usuario quiere grabar, ¿puede hacerlo en modo “Pattern” (encadenado de patrones) o sólo en modo “Phrase” (sin encadenar)”. “¿Puede el usuario ir a la sección “Drums” en grabación?, ¿y volver de ella? ¿Y si en plena grabación el usuario decide cambiar de patrón en tiempo real, dónde se grabarán los datos en este caso?”

La respuesta a todas esas preguntas es una serie de acotaciones en las acciones que indican qué puede hacer el usuario. Por ejemplo, si un usuario cambia la “Phrase” en la que está grabando, todo lo que toque o introduzca a partir de ese instante se registrará en la nueva “Phrase”. Podría haber decidido abortar la grabación, es decir, desactivar el botón “Rec”, aunque eso no sería lógico.

Otro caso es el modo “Pattern”, el encadenamiento de frases (“Phrase” en el GUI). En reproducción, las frases que componen un patrón van reproduciendo conmutándose entre sí y repitiéndose las veces establecidas por el usuario. Pero ¿y en grabación? En este caso la limitación viene por el diseño de REQUIEM, pues en grabación y estando en modo “Pattern”, los patrones no se reproducirán, es decir, es el usuario el que debería pulsar el botón correspondiente para conmutar la frase. Esto tiene una ventaja terrible: permite estar concentrado en cada frase, y cuando está perfecta pasar a la siguiente. Pero la desventaja es no poder realizar una grabación en tiempo real conmutando las frases tal y como están definidas en cada patrón: la latencia del motor de REQUIEM hace que las notas puedan grabarse en parte en otra frase del patrón. De momento no puedo solucionarlo. Y la última pregunta ¿puedo grabar estando en el “Event Editor”? La ventaja de hacerlo desde esa ventana es que tiene herramientas de edición muy útiles. Es en este paso en el que estoy trabajando actualmente.

Hasta luego…

sábado, 13 de febrero de 2010

El interface gráfico de usuario II (ventana Synth Editor)


Hoy te presento un recorrido por el interface gráfico de REQUIEM Environment, desde la primera versión hasta la actual. El objetivo principal es la claridad y facilidad de uso por lo que cuantos menos indicadores mejor. Vayamos a comprobar la evolución del GUI de REQUIEM.

REQUIEM Environment 1:

- La pantalla muestra el primero de los 8 sintetizadores de REQUIEM aunque todavía no hay selector de sintetizador.
- La sección de modulación es muy sencilla: 22 modulaciones generadas por 2 LFOs por dispositivo y 11 modulaciones desde un LFO master (común a todos)
- La sección de efectos cuenta con sus propias modulaciones (2 fuentes / 2 destinos)


REQUIEM Environment 2:

- La sección de modulación ha cambiado por completo. Ahora se dispone de 6 LFOs master y ninguno exclusivo para cada sintetizador. Además es posible asignar la misma fuente de modulación a distintos destinos de modulación y ajustar la cantidad de modulación enviada.
- Introducción de los monitores de modulación: las barras verdes al lado de las modulaciones se mueven dibujando la modulación generada, siendo muy útiles al establecer el ancho de banda de la modulación.
- Se ha introducido el selector de dispositivos (sintetizadores), una barra vertical multicolor que al pulsar en cada casilla cambia el color de los controles en pantalla mostrando el mismo color que el del dispositivo seleccionado.


REQUIEM Environment 3:

- Menos controles y más claridad.


REQUIEM Environment 4:

- Selector de dispositivos en horizontal y sin colorido. Distrae menos.
- La sección "Master" cambia a un fader tipo vector para controlar el volumen y panorama.  


REQUIEM Environment 5:

- Cambio en la sección “Scene”.
- Introducción del “Multimenu”, un sistema de menús que sólo muestra las acciones y funciones pertinentes en cada sección. Así, al mover un parámetro en la sección de síntesis, el "Multimenu" mostrará las funciones de copiar y pegar sonidos (etc…) y al mover un parámetro de la sección de modulación, el "Multimenu" mostraría las acciones para dicha sección.


REQUIEM Environment 6:

- Cambio de posición del "Multimenu”.
- Cambio de posición del contador principal a una posición centrada en el GUI.


REQUIEM Environment 7:

- Cambio en la sección "Master": introducción de un medidor de audio (picómetro basado en bus) El vector se conserva para fines de modulación.
- Los envíos de efectos han sido eliminados de la pantalla principal. Más claridad y espacio para la sección "Master".


REQUIEM Environment 8:

- Selector de dispositivos ampliado: ahora ya es posible ir al dispositivo de ritmos (botón “D” en el selector) y al futuro dispositivo de acordes (botón “C” en el selector)

Lo que has visto es sólo una de las pantallas de REQUIEM. El dispositivo de ritmos tiene una configuración completamente distinta de los controles así como los moduladores, otra pantalla radicalmente distinta a las dos anteriores.


Hasta la próxima…

martes, 2 de febrero de 2010

El interface gráfico de usuario I (visualización)


Esta es la parte que más me gusta diseñar: la creación de las rutas que el usuario debe seguir para lograr su propósito. El mundo de la informática musical está repleta de excelentes interfaces de usuario (GUI), por ejemplo el magistral Reason con el concepto de rack virtual, el curioso interface de Ableton Live o la súper-configuración del GUI de Cubase. Cito estos pero en realidad podría citar cientos de plug-ins con genialidades en la forma en que permiten ser manejados. Lógicamente hay límites que el Environment no puede simular, no puedo crear un interface de usuario que esconda partes para luego volver a mostrarlas, o permitir redimensionar sus elementos. Pero dentro de las severas limitaciones del Environment (es lógico, nunca fue diseñado para crear aplicaciones musicales), es posible lograr resultados muy realistas y sobretodo prácticos.

El cometido básico de un interface de usuario es el de mostrar y editar el contenido de las memorias internas. Cualquier editor MIDI de Cubase, Logic o cualquier secuenciador hace exactamente eso. Es más, todo el programa entero, la parte “visible”, se dedica a mostrarnos la información que hemos creado, ya sea un procesador de textos, un procesador de imagen o un procesador de audio, como nuestros queridos secuenciadores / plug-ins.

Particularmente me gustan los interfaces de usuario que únicamente muestran la información que es susceptible de ser editada en ese instante. Por ejemplo, en el excelente sintetizador FM8 de Native Instruments se nos muestran los parámetros de cada operador de la síntesis FM de forma individual. ¿Para qué ver los datos del primer operador si estamos editando el segundo?, ¿para qué rellenar la pantalla con más datos y cajas que solo nos perturbarán?

Poder esconder datos irrelevantes es una virtud, pero también una necesidad. En Reason puedo encoger los dispositivos que en ese instante no son el objetivo de mi edición. Así ahorro espacio en pantalla pero además no debo estar viendo controles innecesarios que ya he programado y que no pienso editar en ese instante.

Este tipo de interfaces de usuario funcionan conmutando la información del dispositivo o área seleccionada. Por ejemplo, en REQUIEM hay 8 sintetizares virtuales con todos sus parámetros, modulaciones y 128 patrones encadenables. Es absurdo mostrarlo todo en una única pantalla, aunque desde el punto de vista de programación es algo mucho más cómodo y sencillo.

En cambio, cada vez que selecciono uno de los sintetizadores, REQUIEM cambia el color de los controles mostrados según el color del sintetizador seleccionado, y “escupe” los estados de los controles y parámetros de ese sintetizador seleccionado. Pero los otros sintetizadores deben seguir operando “por detrás” (en background), es decir, REQUIEM debe continuar sonando sin importar lo que seleccione en el interface de usuario. Esto requiere de dos rutas principales de datos: los datos reales salientes y los datos del dispositivo virtual seleccionado en ese instante, que deben ser enviados a la “salida” y además mostrar valores en pantalla para permitir su corrección. Así pues hace falta seleccionar el dispositivo (por parte del usuario) y REQUIEMdisparará” los datos pertinentes (usando rutinas de disparo de eventos, de las cuales ya he citado su más importante exponente: meta-evento 99 con valor 0)

El Environment contiene un curioso objeto llamado Alias, que “clona” el aspecto y definición (contenedor en E-Code) de otro objeto que sea de su mismo tipo. De esta forma puedo lograr que un objeto fader tenga un color y tamaño, pero que a pulsar un botón éste se convierta en una caja numérica de otro color y tamaño, modificando además el tipo de evento que puede recibir y/o enviar. Además puedo asignar varios objetos “master”, por ejemplo 5 tipos de faders, e ir conmutando del uno al otro (con el uso de Asignadores de Alias, un objeto Alias y los objetos empleados como modelos).


El Fader resaltado es en realidad un objeto Alias que toma la definición del evento a enviar /recibir y el aspecto gráfico de los objetos conectados a partir de la segunda conexión del Alias Assigner. Observa que ahora el Alias se comporta como el Fader 1 gris inferior, y envía control 7 por el canal 1 (ver Monitor). El valor 100 es la posición actual del Alias. La línea azul delgada enlaza el Alias con el objeto a clonar: es un sencillo indicativo.



Ahora hemos conmutado el Alias Assigner y el Alias superior toma el aspecto y definición del Fader rojo, que envía control 7 por el canal 3. Moviendo el Fader Alias ya no se enviará control 7 por el canal 1, sino que la definición cambia siendo clonada del Fader 3 rojo.


Hemos conmutado el Alias Assigner al Fader 2, definido como control 7 por el canal MIDI 2. Veamos los parámetros del objeto Alias. Podemos indicar que "tome" al nombre del objeto original, que el tamaño coincida o que pueda re-dimensionarse libremente, o re-canalizar los eventos procesados por el Alias.


Ahora veamos el Alias Assigner... en realidad es un conmutador que permite indicar qué conexión se tomará como activa. En la conexión superior se conecta el objeto Alias, y en las siguientes los objetos a clonar. Además el Alias Assigner cuenta con su propia definición de entrada y salida, con lo que podemos controlarlo remotamente. En este caso he creado otro fader que cambia la conmutación de Alias Assigner con un evento de control 7.


Pero por desgracia el uso de los Alias es muy limitado. No puedo usar Alias en Macros, es decir, nunca podré crear una Macro cuyos faders cambien de aspecto dinámicamente. Tampoco puedo convertir un objeto Fader en un objeto Teclado Virtual… sólo puedo conmutar entre objetos del mismo tipo, por ejemplo un objeto retardo con un tiempo de retardo convertido a otro objeto de retardo con otro tiempo de retardo distinto. Pero además hay otras severas limitaciones, hay objetos imposibles de clonar, por ejemplo conmutar entre dos objetos Monitores de distinto tamaño… Y lo más importante: cuando un Alias cambia de aspecto provoca un redibujado de pantalla, Logic actualizará la ventana del Environment automáticamente, así que se producirá un breve parpadeo. Un último detalle, el uso masivo de Alias no es bueno, carga mucho la capacidad de proceso del Environment. No es aconsejable crear todo un interface de usuario únicamente con Alias, eso sería llenar la pantalla con cientos de objetos Alias que Logic debería redibujar constantemente: hay que usarlos sabiamente.

Aún así, el uso de objetos Alias es imprescindible para el diseño de REQUIEM, así que he tratado de exprimir al máximo su uso, tratando de lograr una experiencia de uso lo más cercana posible al de un software “normal”.

viernes, 15 de enero de 2010

4898 objetos y subiendo


Este es el estado actual de REQUIEM Environment:

Motor de dispositivos melódicos:

- Los 8 dispositivos ya suenan enviando las notas generadas por los patrones o cadenas de patrones a los correspondientes sintetizadores ES-M y ES-P (seleccionados en el GUI) La funcionalidad de duración de las notas aún no ha sido implementada. Las notas envían el tono y velocidad, pero no la duración.
- La monitorización en el picómetro opera conmutando el dispositivo melódico visualizado actualmente en el GUI.
- Las secciones de síntesis (ES-M / ES-P) y modulación de cada dispositivo están plenamente operativas: 128 memorias de sonidos para cada sintetizador y 128 memorias de modulaciones (4 fuentes x 4 destinos, 4 x profundidades de modulación, 4 x offsets de modulación) Cada sección cuenta con funciones copiar / pegar.
- Editor de eventos de dispositivos melódicos operando. Funciones de pre-visualización, Undo y proceso destructivo. Las notas pueden ser editadas en tono, velocidad, duración, posición (es posible desplazar las notas) y además permite edición por rango de notas (1/16, 1/8, etc) El editor de eventos cuenta con 20 memorias de usuario para almacenar los ajustes y ediciones deseadas.

Motor del dispositivo rítmico:

- Por diseñar. Como Logic 5.5.1 PC no tiene dispositivos de sonidos rítmicos (sólo el sampler EXS-24), he buscado sintetizadores de percusión VST freeware. HE encontrado dos candidatos sensacionales que ofrecen 8 sonidos simultáneamente y con no más de 6 parámetros por sonido. El usuario debería descargarlos (con enlaces proporcionados desde la documentación de REQUIEM) e instalarlos en la carpeta “VSTplugins” de Logic. NOTA: ¿y en Mac?


Contenido del menú "Edit" en la ventana "Synth Editor".

Motor modo Song (Multi-Scenes):

- Por diseñar

Motor de reconocimiento de acordes a tiempo real desde entrada MIDI:

- Diseño previo operando con resultados mejorables.

Motor de harmonización según acordes (X-Pose):

- Por diseñar, aunque los patrones ya incluyen ese parámetro.

Motor de exportación a pista de Logic:

- Por diseñar


Fallos y mejoras:

- Copia de memorias de edición “Edit Sets” en el editor de eventos.
- Copia de parámetros de síntesis: el dispositivo ES-P tiene 1 parámetro más que ES-M y la función copiar / pegar debe tenerlo en cuenta.
- Los parámetros transposición y velocidad de los dispositivos melódicos solo opera en modo “Pattern” y no en modo “Phrase”. Aunque esto es correcto, ocurrirá también que el “Pattern” seleccionado y no operativo recibirá esas modificaciones.
- Modos de grabación aún no implementados (a tiempo real vía MIDI y paso a paso vía MIDI)
- La selección del tipo de sintetizador debería actualizar el interface gráfico automáticamente. Sin embargo al hacerlo se produce un bucle de datos no resuelto.
- Pre-visualización en audio en el editor de eventos según el dispositivo seleccionado actualmente.
- Funciones “mute” y “solo” en los dispositivos melódicos, y “solo” en el editor de eventos.
- Función “Get Note from Scale” dependiente de la armonización generada.
- Proceso de “Scenes” no implementado (el contenedor que aúna los “Patterns”, “Synths”, “Mods” y “Efectos”, ligándolos a una nota MIDI o paso en Modo "Song")
- Efectos: aunque lo deseable sería parametrizarlos en memorias al igual que los ES-P y ES-M, temo el disparo masivo de los parámetros de edición de 4 efectos por dispositivo melódico (4 x 8). ¿Hace falta crear memorias Preset de efectos?


Ventana "Modulators".

GUI (interface gráfico de usuario)
  • Menús superiores operativos según ventanas finalizadas.

Ventanas finalizadas y operativas:

  • Ventana principal de edición de dispositivos melódicos finalizada y operando. (Synth Editor)
  • Ventana de edición de eventos operando. (Phrase Editor)
  • Ventana de moduladores (LFOs) operando. (Modulators) Falta implementar los "Circular LFO" y el "Arkanoid LFO" con sus funciones de copiar y pegar.

Ventanas en diseño:

  • Ventana del dispositivo rítmico en diseño inicial. (Rhythm Editor)
  • Mezclador. (Mixer)

Ventanas no diseñadas:

  • Editor de patrones rítmicos.(Rhythm Phrase Editor)
  • Editor de efectos.(Effects Editor)
  • Matriz de modulación. (Matrix Editor)
  • Ventana “Song” (Multi-Scenes)
  • Editor de arpegios.(Arp Editor)
  • Preferencias. (Preferences)


4898 objetos empleados hasta la fecha:



martes, 5 de enero de 2010

E-Code Lección 2 – Uso de variables – Faders I


El uso de variables es imprescindible en el Environment al igual que con cualquier lenguaje de programación. Pero a diferencia de los otros, nosotros no contamos con una entidad real, es decir, no existen objetos “variables” sino que debemos tomar uno o varios objetos del Environment y usarlos a modo de variables. Por supuesto tampoco tenemos distintos tipos de variables: nuestras variables sólo admiten valores enteros de 0 a 127, con lo que la precisión de los cálculos es paupérrima. Lo cierto es que no vamos a usar el Environment para crear programas de matemática avanzada, sino aplicaciones musicales, con lo que las capacidades de cálculo (operadores) son más que suficientes.

Los objetos que nos servirán como variables son:

  • Objetos tipo Faders (que a continuación expongo en esta primera parte)
  • Objetos tipo Transformadores

Contenedores de variables

Considerar estos objetos como variables implica abordar otro concepto adicional: el contenedor de la variable. No puede existir un valor o variable de forma autónoma, sino que hay objetos tipo fader que pueden enviar y recibir valores, y objetos tipo transformadores también con las mismas capacidades además de poder procesar esos valores con operadores.

Aunque no existen distintos tipos de variable, si hay distintos tipos de representaciones de esos datos, por ejemplo como números (fader numérico), como controles gráficos (faders en general), o como cadenas de texto (fader de texto). Y también hay distintos tipos de contenedores, y esta es quizás la cuestión más importante. Me refiero a “contenedor” a la definición de los eventos de salida del objeto gráfico que nos permite alterar el valor de la variable, por ejemplo un fader vertical. En un fader definido para que envíe control MIDI número 7, la variable será el valor de control MIDI número 7 enviado / recibido. El contenedor sería el tipo de valor, en este caso, eventos de control MIDI número 7, y el artefacto que nos permite cambiar el valor de la variable es el propio fader gráfico (de tipo que sea, vertical, numérico, etc…)

Definición de un objeto tipo fader. Las definiciones "Fader" y "Meta" no son eventos MIDI sino eventos internos de Logic. "Fader" es el evento interno de Logic que maneja las automatizaciones de plug-ins y canales en el mezclador virtual y "Meta" son eventos internos genéricos de Logic.

Si deseo enviar más de 20 valores simultáneos a través de un objeto para que los procese (por ejemplo un transformador que añada una constante a la variable), deberé usar 20 contenedores distintos, ya que de lo contrario esas 20 señales se mezclarán en la salida y no podré recuperarlas de forma individual. Aquí la solución será definir cada uno de los 20 faders con un evento MIDI distinto, por ejemplo, 20 cambios de programa distintos (del 0 al 19), o 20 valores distintos de un mismo controlador MIDI (por ejemplo el número 7, volumen)

También hay que tener en cuenta que disponemos de 16 canales MIDI, y que podemos usarlos para individualizar las variables, por ejemplo envíar 16 cambios de programa simultáneamente (cada uno en un canal MIDI distinto) en vez de usar 16 controles MIDI en un mismo canal MIDI.

Objeto fader definido para el envío de eventos de control número 7 (tanto de entrada como de salida, observa los campos "In" y "Out" en el canal MIDI número 1.

La decisión de qué tipo de contenedor debemos usar depende de varios factores:

¿Cuántas variables distintas se procesarán en ese instante?

Si vas a procesar un bando de variables grande lo mejor es usar a los controladores MIDI como contenedor, pues tienes 128 tipos y cada uno de ellos puede enviar / recibir 128 valores. Otro evento MIDI que nos da esa facilidad es la post-pulsación polifónica (P-Press en Logic, aftertouch polifónico), que nos ofrece 128 números de nota con 128 valores cada uno. Así pues estos tipos de eventos nos ofrecen 128 variables con 128 valores en cada una (control 0 de 0 a 128, control 1 de 0 a 128, control 2 de 0 a 128… control 127 de 0 a 127) Los eventos de notas también permiten ser usados como 128 variables distintas (números de nota) con 128 valores cada una (velocidades de pulsación). Existe otro tipo de eventos que nos podrían servir: los Meta-Eventos, que requieren de un post especial pero que tienen una limitación que desvelaré en la respuesta a la siguiente pregunta.

El caso contrario serían los cambios de programa: con ellos solo tenemos una misma variable con 128 valores, ya que no hay 128 tipos de cambios de programa sino sólo 1. Lo mismo es válido para la post-pulsación de canal (C-Press en Logic, aftertouch de canal): es decir, una única variable con 128 valores.

¿Esos valores deben poder ser disparados?

La gran mayoría de variables necesitan ser disparadas en algún momento. Los disparadores en E-Code son los llamados Meta-Eventos (hay 128 distintos cuya funcionalidad ha sido prefijada por Emagic). El Meta-Evento 99 con valor 0 actúa como disparador. Este objeto tiene apariencia de botón, pero puede ser enviado también desde un transformador. El problema es que un Meta-Evento no puede disparar el valor de una variable cuyo contenedor sea otro Meta-Evento. Al crear un botón tipo “Disparar al segundo fader” (es el nombre horrible con el que aparece en Logic en español), no se envía ningún valor si el fader al que disparamos envía Meta-Eventos, en cambio si enviará cualquier otro tipo de evento si el fader no es definido para que envíe Meta-Eventos.

Disparo de una variable con un contenedor definido como control número 7

Visualización de la definición del botón: Meta-Evento 99 con valor 0. El resultado es el evento de disparo ("M 99 0") y el valor del fader en ese instante ("1 7 101", dónde "1" es el canal, "7" el contenedor y "101" el valor de la variable)

Ahora la variable tiene un contenedor definido como Meta-Evento número 7. El disparador falla, ya que un Meta-Evento no puede disparar a otro. El resultado es el evento de disparo ("M 99 0") y no el valor del fader en ese instante ("M 7 101")

¿Cómo se representarán esos valores en pantalla?

También podrías decidir el contenedor a usar para tus variables teniendo en cuenta cómo se representarán los datos en pantalla. Por ejemplo, si vas a usar un teclado virtual para “visualizar” las notas almacenadas lo mejor sería operar con eventos de nota como contenedores de variables, ya que el teclado virtual únicamente representa gráficamente ese tipo de eventos.


Variables Locales y Globales

En programación existen variables que se definen y “mueren” al final de un proceso o variables que permanecen operando todo el tiempo en el que usamos la aplicación. Las locales pues dejan de operar, aunque a diferencia de otros lenguajes de programación en E-Code siguen definidas, siguen existiendo. Esto es porque el objeto sigue insertado en el Environment, y aunque ya no disparemos más esa variable, su fader y contenedor sigue ahí.

En REQUIEM hay muchas variables locales, por ejemplo las notas grabadas. Estos datos son leídos y enviados al motor de reproducción, y esos valores ya no vuelven a circular por los objetos hasta que sean reclamados de nuevo.

En cambio, el selector de qué dispositivo virtual de REQUIEM estamos viendo y editando es una variable global, siempre está activa y operando, definiendo qué memorias se visualizarán y qué eventos podrían verse y editarse.

Como ves es todo conceptual, tú decides qué variables son globales o locales, y tener claro qué es cada objeto insertado a modo de variable facilitará mucho el desarrollo de la programación.

Tenemos a dos variables con contenedores control número 7 y control número 10, que son procesadas por un objeto transformador añadiendo 10 a los valores entrantes. Observa que sólo procesará contenedores definidos como controles MIDI 7, 8, 9 y 10 (condición "Dentro de") y que además eliminará cualquier otro evento que no sean esos (condición definida en el menú superior. El resultado es el valor de cada contenedor sumado al operador. Si cada fader tuviera el mismo contenedor, el resultado sería "1 7 110" y "1 7 60", se perdería la individualidad de cada variable.

Nos vemos…