5.4 Hilos

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

