8.1 Funktionen

Funktionen sind Bestandteile im Code, die etwas ganz Bestimmtes machen. Du kannst die Funktion einmal definieren und dann beliebig oft aufrufen. Damit kannst du ziemlich viel Code einsparen und vermeidest Wiederholungen im Code. Als Beispiel ist in Abbildung 25 die Funktion „sound1“ im Code-Editor zu sehen.

Jede Funktion beginnt mit dem Schlüsselwort „define“ und endet mit „end“. Alle Zeilen dazwischen gehören zu der Funktion.
Im Beispiel „sound1“ wird ein bestimmter Sound erzeugt, der aus 4 Klängen besteht. In der Funktion werden dafür die entsprechenden Synths eingestellt. Die Tonhöhe ist für alle Klänge gleich, denn immer steht hinter play die Variable num. Du kannst einfach Code 16 kopieren und ausprobieren.

In diesem Beispiel wird die Funktion 2 mal aufgerufen. Einmal mit dem Parameter 64, und anschließend mit dem Parameter 61. Beim Abspielen kannst Du also 2 Töne mit unterschiedlichen Tonhöhen hören.

Bei dieser Funktion wird genau ein Parameter übergeben, nämlich eine Zahl die beim Aufruf der Variable „num“ zugeordnet wird. In der Funktionsdefinition wird die Variable in senkrechte Striche „|“ eingeschlossen.

Die Übergabe nur einer Variablen ist schon einmal ganz praktisch. Wie funktioniert aber die Verwendung von Funktionen falls man zusätzlich noch die Tonlänge einstellen will. Dann benötigt man also 2 Variablen. Code 17 zeigt genau dieses Beispiel.
Die Parameter werden immer durch ein Komma getrennt. Das gilt sowohl für den Aufruf der Funktion, als auch für die Definition der Funktion, wo die beiden Parameternamen dann von den senkrechten Strichen eingeschlossen werden. Die Zuordnung der Werte im Aufruf der Funktion zu den Variablen in der Definition geschieht über die Reihenfolge: Der erste Wert wird dem ersten Parameter zugeordnet, der zweite Wert dem zweiten Parameter und so fort.

Was passiert nun, wenn die Anzahl der Parameter des Aufrufs und die der Funktionsdefinition nicht übereinstimmt? Nun, dann gibt es eine Fehlermeldung die ziemlich eindeutig ist, siehe Abbildung rechts..

 

Schauen wir uns das Beispiel noch einmal genau an und überlegen, was man noch verbessern kann. Da fallen mir spontan 3 Sachen ein:

1. Name der Funktion: sound1 sagt zwar schon einmal worum es hier geht, nämlich um einen Klang (Sound), aber die „1“ ist doch sehr unspezifisch. Sound_fm&3 wäre hier eindeutig besser.

2. Keine Erklärung, was die Funktion macht: hier fehlt der Kommentar.

3. In Sonic Pi und in vielen anderen Programmiersprachen kann man Argumente mit einem festen Wert vorbelegen. Code 18 Zeigt, wie das funktioniert. Dem zweiten Argument ist der Wert 0.1 zugeordnet. Es gibt jetzt 2 Möglichkeiten. Entweder ich rufe die Funktion mit 2 Argumenten auf, dann werden diese 2 auch verwendet, oder ich rufe sie mit einem Argument auf, und dann wird für das zweite Argument automatisch der Wert 0.1 verwendet.

 

Ein weiteres Beispiel wird in Code 19 gezeigt. Der Schleifenparameter i wird beim Aufruf der Funktion ring_c_d übergeben. Dabei ist es unerheblich, dass der Parameter in der Funktionsdefinition einen anderen Namen hat: tone. Da die Schleife 16 mal durchlaufen wird, wird die Funktion 16 mal aufgerufen und gibt 16 Töne aus. Da die Ringstruktur 8 Töne enthält, wird sie 2 mal ganz durchlaufen.

functions_1

 

###############################
# Functions
# Hans Gruendel
# 25.08.2015
#
################################
in_thread do
sound1 64
sleep 2
sound1 61
end

define :sound1 do |num|
use_synth :fm
play num
use_synth :pretty_bell
play num
use_synth :sine
play num
use_synth :tri
play num
end
Code 16. Beispiel einer Funktion
################################
# Parameter -2
# Hans Gruendel
# 25.08.2015
#
################################
in_thread do
sound1 64, 1
sleep 2
sound1 61, 3
sleep 2
end

define :sound1 do |num, length|
use_synth :fm
play num, release: length
use_synth :pretty_bell
play num, release: length
use_synth :sine
play num, release: length
use_synth :tri
play num, release: length

end
Code 17. Funktion mit 2 Parametern
define :sound1 do |num, length = 0.1|
use_synth :fm
play num, release: length
use_synth :pretty_bell
play num, release: length
use_synth :sine
play num, release: length
use_synth :tri
play num, release: length
end
Code 18. Vorbelegung von Argumenten

 

################################
# functions and rings -3
# Hans Gruendel
# 25.08.2015
#
################################
in_thread do
16.times do |i|
ring_c_d i
sleep 0.25
ring_c_d i+2
sleep 0.25
end
end

define :ring_c_d do |tone|
all_tones = [:c4, :e4, :g4, :c5, :d4, :f4, :a4, :d5].ring
use_synth :fm
play play all_tones[tone]
end
Code 19. Funktion und Ringstruktur