# 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…