Zufallszahlen sind eine tolle Möglichkeit, Deine Musik interessant zu gestalten. Sonic Pi bietet einige Funktionen, um Zufallsfaktoren in Deine Musik einzubauen. Aber bevor wir starten, müssen wir noch einer schockierenden Wahrheit ins Gesicht sehen: In Sonic Pi bedeutet zufällig nicht wirklich zufällig. Was zum Teufel soll das bedeuten? Nun, das verrate ich Dir jetzt.
Eine wirklich nützliche Zufallsfunktion ist rrand
. Sie liefert Dir
einen zufälligen Wert zwischen zwei Zahlen - einem Minimal- und einem
Maximalwert. (rrand
ist ein Kürzel für das englische ranged
random, also eine Zufallszahl innerhalb eines bestimmten
Wertebereichs).
play rrand(50, 95)
Oh, eine zufällige Note wird gespielt. Es war die Note 83.7527
. Eine
nette Note zwischen 50 und 100. Aber hallo, habe ich gerade diese
angeblich zufällige Note exakt vorhergesagt? Da ist doch etwas nicht
ganz astrein. Lasse den Code noch einmal ablaufen. Wieder 83.7527
,
oder? Das kann doch kein Zufall sein!
Die Antwort ist, es ist nicht wirklich zufällig, sondern pseudo-zufällig. Sonic Pi liefert Dir Reihenfolgen von Zufallszahlen, die wiederholbar sind. Das ist sehr nützlich, denn so ist sichergestellt, dass die Musik von Deinem Rechner auf anderen Rechnern identisch klingt - sogar dann, wenn Du einen Zufallsfaktor einbaust.
Klar, wenn in einem bestimmten Musikstück jedesmal die 83.7527
als
‘zufällige’ Zahl gewählt würde, dann wäre das nicht besonders
interessant. Aber so ist es auch nicht. Versuch folgendes:
loop do
play rrand(50, 95)
sleep 0.5
end
Jawohl! Nun klingt es zufällig. Innerhalb eines bestimmten Code-Durchgangs liefern Aufrufe von Zufallsfunktionen auch zufällige Werte. Der nächste Durchgang wird jedoch genau die selbe Folge von Zufallswerten liefern und also auch genau gleich klingen. Es ist, als ob der Code immer zu demselben Zeitpunkt zurückspringt, wenn der Ausführen-Button geklickt wird. Es ist der Groundhog-Day2 der musikalischen Synthese.
Ein großartiges Beispiel von Zufall in Aktion bietet der
“Haunted Bells”-Code. Die “ruhelosen Glocken” spielen das Sample
:perc_bell
mit einer zufälligen Samplerate und Pausenzeit
in einer Endlosschleife3 ab:
loop do
sample :perc_bell, rate: (rrand 0.125, 1.5)
sleep rrand(0.2, 2)
end
Ein anderes spannendes Beispiel für die Randomisierung ist das
zufällige Abschneiden hoher Töne4 eines Synth-Klangs. Der :tb303
-Emulator ist
ein guter Synth, um das auszuprobieren:
use_synth :tb303
loop do
play 50, release: 0.1, cutoff: rrand(60, 120)
sleep 0.125
end
Was aber, wenn Du die Abfolge von Zufallszahlen, die Sonic Pi Dir
liefert, nicht magst? Nun, mit use_random_seed
5 kannst Du
unterschiedliche Startpunkte für diese Folge angeben. Der
Standard-Startpunkt ist die 0. Wähle also einfach einen anderen
Startpunkt und mache eine andere Zufallserfahrung!
Sieh Dir den folgenden Code an:
5.times do
play rrand(50, 100)
sleep 0.5
end
Jedes Mal, wenn Du den Code ablaufen läßt, hörst Du dieselbe Folge von 5 Tönen. Um eine andere Folge zu bekommen, setze einfach einen anderen Startpunkt:
use_random_seed 40
5.times do
play rrand(50, 100)
sleep 0.5
end
Nun produziert Sonic Pi eine andere Folge von 5 Tönen. Indem Du den Startpunkt wechselst und Dir die Ergebnisse anhörst, kannst Du eine Folge finden, die Dir gefällt - und wenn Du den Code dann an andere weitergibst, werden sie genau das hören, was auch Du gehört hast.
Schauen wir uns noch eine andere nützliche Zufallsfunktion an.
Häufig kommt es vor, dass man aus einer Liste von Dingen eines zufällig
auswählen möchte. Zum Beispiel möchte ich einen Ton aus der folgenden
Liste auswählen: 60, 65 oder 72. Dafür ist choose
da.
Zuerst musst Du Deine Zahlen in eine Liste packen. Dafür schreibst Du
sie jeweils durch Kommata getrennt in eckige Klammern. Dann übergibst
Du diese Liste dem Kommando choose
:
choose([60, 65, 72])
Hören wir uns das an:
loop do
play choose([60, 65, 72])
sleep 1
end
rrand
haben wir schon kennengelernt, aber sehen wir uns das noch
einmal genauer an. Es liefert eine zufällige Zahl zwischen zwei Werten,
aber ohne diese Werte selbst; man sagt auch exklusiv dieser beiden
Werte. Das bedeutet, dass sowohl der minimale als auch der maximale
Wert niemals ausgegeben werden, immer nur eine Zahl zwischen diesen
beiden Werten. Die Zahl wird immer eine Gleitkommazahl (engl. Float)
sein, also keine ganze Zahl, sondern eine mit einem Komma6. Einige
Beispiele für Gleitkommazahlen, die der wiederholte Aufruf von
rrand(20, 110)
ausgeben könnte:
Manchmal braucht man eine zufällige, aber ganze Zahl, eben keine
Gleitkommazahl. Hier rettet einen rrand_i
7. Es funktioniert
ähnlich rrand
, kann jedoch auch den minimalen oder maximalen Wert,
den man übergeben hat, als mögliche Zufallszahl auswählen (man kann
auch sagen: es ist inklusiv, also nicht exklusive der Werte, mit
denen man den Bereich für die Auswahl festgelegt hat). rrand_i(20,
110)
könnte zum Beispiel die folgenden Werte ausgeben:
rand
gibt eine zufällige Gleitkommazahl zwischen 0 (inklusiv) und
einem übergebenen Maximalwert (exklusiv) zurück. Standardmäßig - wenn
also kein Maximalwert angegeben wird - wird ein Wert zwischen 0 und 1
geliefert. Deshalb kann man rand
gut dafür gebrauchen, zufällige
Werte für amp:
(also die Lautstärke) auszuwählen.
loop do
play 60, amp: rand
sleep 0.25
end
Ähnlich wie bei rrand_i
und rrand
, wählt rand_i
eine zufällige
ganze Zahl zwischen 0 und einem angegebenen Maximalwert aus.
Manchmal möchte man so tun, als würde man würfeln (engl. to dice) -
das ist ein Sonderfall von rrand_i
, wobei der kleinste Wert immer
die 1 ist. Wenn man dice
verwendet, muss man dabei immer bestimmen,
wie viele Seiten der Würfel hat. Ein normaler Würfel hat 6 Seiten, also
wird dice(6)
entsprechend funktionieren und den Wert 1, 2, 3, 4, 5
oder 6 zurückgeben. Aber - angenommen wir befänden uns in einen
Fantasy-Rollenspiel - ist es Dir vielleicht lieber, wenn der Würfel 4
oder 12, 20 oder sogar 120 Seiten hat!?
Schließlich könnte es sein, das Du so tun willst, als ob Du beim
Würfeln eine 6 hast - also den höchten Wert erreichst. one_in
gibt -
mit einer Wahrscheinlichkeit 1 im Verhältnis zur Menge der Würfelseiten
- den Wert wahr (engl. true) zurück, falls die höchste Zahl
gewürfelt wurde. one_in(6)
wird also mit einer Wahrscheinlichkeit von
1 zu 6 wahr, ansonsten falsch (engl. false). Wahr- und Falsch-Werte
sind sehr nützlich, wenn es um if
-Anweisungen geht, die wir in einem
folgenden Kapitel dieses Tutorials besprechen.
Jetzt los, bring Deinen Code mit ein paar Zufälligkeiten durcheinander!
Randomisierung (engl. Randomisation) bedeutet hier, dass man eine Auswahl von Zahlen zufällig gestaltet, also jedesmal eine andere Zahl bekommt. ↩
Im Film Groundhog Day (deutsch: Und täglich grüßt das Murmeltier) erlebt Bill Murray immer wieder denselben Tag. ↩
Ein Schleife wird mit dem Ausdruck loop
eingeleitet. Alles was
innerhalb der Schleife steht, wird so oft wie angegeben oder
unendlich oft wiederholt. ↩
In Sonic Pi wird das Abschneiden oder Verkürzen hoher Töne
(Filtern) mit dem Ausdruck cutoff
bezeichnet. ↩
Das englische Wort Seed bedeutet im Deutschen Keim oder Samen; hier wird es als Startpunkt übersetzt. ↩
Die Sache wird noch dadurch ein wenig komplizierter, dass im
Englischen anstelle eines Kommas ein Punkt steht. Die Gleitkommazahl
5,978
ist also im Englischen die Floating Point Number (kurz:
Float) 5.978
. Alle Zahlen mit Kommawerten werden also in Sonic
Pi mit einem Punkt dargestellt. ↩
Das kleine i in rrand_i
steht für englisch Integer als eine
ganze Zahl im Unterschied zu den Gleitkommazahlen. ↩