Next: Evaluationszeit (compile-time vs. run-time) , Previous: Process , Up: Scheduling , Home: Einführung

musikinformatik-wise-24.org

Zeitliche Rekursion

Eine weitere Möglichkeit, zeitliche Prozesse in Echtzeit zu steuern ist die Zeitliche Rekursion. Sie wird zumeist im Kontext von Live-Coding eingesetzt.

Dafür wird eine Funktion definiert, die sich selbst rekursiv mit Zeitverzögerung aufruft.

Hier ein Beispiel:

(defun rek01 (time num)
  (when (< num 4)
    (let ((next (+ time 0.2)))
      (output (new sfz :keynum (between 60.0 84) :duration 0.1))
      (at next #'rek01 next (1+ num)))))

(rek01 (now) 0)

Wenn man eine innere Hilfsfunktion für die Rekursion mit Hilfe der special form labels verwendet, lassen sich die Prozesse aus dem letzten Abschnitt auch folgendermaßen definieren:

(defun prozess01 (num)
  (labels ((inner (time n)
             (when (< n num)
               (let ((next (+ time 0.2)))
                 (output (new sfz :duration 0.1))
                 (at next #'inner next (1+ n))))))
    (inner (now) 0)))

(prozess01 4)

Zur Erklärung des Beispiels: Die (labels ...) Form ist ähnlich einem (let ...) Ausdruck: in der Liste, die dem labels Symbol folgt, stehen Listen, die lokalen Funktionsdefinitionen entsprechen.

Im obigen Beispiel wird eine Funktion mit dem Namen inner definiert, die im lexikalischen Kontext (= body) der labels Form verwendet werden kann.

Die Syntax einer Funktionsdefinition innerhalb einer labels Form entspricht der Syntax eines defun: Nach dem Funktionsnamen folgt eine Liste mit den Argumenten und dann der body der Funktionsdefinition.

Im obigen Beispiel wird also im Rahmen des labels eine Funktion mit dem Namen inner definiert, die zwei Argumente, time und n erhält. Wichtig ist, dass innerhalb der Funktionsdefinition Variablen aus dem lexikalischen Kontext der Funktionsdefinition verwendet werden können. Im Beispiel oben ist das Symbol num hinter dem when an den Wert von num bei Aufruf der Funktion prozess01 gebunden.

Die mit labels definierte Funktion inner wird dann in der letzten Zeile der FUnktionsdefinition von prozess01 mit den Argumenten (now) und 0 aufgerufen.

Aufgabe

Reformuliert die Definition von prozess02, prozess03 und prozess04 aus dem letzten Abschnitt mit Hilfe von zeitlicher Rekursion und labels.

Created: 2025-02-12 Mi 20:35

Validate