Aus Raspberry Pi Geek 12/2018

Audio-Programmierung mit Sonic Pi, Teil 1 (Seite 2)

Alle Zeitangaben in Sonic Pi beziehen sich auf die Schlagdauer. Per Voreinstellung dauert ein Schlag eine Sekunde, das Tempo beträgt also 60 Schläge pro Minute (Beats per Minute, kurz: BPM). Bei Bedarf ändern Sie den BPM-Wert – und damit die Dauer eines Schlags – über die Funktion use_bpm. Mit use_bpm 120 verdoppeln Sie das Tempo und halbieren entsprechend die Schlagdauer, die dann eine halbe Sekunde beträgt.

Beim BPM-Wert handelt es sich übrigens nicht um eine globale Variable. Sonic Pi muss als Musikprogramm mehrere Threads (also Programmstränge) parallel ausführen können. Jeder davon enthält eine Reihe lokaler Variablen, die er beim Erzeugen vom Mutter-Thread kopiert; dazu gehört auch der BPM-Wert.

Die einzelnen Programmstränge managen ihr Timing dann vollkommen unabhängig, können sich aber gegenseitig Nachrichten schicken und gemeinsam auf Thread-sichere Variablen zugreifen. Dieser dynamische, nicht hierarchische Umgang mit Zeit stellt eine der Besonderheiten und Stärken von Sonic Pi dar.

Wiederholungen

Musik besteht aus Variation und Wiederholung. Die Funktion times sorgt für das mehrfache Ausführen eines Codeabschnitts.

Sonic Pi ist eine objektorientierte Sprache. Im Beispiel aus den ersten vier Zeilen von Listing 2 handelt es sich bei der 8 um ein Objekt der Klasse Fixnum; times wiederum ist eine Funktion von Fixnum-Objekten.

Der Codeabschnitt zur Wiederholung steht zwischen einem do und einem end in einem sogenannten Block, also einem zur Übergabe an eine Funktion geschnürten Päckchen Code. Es ist wichtig, dieses Prinzip zu verstehen, denn Blöcke begegnen uns bei Sonic Pi an allen Ecken und Enden.

Die Funktion times kann eine Zählervariable an den Block übergeben. Im Beispiel aus den Zeilen 5 bis 8 von Listing 2 dient die (automatisch mit 0 initialisierte) Variable zaehler zur dynamischen Berechnung der Pause zwischen zwei Bassdrum-Schlägen. Sie nimmt bei jedem Schleifendurchgang ab und wird schließlich so kurz, dass Sie einen aufsteigenden Ton hören.

Möchten Sie einen Codeabschnitt endlos wiederholen, dann setzen Sie dazu die Funktion live_loop ein (Listing 2, Zeile 9 bis 12). Auch sie erwartet einen Block und zudem als Argument einen beliebigen Namen (hier :knarzer).

Wie schon bei den Namen der eingebauten Samples handelt es sich beim Namen des Live Loops um ein Symbol. Solche Symbole erkennen Sie am führenden Doppelpunkt. Sie dienen in Sonic Pi zur eindeutigen Adressierung unter anderem von Samples, Effekten, Synthesizern und eben Live Loops: Jeder davon braucht einen eigenen, eindeutigen Namen.

Listing 2

 

8.times do
  sample :elec_blup
  sleep 0.5
end
64.times do |zaehler|
  sample :bd_haus
  sleep 1.0/(zaehler+1)
end
live_loop :knarzer do
  sample :bass_dnb_f, rate: 0.5
  sleep 4
end

Sonic Pi und Ruby

Sonic Pi bedient sich einer für musikalische Zwecke modifizierten Variante der Programmiersprache Ruby. Deshalb können Sie die meisten Ruby-Sprachmittel und Gems in Sonic Pi nutzen, obwohl diese nicht in der Dokumentation stehen. Als besonders nützlich erweisen sich hier etwa Array-Funktionen wie each, permutation und combination. Der gewichtigste Unterschied besteht in der Art, wie man Funktionen definiert. Das passiert in Sonic Pi stets mit der Funktion define, die mit einem Block arbeitet. Generell gilt: Nicht dokumentierte Elemente von Ruby lassen sich zwar benutzen, deren Funktion ist aber nicht garantiert. Sonic-Pi-Schöpfer Sam Aaron spricht hier augenzwinkernd vom Wilden Westen der Sprache.

Live und parallel

Bei Sonic Pi handelt es sich um eine Live-Coding-Sprache, die Sie (mit viel Übung) wie ein Instrument nutzen können. Statt sich auf der Bühne mit Trompete, Orgel und Saxofon abzumühen, kann man auch an der Computertastatur ins Schwitzen kommen und wie Sonic-Pi-Erfinder Sam Aaron mit echtzeitprogrammierten Beats Menschen zum Tanzen bringen [1].

Zu diesem Zweck bieten Live Loops die Möglichkeit, in den Code einzugreifen, während er läuft. Um das auszutesten, starten Sie wie gehabt irgendeinen Live Loop. Nehmen Sie dann eine Änderung im Code vor, im Beispiel aus den letzten vier Zeilen von Listing 2 etwa einen anderen Wert für rate. Starten Sie den Live Loop danach erneut, ohne die Ausführung vorher zu unterbrechen: Der nächste Durchlauf führt dann den modifizierten Code aus.

Jeder Live Loop erzeugt einen eigenen Thread und eröffnet damit einen eigenen Zeitstrang. Das demonstriert Listing 3: Ein zweiter Live Loop mit Namen :der_beat spielt parallel zum :knarzer den Amen Break. Für ein sauberes Zusammenspiel sorgt hier die Sample-Option beat_stretch: 2: Sie dehnt den Amen Break auf eine Dauer von exakt zwei Schlägen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 6 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben