ICST Kristall Motion Map — Benutzerhandbuch
Niveau: Mittel | Zielgruppe: Komponist, Klangestalter, Raumklangtechniker. | Version: 2.2.8
ICST Kristall Motion Map ist ein eigenständiges REAPER-Lua-Skript mit grafischer Echtzeit-Oberfläche. Es ordnet bis zu 64 AmbiEncoder-Quellen als Punkte in einem 3D-Kristallgitter an und bewegt sie mit einem Schritt-Sequenzer durch den Raum. Die Bewegung kann live in der isometrischen Vorschau verfolgt, per OSC an einen ICST AmbiEncoder_64 gesendet und mit instanzspezifischen Transformationen, Quantisierung, Glättung und Interaktion gestaltet werden. Dieses Instrument entstand in Zusammenarbeit mit und inspiriert durch Eli Stine, Gast der ICST Studio Residency 2026.

Dies ist ein kurzes Demobeispiel eines Random-Kristalls von Eli Stine — binaural gerendert.
1. Voraussetzungen
- REAPER v6 oder neuer (v7 empfohlen)
- ICST AmbiEncoder_64 auf dem Ziel-Track — siehe Installation
- Python 3 mit
python-osc— nur für die Live-OSC-Vorschaubrücke erforderlich- macOS / Linux:
pip3 install python-osc - Windows: siehe Python unter Windows unten
- macOS / Linux:
2. Installation
Schritt 1 — Bundle herunterladen
ICST_Kristall_Motion_Map_Bundle.zip herunterladen (auch auf der Downloads-Seite verfügbar) und entpacken, z. B. nach ~/REAPER/Scripts/ICST_Kristall_Motion_Map_Bundle/.
Das Bundle enthält:
scripts/JS_ICST_Kristall_Motion_Map.lua— Hauptskriptjsfx/JS_ICST_Kristall_Controller.jsfx— optionale MIDI/JSFX-SteuereinheitREADME.md— Schnellstart-Anleitung
Schritt 2 — Als ReaScript laden
- In REAPER: Actions → Load ReaScript…
JS_ICST_Kristall_Motion_Map.luaauswählen und Open klicken.- REAPER fügt das Skript der Aktionsliste hinzu. Einmal ausführen — das Kristall-Motion-Map-Fenster öffnet sich.
Python unter Windows
Schritt 1 — Python-Pfad ermitteln. Eingabeaufforderung öffnen und ausführen:
python -c "import os, sys; print(os.path.dirname(sys.executable))"
Beispielausgabe: C:\Users\stine\AppData\Local\Python\pythoncore-3.14-64
Schritt 2 — REAPER auf Python zeigen. In REAPER Preferences → Plug-ins → ReaScript öffnen, „Force ReaScript to use specific Python .dll…" aktivieren und auf die python3xx.dll in diesem Ordner zeigen (z. B. python314.dll).
Schritt 3 — python-osc installieren mit demselben Python:
python -m pip install python-osc
Schritt 3 — Optional: Launcher-Datei
Wenn das Skript in einem versionierten Ordner liegen soll, kann eine einzeilige Launcher-Datei im REAPER-Scripts-Verzeichnis erstellt werden:
-- JS_ICST_Kristall_Motion_Map_Launcher.lua
dofile('/Pfad/zu/JS_ICST_Kristall_Motion_Map.lua')
Diesen Launcher als ReaScript laden. Zum Neuladen nach einer Skriptänderung das Kristall-Fenster schliessen und die Launcher-Aktion erneut ausführen.
3. Die Oberfläche auf einen Blick


Das Fenster ist in vier Bereiche aufgeteilt:
┌─────────────────┬──────────────────────────────────────┐
│ Instanzliste │ Gitter-Vorschau (3D isometrisch) │
│ ├──────────────────────────────────────┤
│ [+Add] [-Rem] │ Parameter-Panel [↺ Def] │
│ [Dup] │ (scrollbar, pro Instanz) │
├─────────────────┴──────────────────────────────────────┤
│ Zeile 1: OSC · Preset-Name · Save · Reset │
│ Zeile 2: Speed · BPM · Fwd/Rev · Pause · Stop · PP · Sync │
│ Zeile 3: Offset X Y Z · Move X Y Z │
│ Zeile 4: Rotate Pt · Yw · Rl · Zoom │
│ Zeile 5: Spin Pt · Yw · Rl · Arrange-Buttons │
│ Preset-Leiste: Cubic · Tetragonal · … · Triclinic │
└────────────────────────────────────────────────────────┘
4. Instanzliste
Das linke Panel listet alle aktiven Instanzen auf. Jede Zeile zeigt Nummer, Farbpunkt, Name und aktuellen Schrittzähler.
| Steuerelement | Aktion |
|---|---|
| Zeile anklicken | Instanz auswählen; Parameter-Panel aktualisiert sich |
| Shift + Klick | Zur Mehrfachauswahl hinzufügen; alle ausgewählten Instanzen teilen Parametereingaben |
| + Add | Neue Instanz mit Standardeinstellungen erstellen |
| − Rem | Ausgewählte Instanz löschen |
| Dup | Ausgewählte Instanz duplizieren |
| Taste A | Instanz hinzufügen |
| Taste D | Ausgewählte Instanz duplizieren |
| Taste R | Ausgewählte Instanz auf Schritt 0 zurücksetzen |
| Taste Cmd+A | Alle Instanzen auf einmal auswählen |
5. Gitter-Vorschau

Das obere rechte Panel zeigt alle aktivierten Instanzen als farbige Punkte in einer isometrischen 3D-Projektion. Ein Einheitswürfel dient als Orientierungsrahmen.
| Interaktion | Wirkung |
|---|---|
| Punkt ziehen | Instanz in der XY-Ebene verschieben (aktualisiert Start X und Start Y) |
| Shift + ziehen | Instanz entlang der Z-Achse verschieben (aktualisiert Start Z) |
| Shift + Punkt anklicken | Instanz zur Mehrfachauswahl hinzufügen |
| Hovern | Zeigt Instanzname und Markierungsring |
Zwischen je zwei Instanzen innerhalb von EDGE_DIST Welteinheiten werden Kanten gezeichnet — so ist die Gitter-Topologie auf einen Blick erkennbar.
6. Parameter-Panel
Die rechte Spalte unterhalb der Vorschau zeigt alle Parameter der ausgewählten Instanz. Mit dem Mausrad scrollen.
In der Panel-Kopfzeile werden Instanznummer und Name angezeigt. Ein kleiner ↺ Def-Button oben rechts im Header setzt alle Parameter der ausgewählten Instanz(en) auf Werksstandard zurück (Position, Offsets, Rate, Schrittanzahl, Modus, Rotation, Skalierung, Grenzen, Glättung). Name und Farbe bleiben erhalten. Bei Mehrfachauswahl werden alle Instanzen gleichzeitig zurückgesetzt.
Werte bearbeiten
Jedes Zahlenfeld unterstützt drei Methoden zur Wertänderung ohne Eintippen:
| Methode | Bedienung | Hinweis |
|---|---|---|
| Mausrad | Feld anklicken zum Fokussieren, dann scrollen | Pro Feldtyp ein passender Schrittweite (siehe Tabelle unten). Shift halten für ×10 gröberen Schritt. |
| Cmd + Ziehen | Cmd halten, Feld anklicken, Maus nach oben (Wert steigt) oder unten (Wert sinkt) ziehen | Shift zusätzlich halten für ×0,1 feineren Schritt. Änderungen werden relativ auf alle ausgewählten Instanzen übertragen. |
| Direkteingabe | Feld anklicken, Wert eintippen, Enter bestätigen | Esc bricht ab. |
Scrollschritte nach Feldtyp:
| Feld | Schritt |
|---|---|
| Schrittanzahl | 1 (nur ganzzahlig) |
| Rotationsfelder | 1,0° |
| Offset-Felder | 0,005 |
| Rate | 0,05 |
| Start-Position | 0,01 |
| Glättung / Glide | 0,01 |
Grundparameter — alles, was für die erste Sitzung benötigt wird:
Identität
| Parameter | Beschreibung |
|---|---|
| Name | Bezeichnung in der Instanzliste |
| Enabled | Deaktiviert: Instanz eingefroren, nicht in OSC-Ausgabe |
Position
| Parameter | Beschreibung |
|---|---|
| Start X / Y / Z | Ursprung der Instanz im Weltkoordinatensystem (in der Vorschau visuell verschiebbar) |
| Offset X / Y / Z | Schrittvektor — Bewegung pro Schritt entlang jeder Achse |
Pro Schritt ergibt sich die Rohposition als:
Position = Start + currentStep × Offset
Timing
| Parameter | Beschreibung |
|---|---|
| Rate | Schritte pro Sekunde (BPM aus) oder Schritte pro Taktschlag (BPM an) |
| Steps | Gesamtschrittanzahl; bestimmt den Umkehrpunkt bei Finite und Pingpong |
| Mode | Infinite — läuft unendlich; Finite — stoppt am letzten Schritt; Pingpong — prallt ab |
Bewegungstransformationen — den Pfad nach der linearen Grundbewegung formen:
Rotation
Dreht um die Start-Position mit einer Euler-Rotationsmatrix. Winkel in Grad.
| Parameter | Beschreibung |
|---|---|
| Rot X / Y / Z | Euler-Winkel in Grad |
| Order | Anwendungsreihenfolge: XYZ, XZY, YXZ, YZX, ZXY, ZYX |
Skalierung
Skaliert den Offset-Vektor relativ zur Start-Position.
| Parameter | Beschreibung |
|---|---|
| Scale X / Y / Z | Skalierungsfaktor pro Achse |
Grenzen (Bounds)
Begrenzt die Position auf eine Box, nach Rotation und Skalierung.
| Parameter | Beschreibung |
|---|---|
| Bounds On | Grenzenverarbeitung aktivieren |
| Mode | None, Clamp (stoppt am Rand), Wrap (springt auf die Gegenseite), Mirror (reflektiert) |
| Min / Max X / Y / Z | Eckpunkte der Begrenzungsbox |
Quantisierung
| Parameter | Beschreibung |
|---|---|
| Space Q. | Endposition auf ein Raster einrasten (vor Glättung) |
| Time Q. | Schrittfortschritt auf Taktunterteilungen quantisieren |
| Grid X / Y / Z | Rasterzellgrösse pro Achse (Space Q.) |
Glättung
Exponentieller Übergang zwischen der schrittweisen Zielposition und der Ausgabe:
alpha = 1 − exp(−dt / glideTime)
currentPos = currentPos + alpha × (targetPos − currentPos)
| Parameter | Beschreibung |
|---|---|
| Smoothing | Filter aktivieren/deaktivieren |
| Glide Time | Zeitkonstante in Sekunden — 0.08 s ist knackig, 0.5 s ist langsam |
Erweitert — Instanzen beeinflussen sich gegenseitig (optional für den Einstieg):
Interaktion

Instanzen können die Geschwindigkeit und Richtung benachbarter Instanzen beeinflussen.
| Parameter | Beschreibung |
|---|---|
| Interaction | Für diese Instanz aktivieren |
| Send Amount | Wie stark diese Instanz andere beeinflusst |
| Receive Amount | Wie stark diese Instanz eingehende Einflüsse aufnimmt |
| Radius | Einflusssphäre in Welteinheiten |
| Falloff Mode | Linear / Inverse Square / Gaussian |
| Affect Offset | Eingehender Einfluss modifiziert die Schrittrichtung |
| Affect Rate | Eingehender Einfluss modifiziert die Schrittrate |
7. Statusleiste — Zeile 1: OSC und Presets

OSC
| Steuerelement | Beschreibung |
|---|---|
| Farbpunkt | Grün = verbunden, rot = getrennt |
| Host | IP-Adresse des OSC-Ziels (Standard 127.0.0.1) |
| Port | UDP-Port des OSC-Ziels (Standard 9001) |
| Connect / Disconnect | OSC-Brücke öffnen oder schliessen |
| in: PORT | Erscheint nach dem Verbinden — UDP-Port für eingehende OSC-Nachrichten (immer Ausgangsport + 1, z. B. 9002 bei Ausgangsport 9001) |
Felder anklicken zum Bearbeiten, Enter zum Bestätigen.
Presets
| Steuerelement | Beschreibung |
|---|---|
| Namensfeld | Preset-Name eintippen |
| ▼ | Gespeicherte Presets als Dropdown öffnen |
| Save | Alle aktuellen Instanzen unter dem Preset-Namen speichern |
| Reset | Alle Instanzen löschen und Standard-Preset laden |
Presets werden im REAPER ExtState gespeichert (projektunabhängig, sitzungsübergreifend persistent).
8. Statusleiste — Zeile 2: Wiedergabe-Steuerung
| Steuerelement | Beschreibung |
|---|---|
| Speed ×N.NN | Globaler Raten-Multiplikator — skaliert alle Instanzraten gleichmässig. Klicken zum Eintippen, Enter bestätigt. |
| BPM | BPM-Sync umschalten. Aus = Schritte/Sekunde. An = Schritte/Taktschlag (folgt REAPER-Tempo). |
| > Fwd / < Rev | Globale Richtung für alle Instanzen. |
| ‖ Pause | Alle Bewegungen einfrieren. Nochmals klicken = weiter. |
| ■ Stop | Alle Instanzen auf Schritt 0 zurücksetzen und sofort pausieren (Wiedergabe startet nicht automatisch). Über ‖ Pause oder Neustart fortsetzen. |
| ⇄ PP | Globalen Pingpong-Modus umschalten — alle Instanzen prallen statt zu wiederholen. |
| ⊙ Sync | Phasen-Akkumulator und Schrittzähler aller ausgewählten Instanzen auf 0 zurücksetzen, um sie zu synchronisieren, ohne nicht ausgewählte Instanzen zu beeinflussen. |
BPM-Modus im Detail
BPM aus: Rate = 2 bedeutet 2 Schritte pro Sekunde, unabhängig vom Tempo.
BPM an: Rate = 1 bedeutet 1 Schritt pro Viertelnote. Bei 120 BPM sind das 2 Schritte/Sek; bei 60 BPM ein Schritt/Sek. Eine Instanz mit 64 Schritten und Rate 1 vollendet einen Zyklus in 64 Viertelnoten (16 Takte in 4/4).
9. Statusleiste — Zeile 3: Globaler Offset und Bewegung
Zeile 3 enthält sechs Scrubber-Slider mit Bereich −2,0 bis +2,0. Horizontal ziehen zum Ändern des Wertes.
Offset X / Y / Z — Globale Translation
Verschiebt alle Instanzpositionen gleichmässig nach allen instanzspezifischen Transformationen. Damit kann das gesamte Kristall im Ambisonics-Raum platziert werden, ohne einzelne Start-Positionen anzufassen.
Beispiel: Offset X = 0,5 verschiebt alle Quellen um 0,5 Einheiten nach rechts.
Move X / Y / Z — Globale Bewegungsrichtung
Fügt allen Instanzen einen zusätzlichen Schritt-Offset überlagert zu ihrem eigenen Offset X/Y/Z hinzu. Damit treibt das gesamte Kristall in eine gewählte Richtung.
Beispiel: Move X = 0,01 addiert pro Schritt 0,01 Einheiten entlang X zu jeder Instanz. Kombination Move X = 0,007 und Move Y = 0,007 ergibt eine Diagonalbewegung.
10. Statusleiste — Zeile 4: Globale Rotation und Zoom
Zeile 4 enthält drei Rotations-Scrubber und einen Zoom-Scrubber, die alle nach instanzspezifischen Transformationen und dem globalen Offset angewendet werden.
Rotation (Pt / Yw / Rl)
Dreht den gesamten Kristall um den Weltursprung. Winkel in Grad, Bereich −180 bis +180.
| Slider | Achse | Wirkung |
|---|---|---|
| Pt (Pitch) | X | Kippt das Kristall vorwärts / rückwärts |
| Yw (Yaw) | Y | Dreht das Kristall links / rechts |
| Rl (Roll) | Z | Rollt das Kristall im / gegen Uhrzeigersinn |
Zoom (×)
Skaliert die gesamte Kristallfigur gleichmässig um den Ursprung — nach der Rotation, vor der Translation. Bereich 0,0–2,0, Neutralpunkt bei 1,0.
| Wert | Wirkung |
|---|---|
| 0,0 | Alle Quellen kollabieren zum Ursprung |
| 1,0 | Keine Änderung (neutral) |
| 2,0 | Figur doppelt so gross |
Der Zoom wirkt in Echtzeit auf die Gittervorschau und den Live-OSC-Ausgang. Den ×-Scrubber horizontal ziehen oder anklicken und einen Wert eintippen.
Alle Slider horizontal ziehen oder anklicken und einen Wert eintippen, dann Enter bestätigen.
Pt/Yw/Rl können auch extern gesteuert werden — siehe §11 Externe Steuerung.
11. Externe Steuerung — OSC-Eingang und MIDI
OSC-Eingang
Wenn die OSC-Brücke verbunden ist (Connect geklickt, Status-Punkt grün), empfängt das Kristall gleichzeitig OSC-Nachrichten auf Ausgangsport + 1 (z. B. Port 9002 bei Ausgangsport 9001). Der Empfangsport wird als in: PORT neben dem Connect-Button angezeigt.
Folgende Nachrichten können von TouchOSC, Max/MSP, OSSIA, SuperCollider oder jedem OSC-fähigen Tool gesendet werden:
| OSC-Adresse | Argumente | Wirkung |
|---|---|---|
/kristall/pitch | <float Grad> | Globalen Pitch setzen (−180…+180) |
/kristall/yaw | <float Grad> | Globalen Yaw setzen (−180…+180) |
/kristall/roll | <float Grad> | Globalen Roll setzen (−180…+180) |
/kristall/rotate | <float pitch> <float yaw> <float roll> | Alle drei gleichzeitig setzen |
Die Werte werden sofort übernommen und überschreiben die Slider. Werte ausserhalb von −180…+180 werden automatisch begrenzt.
Beispiel — Kristall mit TouchOSC drehen:
- Im Kristall-GUI verbinden (Ausgangsport
9001, Ziel127.0.0.1). - In TouchOSC OSC-Ziel auf
127.0.0.1:9002setzen. - Einen Fader auf
/kristall/yaw, Bereich −180 bis +180, zuweisen. - Fader bewegen → Kristall dreht sich in Echtzeit.
MIDI über JSFX-Controller-Brücke
Falls ein Kristall Controller JSFX auf einem Track vorhanden ist, liest das Skript dessen Parameter automatisch:
| JSFX-Slider | Parameter-Index | Bereich | Wirkung |
|---|---|---|---|
| slider6 | 5 | −180…+180° | Globaler Pitch |
| slider7 | 6 | −180…+180° | Globaler Yaw |
| slider8 | 7 | −180…+180° | Globaler Roll |
| slider9 | 8 | −2…+2 | Offset X |
| slider10 | 9 | −2…+2 | Offset Y |
| slider11 | 10 | −2…+2 | Offset Z |
| slider12 | 11 | −2…+2 | Move X |
| slider13 | 12 | −2…+2 | Move Y |
| slider14 | 13 | −2…+2 | Move Z |
| slider15 | 14 | 0…2 | Zoom × |
MIDI-CCs über REAPER’s MIDI-Learn-Dialog oder den FX-Parameter-Lane auf Slider 6–8 für Rotationssteuerung mappen. Für Automation-Envelopes auf Offset, Move und Zoom (Slider 9–15): JSFX in der FX-Kette rechtsklicken → Param → Envelope für den gewünschten Slider aktivieren, dann im REAPER-Envelope-Lane einzeichnen. Die Slider werden jeden Frame ausgelesen, solange das JSFX auf einem Track geladen ist.

12. Eingebaute Presets (Schnellauswahl)
Acht Preset-Schaltflächen am unteren Fensterrand. Jedes Preset löscht alle aktuellen Instanzen und platziert neue. Buttons 1–4 (türkis) sind abstrakte Bewegungslayouts, Buttons 5–8 (bernstein) sind kristallografische Einheitszellenformen.
| # | Preset | Was erstellt wird |
|---|---|---|
| 1 | Cubic | 8 Instanzen an den Ecken eines Einheitswürfels. Jede Ecke pendelt im Pingpong-Modus zum Zentrum (0, 0, 0) und zurück — ein „atmender Würfel"-Effekt. |
| 2 | Tetragonal | Gitter mit gleichem XY-Abstand und anderem Z-Abstand |
| 3 | Hexagonal | 2D-Hexagonalring entlang Z (entspricht typischen Kuppelaufstellungen) |
| 4 | Rnd.Swarm | 20 zufällig in einer Kugel verteilte Instanzen |
| 5 | Orthorhombic | Einheitszelle mit drei ungleichen orthogonalen Achsen (α=β=γ=90°) |
| 6 | Rhombohedral | Einheitszelle mit gleichen Achsen und gleichen nicht-orthogonalen Winkeln (α=β=γ≠90°) |
| 7 | Monoclinic | Einheitszelle mit einer geneigten Achse (α=γ=90°, β≠90°) |
| 8 | Triclinic | Einheitszelle ohne gleiche Achsen und ohne rechte Winkel — maximale Asymmetrie |
13. Erste Schritte — Schnelleinstieg
Schritt 1 — Preset anwenden
Cubic in der Statusleiste klicken. Acht Instanzen erscheinen in der Gittervorschau.
Schritt 2 — Bewegung beobachten
Speed auf ×1,00 belassen, BPM aus. Die Schrittzähler in der Instanzliste zählen hoch.
Schritt 3 — Richtung einstellen
Instanz 1 auswählen. Offset X = 0,02, Offset Y = 0,01, Offset Z = 0 setzen. Diese Instanz bewegt sich nun diagonal in der XY-Ebene.
Schritt 4 — Pingpong-Modus
Mode = Pingpong, Steps = 64. Die Quelle läuft 64 Schritte aus und prallt zurück.
Schritt 5 — Globalen Drift hinzufügen
Den Move X-Slider in Zeile 3 auf ca. 0,008 ziehen. Das gesamte Kristall driftet nun nach rechts, während die einzelnen Instanzen weiterhin pendeln.
Schritt 6 — Kristall drehen
Den Yw-Slider (Yaw) in Zeile 4 ziehen, um das gesamte Kristall um die Hochachse zu drehen. Pt und Rl für zusammengesetzte Orientierungen kombinieren. Die Gittervorschau aktualisiert sich in Echtzeit.
Schritt 7 — OSC verbinden
Host und Port in Zeile 1 eingeben, Connect klicken. Positionen werden in Echtzeit gesendet. Nach dem Verbinden erscheint in: 9002 — dieser Port empfängt externe Rotationssteuerung (siehe §11).
14. Fehlerbehebung
Quellen bewegen sich nicht. Speed > 0 prüfen und Instanz auf Enabled kontrollieren. Im BPM-Modus muss der REAPER-Transport laufen.
Alle Instanzen an derselben Position. Ein Preset anwenden oder manuell unterschiedliche Start-Positionen setzen.
Positionen driften ausserhalb des Arrays. Mode auf Pingpong wechseln oder Bounds mit Mirror-Modus aktivieren.
Move-Slider ändert zu grosse Schritte. Langsam ziehen — der Slider deckt den gesamten Bereich −2 bis +2 ab. Für Feinsteuerung Slider anklicken, Wert eintippen, Enter bestätigen.
OSC verbindet sich nicht. Python-OSC-Brücke (python-osc) prüfen. Host-IP und Port kontrollieren. Bei Erfolg wird der Status-Punkt grün.
OSC verbindet sich nicht (Windows). Drei Punkte prüfen: (1) Python muss im System-PATH stehen — Python neu installieren und „Add Python to PATH" ankreuzen falls es fehlt. (2) Die Windows-Firewall zeigt beim ersten Start einen Dialog — „Zugriff erlauben" klicken. (3) Status-Punkt ist grün, aber keine Bewegung: Host-IP auf 127.0.0.1 prüfen falls AmbiEncoder lokal läuft.
OSC-Eingang (Rotation) hat keine Wirkung. Die OSC-Brücke muss zuerst verbunden sein. Sicherstellen, dass der Controller an Ausgangsport + 1 sendet (Standard: 9002, nicht 9001). Mit einem UDP-Monitor (z. B. Protokol) prüfen ob Pakete ankommen.
Stop-Button pausiert nicht, sondern startet die Wiedergabe. Auf das neueste Skript aktualisieren (v2.2.8) — dieser Fehler bestand nur in frühen Vorversionen.
Siehe auch
- ICST Ambi Motion Map — schrittbasierte 2D/3D-Bewegungsformen
- OSC-Referenz — AmbiEncoder-OSC-Format und Koordinatensystem
- Downloads — Skript-Downloads