2.3.2. Starten von Common Music und der Echtzeitverarbeitung im Detail
In diesem und dem nächsten Abschnitt werde die einzelnen Komponenten für die Nutzung von Common Music in einem Echtzeitkontext detailliert beschrieben, um die Zusammenhänge zu verdeutlichen. Da ein Starten sämtlicher Komponenten recht aufwändig ist, wird am Ende des Kapitels eine Funktion gezeigt, die den gesamten Startvorgang umfasst und damit erheblich vereinfacht. Dennoch sollten die Zusammenhänge bewusst sein, um bei Problemen die Fehlersuche zu vereinfachen.
2.3.2.1. Starten von Common Music
Zunächst muss das Lisp Paket "cm-utils" geladen werden. In diesem Paket sind "incudine" und "common music 2" (abgekürzt 'cm') bereits enthalten:
;; Laden von Common Music 2 (cm) mit Realtime Erweiterung. (ql:quickload "cm-utils")
Die Funktionen von common music müssen innerhalb des Paketes "cm" evaluiert werden. Um dies zu gewährleisten, verwendet man den folgenden Ausdruck, der das aktuelle Paket auf :cm setzt.
(in-package :cm)
Wird dieser Befehl in der REPL evaluiert, erkennt man den Wechsel in das Paket durch das veränderte Prompt CM>
CL-USER> (in-package :cm) #<PACKAGE "CM"> CM>
Sollen Lisp Ausdrücke innerhalb einer Textdatei evaluiert werden, so muss (in-package :cm)
nicht evaluiert werden: Es reicht, wenn dieser Ausdruck in der Datei erscheint, um zu gewährleisten, dass sämtliche Ausdrücke in der Datei, die nach dem (in-package :cm)
erscheinen, im Kontext des :cm
Paketes evaluiert werden.
2.3.2.2. Starten der Echtzeitverarbeitung von incudine
Die Echtzeitverarbeitung von incudine wird mit dem folgenden Befehl gestartet:
CM> (incudine:rt-start) :STARTED CM>
Das Starten ist grob vergleichbar mit dem Aktivieren von dsp in pure data bzw. dem Starten des scsynth in SuperCollider.
Nach der Evaluation sollten in jack Audioinputs und -outputs mit Namen "incudine" erscheinen.
Beendet wird die Echtzeitverarbeitung mit:
CM> (incudine:rt-stop) :STOPPED CM>
Dies ist am ehesten vergleichbar mit dem Ausschalten von dsp in pure data
. Im Unterschied zum Beenden des scsynth in SuperCollider bleiben sämtliche Definitionen von incudine und cm erhalten, so dass es nicht erforderlich ist, nach einem erneuten Start diese Definitionen noch einmal zu evaluieren. Sie können nach dem erneuten Start der Echtzeitverarbeitung mit (incudine:rt-start)
sofort wieder verwendet werden.
Für das Starten und Stoppen der Echtzeitverarbeitung existieren in Emacs auch folgende Tastaturkürzel:
"C-c ." entspricht (incudine:rt-start)
"C-c M-." entspricht (incudine:rt-stop)
2.3.2.3. Midi Input und Output in Echtzeit
Echtzeit Ein- Ausgabe von Midiereignissen wird über 'Streams' und 'Ports' abgewickelt6:
In incudine werden dafür die Klassen jackmidi:output-stream
bzw. jackmidi:input-stream
bereitgestellt. Es handelt sich dabei
um direkte Assoziationen eines Streams mit einem in Jack sichtbaren Port.
In common music existieren zwei vordefinierte Symbole, *midi-out1*
bzw. *midi-in1*
, die als Standardports für die elementare Midi-Anbindung vorgesehen sind.
Funktionen zum Öffnen und Schließen der Standardports:
;;; Öffnen des Standard Output Streams (gebunden an das Symbol *midi-out1*): (midi-open-default :direction :output) ;;; Öffnen des Standard Input Streams (gebunden an das Symbol *midi-in1*): (midi-open-default :direction :input)
Nach Evaluation dieser Funktionen sollten bei jack unter JACK-MIDI bei input und output jeweils ein Eintrag mit Namen "incudine" erscheinen.
Ein Aufklappen dieser Einträge zeigt, dass der Name der Midi Ports "midi_out-1" bzw. "midi_in-1" ist. Wie man erkennen kann, ist dieser Name 'nicht' identisch mit den Symbolen dieser Ports in Common Music (*midi-out1*
bzw. *midi-in1*
).
Anschließend muss in jack (mit Hilfe von QjackCtl oder JackPilot) der Midi Output von incudine mit dem Midi input des Softwaresynthesizers verbunden werden, damit man auch etwas hören kann.
Anschließend sollte die Evaluation des folgenden Ausdrucks einen Ton erzeugen:
(output (new midi) :to *midi-out1*)
Neue Streams/Ports werden mit der Funktion jackmidi:open
erzeugt. Der Rückgabewert der Funktion sollte dabei an ein Symbol gebunden werden, das benötigt wird, wenn man Midiereignisse über diesen Stream ausgeben möchte:
(defparameter *midi-out2* nil) (setf *midi-out2* (jackmidi:open :direction :output :port-name "midi_out-2"))
Nach der Evaluation sollte in JACK-MIDI ein zweiter Port mit Namen "midi_out-2" zu sehen sein.
Wenn dieser Port mit einem Softwaresynthesizer verbunden wird (wie in der Abildung dargestellt), kann man die Ausgabe auf diesen Stream/Port in common musics output
Funktion durch das Keywort :to
spezifizieren:
(output (new midi) :to *midi-out2*)
2.3.2.4. Die rts Funktion
Der gesamte oben beschriebene Startvorgang lässt sich mit der Funktion rts
über einen einzigen Funktionsaufruf zusammenfassen. Die rts
Funktion startet die Echtzeitverarbeitung, initialisiert die Standard jackmidi Ports und initialisert rts-out mit einem incudine-stream, der auf den jackmidi Ports ausgibt.
CL-USER> (in-package :cm) CM> (rts) /\\\ ---\\\--------- ----\\\-------- ----/\\\------- Common Music 2.12.0 ---/--\\\------ --/----\\\----- / \\\/ #<incudine-stream> CM>
Da die rts
Funktion auch in das common music package wechselt, kann man den rts Befehl auch direkt aus der cl-user package heraus aufrufen, wenn man den Paketnamen cm:
for den Funktionsnamen stellt. Die gesamte Startroutine für das rts von einem neu gestarteten Lisp reduziert sich in diesem Fall auf folgende Sequenz:
CL-USER> (ql:quickload "cm-utils") CL-USER> (cm:rts) /\\\ ---\\\--------- ----\\\-------- ----/\\\------- Common Music 2.12.0 ---/--\\\------ --/----\\\----- / \\\/ #<incudine-stream> CM>
6: Es ist schwierig, eine genaue Unterscheidung von 'Stream' und 'Port' zu treffen. Konzeptionell versteht man unter einem Port am ehesten etwas, das einem Hardwareanschluss, wie einer Kopfhörerbuchse entspricht, während ein Stream als geöffnete Verbindung betrachtet wird, über die Daten an den Port übertragen werden. Im Zusammenhang von incudine und Common Music kann man beide Begriffe im Grunde synonym verwenden. In diesem Text wird der Ausdruck 'Port' für die in Jack sichtbaren Anschlüsse verwendet, während die softwareseitige Verwendung mit dem Begriff des 'Streams' beschrieben wird. ↩