1 - Bienvenido amigo :-)

Bienvenido a Sonic Pi. Ojalá estés tan emocionado por comenzar a hacer sonidos de locura, como yo de mostrarte cómo. Va a ser realmente divertido, aprenderás música, síntesis, programación, composición, ejecución y más.

Pero espera, ¡qué rudeza la mía! Deja que me presente - yo soy Sam Aaron - quien creó Sonic Pi. Puedes encontrarme en Twitter@samaaron y estaré encantado de saludarte. Quizás te interese saber más de mis ejecuciones Live Coding Performances donde codifico con Sonic Pi en vivo frente a audiencias.

Si tienes ideas para mejorar Sonic Pi - por favor pásamelas - la retroalimentación es bienvenida. ¡Nunca sabes, tu idea podría ser la próxima gran adición!

Este tutorial está dividido en secciones, agrupadas por categoría. Lo he escrito para tener una fácil progresión desde principio a fin, siéntete libre de saltar de una sección a otra, cuanto te apetezca. Si sientes que hay algo que falta, dímelo y consideraré añadirlo en el futuro.

Finalmente, el observar a otros codificar en vivo es una gran manera de aprender. Yo lo hago en vivo por livecoding.tv/samaaron así que visita, saluda y pregunta todo lo que quieras :-)

OK, comencemos…


1.1 - Live Coding

Uno de los aspectos más excitantes de Sonic Pi es la posibilidad de escribir y modificar código en vivo para hacer música, así como lo harías al tocar una guitarra. Esto significa que con algo de práctica podrás usar Sonic Pi en escena y tocar con él.

Libera tu mente

Antes de entrar en los detalles de cómo funciona Sonic Pi en el resto de este tutorial, me gustaría darte una experiencia de lo que es codificar en vivo. No te preocupes si no entiendes mucho (o nada) de esto. Sólo intenta permanecer sentado y disfrutar…

Un Bucle Vivo

Comencemos copiando el siguiente código en un buffer vacío arriba:

live_loop :flibble do
  sample :bd_haus, rate: 1
  sleep 0.5
end

Ahora presiona el botón “Ejecutar” y escucharás una batería tocada rápidamente. Si en cualquier momento deseas parar el sonido, sólo debes presional el botón “Parar”. Pero no lo pares, aún…En vez de ello sigue los siguientes pasos:

  1. Asegúrate que el sonido de batería sigue sonando.
  2. Cambia el valor “sleep” desde “0.5” a algo más alto como “1”.
  3. Presiona de nuevo el botón “Ejecutar”.
  4. ¿Notas cómo cambió la velocidad de la batería?.
  5. Finalmente, recuerda este momento, esta es la primera vez que has codificado en tiempo real con Sonic Pi y muy probablemente no será tu última…

Ok, eso fue lo suficientemente sencillo. Añadamos algo a la mezcla. Encima de sample :bd_haus añade la línea sample :ambi_choir, rate: 0.3. Tu código debería mirarse, así:

live_loop :flibble do
  sample :ambi_choir, rate: 0.3
  sample :bd_haus, rate: 1
  sleep 1
end

Ahora juega, cambia valores. ¿qué pasa cuando usas valores altos, bajos o negativos? Mira lo que pasa cuando cambias el valor rate: por :ambi_choir ajustalo mìnimamente (digamos a 0.29). ¿Qué pasa si pones un valor muy bajo para sleep ? Mira si puedes hacerlo sonar tan ràpido que tu computadora se paraliza con un error (si eso sucede, simplemente elige un valor más alto para sleep y presiona Ejecutar de nuevo).

Prueba a comentar una de las líneas del ejemplo, añadiendo un # al comienzo:

live_loop :flibble do
  sample :ambi_choir, rate: 0.3
#  sample :bd_haus, rate: 1
  sleep 1
end

¿Notas que el numeral hace que la computadora ignore esa línea? Esto se llama ‘comentar’. En sonic Pi podemos usar comentarios para quitar y añadir cosas a la mezcla.

Finalmente, te dejo con algo divertido con lo que jugar. Toma el siguiente código y cópialo en un buffer vacío. Por el momento no intentes comprender demasiado más que notar que hay dos bucles - lo que significa que hay dos eventos al mismo tiempo - experimenta y juega. Te dejo algunas sugerencias:

Recuerda que debes presionar ‘Ejecutar’ para escuchar el cambio en el próximo bucle. Si termina siendo un relajo, no te preocupes - dale a ‘Parar’, borra el código del buffer y pega una copia fresca para volver a comenzar. Cometiendo errores es como aprenderás más rápidamente.

live_loop :guit do
  with_fx :echo, mix: 0.3, phase: 0.25 do
    sample :guit_em9, rate: 0.5
  end
#  sample :guit_em9, rate: -0.5
  sleep 8
end

live_loop :boom do
  with_fx :reverb, room: 1 do
    sample :bd_boom, amp: 10, rate: 1
  end
  sleep 8
end

Ahora, sigue tocando y experimentando hasta que tu curiosidad acerca de todo esto se dispare y comiences a preguntarte ¿qué más puedes hacer? Ya estás listo para leer el resto del tutorial.

Así que: ¿qué estás esperando?


1.2 - El interfaz de Sonic Pi

Sonic Pi tiene un sencillo interfaz para codificar música. Explorémoslo por un momento.

Sonic Pi Interface

A. Controles de Ejecución

Estos botones rosados son los principales controles para comenzar y parar sonidos. Está el botón de ‘Ejecutar’ para correr el código en el editor y ‘Parar’ para parar todo código en Ejecución en el editor, ‘Guardar’ para guardar el código a un archivo externo y ‘Grabar’ para crear una grabación (archivo WAV) de los sonidos ejecutándose.

B. Controles de edición

Estos botones anaranjados te permiten manipular el editor del código. Los botones Tamaño+ y Tamaño- te permiten cambiar el tamaño del texto. El botón Alinear hará que tu código este más claro y profesional.

C. Info y ayuda

Estos botones azules te dan acceso a información, ayuda y preferencias. El botón Info abre la ventana informativa, la cual contiene información del propio programa Sonic Pi - el equipo base, historia, contribuyentes y la comunidad. El botón de Ayuda cambia entre el sistema de ayuda y el botón Preferencias activa la ventana de preferencias, la cual te permite controlar algunos parametros básicos del sistema.

D. Editor de código

Esta es el área donde escribirás tu código y compndrás/ejecutarás música. Es un sencillo editor de texto donde puedes escribir, borrar, cortar, pegar, etc. Piensa que es una versión simplificada de Word o Google Docs.

El editor colorea las palabras utomáticamente, basado en su significado para el código.Al principio, esto puede parecer extraño, pero pronto lo encontrarás muy útil. Por ejemplo, sabrás que algo es un número, porque es de color azul.

E. Panel de Preferencias

Sonic Pi permite cambiar ciertos parámetros, accesibles a través del botón preferencias . Este botón cambia la visibilidad del panel de preferencias, el cual incluye un número de opciones a ser cambiadas. Ejemplo de ellas son el forzar el modo mono, invertir el estéreo, cambiar a vista/no vista de la bitácora, mando de volumen y un selector de audio para la Raspberry Pi

F. Visor de la bitácora

Cuando ejecutas un código, la bitácora muestra información de lo que está haciendo el programa. Predeterminado está el que veas un mensaje por cada sonido que crees con el tiempo exacto al que fue disparado el sonido. Esto es muy útil para depurar código y entender qué es lo que está haciendo.

G. Sistema de ayuda

Finalmente, una de las partes más importantes del interface de Sonic Pi es el sistema de ayuda que aparece en la parte baja de la ventana. Esta puede ser activada o desactivada al apretar el botón azul «ayuda». El sistema de ayuda contiene información de todos los aspectos de Sonic Pi incluídos en este tutorial, listado de sintetizadores disponibles, sampleos, ejemplos, FX y una lista de todas las funciones que Sonic Pi provee para codificar música.


1.3 - Aprender jugando

Sonic Pi te incita a aprender computación y música a través de jugar y experimentar. Lo más importante es que te diviertas y sin darte cuenta, estarás aprendiendo a codificar, componer y ejecutar.

Los errores no existen

Hablando de eso, déjame darte un consejo, aprendido a través de mis años de escribir código musical en vivo: «no hay errores, sólo oportunidades». Esto es algo que he escuchado a menudo en relación al jazz, pero funciona igualmente bien en el live-coding. No importa lo experimentado que seas -de completo principiante a un algoraver, alguna vez ejecutarás código que salga de maneras inesperadas - Podría sonar increíblemente o no, pero no importa, lo que sí importa es lo que hagas la próxima vez con él. Toma sonido, manipulalo y conviértelo en algo alucinante. El público se volverá « loco».

Comienza sencillo

Cuando estás aprendiendo es tentador querer hacer cosas «ya». Sin embargo, mantén ese deseo como un objetivo para «después». Por ahora, piensa en lo más simple que puedas escribir que pueda ser divertido y satisfactorio, que sea un simple paso para ese increíble objetivo que tienes en la mente. Una vez tengas una idea de ese simple paso, intenta y constrúyelo, juega y mira qué nuevas ideas te trae. En poco tiempo estarás demasiado ocupado y haciendo progresos enormes.

Sólo asegúrate de compartir tu trabajo con los demás!


2 - Sintetizadores

OK, suficiente de introducciones - hagamos algo de sonido.

En esta sección cubriremos las bases de disparar y manipular un sintetizador, que no es más que una palabra rebuscada para algo que produce sonidos. Típicamente los sintetizadores son bastante complicados de usarse - especialmente los análogos con tantos cables para unir los patches y módulos. Sin embargo, Sonic-Pi te da mucho de ese poder en una manera mucho más sencilla.

No te confundas con la sencillez del interfaz de Sonic-Pi. Puedes llegar a manipular con mucha profundidad el sonido, si eso te interesa. Mantente atento…


2.1 - tus primeros Beeps

Échale una mirada al siguiente código:

play 70

Así comienza todo. Adelante, copia y pega en la ventana superior de la aplicación (ese espacio grande en blanco debajo del botón Run) Ahora, presiona ‘Run’

Beep!

Intenso. Presiónalo otra vez, otra vez, otra vez y otra vez… Woah, loco, estoy seguro que podrías seguir así por el resto del día. Pero espera, antes de perderte en un infinito bucle de pitidos, intenta cambiando el número:

play 75

¿Escuchas la diferencia? Intenta con un número menor:

play 60

Así que números menores hacen pitidos de tonos más graves y números mayores hacen pitidos de tonos más agudos…justo como en un piano las teclas más a la izquierda son más graves que las del lado derecho. De hecho, los números se relacionan con las teclas del piano. play 47 significa que toque la tecla 47va del piano; play 48 es un tono arriba (la siguiente tecla a la derecha). Pasa que la tecla número 60 del piano es la 4ta octava de DO. Intenta con: play 60.

Si nada de esto significa algo para tí, no te preocupes, que así fue también cuando yo comenzaba. Lo que importa es que sepas que los números menores significan pitidos más graves que los números mayores.

Acordes

Si tocar una nota es divertido, tocar varias al mismo tiempo lo es aún más. Pruébalo:

play 72
play 75
play 79

Jazzy! cuando escribes múltiples plays, todos se tocan al mismo tiempo. compruébalo tú mismo - ¿cuáles suenan bien, mal? Prueba, experimenta y encuentra por tí mismo.

Melodia

Si tocar notas y acordes es divertido, ¿qué tal si queremos tocar notas en diferentes momentos? ¡Fácil! sólo debes poner un sleep entre las notas:

play 72
sleep 1
play 75
sleep 1
play 79

¡qué adorable pequeño arpeggio! Entonces, ¿qué significa el 1 en sleep 1? Bien, significa la duración de dormir. Realmente significa dormir por un pulso, aunque por ahora podemos pensar que significa dormir por espacio de 1 segundo. Así, ¿cómo haríamos para que el arpeggio suene más rápido? Bueno, necesitaríamos usar valores de ‘sleep’ menores. ¿qué tal, por ejemplo 0.5:

play 72
sleep 0.5
play 75
sleep 0.5
play 79

¿Notaste que se ejecutaron más rápido? ahora prueba tú mismo cambiando los valores, usando diferentes tiempos y notas.

Una cosa a probar es tocar notas como play 52.3 y play 52.63. No hay necesidad alguna de usar notas enteras. Toca, prueba y diviértete

Nombres tradicionales de las notas

Para aquellos de vosotros que poseáis conocimientos de notación musical (no importa si no, no es absolutamente necesario para divertirte) quizás quieras escribir una melodía usando nombres de notas como C y F# en vez de números. Sonic Pi tiene todo eso cubierto. Puedes hacer lo siguiente:

play :C
sleep 0.5
play :D
sleep 0.5
play :E

Recuerda poner los dos puntos ‘:’ delante del nombre de la nota, para que se ponga rosada. también puedes especificar la octava, añadiendo un número delante de la nota:

play :C3
sleep 0.5
play :D3
sleep 0.5
play :E4

Si quieres hacer sostenido de una nota, añádele una ‘s’ al nombre de la nota así:play :Fs3 y si quieres bemolizar, añádele una b así play :Eb3. ahora, hazte “loco” y diviértete con tus propias tonadas.


2.2 - Opciones Synth: Amp y Pan

Asimismo como Sonic Pi te permite controlar cuál nota tocar o cuál sample disparar, también provee un completo rango de opciones para pulir y controlar los sonidos. En este tutorial cubriremos muchos de estos y exite una gran documentación para cada uno en el sistema de ayuda. Sin embargo, por ahora introduciremos dos de los más útiles: amplitude y pan. Miremos primero qué son las opciones.

Opciones

Sonic Pi apoya la noción de optiones (opts, abreviando) para sus sintetizadores. Opts son controles que pasas a pla los cuales modifican y controlan aspectos del sonido que oyes. Cada sintetizador tiene su propio set de opts para sintonizar su sonido. Sin embargo, hay sets comunes de opts que comparten muchos, tales como amp: y opciones de envelopes (cubiertas en otra sección).

Las Opts tienen dos partes principales, su nombre (el nombre del control) y su valor (el valor al que setearás el control). Por ejemplo, puedes tener un control llamado ‘cheese:’ y querer setearlo con un valor de 1.

Los opts se pasan a las llamadas a play por medio del uso de una coma , y después el nombre del opt, tal como amp: (no olvides los dos puntos :) y después un espacio y el valor del opt. Ejemplo:

play 50, cheese: 1

(Nota que cheese: no es un opt válido, lo usamos sólo como ejemplo).

Puedes pasar múltiples opts por medio de comas que los separen: ~~~~ play 50, cheese: 1, beans: 0.5 ~~~~

El orden de los opts no importa, el siguiente será igual al anterior: ~~~~ play 50, beans: 0.5, cheese: 1 ~~~~

Si un Opt no es reconocido por el sintetizador, simplemente es ignorado (como en el caso de cheese y beans ¡los cuales son nombres ridículos, obviamente!)

Si accidentalemente utilizas el mismo opt dos veces con diferentes valores, el último gana. Por ejemplo, beans: aquí tendrá el valor de 2 y no el de 0.5:

play 50, beans: 0.5, cheese: 3, eggs: 0.1, beans: 2

Muchas cosas en Sonic Pi aceptan opts, sòlo debes pasar tiempo aprendiendo cómo usarlas e irás bien. Ejecutemos nuestro primer opt: amp:.

Amplitud

Amplitud es una representación computarizada del volumen de un sonido. Una alta amplitud produce un sonido de alto volumen y baja amplitud produce sonido de bajo volumen. Así como Sonic Pi utiliza números para representar tonos y tiempos, usa números para representar la amplitud. Una amplitud de 0 es silencio (escucharás nada) y amplitud de 1 es volumen normal. Puedes utilizar volumen a amplitudes mayores a 2, 10, 100. Sin embargo, debes tener en cuenta que cuando la amplitud de todos los sonidos se vuelve muy alta, Sonic Pi utiliza un compresor para asegurar que no lleguen a tan alto que dañen tus oídos. Esto puede hacer que los sonidos sean extraños. Intenta con amplitudes bajas, por ejemplo en el rango de 0 to 0.5 para evitar compresión.

Amplifícalo!

Para cambiar la amplitud de un sonido, utiliza el opt amp:. Por ejemplo, para tocar a la mitad de la amplitud, 0.5:

play 60, amp: 0.5

Para hacerlo al doble de amplitud 2:

play 60, amp: 2

El opt amp: sólo modifica la llamada para el play al que está asociado. Así, en este ejemplo, la primera llamada para tocar es a mitad de volumen y la segunda es a la predeterminada (1):

play 60, amp: 0.5
sleep 0.5
play 65

Por supuesto que puedes usar diferentes valores de amp: para cada llamada a play:

play 50, amp: 0.1
sleep 0.25
play 55, amp: 0.2
sleep 0.25
play 57, amp: 0.4
sleep 0.25
play 62, amp: 1

Paneo

Otro concepto divertido de usar es el paneo pan: el cual controla el paneo de un sonido en estéreo. Paneando un sonido a la izquierda, significa que lo escucharás en la bocina izquierda, paneándolo a la derecha, significa que lo escucharás de la bocina derecha. Para nuestros valores, tenemos -1 para representar completamente a la izquierda, 0 para representar el centro y 1 para representar completamente a la derecha. Claro, eres libre de usar cualquier valor en medio de -1 y 1 para controlar la posición exacta de tu sonido.

Toquemos un pitido desde la bocina izquierda:

play 60, pan: -1

ahora que salga de la bocina derecha:

play 60, pan: 1

Finalmente, pongámoslo de nuevo al centro (predeterminado):

play 60, pan: 0

¡Ahora diviértete cambiando las amplitudes y paneos de tus sonidos!


2.3 - Cambiando Sintetizadores

Hasta ahora nos hemos divertido mucho sólo con pitidos. Sin embargo, de seguro ya comienzas a cansarte del sonido básico de pitidos. ¿es eso todo lo que Sonic-Pi tiene para ofrecer? Tiene que haber más que tocar pitidos. Sí, hay mucho más y lo exploraremos en esta sección con el excitante rango de sonidos que Sonic Pi tiene para ofrecer.

Sintetizadores

Sonic Pi posee un rango de instrumentos que se llaman synths, que es como abreviamos sintetizadores. Mientras que los sampleos representan sonidos pregrabados, los sintetizadores son capaces de generar nuevos sonidos dependiendo de cómo los controles (lo cual exploraremos más adelante en el tutorial). Los sintetizadores de Sonic Pi son poderosos y expresivos, tendrás mucha diversión tocando y explorándolos. Primero, aprendamos a seleccionar el synth a usar.

Sierras y Profetas

Un sonido divertido es el de la onda sierra - probémoslo:

use_synth :saw
play 38
sleep 0.25
play 50
sleep 0.25
play 62
sleep 0.25

Probemos otro sonido - el profeta:

use_synth :prophet
play 38
sleep 0.25
play 50
sleep 0.25
play 62
sleep 0.25

¿qué tal si combinamos ambos sonidos. Uno después del otro?

use_synth :saw
play 38
sleep 0.25
play 50
sleep 0.25
use_synth :prophet
play 57
sleep 0.25

Ahora al mismo tiempo:

use_synth :tb303
play 38
sleep 0.25
use_synth :dsaw
play 50
sleep 0.25
use_synth :prophet
play 57
sleep 0.25

Debes notar que el comando use_synth sólo afecta los siguientes play. Piensa en él como un gran switch - nuevas llamadas play tocarán el synth que esté en uso. Puedes mover el synth a un nuevo synth con cada nuevo use_synth.

Descubriendo Synths

Para saber cuáles sintetizadores tiene Sonic Pi, échale un vistazo a la opción Synths en el menú a la izquierda (encima de FX). Hay más de 20 de los cuales elegir. Aquí están algunos de mis favoritos:

Ahora prueba ir cambiando sintetizadores durante tu música. Diviértete combinando synths para hacer nuevos sonidos así como utilizando diferentes sintetizadores para diferentes secciones de tú música.


2.4 - Duración con Sobres

En una sección anterior, miramos cómo utilizar el comando sleep para controlar cuándo disparar sonidos. Sin embargo, aún no hemos podido controlar la duración de nuestros sonidos.

A manera de tener una sencilla, pero poderosa manera de controlar la duración de nuestros sonidos, Sonic Pi provee la noción de un sobre de amplitud ADSR (después cubriremos lo que significa ADSR). Un sobre de amplitud ofrece dos útiles aspectos de contro:

Duración

Duración es la longitud del sonido. Una mayor duración significa que escucharás el sonido por más tiempo. Todos los sonidos de Sonic -Pi tienen un sobre de control de la amplitud y la duración total del sobre es la duración del sonido. Por lo tanto, al controlar el sobre, controlas la duración.

Amplitud

El sobre ADSR no sólo controla la duración, también te permite control fino de la amplitud del sonido. Todos los sonidos audibles comienzan y terminan en silencio, conteniendo partes no-silentes en medio. Los sobres permiten deslizar y mantener la amplitud de las partes no-silente. Es como darle instrucciones a alguien sobre cómo subir y bajar el volumen del amplificador de una guitarra. Por ejemplo, puedes pedirle a alguien “comienza en silencio, lentamente llega a máximo volumen, manténlo por un momento y rápidamente vuelve a silencio”. Sonic Pi te permite controlar exactamente esta conducta con los sobres.

Recapitulando lo visto anteriormente, una amplitud de 0 es silencio y una amplitud de 1 es volumen normal

Ahora, veamos cada parte del sobre.

Fase Release (desenganche)

La única parte del sobre que es utilizada predeterminadamente es el release, que es el tiempo que le toma al sintetizador para apagar el sonido completamente. Todos los sintetizadores tienen un tiempo de release de 1, lo que significa que tienen una duración de un pulso (el cual por defecto es 1 segundo, si el BPM es 60)

play 70

La nota será audible por 1 segundo. Vamos, cronométralo! Esta es la manera abreviada de decir lo mismo que:

play 70, release: 1

¡Notas que suenan exactamente igual los últimos dos comandos! Sin embargo, es ahora muy fácil cambiar la duración con tan sólo modificar el valor del release: :

play 60, release: 2

Podemos hacer que el sintetizador suene por un periodo de tiempo muy corto al poner un valor de release muy pequeño:

play 60, release: 0.2

La duración del apagado del sonido es lo que llamamos fase de release y por defecto es una transición lineal. El siguiente diagrama ilustra esta transición:

release envelope

La línea vertical en la izquierda del diagrama muestra que el sonido comienza con 0 amplitud, pero llega a amplitud completa (esto es el ataque, que cubriremos próximamente). Una vez que la amplitud es máxima, se mueve en línea recta hacia abajo hasta llegar a cero, tomando el tiempo que para ello se especificó en release:. Entre más largos son los tiempos de release, más tiempo le toma al sintetizador desvanecerse.

Puedes, por tanto, cambiar la duración de tu sonido, cambiando el tiempo de release. ¡Prueba varios tiempos de release en tu música!

Fase de Ataque

Por defecto, la fase de ataque es 0 para todos los sintetizadores, lo que significa que pasan de amplitud 0 a 1 inmediatamente. Esto le da al sintetizador un percusivo sonido inicial. Sin embargo, podrías desear encender tu sonido de a poco. Esto se logra con el operador attack: . Prueba encender tu sonido de a poco:

play 60, attack: 2
sleep 3
play 65, attack: 0.5

Puedes utilizar múltiples operadores al mismo tiempo. Por ejemplo para un ataque corto y un largo release, prueba:

play 60, attack: 0.7, release: 4

Este sobre con ataque corto y largo release queda ilustrado en el siguiente diagrama:

attack release envelope

También puedes invertir las cosas. Intenta con un ataque largo y un release corto:

play 60, attack: 4, release: 0.7

long attack short release envelope

Finalmente, puedes tener el ataque y el release cortos, para obtener sonidos cortos.

play 60, attack: 0.5, release: 0.5

short attack short release envelope

Fase de Sostenimiento

Adicionalmente a especificar los tiempos de ataque y release, también puedes especificar el tiempo de sostenimiento para controlar la fase de sostenimiento. Este es el tiempo en el cual el sonido es mantenido a máxima amplitud entre las fases de ataque y release.

play 60, attack: 0.3, sustain: 1, release: 1

ASR envelope

El sostenimiento es útil para importantes sonidos a los que desees darles máxima presencia a la mezcla antes de entrar a la fase de release. Claro, es totalmente válido usar ambos operandos, attack: y release: opts a 0 y dejar el sostenimiento sin aparecimiento gradual ni desvanecimiento. Sin embargo, ten en cuenta que un release de 0 puede producir clicks en el audio y es aconsejable usar un valor muy pequeño como 0.2.

Fase de Decaimiento

Para un nivel extra de control, también puedes especificar el tiempo de decaimiento. Esta es la fase del sobre que está entre el ataque el ataque y el sostenimiento, especifica el tiempo donde la amplitud bajará desde el nivel de ataque al de desvanecimiento attack_level: decay_level: (a menos que especiques que será sujetado al nivel de sostenimiento sustain_level:). De hecho, el decay: operando es 0 y tanto el ataque como el sostenimiento tienen valor 1, así que deberás especificarlos para que el tiempo de decaimiento tenga efecto.

play 60, attack: 0.1, attack_level: 1, decay: 0.2, sustain_level: 0.4, sustain: 1, release: 0.5

ADSR envelope

Nivel de Decaimiento

Un último truco es que aunque el decay_level: opt está predeterminado a ser el mismo valor que el sustain_level: puedes ser explícito y asignarles diferentes valores para un completo control del sobre. Esto permite crear sobres como el siguiente:

play 60, attack: 0.1, attack_level: 1, decay: 0.2, decay_level: 0.3, sustain: 1, sustain_level: 0.4, release: 0.5

ASR envelope

También es posible poner el decay_level: más elevado que el sustain_level::

play 60, attack: 0.1, attack_level: 0.1, decay: 0.2, decay_level: 1, sustain: 0.5, sustain_level: 0.8, release: 1.5

ASR envelope

Sobres ADSR

Para resumir, los sobres ADSR de Sonic Pi tienen las siguientes fases:

  1. ataque - tiempo desde amplitude 0 hasta el attack_level,
  2. decaimiento - tiempo para mover la amplitud desde attack_level a decay_level,
  3. sostenimiento - tiempo para mover la amplitud desde decay_level a sustain_level,
  4. release - tiempo para mover la amplitud desde sustain_level a 0

Es importante recalcar que la duración de un sonido es la sumatoria de los tiempos de todas las fases. Por tanto, el siguiente sonido tendrá una duración de 0.5 + 1 + 2 + 0.5 = 4 pulsos:

play 60, attack: 0.5, attack_level: 1, decay: 1, sustain_level: 0.4, sustain: 2, release: 0.5

Ahora ve a jugar con sobres en tus sonidos…


3 - Sampleos

Otra gran manera de desarrollar tu música es usando sonidos pre-grabados. En la gran tradición de la “música concreta”, llamamos a estos sonidos pre-grabados “sampleos”. Another great way to develop your music is to use pre-recorded sounds. Así que si tomas un micrófono afuera y grabas el sonido de la lluvia golpeando la tela, ya creaste un sampleo.

Sonic Pi te deja hacer muchas y divertidas cosas con los sampleos. No sólo viene con cerca de 90 sampleos de libre dominio para que ser utilizados, sino que te deja manipular los tuyos. Veamos…


3.1 - Disparando sampleos

Ejecutar pitidos es sólo el principio. Algo que sí es divertido es disparar sampleos pre-grabados. Inténtalo:

sample :ambi_lunar_land

Sonic Pi incluye muchos sampleos para que uses. Utiliza el comando play para dispararlos. Para tocar múltiples sampleos y notas, simplemente escríbelos uno detrás del otro:

play 36
play 48
sample :ambi_lunar_land
sample :ambi_drone

Si quieres espacearlos en el tiempo, usa el comando sleep :

sample :ambi_lunar_land
sleep 1
play 48
sleep 0.5
play 36
sample :ambi_drone
sleep 1
play 36

¿Notas que Sonic Pi no espera a finalizar un sonido para comenzar el siguiente? El comando sleep sólo describe la separación de los sonidos disparados. Esto te permite hacer capas de sonidos fácilmente, creando interesantes efectos de capas superpuestas. Más tarde en el tutorial miraremos cómo controlar la duración de los sonidos con los sobres.

Descubriendo los sampleos

Hay dos maneras de descubrir el rango de sampleos provistos por sonic Pi. Primero, puedes utilizar este sistema de ayuda. Click en Samples en el menú vertical a la izquierda, elige tu categoria y verás un listado de sonidos disponibles.

Alternativamente puedes usar el “sistema de auto-compleción”. Simplemente teclea el comienzo de un grupo de sampleo tal como: sample :ambi_ y verás el menú de nombres de sampleos disponibles para que selecciones. Intenta las siguientes categorias de prefijos:

¡Ahora puedes comenzar a mezclar sampleos en tus composiciones!


3.2 - Parámetros de Sampleo: Amp y Pan

Como ya vimos con los sintetizadores, podemos controlar con facilidad nuestros sonidos con parámetros. Los sampleos permiten exactamente el mismo mecanismo de parametrización. Veamos a nuestros viejos conocidos amp: y pan:.

Amplificando los sampleos

Puedes cambiar la amplitud de los sampleos exactamente de la misma forma que utilizamos para los sintetizadores:

sample :ambi_lunar_land, amp: 0.5

Paneando sampleos

También podemos utilizar el parámetro pan: en sampleos. Por ejemplo, aquí te muestro como tocaríamos la pausa amén en el oído izquierdo y después a la mitad, la tocaríamos en el oído derecho:

sample :loop_amen, pan: -1
sleep 0.877
sample :loop_amen, pan: 1

Nota que al 0.877 (en segundos) está la mitad de la duración del sampleo :loop_amen .

Finalmente, nota que si seteas algunos sintetizadores por defecto con use_synth_defaults (que discutiremos luego), estos serán ignorados por sample.


3.3 - Estirando Samples

Ahora que ya podemos tocar una variedad de synths y samples para crear música, es tiempo de aprender a modificar tanto los synths como los samples para hacer la música más interesante y única. Primero, exploremos la habilidad de “estirar” y “aplastar” los samples.

Representación de Sampleos

Los Samples son sonidos pregrabados guardados como números que representan cómo mover los conos de los parlantes para reproducir sonidos, estos conos se pueden mover hacia dentro y hacia afuera, así que los números sólo deben representar ese movimiento en cada momento dado. Para poder reproducir fielmente un sonido, el sample debe guardar miles de números por segundo, Sonic Pi toma esta lista de números y los alimenta a la velocidad correcta para mover los parlantes de tu computadora a la velocidad correcta para reproducir sonido. Sin embargo, también es divertido cambiar la velocidad a la que los números son alimentados al parlante para cambiar el sonido

Cambiando la Velocidad

Ejecutemos uno de los sonidos ambiente: :ambi_choir. Para tocarlo con la velocidad predeterminada, puedes añadir rate: a sample:

sample :ambi_choir, rate: 1

Así lo ejecuta a tiempo normal (1), nada especial. Sin embargo, podemos cambiar ese número a otros. ¿qué tal a 0.5 ?:

sample :ambi_choir, rate: 0.5

Woah! ¿qué sucedió? Bueno, dos cosas: Primero, el sample se ejecutó en el doble del tiempo; Segundo, sonó una octava más grave. Exploremos todo ello en más detalle.

Estiremos

Un sample que es divertido estirar y comprimir es el Amen Break. A velocidad normal, podemos imaginar poner una pista de drum ‘n’ bass :

sample :loop_amen

Sin embargo, cambiando la velocidad podemos cambiar “géneros”. Intenta con la mitad de la velocidad para un “hip hop de vieja escuela”:

sample :loop_amen, rate: 0.5

Si lo aceleramos, entramos al territorio estilístico de jungle:

sample :loop_amen, rate: 1.5

Vamos a nuestro último truco - veamos qué sucede si utilizamos una velocidad negativa:

sample :loop_amen, rate: -1

Ahaa! ¡Se toca al revés! Ahora intenta toca distintos samples y velocidades, tales como rápidas y lentísimas, observa qué sucede.

Velocidad de sampleo: una explicación sencilla

Una manera sencilla con los sampleos es pensando en ellos como resortes. La velocidad de ejecución es como “estirar” o “comprimir” resortes. Si tocas a velocidad 2 estás comprimiendo el resorte a la mitad de su tamaño, por tanto le toma la mitad del tiempo en ejecutarse, ya que es más corto. Si ejecutas el sampleo a la mitad de velocidad, estás en efecto alargándo el resorte, por tanto estás doblando su tamaño y toma el doble de tiempo el ejecutarse. Entre más comprimas (mayor velocidad), más corto se vuelve el tiempo y viceversa.

Comprimiendo un resorte incremeta su densidad (el número de embobinados por cm.), lo cual es similar a que el sampleo suene a tonos más altos. Estirándo el resorte, decrece su densidad y simlarmente el sonido es más grave.

La matemática de la velocidad de sampleo

(Esta sección es para aquellos interesados en los detalles. Eres libre de saltártela)

Como hemos visto, un sample está representado por una larga lista de números representando adónde debe estar el parlante a través del tiempo. Podemos tomar este listado de números y usarlo para dibujar un gráfico que sería similar a:

sample graph

Quizás hayas visto imágenes parecidas a esa. Se llaman “forma de onda” de un sampleo. Simplemente es la graficación de números. Típicamente una forma de onda como ésta tendrá 44100 puntos por segundo de dato (esto debido al teorema de sampleo de Nyquist-Shannon) Así que si un sample dura 2 segundos, la forma de onda será representada por 88200 números, alimentándo a los parlantes a una velocidad de 44100 puntos por segundo. Claro, podemos también alimentarlos a una velocidad doble, que sería de 88200 puntos por segundo, lo cual tomaría sólo 1 segundo para ser tocado. También podríamos tocarlo a la mitad de velocidad, lo que daría 22050 puntos por segundo tomando 4 segundos de tiempo de ejecución.

La duración del sample es afectada por la velocidad de ejecución:

Esto lo representaremos con esta fórmula:

nuevo_sample_ = (1 / velocidad) * duración_sample 

Cambiando la velocidad de ejecución se afecta el tono del sampleo. La frecuencia o tono de una forma de onda está determinada por cuán rápido se mueve hacia arriba y hacia abajo. De alguna manera, nuestro cerebro toma los movimientos rápidos de los parlantes a notas agudas, igualmente, torna movimientos lentos de los parlantes en notas graves. Por eso es que puedes ver los parlantes de bajos moverse cuando están dando notas muy bajas, porque en realidad sí se están moviendo adentro/afuera del parlante mucho más lentamente que al producir notas altas.

Si tomas una forma de onda y la comprimes, se moverá más veces por segundo hacia arriba y hacia abajo, lo que producirá un sonido más agudo. Significa que doblando la cantidad de movimientos verticales (oscilaciones) dobla la frecuencia. Así: ejecutar tu sampleo al doble de velocidad, doblará la frecuencia escuchada. Asimismo, reduciendo la velocidad a la mitad, también reduce la frecuencia a la mitad. Otras velocidades afectarán la frecuencia en acordancia.


3.4 - Sobres para sampleos

Es posible modificar la duración y amplitud de un sampleo usando un sobre ADSR. sin embargo, esto funciona algo diferentemente que con los sintetizadores (synths), ya que los sobres para sampleos sólo te permiten reducir la amplitud y duración de un sampleo, pero nunca incrementarlo. El sampleo terminará su ejecución ya sea cuando se acabe o cuando el sobre lo haga, lo que suceda antes. Así que si utilizas un largo ‘release’, ello no extenderá la duración del sampleo.

Sobres para Amen

Volvamos a nuestro amigo, el Amen Break:

sample :loop_amen

Sin operandos, escuchamos el sampleo completo y amplitud completa. Si quisiéramos aparecerlo dentro de 1 segundo, podemos utilizar el parámetro attack: :

sample :loop_amen, attack: 1

Para un desaparecimiento más corto, elegiríamos un valor de ataque menor:

sample :loop_amen, attack: 0.3

Auto Sustain

Donde el sobre ADSR difiera en su conducta con el de un sintetizador es en el valor del sustain. En el sobre de un sintetizador, el sustain está predeterminado a 0 si no lo cambias manualmente. Con sampleos, el valor predeterminado de sustain está en automágico - el tiempo que resta para terminar el resto del sampleo. A ello se debe que podamos escuchar el sampleo completo cuando no pasamos parámetros. Si los valores de ataque, decaimiento,sustain y release fueran 0, nunca escucharíamos el sampleo. Por eso Sonic Pi calcula qué tan largo es el sampleo, deduce su ataque, decaimiento y tiempo de release, para utilizar esa sumatoria como tiempo de sustain. Si los valores de ataque, decaimiento y release son mayores al sampleo, el sustain se vuelve 0, simplemente.

Apagando (fade out)

Para explorar esto, consideremos nuestra pista Amen break en detalle. Si le preguntamos a Sonic Pi cuán largo es el sampleo:

print sample_duration :loop_amen

Imprimirá 1.753310657596372 que es el tamaño del sampleo en segundos. Consideremos redondearlo a 1.75 por conveniencia. Ahora, si seteamos el release a 0.75, algo sorpresivo pasará:

sample :loop_amen, release: 0.75

Ejecutará el primer segundo del sampleo a amplitud completa antes de desvanecerse por un periodo de 0.75 segundos. Esto es el auto sustain en acción. Predeterminado, el release siempre trabaja al final del sampleo. si tu sampleo fuera 10.75 segundos de largo, ejecutaría los primeros 10 segundos a completa amplitud antes de comenzar a desvanecerse por los 0.75 segundos finales.

Aparecimiento y desvanecimiento (Fade In and Out)

Podemos utilizar tanto el attack: como el release: juntos con el auto sustain para aparecer y desvanecer en la duración del sampleo:

sample :loop_amen, attack: 0.75, release: 0.75

Como la duración total del sampleo + attack + release suman 1.5s, el sustain queda automáticamente en 0.25s. Esto nos permite aparecer y desvanecer el sampleo con facilidad.

Explicit sustain

Podemos fácilmente volver a los parámetros normales de nuestro ADSR de sintetizador al setear manualmente el sustain: a un valor como 0:

sample :loop_amen, sustain: 0, release: 0.75

Ahora bien, nuestro sampleo suena por 0.75 en total. Los parámetros pre- determinados para ‘attack: y decay:` son 0, el sampleo salta directamente a full amplitud por 0s y después baja a 0 de amplitud por un periodo de release de 0.75s

Percussive cymbals

Podemos utilizar esta conducta a buen efecto para sampleos más largos que requieran los acortemos y percusivos. Considera el siguiente sampleo:

:drum_cymbal_open:

sample :drum_cymbal_open

Puedes escuchar el sonido del platillo por un periodo de tiempo. Sin embargo, podemos usar el sobre para hacerlo más percusivo:

sample :drum_cymbal_open, attack: 0.01, sustain: 0, release: 0.1

Puedes emular el golpeo del platillo y después apagarlo, al incrementar el periodo de sustain:

sample :drum_cymbal_open, attack: 0.01, sustain: 0.3, release: 0.1

Ahora ve y diviértete poniendo sobres en los sampleos. Intenta cambiar la velocidad, también para unos resultados realmente interesantes.


3.5 - Sampleos parciales

Esta sección concluirá nuestra exploración del ejecuta sampleos de Sonic Pi. Hagamos un pequeño resumen;

Hasta ahora hemos mirado cómo podemos disparar sampleos:

sample :loop_amen

Después miramos cómo cambiar la velocidad de los sampleos tales como ejecutarlos a media velocidad:

sample :loop_amen, rate: 0.5

Después miramos como podíamos aparecer un pequeño sampleo (haámoslo a media velocidad):

sample :loop_amen, rate: 0.5, attack: 1

También miramos como podíamos usar el comienzo de un sampleo percusivamente al darle a sustain: un valor explícito y setear ambos el ataque y el release con valores cortos:

sample :loop_amen, rate: 2, attack: 0.01, sustain: 0, release: 0.35

Sin embargo, ¿No sería mejor si no tuviésemos que comenzar por el principio ó terminar por el fin..siempre?

Escogiendo un punto de inicio

Es posible elegir un punto de inicio arbitrario en el sampleo con un valor entre 0 y 1, donde 0 es el punto de comienzo, 1 es el punto de final y 0.5 es la mitad del sampleo. Intentemos ejecutar únicamente la última mitad del sampleo de amen break:

sample :loop_amen, start: 0.5

¿Qué tal escuchar el último cuarto del sample?:

sample :loop_amen, start: 0.75

Escogiendo punto de termino

Igualmente, es posible escoger un punto de termino arbitrario en el sample, con un valor entre 0 y 1. Vamos a terminar el amen break a la mitad:

sample :loop_amen, finish: 0.5

Especificando el comienzo y el fin

Por supuesto que podemos combinar dos para tocar segmentos del archivo de audio arbitrariamente. ¿Qué tal una pequeña sección en el medio?

sample :loop_amen, start: 0.4, finish: 0.6

¿Qué pasa si elegimos comenzar en una posición después del final?

sample :loop_amen, start: 0.6, finish: 0.4

¡Cool! ¡Se toca al revés!

Combinando con velocidad

Podemos combinar esta nueva herramienta para tocar segmentos arbitrarios de audio con nuestro amigo rate:. Por ejemplo, podemos tocar una pequeña sección al medio de amen break muy lentamente:

sample :loop_amen, start: 0.5, finish: 0.7, rate: 0.2

Combinando con sobres

Finalmente podemos combinar todo esto con el sobre ADSR para producir resultados interesantes:

sample :loop_amen, start: 0.5, finish: 0.8, rate: -0.2, attack: 0.3, release: 1

Ahora vete y juega con sampleos y todas estas divertidas herramientas…


4 - Aleatoriedad

Una manera de añadir interés a tu música es usando números aleatorios. Sonic Pi tiene gran funcionalidad añadiendo aleatoriedad a la música, pero antes de comenzar, debemos aprender una verdad chocante: en Sonic Pi no existe aleatoriedad real. ¿Qué significa eso?

Repetibilidad

Una función realmente útil es rrand la cual te da un valor aleatorio entre dos números - un min y un max. (rrand es la abreviatura para ranged random). Intentemos tocar una nota al azar:

play rrand(50, 95)

¡Ooh, tocó una nota al azar! Tocó la nota 83.7527. Una nota entre 50 y 95 Woah, espera, predije el número correcto que obtuviste? ¡Algo raro sucede! Intenta con el código de nuevo. ¿qué? Otra vez 83.7527 ? ¡Eso no es aleatorio!

La respuesta es que no es realmente aleatorio, es pseudo-aleatorio. Sonic Pi te dará números como al azar en una manera repetitiva, lo cual es muy útil para asegurar que la música que creas en tú máquina suene idéntica en cualquier otra máquina - aunque utilices números al azar en tú composición.

Claro que en una pieza musical donde quieras colocar notas al “azar” y siempre eliga 83.7527 no sería ni aleatorio ni interesante. Sin embargo, no es así. Intenta lo siguiente:

loop do
  play rrand(50, 95)
  sleep 0.5
end 

¡Sí! Finalmente suena aleatorio. Dentro de una misma corrida las subsecuentes llamadas a funciones aleatorias dan valores..aleatorios. Sin embargo, la próxima corrida volverá a dar la misma secuencia de valores “aleatorios” y sonar exactamente igual. Es como si Sonic Pi volvió en el tiempo al mismo punto cuando se corrió run la primera vez. ¡Es el Groundhog Day de la síntesis musical!

Haunted Bells

Una buena ilustración de aleatoriedad en acción es el ejemplo haunted bells que buclee el sampleo de :perc_bell con velocidad de Aleatoriedad y tiempo de pausa entre los sonidos:

loop do
  sample :perc_bell, rate: (rrand 0.125, 1.5)
  sleep rrand(0.2, 2)
end

Corte aleatorio

Otro buen ejemplo de aleatoriedad es modificar el momento de corte de un sintetizador, en forma aleatoria. Un gran synth en el que hacerlo es el emulador :tb303

use_synth :tb303

loop do
  play 50, release: 0.1, cutoff: rrand(60, 120)
  sleep 0.125
end

Semillas aleatorias

¿Entonces qué, no te gusta la particular secuencia de números al azar que provee Sonic Pi? Bueno, es totalmente posible elegir un punto de comienzo via use_random_seed. Predeterminado está a 0, así que: ¡elige una semilla diferente para una aleatoriedad diferente!

Considera el siguiente:

5.times do
  play rrand(50, 100)
  sleep 0.5
end

Cada vez que corras ese código escucharás la misma secuencia de 5 notas. Para cambiar la secuencia, simplemente cambia el valor de seed_:

use_random_seed 40
5.times do
  play rrand(50, 100)
  sleep 0.5
end

Esto producirá una diferente secuencia de 5 notas. Al cambiar el valor de seed y escuchar los resultados, puedes encontrar algo que te guste y cuando lo compartas con otros, escucharán exactamente lo mismo.

Veamos otras útiles funciones de aleatoriedad.

Elegir (choose)

Una cuestión común es elegir un ítem desde una lista de ítems conocidos Por ejemplo, quiero tocar una nota de entre las siguientes: 60, 65 or 72. Puedo lograr eso con choose pues me deja elegir un ítem de esa lista. Primero necesito confeccionar mi listado entre paréntesis cuadrados y separándolos por comas: [60, 65, 72]. Después sólo necesito pasarlos por choose:

choose([60, 65, 72])

Escuchemos a lo que suena:

loop do
  play choose([60, 65, 72])
  sleep 1
end

Rango aleatorio (rrand)

Ya hemos visto la función rrand, pero adentrémonos más en ella. Nos proporciona un número aleatorio entre dos valores. Eso significa que nunca nos dará los números extremos del rango, sólo entre ellos. Ese número será un ‘flotante’, lo que significa que no es un número entero, sino una fracción de número. He aquí ejemplos de flotantes:

rrand(20, 110):

Rango aleatorio ínclusivo ( rrand_i)

Ocasionalmente querrás un número entero aleatorio, no un flotante. Es entonces que rrand_i viene al rescate. Funcional similarmente a rrand excepto que incluye los valores mínimo y máximo como potenciales aleatorios (lo que significa que es inclusiva y no excluyente de los valores extremos del rango). Ejemplos de números con rrand_i(20, 110) son:

rand

Esta función te regresará un número aleatorio flotante incluyendo los valores 0 y el máximo especificado. Predeterminado está el rango entre 0 y 1. Por ello es útil para elegir valores de amp: aleatorios:

loop do
  play 60, amp: rand
  sleep 0.25
end

rand_i

De maneara similar a rrand_i y rrand, rand_i nos dará un número leatorio ENTERO entre 0 y el máximo especificado.

Dado (dice)

Alguna vez querrás emular el tiro de un dado. Para ello tenemos un caso especial de rrand_i donde el valor inferior será siempre 1. El uso de dice requiere que especifiques el número de lados del dado. Un dado estándard tiene 6 lados, así dice(6) actuará similarmente, dando valores de1, 2, 3, 4, 5, or 6. Sin embargo, como en los juegos de role-play encontrarás necesidad de un dado de 4, 12, 20 o inclusive de 120 caras..

one_in

Finalmente cuando quieras emular tirar el máximo puntaje con un dado, como 6 en un dado estándard one_in te dará eso con una posibilidad de uno en número de lados del dado. Por lo tanto, one_in(6) nos dará verdad con una probabilidad de 1 en 6 o falso. Verdadero y falso son valores muy útiles para if el cual cubriremos en la siguiente sección de este tutorial.

¡Ahora ve a jugar con códigos y algo de aleatoriedad!


5 - Estructuras de Programación

Ahora que has aprendido lo básico de crear sonidos con play y sample y crear ritmos y melodías simples con sleep en medio de los sonidos, podrías preguntarte ¿Qué es lo que codificar puede ofrecerte?

Bueno, estás a punto de ser sorprendido, porque resulta que herramientas básicas de estructuras de programación como bules, condicionales, funciones e hilos, te dan grandes posibilidades de expresión musical.

Concentrémonos en la base…


5.1 - Bloques

Una estructura que verás a menudo en Sonic Pi es el bloque. Los Bloques nos permiten hacer cosas útiles con largas sábanas de código. Por ejemplo, con parámetros de synth y sample podíamos cambiar cosas en una sóla línea. sin embargo, algunas veces queremos hacer algo significativo para un número de líneas de código. Por ejemplo buclear, añadir reverberación, pero sólo correrlo 1 de cada 5 veces. Considera el siguiente código:

play 50
sleep 0.5
sample :elec_plip
sleep 0.5
play 62

Para hacer algo con un manojo de códifo, necesitamos decirle a Sonic Pi dónde comienza el bloque de código y dónde termina. Usamos para el comienzo do y para el final end . Por ejemplo:

do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Sin embargo, ese código está incompleto, porque no le hemos dicho a Sonic Pi lo que queremos hacer con ese bloque do/end (intenta y te dará error). Eso se lo decimos a Sonic Pi al escribir algunos códigos especiales antes del do. Veremos un estos códigos especiales más adelante en este tutorial Por ahora es importante conocer que envolver tu código entre do y end le dice a Sonic Pi que deseas hacer algo especial con ese pedazo de código.


5.2 - Iteración y Bucles

Hasta ahora hemos invertido tiempo en los diferentes sonidos que puedes crear con bloques de play y sample. También hemos aprendido a disparar estos sonidos a través de sleep.

Como probablemente ya notaste, hay mucha diversión a ser obtenida con estos bloques básicos de construcción. Sin embargo, una dimensión totalmente diferente de diversión se abre cuando comienzas a usar el poder de codificar para estructurar tu música y composiciones. En los próximos segmentos exploraremos algunas de estas poderosas herramientas. Primero están las iteraciones y bucles.

Repetición

¿Has escrito código que te gustaría se repita unas cuantas veces? Por ejemplo, algo así:

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

¿qué tal si quieeres repetirlo 3 veces? Bueno, podrías hacer algo simple y copiarlo 3 veces:

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

play 50
sleep 0.5
sample :elec_blup
sleep 0.5
play 62
sleep 0.25

¡Eso fué bastante código! ¿qué pasa si quieres cambiar el sample a :elec_plip? Tendrías que buscar todos los lugares con el original :elec_blup y cambiarlo. Más importantemente, ¿qué si quisieras repetir l apieza original 1000 veces? Eso tomaría muchas líneas de código y lugares a los que ir a alterar si quisieses cambiar algo.

Iteración

De hecho, repetir código debería ser tan fácil como decirle haz esto tres veces. Bueno, así es, casi..Recuerda nuestro viejo amigo el bloque de código, lo podemos usar para marcar el comienzo y final de código que querramos repetir tres veces. Después usamos el código especial 3.times. Así, en vez de escribir do this three times, escribimos 3.times do - ¿sencillo, no? Sólo recuerda escribir end al final del código que quieras repetir:

3.times do
  play 50
  sleep 0.5
  sample :elec_blup
  sleep 0.5
  play 62
  sleep 0.25
end

¿Eso fué mucho más elegante que cortar y pegar! Así crearemos muchas estructuras repetitivas_:

4.times do
  play 50
  sleep 0.5
end

8.times do
  play 55, release: 0.2
  sleep 0.25
end

4.times do
  play 50
  sleep 0.5
end

Iteraciones anidadas

Podemos insertar iteraciones dentro de iteraciones para crear patrones interesantes. Por ejemplo:

4.times do
  sample :drum_heavy_kick
  2.times do
    sample :elec_blip2, rate: 2
    sleep 0.25
  end
  sample :elec_snare
  4.times do
    sample :drum_tom_mid_soft
    sleep 0.125
  end
end

Bucleando

Si deseas que algo se repita muchas veces, te puedes encontrar usando números realmente grandes como 1000.times do. En este caso es mejor pedirle a Sonic Pi que repita al infinito (hasta que aprietes el botón de parar). Bucleemos el amen break infinitamente:

loop do
  sample :loop_amen
  sleep sample_duration :loop_amen
end

Lo importante de saber acerca de los blucles (loops) es que actúan como hoyos negros para el código. Una vez que se entra ahí, sólo se sale con el botón de parar (stop). Esto significa que si tienes código después del loop, nunca lo escucharás. Por ejemplo, el platillo después de este bucle nunca se ejecutará:

loop do
  play 50
  sleep 1
end

sample :drum_cymbal_open

¡Ahora ve a estructurar tus códigos con iteración y bucles!


5.3 - condicionales

Algo común que seguramente querrás hacer es tocar más que notas al azar sino también tomar decisiones al azar y, dependiendo de cómo salga, correr más código u otro código. Por ejemplo, el querer tocar al azar una batería o platillo. Esto lo podemos hacer con if .

Tirar una moneda

Tiremos una moneda: si sale cara, que suene una batería, si sale cruz, que sea un platillo. Fácil. Podemos imitar el tiro de una moneda con la función one_in (introducida en la sección de aleatoriedad) especificando una probabilidad de 1 en 2 one_in(2). Entonces podemos utilizar el resultado para decidir entre dos piezas de código, el de batería o el de platillos:

loop do

  if one_in(2)
    sample :drum_heavy_kick
  else
    sample :drum_cymbal_closed
  end
  
  sleep 0.5
  
end

Debes notar que los if están compuestos de tres partes:

Típico de lenguajes de programación, la noción de ‘sí’ está representada por el término true y la noción de ‘no’, por false. Así que debemos encontrar una pregunta que nos dé una respuesta true ofalse que es exactamente lo que hace one_in .

¿notas que la primera opción está envuelta entre el if y el else y que la segunda opción está envuelta entre el else y el end?. Igual que con los bloques do/end puedes poner múltiples líneas de código en cualquiera de esos lugares. Por ejemplo:

loop do

  if one_in(2)
    sample :drum_heavy_kick
    sleep 0.5
  else
    sample :drum_cymbal_closed
    sleep 0.25
  end
  
end

Esta vez estaremos pausando por un tiempo distinto dependiendo de cuál elección hagamos.

Condicional simple “if”

Algunas veces querrás ejecutar sólo una línea de código. Esto es posible al colocar if y después la pregunta al final. Por ejemplo:

use_synth :dsaw

loop do
  play 50, amp: 0.3, release: 2
  play 53, amp: 0.3, release: 2 if one_in(2)
  play 57, amp: 0.3, release: 2 if one_in(3)
  play 60, amp: 0.3, release: 2 if one_in(4)
  sleep 1.5
end

Eso tocará acordes de diferentes números con una probabilidad diferente para cada nota .


5.4 - Hilos

Así que hiciste una gran línea de bajo y un gran pulso. ¿cómo los tocas al mismo tiempo? Una manera de hacerlo es coserlos juntos manualmente - toca bajo, después un poco de batería y así… Sin embargo, cada vez se vuelve más complicado mantener el timing, especialmente Si’coses’ más y más elementos.

¿qué tal si Sonic Pi pudiese coser todo automáticamente para tí? Bueno, puede y lo hace con algo especial llamado thread.

Bucles infinitos

Para mantener este ejemplo sencillo, vas a tener que imaginar que es un gran pulso y bajo:

loop do
  sample :drum_heavy_kick
  sleep 1
end

loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

Como vimos anteriormente, bucles son como ‘hoyos negros’ para el programa, una vez entras a uno, sólo puedes salir de él con el botón ‘stop’. Así que para tocar ambos bucles al mismo tiempo, debemos indicarle a Sonic Pi que queremos comenzar algo al mismo tiempo que el resto del código, aquí es cuando los hilos vienen al rescate.

Hilos al rescate

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end

loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

Al envolver el primer bucle de bloque do/end con in_thread le decimos a Sonic Pi que corra los contenidos del bloque do/end exactamente al mismo tiempo que el siguiente bloque do/end (que es nuestro segundo bucle) ¿Inténtalo y escucharás ambos, el bajo y la batería conectados!

Ahora, si quisiésemos añadir un sintetizador, haríamos algo así:

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end

loop do
  use_synth :fm
  play 40, release: 0.2
  sleep 0.5
end

loop do
  use_synth :zawa
  play 52, release: 2.5, phase: 2, amp: 0.5
  sleep 2
end

Ahora volvemos a tener el mismo problema que antes, ya que los primeros dos bucles se tocan al mismo tiempo, gracias a in_thread. Sin embargo, el tercer bucle nunca se alcanza. Por lo tanto, necesitamos otro hilo:

in_thread do
  loop do
    sample :drum_heavy_kick
    sleep 1
  end
end

in_thread do
  loop do
    use_synth :fm
    play 40, release: 0.2
    sleep 0.5
  end
end

loop do
  use_synth :zawa
  play 52, release: 2.5, phase: 2, amp: 0.5
  sleep 2
end

Ejecutar como hilos

Puede sorprenderte que cuando aprietas el botón de Correr (Run), de hecho estás creando un nuevo hilo para que corra el código. Esta es la razón por la que al apretar el botón múltiples veces, suenan las capas de sonido una encima de la otra, ya que las corridas son de hecho hilos cosidos automáticamente para sonar.

Ámbito

En cuanto más aprendas Sonic Pi, apreciarás que los hilos son los bloques de construcción más importantes para tú música. Uno de los trabajos más importantes que realiza es aislar la noción de seteos actuales respecto a otros hilos. ¿qué significa eso? Bien, cuando cambias sintetizadores por medio de use_synth realmente estás cambiando el sintetizdor en el hilo actual, ya que ningún otro hilo cambiarás su sintetizador. Veamos esto en acción:

play 50
sleep 1

in_thread do
  use_synth :tb303
  play 50
end

sleep 1
play 50

¿Notaste que el sonido de en medio era diferente a los otros? el use_synth solamente afectó el hilo en el que se encontraba, no así el hilo externo principal.

Herencia

Cuando creas un nuevo hilo con in_thread, este automáticamente hereda la configuración del hilo actual. Veamos:

use_synth :tb303
play 50
sleep 1

in_thread do
  play 55
end

¿Notaste que la segunda nota es tocada por el sintetizador :tb303 aunque era de un hilo separado? Cualquier seteo modificado con las funciones use_* se comportará de igual manera.

Cuando se crean hilos, ellos heredan todos los seteos de su padre, pero no los comparten a su vez.

Nombres para los Hilos

Por último, podemos darles nombre a los hilos:

in_thread(name: :bass) do
  loop do
    use_synth :prophet
    play chord(:e2, :m7).choose, release: 0.6
    sleep 0.5
  end
end

in_thread(name: :drums) do
  loop do
    sample :elec_snare
    sleep 1
  end
end

Mira el panel de bitácora cuando corras este código. ¿ves que reporta el nombre del hilo?

[Run 36, Time 4.0, Thread :bass]
 |- synth :prophet, {release: 0.6, note: 47}

Sólo es permitido un nombre por hilo

Una cosa más al respecto de nombrar hilos es que sólo un hilo con su nombre puede estar corriendo a la vez. Exploremos esto, considerando el código:

in_thread do
  loop do
    sample :loop_amen
    sleep sample_duration :loop_amen
  end
end

Pega eso en un buffer y córrelo. Presiona Correr un par de veces. Escucha la cacofonía de los múltiples amen breaks bucleando desincronizadamente. Ok, ya puedes pararlo.

Esta es la conducta que hemos visto innumerables veces - si presionas el botón Correr, capas de sonidos suenan encima de otras. Así que si tienes un loop y presionas el botón Correr tres veces, obtendrás tres capas de bucles sonando simultáneamente.

sin embargo, con hilos nombrados, es diferente:

in_thread(name: :amen) do
  loop do
    sample :loop_amen
    sleep sample_duration :loop_amen
  end
end

Intenta presionando el botón Correr múltiples veces con este código. Sólo escucharás un bucle del amen break. También verás lo siguiente en la bitácora:

==> Skipping thread creation: thread with name :amen already exists.

Sonic Pi te está diciendo que un hilo con el nombre :amen ya existe, así que no creará otro.

Esta conducta puede no aparentar utilidad para tí - pero verás que la tiene cuando comencemos a hacer Código-vivo…


5.5 - Funciones

Cuando comiences a escribir mucho código, desearás encontrar una manera de organizar y estructurar todo para hacerlo más entendible. Las funciones permiten hacer exactamente eso, permitiéndonos darle nombre a muchas partes de nuestro código. Veamos:

Definiendo Funciones

define :foo do
  play 50
  sleep 1
  play 55
  sleep 2
end

Aquí definimos una nueva función llamada foo. Lo hacemos con nuestro viejo amigo el bloque de do/end y la palabra mágica define seguidos del nombre que queremos darle a nuestra función. No necesitábamos llamarla foo, podríamos haberla llamado cualquier cosa que quisiésemos, tales como bar, baz o idealmente algo significativo para tí como main_section o lead_riff.

Recuerda anteponer dos puntos : al nombre de la función que defines.

Llamando las Funciones

Una vez hemos definido nuestra función, podemos llamarla simplemente escribiendo su nombre:

define :foo do
  play 50
  sleep 1
  play 55
  sleep 0.5
end

foo

sleep 1

2.times do
  foo
end

Incluso podemos usar foo dentro de bloques de iteración o cualquier lugar donde hayamos escrito play o sample. Esto nos da una fantástica manera de expresar y crear nuevas palabras significativas a usar en nuestras composiciones.

Las funciones permanecen en memoria

Hasta ahora, cada vez que presionamos el botón de Ejecutar, Sonic Pi ha comenzado de cero. Sólo conoce lo que está en el buffer actual. No puedes referenciar código en otro buffer o hilo. sin embargo, las funciones cambian eso. Cuando defines una función, Sonic Pi recuerda. Probemos borrando todo el código en tu buffer y reemplazandolo por:

foo

Presiona el botón de Ejecutar y escucha. ¿Dónde se fue el código?¿cómo supo Sonic Pi qué tocar? Sonic Pi recordó tu función, inclusive cuando la borraste del buffer. Esta conducta sólo funciona con las funciones creadas con define (y defonce).

Funciones parametrizadas

Quizás te interese saber que al igual que podías pasar valores mínimos y máximos con rrand, también puedes enseñar a tus funciones a aceptar argumentos. Miremos:

define :my_player do |n|
  play n
end

my_player 80
sleep 0.5
my_player 90

Esto no es tan excitante, pero ilustra el punto. Creamos nuestra propia versión de play llamada my_player y la cual está parametrizada.

Los parámetros deben ir después del do y define en el bloque do/end, rodeado de postes verticales | y separados por comas ,. Puedes usar cualquier palabra para los nombres de los parámetros.

Lo mágico sucede dentro del bloque do/end del define . Puedes usar nombres de parámetros como si fueran valores reales. En este ejemplo estoy tocando la nota n. Puedes considerar los parámetros como una especie de promesa de que cuando el código se ejecute, ellos serán reemplazados por los valores. Esto lo haces al pasar un parámetro a la función, cuando la llamas. Yo lo hago con my_player 80 para tocar la nota 80. Dentro de la definición de la función n se reemplaza con 80, así play n se convierte en play 80. Cuando la llamo otra vez con my_player 90, n es reemplazada por 90, así que play n se convierte en play 90.

Veamos un ejemplo más interesante:

define :chord_player do |root, repeats| 
  repeats.times do
    play chord(root, :minor), release: 0.3
    sleep 0.5
  end
end

chord_player :e3, 2
sleep 0.5
chord_player :a3, 3
chord_player :g3, 4
sleep 0.5
chord_player :e3, 3

Aquí usé repeats como si fuera un número para la línea de repeats.times do. También usé root como si fuera un nombre de nota en mi llamada a play.

¡Nota cómo podemos utilizar algo muy expresivo y fácil de leer sólo con mover mucho de nuestra lógica en el código!


5.6 - Variables

Algo útil para hacer con tú código es crear nombres para las cosas. Sonic Pi hace esto muy fácil, escribes el nombre que deseas utilizar, un símbolo de (=), después lo que quieres recordar:

sample_name = :loop_amen

Aquí hemos ‘recordado’ el símbolo :loop_amen en la variable sample_name. Ahora podemos usar sample_name en cualquier lugar donde pudiésemos usar :loop_amen. Por ejemplo:

sample_name = :loop_amen
sample sample_name

Hay tres razones principales para utilizar variables en Sonic Pi: comunicar significado, administrar repeticón y capturar los resultados de las cosas.

Comunicando significado

Cuando escribes código, es fácil pensar que sólo le dices a la computadora cómo hacer algo - mientras ella entienda, todo está bien. Sin embargo, es importante recordar que no sólo la computadora leerá el código. Otra gente podría leerlo e intentar comprender qué es lo que sucede. También sucede que quieras entender tu propio código en el futuro. Aunque pueda ser obvio para tí, ahora, ¡podría no serlo para otros o para tí en el futuro! When you write code it’s easy to just think you’re telling the computer how to do stuff - as long as the computer understands it’s OK. However, it’s important to remember that it’s not just the computer that reads the code. Other people may read it too and try to understand what’s going on. Also, you’re likely to read your own code in the future and try to understand what’s going on. Although it might seem obvious to you now - it might not be so obvious to others or even your future self!

One way to help others understand what your code is doing is to write comments (as we saw in a previous section). Another is to use meaningful variable names. Look at this code:

sleep 1.7533

¿Por qué utiliza el número 1.7533? ¿de dónde proviene? ¿qué significa? Miremos el código siguiente:

loop_amen_duration = 1.7533
sleep loop_amen_duration

Ahora está mucho más claro lo que significa 1.7533 : es la duración del sample :loop_amen! claro que puedes pensar que es mucho más simple escribir:

sleep sample_duration(:loop_amen)

Lo cual es una muy buena manera de comunicar la intención del código.

Administrando las repeticiones

a menudo ves muchas repeticiones en tu código y cuando quieres cambiar algo, tienes que cambiarlo enmuchos lugares. Mira este código:

sample :loop_amen
sleep sample_duration(:loop_amen)
sample :loop_amen, rate: 0.5
sleep sample_duration(:loop_amen, rate: 0.5)
sample :loop_amen
sleep sample_duration(:loop_amen)

Estamos haciendo muchas cosas con :loop_amen! ¿qué pasa si quisiésemos escuchar otro sampleo como :loop_garzul? tendríamos que buscar y reemplazar todos los :loop_amen con :loop_garzul. Eso estaría bien si tienes mucho tiempo - pero ¿qué si está en vivo? algunas veces no tendrás el lujo del tiempo - especialmente si quieres que la gente se mantenga bailando.

¿qué tal si hubieses escrito tú código, así?:

sample_name = :loop_amen
sample sample_name
sleep sample_duration(sample_name)
sample sample_name, rate: 0.5
sleep sample_duration(sample_name, rate: 0.5)
sample sample_name
sleep sample_duration(sample_name)

Eso hace exactamente lo mismo que lo anterior (pruébalo). también nos da la habilidad de cambiar una línea sample_name = :loop_amen a sample_name = :loop_garzul y podemos hacerlo en muchos lugares gracias a las variables.

Capturando los resultados

Un buen motivo para utilizar variables es capturar los resultados de las cosas. Por ejemplo, quizás desees hacer algo con la duración de un sampleo:

sd = sample_duration(:loop_amen)

Ahora podemos usar sd en cualquier lugar donde necesitemos la duración del sampleo :loop_amen.

Más importantemente, una variable nos permite capturar el resultado de una llamada a play o sample:

s = play 50, release: 8

Ahora hemos atrapado y recordado s como una variable, lo que nos permite controlar el sintetizador mientras corre:

s = play 50, release: 8
sleep 2
control s, note: 62

Veremos en más detalle cómo controlar los sintetizadores más tarde.


5.7 - Sincronización de hilos

Cuando estés lo suficientemente avanzado en live-coding con un número de funciones e hilos simultáneamente, notarás que es muy fácil cometer un error en uno de los hilos y eso lo mata. Eso no es gran cosa, porque puedes fácilmente recomenzar el hilo con apretar Run. Sin embargo, cuando recomiences el hilo estará out of time con los hilos actuales.

Tiempo heredado

Como discutíamos anteriormente, nuevos hilos creados con in_thread heredan todos los seteos del hilo padre. Esto incluye el tiempo actual, lo que significa que los hilos estarán siempre en el tiempo con los demás cuando comenzados simultáneamente.

Sin embargo, cuando comienzas un hilo aparte, comienza con su propio tiempo que difícilmente estará sincronizado con alguno de los otros que estén siendo corridos.

Cue y Sync (funciones)

Sonic Pi provee una solución a este problema con las funciones cue y sync.

cue permite enviar mensajes de pulso a todos los otros hilos, los cuales, en principio no están interesados e ignoran estos mensajes. Sin embargo. puedes registrar fácilmente su interés con la función sync.

Lo importante de notar es que sync es similar a sleep en que para el hilo actual por un tiempo. Sin embargo, con sleep tu especificas cuánto tiempo va a esperar, en cambio con sync no sabes cuánto tiempo esperará - ya que sync espera por el siguiente cue de otro hilo.

Exploremos esto en más detalle:

in_thread do
  loop do
    cue :tick
    sleep 1
  end
end

in_thread do
  loop do
    sync :tick
    sample :drum_heavy_kick
  end
end

Aquí tenemos dos hilos - uno actuando como un metrónomo, no haciendo sonidos sino que enviando :tick mensajes de pulso. El segundo hilo está sincronizandose con los mensajes de tick y cuando recibe uno, hereda el tiempo del hilo de cue y continúa tocando.

El resultado es que escuchamos el sample de :drum_heavy_kick exactamente cuando el otro hilo envía el mensaje :tick, aunque ambos hilos no comenzaron su ejecución al mismo tiempo:

in_thread do
  loop do
    cue :tick
    sleep 1
  end
end

sleep(0.3)

in_thread do
  loop do
    sync :tick
    sample :drum_heavy_kick
  end
end

Esa llamada sleep típicamente haría que el segundo hilo vaya fuera de fase con el primero. Sin embargo, por estar usando cue y sync, sincronizamos ambos hilos automáticamente.

Nombres de Cue

Eres libre de utilizar cualquier nombre que quieras a los mensajes de cue - no sólo :tick. Sólo debes asegurarte que los otros hilos estén sync sincronizándose en el nombre correctoe - de otro modo se quedarán esperando por siempre (o hasta presionar el botón de Parar)

Juguemos con unos cuantos nombres para cue:

in_thread do
  loop do 
    cue [:foo, :bar, :baz].choose
    sleep 0.5
  end
end

in_thread do
  loop do 
    sync :foo 
    sample :elec_beep
  end
end

in_thread do
  loop do
    sync :bar
    sample :elec_flip
  end
end

in_thread do
  loop do
    sync :baz
    sample :elec_blup
  end
end

Aquí tenemos un cue principal bucleado, el cual envía aleatoriamente uno de los nombres de pulso :foo, :bar o :baz. Después tenemos también tres bucles de hilos sincronizándose entre ellos independientemente y tocando un sampleo diferente. El efecto es que escuchamos un sonido cada 0.5 pulsos que cada uno de los hilos está aleatoriamente sincronizándose sync con el hilo de cue y toca su sampleo.

Por supuesto que esto también funciona si ordenas los hilos en reversa, ya que los hilos sync siempre esperarán al siguiente cue.


6 - Estudio FX

Uno de los aspectos más satisfactorios y divertidos de Sonic Pi es su habilidad de añadir efectos de estudio a tus sonidos. Por ejemplo, si quieres añadir reverberación, eco o distorsión.

Sonic Pi provee una manera simple y poderosa de añadir efectos FX. Inclusive te permite encadenarlos (así pasas tus sonidos por la distorsión, después el eco y la reverberación). También controlar cada unidad individual de FX con operandos (similar a darle parámetros a los sintetizadores y sampleos). Inclusive puedes modificar los operandos del FX mientras se ejecutan. Por ejemplo, puedes incrementar la reverberación del bajo a través de la pista…

Pedales de Guitarra

Si todo suena un poco complicado, no te preocupes. Una vez juegues con con esto, se aclarará. Antes de eso, una simple analogía es la de los pedales de efectos de una e-guitarra. Hay muchos pedales que puedes comprar. Algunos añaden reverberación, otros distorsión etc. Una guitarrista conecta su guitarra en un pedal, después a otro y así (cadena) La salida del pedal de reverberación termina siendo conectada al amplificador:

Guitar -> Distortion -> Reverb -> Amplifier

Esto se llama efectos FX en cadena. Sonic Pi soporta eso. Adicionalmente cada pedal a menudo tiene diales y deslizadores para controlar cuánta distorsión, reverberación, eco etc. aplicar. Sonic Pi soporta También esta clase de control. Finalmente, imagina un guitarrista tocar mientras otra persona controla los efectos DX. Sonic Pic también permite esto, pero en vez de otra persona, te permite a tí controlarlo todo.

¡¡ Exploremos los efectos (FX) !!


6.1 - Añadiendo efectos FX

En esta sección veremos los efectos: reverberación y eco. Veremos cómo usarlos, controlar sus operandos y encadenarlos. Llamaremos “FX” a los efectos.

El sistema de efectos de Sonic Pi, utiliza bloques. Así que si no has leído la sección 5.1, deberías.

Reverberación

Si queremos usar reverberación, escribimos with_fx :reverb como el código especial para nuestro bloque, así:

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Cuando tocas este código tendrá reverberación. ¿suena bien, no? todo suena mejor con reverberación.

Ahora veamos qué sucede si dejamos código fuera del bloque do/end:

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

sleep 1
play 55

Nota que el lay play 55 no se ejecutó con reberveración. Esto es porque está fuera del bloque do/end, así que no es capturado por el FX reverberación.

Similarmente, si haces sonidos antes del bloque do/end, tampoco los capturará:

play 55
sleep 1

with_fx :reverb do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

sleep 1
play 55

Echo

Hay muchos FX (efectos) para escoger. ¿probamos con eco?

with_fx :echo do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Uno de los aspectos más sobresalientes de Sonic Pi es que los bloques de efectos operan con parámetros similares a los utilizados con play y sample. Por ejemplo, un parámetro interesante es phase: que representa la duración de un eco dado en pulsos. Hagamos el eco más lento:

with_fx :echo, phase: 0.5 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Ahora hagamos el eco más rápido:

with_fx :echo, phase: 0.125 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Hagamos que al eco le tome 8 pulsos en desvanecerse, gracias a decay:

with_fx :echo, phase: 0.5, decay: 8 do
  play 50
  sleep 0.5
  sample :elec_plip
  sleep 0.5
  play 62
end

Anidando FX

Uno de los más poderosos aspectos de los bloques de FX es que puedes anidarlos, con lo que logramos encadenarlos con facilidad. Por ejemplo, si quisieras tocar código con eco y después reverberación, fácilmente pones un Fx dentro de otro:

with_fx :reverb do
  with_fx :echo, phase: 0.5, decay: 8 do
    play 50
    sleep 0.5
    sample :elec_blup
    sleep 0.5
    play 62
  end
end

Piensa en el audio fluir desde adentro. El sonido de todo el códido dentro del bloque interno do/end como play 50 es primero enviado al FX de eco y a su vez, éste es enviado al FX reverberación.

Podemos hacer uso de anidados muy profundos para resultados extremos. Sin embargo, ten presente que los Fx consumen muchos recursos y que al anidarlos estás de hecho corriendo muchos FX simultáneamente. Así que sé consciente de su uso, especialmente en plataformas de bajo rendimiento como la Raspberry Pi.

Descubriendo FX

Sonic Pi tiene muchos efectos con los cuales jugar. Para verlos, cliquea en FX a la izquierda de este sistema de Ayuda y verás el listado. Aquí te deja algunos de mis favoritos:

¡Ahora haz locuras con los FX, añadiéndolos en todas partes para crear nuevos sonidos!


6.2 - FX en la práctica

Aunque a simple vista sean simples, los FX son - internamente - unas bestias complejas. Su simplicidad a veces promueve a que la gente los sobre use en su música. Esto no es un problema si tienes una máquina poderosa, pero si - como yo - usas una Raspberry Pi para tus jams, debes ser cuidadoso acerca de cuanto trabajo le asignas para asegurarte que todo fluya sin pausas.

Considera este código:

loop do
  with_fx :reverb do
    play 60, release: 0.1
    sleep 0.125
  end
end

En este código estamos tocando la nota 60 con un tiempo de release muy, corto, por lo que es una nota muy corta. También queríamos reverb, así que lo envolvimos en un bloque de reverberación. Todo bien, excepto…

Veamos lo que hace el código. Primero bucleamos para que se repita por siempre todo lo que está dentro de él. Después tenemos un bloque with_fx Esto significa que crearemos un FX reverberación cada vez que buclee. Esto es como tener un pedal de reverberación por cada vez que toques una cuerda de la guitarra. Es bueno poder hacerlo, pero no siempre lo querrás. Por ejemplo, este código tendrá dificultades en una Raspberry Pi. Todo el trabajo de crear la reverberación y después esperar hasta que ncesite ser parado y removido, es hecho por with_fx pero esto consume mucho del CPU.

¿cómo lo haríamos más similar a cuando un guitarrista tiene sólo un pedal de reverberación a través del cual pasan todos los sonidos? Simple:

with_fx :reverb do
  loop do
    play 60, release: 0.1
    sleep 0.125
  end
end

Poniendo nuestro bucle dentro del bloque with_fx. Así sólo creamos un paso a reverb para todas las notas del bucle. Este código es mucho más eficiente y funcionará bien en una Raspberry Pi.

Al utilizar with_fx sobre una iteración en un bucle:

loop do
  with_fx :reverb do
    16.times do
      play 60, release: 0.1
      sleep 0.125
    end
  end
end

Sacando el with_fx de la parte interna del bucle, ahora la reverberación es cada 16 notas.

Recuerda que no hay errores, sólo posibilidades. Sin embargo, según qué manera, se producen diferentes sonidos y características de ejecución. Así que experimenta y utiliza lo que te suene mejor y funcione en la plataforma que tengas.


7 - Controlando los sonidos en ejecución

Hasta ahora hemos visto cómo disparar sintetizadores y sampleos, cambiar sus operandores tales como amplitude, paneo, seteos de sobres y más. Cada sonido disparado es, esencialmente, su propio sonido con su lista de opciones por la duración del sonido.

¿Te gustaría cambiar los operadores de los sonidos cuando aún están sonando, así como cuando vibras la cuerda de una guitarra?

¡Tienes suerte, pues ésta sección te mostrará cómo hacerlo!


7.1 - Controlando Sintetizadores en ejecución

Hasta el momento nos hemos concentrado en disparar nuevos sonidos y FXs. Sin embargo, Sonic Pi te da la posibilidad de manipular y controlar sonidos en ejecución. Esto lo hacemos al utilizar una variable para capturar una referencia de un sintetizador:

s = play 60, release: 5

Aquí utilizamos una variable de ejecución local, s que representa el sintetizador tocando la nota 60. Al ser local no puede ser accesada desde otras ejecuciones, como sucede con las funciones.

Con s, utilizaremos la función control:

s = play 60, release: 5
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Es de notar que no se disparan 4 diferentes sintetizadores, sino que usando uno al que le cambiamos los tonos 3 veces durante su ejecución.

Podemos pasar operandos para control como amp, cutoff: o pan:.

Opciones no-controlables

Algunos de los operandos no pueden ser controlados una vez comenzado el sintetizador. Este es el caso de los parámetros de sobres ADSR. Puedes encontrar cuáles operandos sí pueden ser controlados en el sistema de ayuda. Si la documentación dice no puede ser cambiado una vez seteado, es que no puedes controlar los operandos cuando el sintetizador ha comenzado.


7.2 - Controlando efectos (FX)

También es posible controlar los efectos, aunque de una manera diferente:

with_fx :reverb do |r|
  play 50
  sleep 0.5
  control r, mix: 0.7
  play 55
  sleep 1
  control r, mix: 0.9
  sleep 1
  play 62
end

En vez de usar una variable, usamos parámetros de poste “|” de los bloques do/end. Dentro de los postes |, debemos especificar un nombre específico para nuestro efecto en ejecución, el cual después referenciaremos desde el bloque do/end que lo contiene. Esta conducta es idéntica a usar funciones parametricazadas.

¡Ahora ve a controlar sintetizadores y efectos! Now go and control some synths and FX!


7.3 - Opciones con Deslizadores

Mientras explorábamos las opciones con sintetizadores y efectos, habrás notado que hay un número de opciones que terminan en _slide. Quizás intentaste utilizarlos y no hubo efecto. Esto es porque ellos son parámetros especiales que sólo funcionan cuando controlas los sintetizadores como dijimos en la sección anterior.

Considera el siguiente ejemplo:

s = play 60, release: 5
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Aquí puedes escuchar el sintetizador cambiando tono inmediatamente en cada llamada de control. Sin embargo, quizás querramos que el tono se deslice entre cambios. Ya que estamos controlando el parámetro note, para añadir deslizamiento (slide), debemos setear el note_slide del sintetizador:

s = play 60, release: 5, note_slide: 1
sleep 0.5
control s, note: 65
sleep 0.5
control s, note: 67
sleep 3
control s, note: 72

Ahora escuchamos las notas “deslizadas” entre cada llamada de control. ¿suena bien, no? Puedes acelerar/desacelerar el arraster usando tiempos más cortos en note_slide: 0.2.

Cada parámetro que puede ser controlado, tiene su correspondiente _slide con el que jugar.

Deslizar es pegajoso

Una vez que determines un parámetro de _slide en un sintetizador, será recordado y usado cada vez que deslices el correspondiente parámetro. Para detener el deslizamiento, debes setear el valor de _slide a 0 antes de la siguiente llamada a control.

Deslizando opciones de Efectos (FX)

También es posible deslizar opciones de efectos (FX):

with_fx :wobble, phase: 1, phase_slide: 5 do |e|
  use_synth :dsaw
  play 50, release: 5
  control e, phase: 0.025
end

Ve y diviértete deslizando todo para unas transiciones suaves y control fluído… Now have fun sliding things around for smooth transitions and flowing control…


8 - Estructuras de Datos

Una herramiento útil para los programadores es la Estrutura de Datos.

Algunas veces puedes desear usar más de una cosa. Por ejemplo, el tocar una serie de notas que se toquen una después de la otra. Los lenguajes de programación tienen estructuras de datos para permitirte eso.

Hay muchas estructuras de datos exóticas y excitantes a disposición de los programadores - y se siguen inventando nuevas. Sin embargo, por ahora sólo necesitamos considerar una estructura de datos muy sencilla - la lista.

Mirémosla en mayor detalle. Cubriremos su forma básica y también el modo de utilizarlas para representar escalas y acordes.


8.1 - Listas

En esta sección miraremos una Estructura de Datos muy útil: la Lista. Ya la vimos -brevemente- en la sección de aleatoriedad, cuando de una lista de notas elegía al azar las notas a tocar:

play choose([50, 55, 62])

Ahora también exploraremos listas que que representan acordes y escalas. Primero repasemos cómo tocar un acorde. Recuerda que si no usamos sleep, todos los sonidos suceden al mismo tiempo:

play 52
play 55
play 59

Veamos otras maneras de representar este código.

Ejecutando una Lista

Una opción es colocar todas las notas en una lista: [52, 55, 59]. Nuestro amigable play es lo suficientemente listo para entender cómo tocar una lista de notas. Probemos:

play [52, 55, 59]

Ohh, eso ya está mejor para leer. El tocar un listado de notas no significa que no puedas usar los otros parámetros, normalmente:

play [52, 55, 59], amp: 0.3

Por supuesto, puedes usar los nombres tradicionales de notas en vez de números MIDI

play [:E3, :G3, :B3]

Ahora, esos suertudos de ustedes con estudios en teoría musical, podrán reconocer que el acorde es Mi menor tocado en la 3ra octava.

Accediendo a una Lista

Otro aspecto útil de una lista es la habilidad de obtener información de la misma. Puede sonar extraño, pero es igual a alguien pidiéndote que pases a la página 23 de un libro. Con una lista, dirías, ¿qué elemento hay en el índice 23? Lo único diferente es que en índices de programación se comienza con 0 y no con 1. Con índices de listas no contamos 1, 2, 3… sino que 0, 1, 2…

Veamos eso en mayor detalle en esta lista:

[52, 55, 59]

No hay algo espcialmente de susto en ello. Ahora, ¿qué es el segundo elemento en esa lista? Si, claro, es 55. Fácil. Veamos si la computadora puede respondernoslo, también:

puts [52, 55, 59][1]

Si se mira algo raro, confía en mí, no lo es. Hay tres partes en la línea de arriba: la palabra puts, nuestra lista 52, 55, 59 y nuestro índice [1]. Primero pedimos puts para que Sonic Pi imprima la respuesta en la bitácora. Después, le damos nuestra lista y finalmente nuestro índice le pide el segundo elemento. Necesitamos rodear nuestro índice con paréntesis cuadrados y ya que el conteo comienza en 0, el índice para el segundo elemento es 1. Mira:

# indexes:  0   1   2
           [52, 55, 59]

Prueba con puts [52, 55, 59][1] y verás 55 en la bitácora. Cambia el índice 1 a otros índices, intenta con listas más largas en tu próximo código. Por ejemplo, estructuras musicales que podrían representarse como series de números


8.2 - Acordes

Sonic Pi soporta nombres de acordes que regresarán listas. Pruébalo:

play chord(:E3, :minor)

¡Ahora estamos en algo!. Eso se mira mucho mejor que listas crudas y es más fácil de leer para otros. ¿qué otros acordes soporta Sonic Pi? Bueno, muchos. Prueba con estos:

Arpegios

Podemos convertir acordes en arpegios con facilidad, gracias a la función play_pattern :

play_pattern chord(:E3, :m7)

Ok, eso no fue tan divertido, se ejecutó muy despacio. play_pattern va a tocar cada nota en la lista separada por una llamada a sleep 1 entre cada llamada a play. Podemos usar otra función play_pattern_timed para especificar nuestros propios tiempos y acelerar las cosas:

play_pattern_timed chord(:E3, :m7), 0.25

Inclusive podemos pasar una lista de tiempos, los cuales serán tratados como un círculo de tiempos:

play_pattern_timed chord(:E3, :m13), [0.25, 0.5]

Eso equivale a:

play 52
sleep 0.25
play 55
sleep 0.5
play 59
sleep 0.25
play 62
sleep 0.5
play 66
sleep 0.25
play 69
sleep 0.5
play 73

¿qué preferirías escribir?


8.3 - Escalas

Sonic Pi incluye un gran rango de escalas. ¿qué tal tocar una escala de Do3 mayor?

play_pattern_timed scale(:c3, :major), 0.125, release: 0.1

Podemos pedir para más octavas:

play_pattern_timed scale(:c3, :major, num_octaves: 3), 0.125, release: 0.1

¿qué tal todas las notas de la escala pentatónica?

play_pattern_timed scale(:c3, :major_pentatonic, num_octaves: 3), 0.125, release: 0.1

Notas al Azar

Los Acordes y Escalas son una buena manera de restringir una elección aleatoria para hacer algo significativo. Toca esl siguiente ejemplo que agarra notas al azar del acorde de E3 menor:

use_synth :tb303
loop do
  play choose(chord(:E3, :minor)), release: 0.3, cutoff: rrand(60, 120)
  sleep 0.25
end

Intenta cambiar los nombres de acordes y los rangos de corte.

Descubriendo Acordes y Escalas

Para saber cuáles acordes y escalas vienen con Sonic Pi, simplemente cliquea el botón Lang a la izquierda de este tutorial y elige acorde o escala de la lista API. En la información en el panel principal, baja hasta ver una larga lista de acordes y escalas (dependiendo de cuál estés viendo).

¡Diviértete y siempre recuerda que no hay errores, sólo oportunidades!


8.4 - Anillos

Una variación interesante a las listas, son los anillos. Si sabes algo de programación, puedes haberte topado con anillos de buffers o arrays. Aquí sólo iremos con los anillos - es corto y simple.

En la sección anterior de listas, vimos cómo sacar elementos de ellas a través del mecanismo de indexado:

puts [52, 55, 59][1]

Ahora, ¿qué sucede si quieres el índice 100? Bueno, claramente no existe un elemente en el índice 100, ya que sólo hay 3 elementos dentro. Así que Sonic Pi te responderá un nil. Sin embargo, considera que tienes un contador tal como el pulso actual que se va incrementando. Hagamos nuestro contador y lista:

counter = 0
notes = [52, 55, 59]

We can now use our counter to access a note in our list:

puts notes[counter]

Grandioso, obtuvimos 52. Ahora, incrementemos nuestro contador y obtengamos otra nota:

counter = (inc counter)
puts notes[counter]

Super, obtuvimos 55y después 59. Sin embargo, si lo hacemos de nuevo, se nos acaban los números de la lista y obtenemos nil. Si quisiésemos buclear y volver a comenzar la lista, usaríamos los anillos.

Creando Anillos

Podemos crear anillos de dos maneras: con la función ringy los elementos del anillo como parámetros:

(ring 52, 55, 59)

O podemos tomar una lista normal y convertirla a anillo con el mensaje .ring:

[52, 55, 59].ring

Indexando Anillos

Un anillo puede ser utilizado de la misma manera que una lista, exceptuando que puedes usar índices negativos y mayores al tamaño del anillo mismo, los cuales envolverán y apuntarán siempre a alguno de los elementos del anillo:

(ring 52, 55, 59)[0] #=> 52
(ring 52, 55, 59)[1] #=> 55
(ring 52, 55, 59)[2] #=> 59
(ring 52, 55, 59)[3] #=> 52
(ring 52, 55, 59)[-1] #=> 59

USando Anillos

Usemos una variable para representar el número del pulso actual. Podemos usar esto como un índice a nuestro anillo para agarrar notas a ser tocadas o tiempos de release o cualquier cosa útil que tengamos en nuestro anillo, independientemente del pulso en el que estemos.

Las escalas y acordes son anillos

Algo útil de saber es que las listas regresadas por scale y acorde también son anillos que te permiten las accedas con índices arbitrarios.

Constructores de Anillos

Además de ring hay un número de funciones que construyen anillos por nosotros.

Mira la documentación de cada uno para más información.


9 - Live Coding

Uno de los aspectos más excitantes de Sonic Pi es que permite escribir y modificar código ‘al vuelo’ para hacer música, así como harías con una guitarra. Una ventaja de esto es que te da más retroalimentación mientras compones (corre un bucle sencillo (juega con él hasta que sea perfecto). Sin embargo, la mayor ventaja es poder ejecutar Sonic Pi en vivo en escena.

En esta sección cubriremos lo fundamental de tornar tu código estático de composiciones en ejecuciones dinámicas.

¡Prepárate!


9.1 - Live Coding

Ya sabemos lo suficiente para comenzar a divertirnos en serio. En esta sección te mostraré cómo comenzar a crear composiciones musicales en vivo y convertirlas en ejecuciones. Para ello necesitamos 3 ingredientes:

¡Muy bien, comencemos! Hagamos nuestros primeros sonidos de códigos en vivo Primero necesitamos una función conteniendo el código que necesitamos tocar Comencemos con algo simple. También necesitamos llamadas en bucle a esa función en un hilo: ~~~~ define :my_loop do play 50 sleep 1 end

in_thread(name: :looper) do loop do my_loop end end ~~~~

Si te parece complicado, vuelve a leer las secciones de funciones e hilos. No es tan complicado una vez entiendes bien esos conceptos.

Lo que tenemos es una función que toca la nota 50 y duerme por un pulso. Después definimos un hilo llamado :looper que bucle llamando my_loop repetidamente.

Si corres este código, escucharás la nota 50 una y otra vez…

¡Cambiandolo al vuelo!

Aquí es donde comienza la diversión. Mientras el código aún corre cambia 50 a otro número, digamos 55, y presiona Run otra vez. ¡Woah! ¡cambió en vivo!

No añadió una nueva capa porque usamos hilos nombrados, los que sólo permiten un hilo por cada nombre. El sonido cambió porque redefinimos la función. LE dimos a :my_loopuna nueva definición. CUando el hilo :looper bucleó, simplemente llamó la nueva definición.

Sigue cambiándolo, cambia la nora, el tiempo de pausa. ¿qué tal añadir un use_synth? Por ejemplo, esto:

define :my_loop do
  use_synth :tb303
  play 50, release: 0.3
  sleep 0.25
end

Ahora suena interesante, pero podemos mejorarlo, aún. En vez de tocar la misma nota, hagámoslo con un acorde:

define :my_loop do
  use_synth :tb303
  play chord(:e3, :minor), release: 0.3
  sleep 0.5
end

¿tocamos notas del acorde al azar?:

define :my_loop do
  use_synth :tb303
  play choose(chord(:e3, :minor)), release: 0.3
  sleep 0.25
end

o usando un valor de corte al azar:

define :my_loop do
  use_synth :tb303
  play choose(chord(:e3, :minor)), release: 0.2, cutoff: rrand(60, 130)
  sleep 0.25
end

Al final, añadamos un poco de batería:

define :my_loop do
  use_synth :tb303
  sample :drum_bass_hard, rate: rrand(0.5, 2)
  play choose(chord(:e3, :minor)), release: 0.2, cutoff: rrand(60, 130)
  sleep 0.25
end

¡Ahora está volviéndose excitante!

Sin embargo, antes de saltar y comenzar a Live Coding con funciones e hilos, lee la próxima sección sobre live_loop que cambiará la manera en la que codifiques con Sonic Pi para siempre…


9.2 - Bucles en Vivo

Bien, ésta sección del tutorial es la joya de la corona. Si leyeses sólo una sección, debería ser ésta. Si leíste la sección previa sobre los Fundamentos de Live Coding, live_loop es una manera simple de hacer exactamente eso, pero sin tener que escribir tanto.

Si no leíste la sección anterior, live_loop es como mejor se puede tocar con Sonic Pi.

Toquemos algo. Escribe el siguiente código en un buffer nuevo:

live_loop :foo do
  play 60
  sleep 1
end

Presiona el botón de Run. Escucharás un beep básico en cada pulso. Nada muy divertido en ello. Sin embargo, todavía no presiones Stop. Cambia el 60 a 65 y presiona otra vez Run.

¡Woah Se cambió automáticamente sin perder un tan sólo pulso!¡Esto es Live Coding!

Hagámoslo más a bajo, sólo cambiemos el código un poco: ~~~~ live_loop :foo do use_synth :prophet play :e1, release: 8 sleep 8 end ~~~~

Ahora aprieta Run

Movamos el punto de corte:

live_loop :foo do
  use_synth :prophet
  play :e1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Presiona Run otra vez.

Añadamos baterías:

live_loop :foo do
  sample :loop_garzul
  use_synth :prophet
  play :e1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Cambiemos la nota de e1 a c1:

live_loop :foo do
  sample :loop_garzul
  use_synth :prophet
  play :c1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

Ahora deja de leerme y cambia lo que quieras por tu cuenta. ¡Diviértete!


9.3 - Múltiples Bucles en Vivo

Considera el siguiente bucle en vivo:

live_loop :foo do
  play 50
  sleep 1
end

Quizás te preguntas el por qué es importante el nombre foo, la respuesta es que es importante porque significa que este bucle es diferente de TODOS los otros.

Nunca pueden haber dos bucles en vivo con el mismo nombre ejecutándose simultáneamente

Esto significa que si queremos múltiples bucles concurrentes, debemos darles diferentes nombres:

live_loop :foo do
  use_synth :prophet
  play :c1, release: 8, cutoff: rrand(70, 130)
  sleep 8
end

live_loop :bar do
  sample :bd_haus
  sleep 0.5
end

Ahora puedes actualizar y cambiar cada bucle independientemente y funcionará siempre.

Sincronizando bucles en vivo

Una cosa que ya habrás notado es que los bucles en vivo trabajan automáticamente automáticamente con el mecanismo de marca de hilos que exploramos anteriormente. Cada bucle en vivo genera un evento cue Gracias a ello podemos sincronizarlos para asegurar bucles sin pausa.

Considera este código mal sincronizado:

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.4
end

live_loop :bar do
  sample :bd_haus
  sleep 1
end

Veamos si podemos arreglar el timing y sincronizar sin parar. Primero, arreglemos el bucle :foo para hacer el factor de sleep 1 a algo como 0.5:

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.5
end

live_loop :bar do
  sample :bd_haus
  sleep 1
end

Todavía no terminamos, pues notarás que los pulsos no se alinean correctamente. Esto se debe a que los bucles están desfasados out of phase. Arreglemos Esto sincronizándolos entre sí:

live_loop :foo do
  play :e4, release: 0.5
  sleep 0.5
end

live_loop :bar do
  sync :foo
  sample :bd_haus
  sleep 1
end

¡Wow, todo está sincronizado ahora y sin parar!

¡Ahora ve y codifica en vivo con bucles en vivo!


9.4 - Ticking

Algo con lo que seguramente te encontrarás haciendo muchas veces al hacer live coding es buclear a través de anillos (rings), para poner notas a melodías, pausas a ritmos, progresiones de acordes, variaciones timbrales, etc. etc.

Ticking Anillos

Sonic Pi provee una herramienta muy útil para trabajar con anillos dentro de bucles en vivo. Se llama el sistema de tick, que provee la habilidad de tickear a través de anillos. Veamos un ejemplo:

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick, release: 0.1
  sleep 0.125
end

Aquí, simplemente tomamos la escala pentatónica menor de E3 y tickeamos a cada elemento al añadirles .tick al final de la declaración de escala. Este tick es local al bucle en vivo, por lo que cada bucle debe tener su propio e independiente tick:

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick, release: 0.1
  sleep 0.125
end

live_loop :arp2 do
  use_synth :dsaw
  play (scale :e2, :minor_pentatonic, num_octaves: 3).tick, release: 0.25
  sleep 0.25
end

Tick

También puedes llamar tick como una función estándar y usar el valor como un índice:

live_loop :arp do
  idx = tick
  play (scale :e3, :minor_pentatonic)[idx], release: 0.1
  sleep 0.125
end

Sin embargo, es mejor llamar .tick al final. La función tick está para cuando quieras hacer cosas sofisticadas con el valor de tick y para cuando quieras hacer más que indexar dentro de los anillos.

Mirar

Lo mágico acerca de tick es que no sólo te da un nuevo índice (o el valor del anillo en ese índice), sino que también te asegura que al próximo llamado de tick, será el próximo valor. Mira los documentos para ver ejemplos de trabajar con tick . Sin embargo, por ahora es importante notar que a veces querrás mirar al valor tick actual sin que aumente, lo cual se logra con la función look. La cual puede ser utilizada como una función estándar o añadiendo .look al final de un anillo. to the end of a ring.

Nombrando los ticks

Finalmente, algunas veces necesitarás más de un tick por bucle en vivo. Esto lo lograrás nombrando a tus ticks:

live_loop :arp do
  play (scale :e3, :minor_pentatonic).tick(:foo), release: 0.1
  sleep (ring 0.125, 0.25).tick(:bar)
end

Aquí estamos utilizando dos ticks, uno para la nota a ser tocada y otro para el tiempo de pausa. Como ambos están en el mismo bucle, debemos separarlos nombrándolos diferentemente. Es lo mismo que hiciéramos con live_loop - pasamos un símbolo prefijado con un :. En el anterior ejemplo, llamamos a un tick :foo y al otro :bar. Si queremos mirarlos sólo debemos pasar el nombre del tick a look.

No lo compliques tanto..

La mayor parte del poder del sistema de tick no es útil al comenzar. No intentes aprender todo en esta sección, enfócate en el tick de un sólo anillo. Eso es lo que más te beneficiará y simplificará tickear dentro de anillos en bucles en vivo.

Mira la documentación de tick, donde tienes muchos ejemplos..


10 - Conocimiento Esencial

Esta sección cubre algo muy útil - de hecho esencial - Conocimiento para sacar el mayor partido a tu experiencia con Sonic Pi.

Cubriremos como sacar provecho de muchos atajos disponibles para tí, como compartir tu trabajo y algunos trucos de ejecución con Sonic Pi.


10.1 - Usando atajos

Sonic Pi es tanto un instrumento como un ambiente de código. Los atajos te hacen tocar Sonic Pi de una manera mucho más eficiente y natural. Especialmente si tocas en frente de una audiencia en vivo.

Mucho de Sonic Pi puede ser controlado a través del teclado. Mientras te familiarizas trabajando con Sonic Pi, probablemente usarás más y más atajos. personalmente soy del tipo toca-teclea (lo que recomiendo aprender) y me frustra el tener que ir al ratón, ya que me ralentiza. Por ello es que utilizo estos atajos regularmente.

Por tanto, si te aprendes los atajos, utilizarás tu teclado de manera eficiente y codificarás como un profesional en poco tiempo.

Sin embargo no intentes aprender todo al mismo tiempo, sólo intenta recordar los que más utilizas y continua añadiendo otros a tú práctica.

Consistencia a través de las plataformas

Imagina que estás aprendiendo el clarinete. Esperarás que todos los clarinetes de cada constructor tenga controles y digitalizaciones similares. Si no fuese así, sería complicado cambiar de clarinetes y tendrías que usar sólo uno.

Desafortunadamente los tres principales sistemas operativos (Linux, Mac OS X y Windows) vienen con acciones como cortar y pegar determinadas. Sonic Pi intentará honrar estos estándares. Sin embargo priorizaremos consistencia a través de las plataformas dentro de Sonic Pi. Esto significa que te sentirás cómodo y en casa ya sea que toques con la Raspberry Pi, Mac o PC.

Control y Meta

Parte de la noción de consistencia es el nombramiento de los atajos. En Sonic Pi usamos los nombre Control y Meta para referirnos a las dos principales combinaciones de teclas. En todas las plataformas Control es igual. Sin embargo, en Linux y Windows, Meta es la tecla Alt, mientras que en Mac es la tecla Command. Por consistencia, utilizaremos el término Meta - sólo recuerda mapear la tecla apropiada a tu OS.

Abreviaciones

Para mantener las cosas simples y legibles, utilizaremos la abreviación C- para Control más otra tecla y M- por Meta más otra tecla. Por ejemplo, si un atajo te requiere que mantengas apretadas ambas Meta y r, escribiremos elso, así M-r. El - significa que es al mismo tiempo.

Los siguientes son los atajos que encuentro más útiles.

Para y comenzar

En vez de comenzar tu código conel ratón, puedes simplemente presionar M-r. Similarmente puedes pararlo con M-s.

Sin los atajos de navegación estaría perdido. Así que recomiendo que los aprendas. Estos atajos funcional fenomenalmente cuando hayas aprendido a tocar y teclear, ya que usan letras estándar, en vez de requerir que vayas al ratón o las flechas del teclado.

Puedes moverte al inicio de una línea con C-a, al final de la línea con C-e, una línea arriba con C-p, abajo con C-n, un carácter adelante con C-f, y atrás un carácter con C-b. puedes borrar todos los caracteres desde el cursor hasta el final de la línea con C-k.

Código legibles

Para auto-alinear el código, simplemete presiona M-m.

Sistema de ayuda

Para aparecer el sistema de ayuda, presiona M-i. Sin embargo, un atajo mucho más útil es C-i que buscará la palabra debajo del cursor y mostrará los documentos si encuentra algo. ayuda instantánea.

Para una lista completa, mira la sección 10.2 Tabla de Atajos.


10.2 - Tabla de Atajos

Este es un resumen de los atajos principales dentro de Sonic Pi. Te remito a la sección 10.1 para motivación.

Convenciones

En esta lista, usaremos la siguiente convención (donde Meta es uno de los Alt en Windows/Linux o Cmd en Mac):

Manipulación de la aplicación principal

Seleccionar/Copiar/Pegar

Manipulación de Texto

Borrado

Características avanzadas del Editor


10.3 - Compartiendo

Sonic Pi se trata de compartir y aprender de todos.

Cuando hayas aprendido a codificar música, compartir tus composiciones es tan sencillo como enviar un correo conteniendo tu código. Por favor comparte tu código con los demás, para que ellos puedan aprender de tu trabajo e inclusive utilizar partes del mismo en nuevas obras.

Si tienes dudas de cuál es la mejor manera de compartir tu trabajo con otros, te recomiendo ponerlo en GitHub y tu música en SoundCloud. Así podrás llegar a mayores audiencias.

Código -> GitHub

GitHub es un sitio para compartir código, utilizado por desarrolladores profesionales y artistas para compartir y colaborar con código. La manera más sencilla de compartir una nueva pieza de código (inclusive de obras no terminadas) es creando un Gist. Un Gist es una manera simple de subir tu código para ser visto por los demás para ver, copiar y compartir.

Audio -> SoundCloud

Otra manera de compartir es grabando el audio y subiéndolo a SoundCloud. Una vez subido, otros pueden comentar y discutir tu obra.También recomiendo poner un enlace al Gist de tu código en la descripción de la pista.

Para grabar tu trabajo, presiona el botón Rec y comenzará inmediatamente. Dale a Run para comenzar tu código si no está ya en ejecución. Cuando estes listo con tu grabación, vuelve a presional el parpadeante botón Rec y te pedirá un nombre para el archivo, que será guardado como WAV, el cual puede ser editado y convertido a MP3 por muchos programas libres (prueba Audacity, por ejemplo).

Esperanza

Te invito a compartir tu trabajo y espero realmente que todos nos enseñemos mutuamente nuevos trucos y movimientos con Sonic Pi. Realmente me interesa ver qué es lo que me mostrarás.


10.4 - Ejecutando

Uno de los aspectos más excitantes de Sonic Pi es que usa código como un instrumento musical. Lo que significa que escribir código puede ser visto como una nueva manera de ejecutar música. Que es lo que llamamos Live Coding.

Muestra tú pantalla

Cuando hagas código en vivo, te recomiendo que muestres tu pantalla a la audiencia. De otra manera es como tocar guitarra escondiendo tus dedos y cuerdas. Cuando practico en casa, uso una Raspberry Pi y un mini proyector en el muro de mi sala. Puedes usar tu TV o uno de los proyectores de tu escuela/trabajo para dar una muestra. ¡Inténtalo que es muy divertido!

Forma una banda

No sólo toques por tí mismo - ¡forma una banda de live coding! Es divertido tocar con otros. Una persona puede hacer pulsos, otra sonidos ambiente, etc. Busca interesantes combinaciones de sonido para hacer.

TOPLAP

Live coding no es completamente nuevo - un puñado de gente lleva haciéndolo por años, típicamente utilizando equipo hecho por ellos mismos. Un buen lugar para encontrar otros live coders es TOPLAP.

Algorave

Otra fuente importante a explorar el mundo de live coding es Algorave. Aqui puedes encontrar todo lo relacionado a música con live codign para nightclubs.


11 - Minecraft Pi

Sonic Pi soporta una simple API para interactuar con Minecraft Pi - la edición especial de Minecraft instalada en el sistema operativo basado en Linux que trae la Raspberry Pi, elRaspbian.

Sin necesidad de importar librerías

La integración de Minecraft Pi está diseñada para ser extremadamente fácil de usar. Sólo necesitas lanzar Minecraft Pi y crear un mundo. De ahí tienes libertad de usar mc_* fns tanto como utilizasplay y synth. No hay necesidad de importar algo o instalar librerías. Todo está listo para funcionar.

Conexión automática

El API de Minecraft Pi se encarga de manejar tu conexión a la aplicación Minecraft Pi. Esto significa que no tienes algo de lo que preocuparte. Si intentas utilizar el API de Minecraft Pi cuando Minecraft Pi no está en funcionamiento, Sonic Pi te lo dirá. Similarmente, si cierras Minecraft Pi mientras se ejecuta un live_loop que utiliza la API, el bucle se detendrá y te dirá que no se puede conectar. Para reconectar, simplemente lanza Minecraft Pi de nuevo y Sonic Pi detectará automáticamente y recreará la conexión para tí.

Diseñado para ser Live Coded

La API de Minecraft fue diseñada para trabajar dentro de live_loops. Esto significa que es posible sincronizar modificaciones en tus mundos de Minecraft Pi con modificaciones en tu Sonic Pi. Videos instantáneos de música basada en Minecraft! Nota que Minecraft Pi es software alfa y conocido por algunos problemillas. Si encuentras algunos problemas, reinicia Minecraft Pi y continúa como anteriormente. La funcionalidad de conexión automática de Sonic Pi se encargará por tí.

Requiere una Raspberry Pi 2.0

Es recomendable usar una Raspberry Pi 2 si pretendes correr al mismo tiempo Sonic Pi y Minecraft, especialmente si deseas utilizar las capacidades de Sonic Pi.

Soporte API

Por ahora, Sonic Pi soporta las manipulaciones básicas de bloque y ejcutante, que fueron detalladas en la sección 11.1. En futuras versiones se pretende soportar llamadas de eventos disparadas por interacciones de ejecutantes en el mundo.


11.1 - API Básico de Minecraft Pi

Sonic Pi actualmente soporta las siguientes interacciones básicas con Minecraft Pi:

Veamos cada una de ellas ahora.

Mostrnado mensajes de chat

Veamos cuán fácil es controlar Minecraft Pi desde Sonic Pi. Primero, asegúrate de tener abiertos tanto Minecraft Pi como Sonic Pi al mismo tiempo y haber entrado a un mundo de Minecraft en el que puedas caminar.

Escribe lo siguiente en un buffer vacío de Sonic Pi:

mc_message "Hello from Sonic Pi"

Cuando presiones el botón Run, verás tu mensaje en la ventana de Minecraft. ¡Felicidades, acabas de escribir tu primer código de Minecraft! ¿fácil, no?

Estableciendo la posición del usuario

Hagamos un poco de magia. Teletransportémonos a alguna parte. Prueba lo siguiente:

mc_teleport 50, 50, 50

Cuando le das al botón Run - ¡boom! Te teletransporta a otro lugar. Lo más usual es que sea un lugar en el cielo y que caigas en un lugar seco o en agua. Ahora, ¿cuáles eran esos números 50, 50, 50? Esas son coordenadas de la posición a la que te quieres teletransportar. Tommos un rato para explorar qué son esas coordenadas y cómo trabajan, porque son muy, muy importantes para progrmar Minecraft..

Coordenadas

Imagina un mapa pirata con una gran X marcando la localización de un tesoro. La localización exacta de X puede ser descrita con dos números - cuán lejos en el mapa de izquierda a derecha y qué tan lejos de arriba a abajo. Por ejemplo 10cm cruzando y 8cm arriba. Estos dos números 10 y 8 son coordenadas. Fácilmente podrías imaginar describir las localizaciones de otros tesoros con otros pares de números. Quizás existe un enorme baúl de oro en 2 cruzando y 9 arriba…

Ahora, en Minecraft dos números no son suficientes. También necesitamos saber qué tan alto nos encontramos. Por lo tanto necesitamos tres números:

Una última cosa: típicamente describimos estas coordenadas en este orden: x, y, z.

Encontrando tus coordenadas actuales

Juguemos con las coordenadas. Navega a algún lugar bonito en el mapa de Minecraft y después pásate a Sonic Pi. Ahora pon el siguiente código:

puts mc_location

Cuando presionas el botón Run verás las coordenadas de tu posición actual en la ventan de la bitácora. Apúntalas, muévete adelante en el mundo y vuelve a probar. ¡Nota que las coordenadas han cambiado! Ahora, yo recomiendo que pases algún tiempo repitiendo esto exactamente - muévete un poco en el mundo, mira las coordenadas y repite. Hazlo hasta que sientas cómo cambian las coordenadas cuando te mueves. Una vez lo entiendas, programar con el APi de Minecraft será un paseo.

¡Construyamos!

Ahora que ya sabes cómo encontrar la posición actual y teletransportarte utilizando las coordenadas, tienes entonces las herramientas necesarias para comenzar a construir cosas en Minecraft con código. Digamos que quieres convertir en vidrio el bloque en las coordenadas 40, 50, 60. Super fácil:

mc_set_block :glass, 40, 50, 60

Haha, fué realmente fácil. Para ver tu trabajo, simplemente teletranspórtate a las cercanías y echa un vistazo:

mc_teleport 35, 50, 60

¡Ahora mira alrededor y deberías ver un bloque de vidrio! Intenta cambiarlo a diamante:

mc_set_block :diamond, 40, 50, 60

Si estabas mirando en la dirección correcta, puedes haberlo visto cambiar. Es el comienzo de algo excitante…

Viendo los bloques

Veamos lo último antes de movernos a algo más envolvente. Si damos un set de coordenadas, podemos preguntarle a Minecraft qué tipo de bloque espeecífico es. Intentémoslo con el bloque de diamante que acabamos de crear:

puts mc_get_block 40, 50, 60

Yey! Es :diamond. Intenta cambiandolo a glass y preguntar otra vez - ¿dice :glass? Estoy seguro que si :-)

Tipos de bloques disponibles

Antes de ponerte a programar en Minecraft Pi como un obseso, podrías ojear la siguiente lista de bloques disponibles:

    :air
    :stone
    :grass
    :dirt
    :cobblestone
    :wood_plank
    :sapling
    :bedrock
    :water_flowing
    :water
    :water_stationary
    :lava_flowing
    :lava
    :lava_stationary
    :sand
    :gravel
    :gold_ore
    :iron_ore
    :coal_ore
    :wood
    :leaves
    :glass
    :lapis
    :lapis_lazuli_block
    :sandstone
    :bed
    :cobweb
    :grass_tall
    :flower_yellow
    :flower_cyan
    :mushroom_brown
    :mushroom_red
    :gold_block
    :gold
    :iron_block
    :iron
    :stone_slab_double
    :stone_slab
    :brick
    :brick_block
    :tnt
    :bookshelf
    :moss_stone
    :obsidian
    :torch
    :fire
    :stairs_wood
    :chest
    :diamond_ore
    :diamond_block
    :diamond
    :crafting_table
    :farmland
    :furnace_inactive
    :furnace_active
    :door_wood
    :ladder
    :stairs_cobblestone
    :door_iron
    :redstone_ore
    :snow
    :ice
    :snow_block
    :cactus
    :clay
    :sugar_cane
    :fence
    :glowstone_block
    :bedrock_invisible
    :stone_brick
    :glass_pane
    :melon
    :fence_gate
    :glowing_obsidian
    :nether_reactor_core

12 - Conclusiones

Con esto concluye el tutorial introductorio a Sonic Pi. Ojalá hayas aprendido algo por el camino. No te preocupes si crees que no entendiste todo - sólo juega y diviértete y verás que entiendes a tu propio ritmo - Vuelve cuando tengas alguna duda que pueda haber sido cubierta en una de las secciones.

Si tienes preguntas que no están cubiertas en el tutorial, por favor dirígete a Sonic Pi forums y haz tu pregunta. Seguro encuentras alguien amistoso que te eche una mano.

Finalmente, te invito a que estudies el resto de la documentación en el sistema de ayuda. Hay un número de características no cubiertas en el tutorial que esperan a ser descubiertas.

Así que juega, diviértete, comparte código con amigos, muestra tu pantalla y recuerda:

No hay errores, sólo oportunidades.

Sam Aaron