# Threads

Dus je hebt je fatale baslijn en een vette beat. Hoe speel je ze op hetzelfde moment? Een oplossing is deze handmatig verweven- een beetje bas , dan wat drums, wat meer bas… Lang gaat het niet duren eer je je de timing moeilijk kan voorstellen, zeker als je nog meer elementen hierin wil verweven.

Wat als Sonic Pi deze automatisch kan verweven voor jou? Nou, het kan, en je het doet dat met wat heet een thread.

## Oneindige Loops

Om het voorbeeld eenvoudig te houden, moet je je voorstellen dat dit een waanzinnige baslijn is en een vette beat:

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

Zoals we reeds eerder bespraken, zijn loops zoals zwarte gaten voor het programma. Zodra je in loop bent geraakt, kan je deze niet verlaten totdat u op stop hebt gedrukt. Hoe spelen we dan deze beide loops op hetzelfde moment? We moeten Sonic Pi vertellen dat we iets op hetzelfde moment als de rest van de code willen beginnen. Dit is waar de threads ons redding brengen.

## Threads bieden redding

    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

Door de eerste loop in een `in_thread` do/end block te plaatsen, vertellen we Sonic Pi de inhoud van de do/end block uit te voeren op exact hetzelfde moment als de volgende instructie na de do/end block (toevallig ook onze tweede lus). Probeer het en je zal de baslijn en de drums samen horen spelen!

Wat als we hieraan nog een synth willen toevoegen? Zoiets als:

    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

Nu hebben we hetzelfde probleem als hiervoor. De eerste loop wordt gespeeld op hetzelfde moment als de tweede loop, door onze ‘in_thread’. De derde loop wordt weer nooit bereikt. Daarom hebben we een andere thread nodig:

    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

## Voert uit als threads

Wat je mischien zal verbazen is dat iedere keer je op de afspeel-knop drukt je eigenlijk een nieuwe thread aanmaakt voor de uitvoerende code. Vandaar dat, wanneer je meerdere keren op afspelen drukt, de klanken op elkaar hoort opstapelen. Vermits deze een thread op zich is, verweeft hij deze code voor jou automatisch.

## Toepassingsgebied

Als je Sonic Pi leert beheersen, ga je zien dat threads de belangrijkste bouwstenen voor jouw muziek zullen zijn. Eén van de belangrijkste taak die zij hebben is het isoleren van de huidige staat van andere threads. Wat betekend dit? Wel, wanneer je van synth overschakeld door het gebruik van `use_synth` schakel je van synth in de huidige thread - geen enkele andere thread zal van synth veranderen. Laten we dit in actie zien:

    play 50
    sleep 1
    in_thread do
      use_synth :tb303
      play 50
    end
    sleep 1
    play 50

Merk je op dat de middelste klank anders is dan de andere? De `use_synth` declaratie zal enkel invloed hebben op de thread waarin deze zich bevind en niet op de threads daarbuiten.

## Erfenis

Wanneer je een nieuwe thread met `in_thread` creëert, zal de nieuwe thread de instellingen van de huidige thread overnemen. Laten we dit even bekijken :

    use_synth :tb303
    play 50
    sleep 1
    in_thread do
      play 55
    end

Merk je op hoe de tweede noot met de ‘: tb303’ synth wordt gespeeld, hoewel het door een aparte thread werd aangestuurd? Elk van de met verschillende `use_*` functies gewijzigde instellingen, zullen zich op dezelfde manier gaan gedragen.

Wannneer threads worden gecreëerd, erven zij alle instellingen over van bovenliggende (parent) maar zij delen geen veranderingen aan hen terug.

## Naamgeving aan Threads

Ook nog kunnen wij namen geven aan threads:

    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

Kijk naar het log venster wanneer u deze code uitvoert. Zie je hoe het logboek de naam rapporteert van de thread met een bericht?

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

## Slechts één thread per naam toegestaan

Wat je nog moet weten over benoemde threads is dat slechts één thread met een bepaalde naam tegelijkertijd kan worden uitgevoerd. Laten we dit onderzoeken met de volgende code:

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

Ga je gang en plak deze in een buffer en druk op de knop afspelen. Druk er opnieuw een paar keer. Luister naar de kakofonie van meerdere amen breaks in loop, uit de maat afspelen . OK, je mag nu op Stop drukken.

Dit soort gedrag hebben we al keer op keer gezien - dat als je de afspeelknop aanklikt, geluidslagen op bestaande klanken gaan stapelen. Dus als je een loop hebt en je klikt drie keer op afspelen zal je drie lagen loops tegelijkertijd horen afspelen.

Met benoemde threads is dat echter anders:

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

Probeer de afspeel-knop meerdere malen met deze code. Je zal nu één enkele amen break loop horen. Ook zie je dit in het logboek:

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

Sonic Pi vertelt je hier dat een thread met de naam `:amen` al aan het spelen is , en gaat geen andere creëren.

Dit gedrag lijkt misschien niet onmiddellijk bruikbaar voor je nu - maar het zal erg handig worden wanneer we beginnen met het spelen van code live…