Sonic Pi: Was Sie schon immer über Threads wissen wollten

Der folgende Code spielt zunächst viermal den Sound elec_blup ab, danach achtmal elec_flip:

4.times do
  sample :elec_blup
  sleep 0.5
end

8.times do
  sample :elec_flip
  sleep 0.25
end

Wenn man die beiden Codeabschnitte jeweils in einen Live Loop verpackt, werden sie nicht hintereinander, sondern gleichtzeitig und in Endlosschleife ausgeführt:

live_loop :blup do
  4.times do
    sample :elec_blup
    sleep 0.5
  end
end

live_loop :flip do
  8.times do
    sample :elec_flip
    sleep 0.25
  end
end

Dieses gleichzeitige Abspielen wird im Hintergrund dadurch erreicht, daß jeder Live Loop automatisch seinen eigenen Thread eröffnet. Thread (zu Deutsch= Faden oder Strang) ist ein Fachbegriff aus der Informatik. Dabei geht es im Kontext von Sonic Pi schlicht gesagt um folgendes: Normalerweise arbeitet Sonic Pi den eingegebenen Code Zeile für Zeile ab, bis die letzte Zeile erreicht ist oder der Nutzer den Stop-Button drückt. Mit Threads kann man erreichen, daß mehrere Codeabschnitte parallel abgearbeitet werden.

Mit der Funktion in_thread kann man Threads eröffnen. Hier noch einmal das erste Codebeispiel, bei dem aber diesmal die beiden Abschnitte in einem eigenen Thread ausgeführt werden:

in_thread do
  4.times do
    sample :elec_blup
    sleep 0.5
  end
end

in_thread do
  8.times do
    sample :elec_flip
    sleep 0.25
  end
end

 

Die beiden letzten Codebeispiele zeigen eine konkrete Anwendung von in_thread. Die in Zeile 1-6 definierte Funktion klopfer spielt zufallsgesteuert zwei- bis sechsmal den Sound elec_flip ab, die Pause nach jedem einzelnen flip-Sound dauert – per choose ebenfalls zufällig ausgewählt – manchmal 0.125, manchmal 0.0625 Beats. Im Ergebnis varriiert die Gesamtdauer einer Ausführung von klopfer bei jedem Aufruf. Wenn man die Funktion in einem Live Loop (Zeile 8-13) verwendet, hat der Loop kein definiertes Timing.

define :klopfer do
  rand_i(2..6).times do
    sample :elec_plip
    sleep [0.125, 0.0625].choose
  end
end

live_loop :beat do
  sample :bd_haus
  sleep 0.5
  klopfer
  sleep 0.5
end

Um ein definiertes Timing zu erreichen wurde in folgender Variante der Code der klopfer-Funktion in einen eigenen Thread verpackt. Das bedeutet: bei jedem Aufruf der Funktion wird ein neuer Thread eröffnet. Nun läuft der Beat rund, jeder Schleifendurchlauf des Live Loop hat exakt dieselbe Dauer:

define :klopfer do
  in_thread do
    rand_i(2..6).times do
      sample :elec_plip
      sleep [0.125, 0.0625].choose
    end
  end
end

live_loop :beat do
  sample :bd_haus
  sleep 0.5
  klopfer
  sleep 0.5
end