Next: Erste Version des Codes für das gesamte Stück , Previous: Die Partitur , Up: Steve Reich: Piano Phase , Home: Allgemeine Einführung

Algorithmische Komposition mit Common Lisp

Die Partitur mit errechneten Wiederholungen der Sektionen

Die Partitur enthält als erstes Element in allen Sektionen die Mindest- und Maximalanzahl der Wiederholungen. Um daraus eine Partitur mit einer definierten Zahl von Wiederholungen zu ermitteln, wird eine Funktion get-real-score definiert, die den Wertebereich bei der Anzahl von Wiederholungen durch eine zufällig gewählte Zahl in diesem Wertebereich ersetzt und die transformierte Partitur zurückgibt.

Für die zufällige Ermittlung der Wiederholungen kann man die Funktion between von Common Music verwenden. Diese Funktion erhält zwei Argumente, min und max und liefert eine Zufallszahl im Bereich [min..max[ zurück. Dabei ist zu beachten, dass die Zufallszahl eine ganze Zahl ist, wenn min und max ganze Zahlen sind, und eine Fließkommazahl, wenn min oder max eine Fließkommazahl ist. Zu beachten ist auch, dass der zurückgegebene Zufallswert immer kleiner, als max ist.

Hier ein paar Beispiele:

(loop repeat 20 collect (between 10 13))
;; => (11 10 11 11 10 12 10 10 10 12 11 12 11 10 11 10 12 10 10 11)

(loop repeat 20 collect (between 10.0 13))
;;  => (11.467623 10.235106 11.624109 12.67795 10.48789 11.58204 12.618152 10.352923
;;      10.894614 11.103058 11.890159 12.987693 10.6728115 10.107074 12.509263
;;      12.965458 12.811146 12.12911 11.088438 12.774424)

Für die Anzahl der Wiederholungen muss daher der Wert für die maximalen Wiederholungen um 1 erhöht werden, damit bei den Zufallsoperationen auch der Maximalwert der Wiederholungen möglich ist.

Die Funktion zur Ersetzung in der Partitur kann dann folgendermaßen definiert werden:

(defun get-real-score (score)
  (loop
    for part in score
    collect (loop
              for section in part
              collect (destructuring-bind ((min max) &rest rest) section
                        (cons (between min (1+ max)) rest)))))

(get-real-score *piano-phase-score*)
;; => (((6 (0 nil)) (18 (0 0) (nil :cresc)) (14 (0 1)) (17 (0 0)) (11 (0 1))
;;      (21 (0 0)) (15 (0 1)) (24 (0 0)) (15 (0 1)) (23 (0 0)) (15 (0 1)) (18 (0 0))
;;      (13 (0 1)) (17 (0 0)) (14 (0 1)) (19 (0 0)) (12 (0 1)) (13 (0 0)) (16 (0 1))
;;      (22 (0 0)) (4 (0 1)) (19 (0 0)) (5 (0 1)) (22 (0 0)) (11 (0 1))
;;      (4 (0 0) (nil :decr)) (5 (0 nil)))
;;     ((6 (0 nil)) (32 (0 0) (nil :cresc)) (10 (0 1)) (23 (0 0)) (17 (0 1))
;;      (26 (0 0)) (15 (0 1)) (21 (0 0)) (11 (0 1)) (16 (0 0)) (9 (0 1)) (22 (0 0))
;;      (7 (0 1)) (16 (0 0)) (9 (0 1)) (30 (0 0)) (7 (0 1)) (13 (0 0) (:decr nil))
;;      (9 (nil 0)))
;;     ((2 (nil 0)))
;;     ((14 (nil 0)) (45 (0 0)) (17 (0 1)) (60 (0 0)) (18 (0 1)) (55 (0 0))
;;      (23 (0 1)) (56 (0 0)) (29 (0 1)) (24 (0 0))))