ICST Ambisonics Workshop 2026
Csound – 4 Module

10 Dateien · ZHdK ICST
📦 Übersicht
🔵 Modul 1 – Decoder
🟣 Modul 2 – HOA Synthese
🟠 Modul 3 – OSC Bewegung
🟢 Modul 4 – Klangerzeuger
System-Patchbay
Signalfluss aller 4 Module im Überblick
Modul 1 ambisonics_icst_decoder bformenc1 → VST3 Decoder VST3 Modul 2 additive_synth_hoa16 bformenc1 × 16 → 16ch HOA 16 ch Modul 3 pendulum / Lissajous OSCsend XYZ → Port 50001 OSC Modul 4 fof_choir / dust / granulator OSClisten :50002 → Audio ICST AmbiEncoder_64 OSC :50001 · XYZ/AED B-Format HOA Bus (16–64 ch) REAPER Ambi-Bus AmbiDecoder ICST VST3 8/16-ch Speaker 🔊 OSC :50001 → AmbiEncoder (Modul 3) OSC :50002 → Csound Instruments (Modul 4) HOA Audio direkt (Modul 1 & 2) Max/REAPER → AmbiEncoder → Decoder
OSC Port-Übersicht
PortRichtungAdresseArgumenteBenutzt von
50001 → AmbiEncoder /icst/ambi/source/xyz
/icst/ambi/sourceindex/xyz
i ff (index, x, y) oder fff pendulum_12ch, pendulum_waves, ICST_Lissajous16
9001 → AmbiEncoder /icst/ambi/source/aed fff (az, el, dist) ICST_Lissajous_OSC (konfigurierbar)
50002 → Csound /xy ff (vowel 0–1, octDiv 0–4) fof_choir_osc (Empfänger)
50002 → Csound /xyz fff (toneVar, pitch Hz, dustFreq) dust_osc (Empfänger)
50010 → Max /act/scene/target s (scene_name) REAPER → ACT_Circle_Mover_Main
4000 → AmbiEncoder /icst/ambi/source/xyz i ff pendulum_waves_osc (alt. Port)
Module im Überblick
Modul 1 · Einstieg
Ambisonics-Decoder
Komplette Signal-Kette: Csound bformenc1 → ICST AmbiDecoder VST3 → 8 Lautsprecher. Versteht den Workflow Encoding ↔ Decoding.
ambisonics_icst_decoder.csd
Modul 2 · HOA Synthese
Additive Synthese → HOA
bformenc1-Opcode im Detail: 16 Partials an 16 HOA-Kanälen. Dann 30 Partials live per MIDI spielen und Klangfarben erkunden.
additive_synth_hoa16.csd additive_30partials_16ch.csd
Modul 3 · Dynamik
OSC-Bewegung im Raum
Csound rechnet Physik/Geometrie, AmbiEncoder bewegt Quellen. 12 Pendel, Lissajous-Figuren, 16 simultane Quellen.
pendulum_12ch_osc.csd pendulum_waves_osc.csd ICST_Lissajous_OSC.csd ICST_Lissajous16_OSC_AmbiEncoder64.csd
Modul 4 · Kombination
Gesteuerte Klangerzeuger
Csound als OSC-Empfänger: FOF-Chor und Dust extern steuern. Granulator als 16-Kanal Klangquelle. Kombination mit REAPER/Max.
fof_choir_osc.csd dust_osc.csd granulator_16ch.csd
Alle Dateien in diesem Ordner
📁Modul_1_Decoder/
🎵ambisonics_icst_decoder.csdbformenc1 · VST3
📁Modul_2_HOA_Synthese/
🎵additive_synth_hoa16.csd16-Partial HOA · MIDI
🎵additive_30partials_16ch.csd30-Partial · 16ch
📁Modul_3_OSC_Bewegung/
🎵pendulum_12ch_osc.csd12 Pendel · OSCsend :50001
🎵pendulum_waves_osc.csdPendulum Waves · 12 src
🎵ICST_Lissajous_OSC.csdLissajous AED · :9001
🎵ICST_Lissajous16_OSC_AmbiEncoder64.csd16 src XYZ · :50001
📁Modul_4_Klangerzeuger/
🎵fof_choir_osc.csdFOF Vocal · OSClisten :50002
🎵dust_osc.csdStochastisch · OSClisten :50002
🎵granulator_16ch.csdGranular · 16ch
Modul 1 – Ambisonics-Decoder
Komplette Signalkette: Csound → ICST AmbiDecoder VST3 → 8 Lautsprecher

Lernziel

Verstehen wie bformenc1 eine Mono-Quelle in B-Format enkodiert und der ICST AmbiDecoder VST3 diesen für ein Lautsprecher-Array aufbereitet. Zwei Quellen — eine rotierende und eine statische — demonstrieren den Unterschied.

Voraussetzungen

  • Csound 6.18+ mit vst4cs Opcode-Plugin installiert
  • ICST AmbiDecoder.vst3 in /Library/Audio/Plug-Ins/VST3/ICST Ambisonics Plugins/
  • Csound-Output auf 8 Kanäle konfiguriert (Interface oder DAW)

Schritt-für-Schritt

  • 1.
    Cabbage (oder Csound direkt) starten → Modul_1_Decoder/ambisonics_icst_decoder.csd öffnen.
  • 2.
    VST3-Pfad prüfen: Zeile vst3init – Pfad auf dein System anpassen falls nötig. Standard: /Library/Audio/Plug-Ins/VST3/ICST Ambisonics Plugins/AmbiDecoder.vst3
  • 3.
    Render starten → Instrument 1 erzeugt rotierende Quelle (Sinuston + Obertöne), Instrument 2 eine statische Quelle rechts-vorne.
  • 4.
    Beobachten: bformenc1-Ausgabe (W, X, Y, Z) → AmbiDecoder verteilt auf 8 Kanäle → Lautsprecher-Ortung hörbar.
  • 5.
    Experiment: Azimut-Wert in Instrument 2 von 0.5 auf 1.0, 2.0, 3.14 etc. ändern und Effekt beobachten.
💡 Schlüssel-Opcode: bformenc1 aW,aX,aY,aZ, aSig, kAzimuth, kElevation — Azimuth in Radians (0=vorne, π/2=links, π=hinten)

Kerncode-Ausschnitt

; FOA Encoding einer Sinusquelle mit rotierendem Azimut
instr 1
  kAzimuth phasor 0.1           ; langsame Rotation (0.1 Hz)
  kAzimuth = kAzimuth * 6.2832  ; → 0..2π
  aSig     oscil  0.5, 440
  aW,aX,aY,aZ bformenc1 aSig, kAzimuth, 0
  vst3audio iVST, aW,aX,aY,aZ  ; → AmbiDecoder
endin
Modul 2 – HOA Additive Synthese
16 bis 30 Partials, jede an eigenem Azimut-Platz, 3rd Order HOA (16 Kanäle)

Lernziel

Additive Synthese und Ambisonics-Encoding direkt verbinden: Jeder Oberton hat seine eigene Raumposition. Klangfarbe ≡ Klangbild im Raum.

A: additive_synth_hoa16.csd – 16 Partials auf HOA 3rd Order

  • 1.
    In Cabbage öffnen → MIDI-Keyboard anschliessen (oder «Play» Button im GUI)
  • 2.
    Positionen: 16 Partials verteilt auf 0°, 22.5°, 45°, …, 337.5° — gleichmässig um den Hörer.
  • 3.
    LFO-Modus wählen: Tremolo / Vibrato / Both → moduliert Amplitude/Frequenz pro Partial individuell.
  • 4.
    Inharmonicity-Koeffizient (B) erhöhen → Partiell-Frequenzen leicht verstimmen → Klang wird rauer, räumlich diffuser.
  • 5.
    16-Kanal-Ausgang → direkt in REAPER Ambi-Bus routen (HOA 3rd Order FuMa).
ℹ️ Output-Format: HOA FuMa (W, X, Y, Z, R, S, T, U, V, K, L, M, N, O, P, Q) — 16 Kanäle = 3rd Order

B: additive_30partials_16ch.csd – 30 Partials, MIDI-spielbar

  • 1.
    In Cabbage öffnen → MIDI-Keyboard: Grundton bestimmt alle Partial-Frequenzen.
  • 2.
    XY-Pad: X steuert Partial-Amplituden-Spread, Y den Basis-Level.
  • 3.
    Preset-Buttons: «Harmonic» → natürliche Obertöne, «Randomize» → zufällige Partial-Ratios, «Zero» → stille Partials.
  • 4.
    Partials 17–30 wrappen auf Kanäle 1–14 (summiert) → dichteres Klangbild als Modul 2A.
  • 5.
    Reverb-Send (Global Reverb per reverbsc) auf allen 16 Kanälen gleichzeitig aktiv.
💡 Vergleich der beiden Dateien: hoa16 hat Ambisonics-Encoding (bformenc1), 30partials sendet direkte Kanal-Zuweisungen. Zwei verschiedene Ansätze für mehrkanal Synthese.
Modul 3 – OSC Bewegung im Raum
Csound berechnet Trajektorien → OSC → ICST AmbiEncoder_64 bewegt die Quellen

Lernziel

Csound als räumlichen Algorithmus-Generator: Physikmodelle und Lissajous-Figuren liefern XYZ-Koordinaten, die via OSC den AmbiEncoder in Echtzeit steuern.

⚠ ACT_Circle_Mover_Main.app muss vor den Csound-Patches gestartet sein und auf Port 50001 hören.

A: pendulum_12ch_osc.csd – 12 Pendel im Kreis

  • 1.
    App starten → Port-Nummer im GUI einstellen (Standard: konfigurierbar). AmbiEncoder auf 50001 hören.
  • 2.
    12 Pendel: jedes an 30°-Abstand (0°, 30°, 60°, …). Individuelle BPM-Frequenzen → Schwebungen entstehen.
  • 3.
    Damping-Zeit anpassen: kurze Dämpfung → schnelle Pendel-Abklingzeit, langer → anhaltende Bewegung.
  • 4.
    OSC-Rate: 10 Hz (alle 100 ms) → ausreichend für wahrnehmbare Bewegung.
  • 5.
    Audio-Output: Stereo-Monitor (nur Kontrolle) — räumliches Signal kommt vom AmbiEncoder.

B: pendulum_waves_osc.csd – Interferenz-Patterns (12 Quellen)

  • 1.
    Port auf 4000 oder 50001 stellen (im GUI).
  • 2.
    Speed erhöhen: Pendel-Frequenz-Schritte werden grösser → Interferenz-Muster ändern sich schneller.
  • 3.
    Sound-Auswahl: «Ping» (Sinuston) oder «Sample» (Audiodatei laden). 12 diskrete Ausgangskanäle.
  • 4.
    Swing-Mapping: X-Achse der Pendelschwingung → Raum-X; Pendel-Index (1–12) → Raum-Y-Tiefe.
  • 5.
    «Record Out» aktivieren → WAV-Datei mit Timestamp wird gespeichert.
ℹ️ Pendulum Waves erzeugen charakteristische Phasenmuster: Alle Pendel starten synchron, divergieren und kehren nach exakter Zeit wieder zur Synchronisation zurück.

C: ICST_Lissajous_OSC.csd – Lissajous-Figur (1 Quelle, AED)

  • 1.
    Cabbage-Plugin starten → GUI-Port auf 9001 (oder was AmbiEncoder hört).
  • 2.
    Freq X / Freq Y (1–12): Verhältnis bestimmt die Lissajous-Form. 1:1 = Kreis, 2:1 = ∞-Figur, 3:2 = komplexere Kurve.
  • 3.
    Speed (logarithmisch): steuert wie schnell die Quelle die Figur durchläuft.
  • 4.
    Distance: setzt den Radius der Figur (0.0–1.0). Kleine Werte → enge Bewegung um Zentrum.
  • 5.
    OSC-Adresse: /icst/ambi/source/aed mit Azimuth, Elevation, Distance.

D: ICST_Lissajous16_OSC_AmbiEncoder64.csd – 16 simultane Quellen

  • 1.
    Score-basiert: 16 Instrumente mit unterschiedlichen Lissajous-Parametern laufen parallel.
  • 2.
    OSC: 50001, Adresse /icst/ambi/sourceindex/xyz — AmbiEncoder muss 16 Sources unterstützen.
  • 3.
    Shape-Varianten: 4 Morphing-Varianten (via Score-Parameter) → verschiedene Kurven-Familien.
  • 4.
    Z-Depth: Elevation-Kontrolle unabhängig pro Quelle.
✓ Maximale Komplexität: 16 Quellen gleichzeitig, alle in Bewegung — perfekt als Abschluss-Demo für Modul 3.
Modul 4 – Gesteuerte Klangerzeuger
Csound als OSC-Empfänger: FOF-Chor, Dust und Granulator extern steuern

Lernziel

Csound als «Instrument», das von aussen — aus Max, REAPER, einem anderen Csound-Patch oder einem Controller — gesteuert wird. OSC-Empfang kombiniert mit Ambisonics-Routing.

A: fof_choir_osc.csd – FOF Vokal-Synthesizer

  • 1.
    In Cabbage als Plugin laden (VST3/AU) oder standalone starten. Csound hört auf 50002.
  • 2.
    5 Stimmtypen: Bass, Tenor, Countertenor, Alto, Soprano — per Dropdown wählen. Jede hat eigene Formant-Tabellen.
  • 3.
    OSC steuern via Max oder Python:
    Adresse /xy, 2 Floats: vowel (0.0–1.0 = A→E→I→O→U), octDiv (0–4 = Oktav-Division)
  • 4.
    MIDI-Kontrolle: CC1 → Vibrato/Tremolo, CC2 → Vokal-Morphing. Keyboard → Tonhöhe.
  • 5.
    Kombinations-Beispiel: pendulum_waves steuert räumliche Position via AmbiEncoder, ein separater Patch sendet auf Port 50002 die Vokal-Parameter → Chor bewegt sich und verändert gleichzeitig seinen Vokal.
💡 FOF (Fonction d'Onde Formatique) ist Csounds Vokal-Synthesizer-Opcode: 5 Formant-Filter pro Stimme, natürliche Vokalklang-Simulation.

OSC-Testbefehl (Python)

import socket, struct

def osc(addr, *floats):
    def pad(d): return d + b'\0'*((4-(len(d)%4))%4)
    p  = pad(addr.encode()+b'\0')
    p += pad((','+'f'*len(floats)).encode()+b'\0')
    p += struct.pack(f'>{len(floats)}f', *floats)
    socket.socket(socket.AF_INET,socket.SOCK_DGRAM).sendto(p,('127.0.0.1',50002))

# Vokal = 0.3 (zwischen A und E), Oktav-Division = 1
osc('/xy', 0.3, 1.0)

B: dust_osc.csd – Stochastischer Generator

  • 1.
    In Cabbage laden → 50002 hört auf /xyz, 3 Floats.
  • 2.
    X (0.0–1.0): ToneVar = Tonhöhen-Variation der Impulse. 0 = alle gleich, 1 = maximale Streuung.
  • 3.
    Y (0.1–20000 Hz): Pitch / Filter-Cutoff. Niedrig = tiefe dunkle Impulse, hoch = Zischen.
  • 4.
    Z (−1.0–+1.0): Dust-Frequenz. Negativ = sehr sparse (einzelne Clicks), positiv = dichtes Rauschen.
  • 5.
    Kombination mit Modul 3: pendulum_waves sendet XYZ für AmbiEncoder (Port 50001) + gleichzeitig an Port 50002 → Pendel-Position steuert auch die Klang-Textur.
ℹ️ Beide Patches (fof_choir + dust) können gleichzeitig laufen — unterschiedliche OSC-Adressen, gleicher Port 50002. Sender muss entsprechend beide Adressen beschicken.

C: granulator_16ch.csd – Sample-Granulator (16 Kanäle)

  • 1.
    In Cabbage laden → Audiodatei via File-Chooser im GUI laden.
  • 2.
    Grain Size: 10–500 ms. Klein = körnig/perkussiv, gross = fliessend/pitched.
  • 3.
    Density: Anzahl gleichzeitiger Grains. Hoch = dichter Klang-Teppich.
  • 4.
    Spread: Kanal-Verteilung der Grains auf 16 Kanäle. 0 = alle auf Ch1, 1 = gleichmässig verteilt.
  • 5.
    Envelope: Hann / Gaussian / Trapezoid / Ramp — Grain-Hüllkurve wählen.
  • 6.
    16-Kanal-Ausgang → AmbiDecoder oder 16-Kanal-Interface routen.
💡 Granulator hat kein OSC — wird manuell über das Cabbage-GUI gesteuert. Als Klangquelle für Modul-4-Kombinations-Patches ideal.

Kombinations-Szenario: Alle Module zusammen

Signal-Routing
pendulum_waves → 50001 → AmbiEncoder
pendulum_waves → 50002 → fof_choir
Lissajous16 → 50001 → AmbiEncoder
granulator → 16ch → REAPER Bus
REAPER → 50010 → Max Scenes
Effekt
12 Pendel bewegen sich im Raum
+ Vokal ändert sich mit Position
+ 16 Lissajous-Quellen überlagert
+ Granulat-Teppich als Basis
+ Scene-Wechsel via REAPER-Marker