musikinformatik-wise-24.org
Generatoren
Mit Hilfe von Closures kann man eine Generatorabstraktion (wie zum Beispiel einen Oszillator) bauen, die man starten und stoppen kann:
(in-package :clamps) (defun make-lfo (ref &key (freq 1) (max 127) (phase 0.5) (resolution 0.1)) "Mechanismus mit Closure für einen LFO mit start/stop/freq/phase." (let* ((running nil) (proc (process ;;; "Phasor" von [0..1] while running do (progn (setf phase (mod (+ phase (* freq resolution)) 1)) (set-val ref (* max (abs (- 1 (* 2 phase)))))) wait resolution))) (lambda (command &rest args) (case command (:start (setf running t) (sprout proc)) (:stop (setf running nil)) (:freq (setf freq (first args))) (:phase (setf phase (+ 0.5 (first args))) (set-val ref (* max (abs (- 1 (* 2 phase)))))))))) (defparameter *lfo1* (make-lfo *slider1*)) ;;; Aufrufsyntax für den lfo: (funcall *lfo1* :freq 0.1) (funcall *lfo1* :start) (funcall *lfo1* :stop) (funcall *lfo1* :phase 0)
Die Funktion #'make-lfo
erzeugt und evaluiert zu einer Closure,
die man in einer Variable speichern kann. Diese Closure ist in
mancher Hinsicht vergleichbar zu der Instanz einer Klasse: Indem
es die "Instanz" einer Closure erzeugt, hat #'make-lfo
eine
ähnliche Funktion, wie #'make-instance
im Common Lisp Object
System (CLOS), der objektorientierten Erweiterung von Common
Lisp. Die Definitionen in den case Unterscheidungen im body der
closure von #'make-lfo
sind dabei vergleichbar mit
Methodendefinitionen einer Klasse1.
Aufgaben
Reformuliert die Definition von make-lfo
mit Hilfe von
zeitlicher Rekursion und labels.
Schreibt analog zu make-lfo
Definitionen für
make-phasor
. Schreibt dabei eine Definition unter Verwendung von
process
und eine andere unter Verwendung von temporaler
Rekursion.
Fußnoten:
Dieser Mechanismus ist ganz ähnlich, wie bei messages, die in pd oder Max/MSP an ein Objekt gesendet werden. Ein "Objekt" wird in pd instantiiert, indem man in eine Objektbox einen Namen tippt und anschließend in den Canvashintergrund klickt. In dem Objekt werden dann verschiedene Messages, die es über einen Inlet erhält, unterschiedlich verarbeitet. Die Auswahl der Aktion, die abhängig von der Message ausgeführt werden soll, nennt man "dispatch", im Falle von PD/Max "message dispatch". Das "route" Objekt hat in diesen Systemen eine ähnliche Aufgabe des vom Anwender programmierbaren "message dispatching".
Created: 2025-02-12 Mi 20:35