3 puntos por GN⁺ 2024-08-11 | 1 comentarios | Compartir por WhatsApp
  • Sonic Pi se presenta como un entorno para crear música incluso sin instrumentos ni equipo, y permite escribir directamente notas, acordes, escalas y tiempos con un DSL basado en Ruby
  • Aprovechando funciones, arreglos, condicionales, repeticiones y alcance de Ruby, se pueden combinar play, sleep, play_pattern_timed, chord y scale para construir de forma concisa patrones repetitivos y arpegios
  • Al combinar in_thread, ring, flatten, el operador splat y with_fx, se pueden ejecutar varios “instrumentos” al mismo tiempo y superponer notas apiladas y ritmos distintos
  • El ajuste de attack, decay, sustain y release de la envolvente ADSR se enfoca menos en recrear un coro real y más en lograr duración y separación entre las notas
  • live_loop puede volver a ejecutar código mientras se actualiza durante la reproducción, convirtiendo a Sonic Pi en una herramienta para performance en vivo y haciendo ver el código como texto legible y como acto creativo

Sonic Pi controlado con código

  • Sonic Pi es, a diferencia de una aplicación de audio convencional, un sintetizador de software controlado únicamente por código
  • Su lenguaje de control es un lenguaje específico de dominio (DSL) que extiende Ruby y mapea conceptos musicales y de audio sobre la sintaxis de Ruby
  • Los elementos básicos están formados por valores de Ruby y funciones de Sonic Pi
    • Los nombres de nota como :c4 se usan como símbolos que corresponden a ese código MIDI
    • Se pueden crear acordes pasando una nota raíz y una estructura de acorde como argumentos, por ejemplo chord(:d3, :maj7)
    • play reproduce una nota, y junto con sleep de Ruby permite controlar los intervalos de tiempo
    • play_pattern_timed recibe una lista de notas y una lista de tiempos para reducir el código repetitivo de reproducción
  • El objetivo del ejemplo es crear con código un acompañamiento de demostración usando solo funciones básicas de Sonic Pi, sin MIDI externo ni samples
  • Si instalas la app de Sonic Pi, puedes pegar el código del ejemplo y seguirlo, y también incluye documentación del lenguaje y tutoriales

Crear patrones repetitivos con sintaxis de Ruby

  • El ejemplo básico cambia el BPM con use_bpm 70 y usa el sintetizador pulse con use_synth :pulse en lugar de la onda seno predeterminada
  • Si repites play :c2, sleep 0.25, puedes reproducir notas en secuencia; la misma estructura puede escribirse más corto con play_pattern_timed [ :c3, :d3, :e3, :g3 ], 0.25
  • Como el lenguaje de control está construido sobre Ruby, los patrones pueden abstraerse con funciones y repeticiones
    • La función arpeggiate recibe una nota raíz y, opcionalmente, si es menor, para crear un patrón ascendente y descendente
    • La repetición 4.times ejecuta el mismo patrón a lo largo de varias octavas
    • Con condicionales se cambia la tercera si es menor, y con map del arreglo se genera una lista de notas sumando intervalos a la raíz
  • Primero se pueden definir opciones predeterminadas del sintetizador, como use_synth_defaults amp: 0.1, y también se pueden pasar opciones directamente a play o play_pattern_timed
  • En Ruby, los paréntesis en las llamadas a funciones son opcionales, pero en casos como play chord(:a3, maj7) puede ser necesario aclarar la separación

Ejecución en paralelo y layering

  • El bloque in_thread do se usa en Sonic Pi para ejecutar código en paralelo
  • Si se usan distintos bloques in_thread, se pueden ejecutar dos “instrumentos” separados al mismo tiempo
    • Un hilo puede encargarse del patrón de arpegio
    • Otro hilo puede reproducir una línea melódica aparte usando use_synth :saw, un arreglo de melodía y un arreglo de ritmo
  • play_pattern_timed no solo puede recibir una lista de notas, sino también una lista de intervalos de tiempo
    • [1] * 2 expande la longitud del arreglo repitiendo su contenido, como [1, 1]
    • Los arreglos anidados no pueden pasarse tal cual a play_pattern_timed, así que se usa flatten para convertirlos en un arreglo de un solo nivel
  • Para crear notas superpuestas como en un coro, se pueden agrupar varias notas juntas con algo como ring(:c5, :e5)
  • flatten también puede aplanar las listas dentro de ring, así que en ese caso se usa el operador splat * para expandir el contenido de la lista dentro del arreglo padre

Alcance, efectos y construcción de partes corales

  • Si se usa in_thread anidado, se pueden compartir fragmentos de ritmo del alcance externo y aun así reutilizar el mismo nombre de variable dentro de cada hilo interno
  • Si las partes, como soprano y alto, se separan en hilos distintos, cada bloque tiene su propio alcance, así que no acceden directamente a las variables del otro
  • with_fx :reverb, mix: 0.2 crea un bloque de efecto, y el flujo de señal empieza en la capa más interna y se mueve hacia la cadena de efectos exterior
  • mix indica cuánto se mezclan la señal wet y la señal dry
    • La señal wet es la señal con el efecto aplicado
    • La señal dry es la señal sin efecto
  • Envolver todo el grupo en un solo efecto puede usarse de forma similar a un bus en un DAW, pero el ruteo más profundo es manual y, por cuestiones de alcance, en general debe construirse de arriba hacia abajo
  • Sonic Pi se siente más natural como un instrumento que como una herramienta de producción sofisticada

Ajustar la duración de las notas con la envolvente ADSR

  • play_pattern_timed agrega el valor de sustain, por lo que la duración de acordes largos y cortos puede ajustarse directamente
  • attack, decay, sustain y release forman la envolvente ADSR, que describe cómo cambia el volumen con el tiempo
    • attack es el tiempo que tarda en ir de 0 al primer pico, equivalente al golpe inicial, como al pulsar una cuerda o cuando el martillo del piano hace contacto
    • decay es el tiempo de descenso desde ese primer pico, como cuando el sonido de un piano o una guitarra va bajando poco a poco aunque la tecla o la cuerda sigan presionadas
    • sustain es el tiempo durante el cual el sonido se mantiene en un volumen estable, como en una cuerda frotada con arco o una voz sostenida
    • release es el tiempo que tarda en apagarse de verdad después de soltar el sonido
  • No todos los sonidos tienen necesariamente todos los elementos de ADSR
    • Un tono de sintetizador es un sonido generado, así que no siempre tiene una fase inicial de crecimiento ni una cola resonante
    • En los instrumentos acústicos, la proporción entre estos elementos cambia según la forma de interpretación
  • La simulación coral del ejemplo se enfoca menos en el realismo y más en hacer que las notas duren el tiempo exacto y que haya una ligera separación entre acordes
  • La función choral_rings notes, sus recibe una lista de notas y una duración, las reproduce juntas con ring(*notes), calcula sustain y release, y luego espera hasta el siguiente evento con sleep sus

Live coding con live_loop

  • Con live_loop, el código puede repetirse indefinidamente
  • Sonic Pi es una herramienta pensada en gran medida para la performance en vivo, y el código dentro de live_loop sigue ejecutándose hasta que se detiene el programa
  • Incluso durante la reproducción se puede cambiar el contenido del loop, y si se vuelve a ejecutar el comando de inicio, el loop actualizado se aplica desde la siguiente repetición
  • El loop externo existente con in_thread puede cambiarse a la forma live_loop :some_unique_name
  • Como la cadena de efectos se vuelve a crear en cada vuelta del loop, mientras más efectos se acumulen, más conveniente es dejarlos fuera de live_loop por eficiencia de recursos
  • El ejemplo final está compuesto por live_loop :harp y live_loop :choir
    • El loop :harp usa el sintetizador :square y un patrón de arpegio con duración de 0.25
    • El loop :choir reproduce acordes corales con el sintetizador :saw, sleep 64, with_fx :reverb, mix: 0.75 y llamadas a la función choral_rings

Ver la programación como un acto creativo

  • El trabajo técnico suele discutirse desde la perspectiva de la informática, pero la programación también puede ser arte
  • No solo es artística cuando produce resultados intencionalmente creativos, como generación de audio o layouts en CSS
  • El código no es solo un conjunto de instrucciones optimizadas para una máquina, sino también texto organizado que otras personas y tu yo del futuro leen
  • Un buen código es aquel que está escrito para que otra persona, o tú mismo seis meses después, pueda entenderlo de inmediato
  • A veces, el valor artístico del código es un fin en sí mismo, y el ejemplo de Sonic Pi muestra ese punto a través de la creación musical

1 comentarios

 
GN⁺ 2024-08-11
Opiniones de Hacker News
  • Si te interesa el live coding, también vale la pena probar Glicol(https://glicol.org)
    También está TidalCycles, y la capacidad de Haskell y Ruby para crear DSL es realmente digna de elogio
    En Glicol se enfocan en una sintaxis inspirada en sintetizadores, la velocidad de composición y la comodidad para el diseño de sonido. La idea es diseñar un DSL que tome hábitos de programación existentes, pero que no quede encerrado en un lenguaje específico

  • Hace unos años vi en YouTube un video de alguien recreando el THX Deep Note con Sonic Pi
    Al principio no explicaba qué iba a crear; hacía un solo “tono” del sonido y lo llamaba abeja. Iba ajustando y reproduciendo poco a poco ese sonido de abeja, y al final avanzaba con algo como “hagamos unos cientos de estas abejas y veamos cómo suenan en una colmena”; en ese momento aparecía el Deep Note
    Ese video me encantó, pero desde entonces no he podido volver a encontrarlo. Si alguien conoce el enlace, sería genial que lo compartiera

  • Creo que es uno de los casos donde Ruby brilla. Gracias a la metaprogramación, se puede hacer que la sintaxis parezca casi inglés

    • Es cierto, pero el DSL de Sonic Pi se siente un poco más cercano a Lisp que a lenguaje natural
    • Sí, es metaprogramación
  • Hace unos años vi a Sam Aaron, es decir, el creador de Sonic Pi, dar una presentación en vivo con Sonic Pi
    Cada vez que el código cambiaba en tiempo real, la música también seguía evolucionando, y de verdad sonaba bien

    • Yo también conocí a Sam. Después de una charla en Clojure Conj, alrededor de 2008~2010, cenamos juntos; ya entonces me pareció una gran persona y la presentación también fue excelente
  • Si quieres ejemplos de artistas que usan Sonic Pi, hace tiempo descubrí a DJ_Dave, y me parece un buen caso de una música talentosa y experimentada usando bien esta herramienta
    También hizo un AMA en Reddit hace tiempo, y parece que tiene trabajos en GitHub
    [1] https://www.youtube.com/watch?v=JiQHclg_648
    [2] https://www.reddit.com/r/audius/comments/19dxmy6/hey_audius_...
    [3] https://github.com/algorave-dave

  • Como desarrollador de Ruby, se ve realmente genial. Creo que sería divertido usarlo para música generativa algorítmica, y alguna vez quise convertir los eventos ruidosos de un repositorio git en algún tipo de música algorítmica; esto parece encajar bien
    Pero, como músico con varios instrumentos de teclado, si quiero componer una canción puedo tocar con un teclado MIDI o grabar un instrumento acústico y hacer loops, así que no veo del todo por qué tendría que programar una secuencia musical en Ruby. Entiendo que se puede escribir lo que uno quiere con un DSL de Ruby, pero es difícil decir que la experiencia de usuario sea mejor que la de un teclado de piano
    Dicho de otro modo, no creo que usaría esto para reemplazar Logic. Claro, es una preferencia personal
    Referencia: http://listen.hatnote.com/

    • Aun así, en algunos aspectos un DSL de Ruby expresa la intención con más claridad que una secuencia MIDI
      En la práctica, a veces uno piensa cosas como “ahora un arpegio en do menor, ahora un arpegio en fa mayor”, y me gusta que esa intención pueda componerse de forma muy clara con funciones
    • Sonic Pi parece estar más enfocado en la música creada con algoritmos, especialmente en el live coding, que en ser una herramienta de composición general
      El punto central parece ser generar con algoritmos, más que tocar cada nota una por una
      Aun así, usar de forma interesante una herramienta que normalmente no se usaría, debido a restricciones inusuales, encaja bastante bien con los intereses de Hacker News
    • Puede ser adecuado para teóricos de la música con poca coordinación y poca motricidad fina
    • Como también insinuaba el artículo original, la mayor parte se debe a restricciones prácticas
      Tengo un teclado que me gusta y, en teoría, podría usarlo para esto, pero personalmente, por circunstancias complicadas, todos mis instrumentos están guardados en un depósito desde hace tiempo
  • Hace unos días justo estaba pensando en Sonic Pi y vi algunos videos en línea
    Lo único que había hecho fue probarlo brevemente hace unos años, y en ese entonces toqué canciones clásicas como Old MacDonald y Hot Cross Buns

  • Si te interesan otros enfoques para programar música, aunque no sea en vivo, también vale la pena ver scamp[0] para Python
    Su creador subió a YouTube muchos videos de trabajos hechos con esto; por ejemplo, está el video Fourier Elise[1]
    [0] http://scamp.marcevanstein.com/
    [1] https://www.youtube.com/watch?v=zq32bIud3OM

  • Parece que los comentarios HTML no funcionan. Da la impresión de que el editor convirtió los dos guiones -- en un solo em dash

    • Bien visto. En realidad hice un buscar/reemplazar demasiado apresurado y se me escaparon varios casos como este XD
  • También recomiendo a mi live coder favorito de Sonic Pi, alsoknownasrox
    https://www.youtube.com/watch?v=wXIvXrBQFkE