Programmieren für Tonmeister mit Max
Text und Bilder: Jonas Kieser
Text und Bilder: Jonas Kieser
Die Wurzeln von Max reichen zurück bis in die 1980er Jahre, als Miller Puckette am Pariser Institut IRCAM begann, die Grundlagen dafür zu legen, was heute als eine der meistgenutzten Plattformen für audiovisuelle Programmierung gilt. Im Laufe der Jahre hat sich Max – durch die Übernahme und Weiterentwicklung durch Cycling ’74 und später durch die Übernahme der Ableton AG und die Integration in Ableton Live als Max for Live (M4L) – zu einer robusten und flexiblen Plattform etabliert, die sowohl für kreative Neueinsteiger als auch für erfahrene Programmierer geeignet ist.
Max ist sowohl Name der visuellen Programmiersprache als auch der Entwicklungsumgebung. Der Programmcode, bzw. Signalfluss (Patch) entsteht durch das Verbinden (patchen) von vorgefertigten Objekten, die jeweils eine Funktionseinheit darstellen.
Mit den Objekten der Programmiersprache Max werden primär Steuerdaten (z.B. MIDI) verarbeitet. Objekte der MSP-Sprache, operieren in Audiorate (z.B. 48kHz) und bieten Funktionalitäten zur Audiosignalverarbeitung (z.B. Oszillatoren, Filter). Ebenfalls in Audiorate operieren Objekte der Gen-Sprache, die sich von MSP-Objekten dahingehend unterscheiden, Audiosignale auf Sample-Basis und nicht auf Block-Basis zu prozessieren. Samplegenaue Verarbeitung ist beispielsweise für die Entwicklung von Filtern oder Halleffekten wichtig. Jitter-Objekte sind auf Matrix-Operationen ausgelegt und eignen sich für die Bildsignalverarbeitung.
In der Entwicklungsumgebung Max können neben den visuellen Programmiersprachen Max, MSP, Jitter und Gen auch textbasierte Sprachen zum Einsatz kommen: JavaScript für Graphik und Zugriff auf die Max-API (Programmierschnittstelle), C/C++ in Externals (eigens geschriebene Max-Objekte) sowie Java. Für den kreativen Prozess wertvoll ist die Echtzeit-Feedback-Schleife, bei der Änderungen am Patch unmittelbar hörbar bzw. sichtbar sind. Um diese zu realisieren verwendet Max zur Ausführung der MSP-Sprache Konzepte wie die Interpretation vorkompilierter Binaries zur Laufzeit und für Jitter und Gen verschiedene Arten von JIT (Just-in-time)-Kompilierung.
Die Entwicklungsumgebung Max ist Interpreter, bzw. Kompiler für die Patches, womit deren Plattformunabhängigkeit einhergeht: Max Patches können ohne weiteren Aufwand sowohl unter Windows als auch unter macOS ausgeführt werden. Aufgrund dieser Architektur sind die Optimierungsoptionen von Max-Patches deutlich geringer als bei kompilierten Sprachen, wie z.B. C++, was sich unter Umständen in einer geringeren Ausführungsgeschwindigkeit bemerkbar macht.
Es gibt viele alternative Programmiersprachen für Multimedia. Nachfolgend eine unvollständige Auflistung:
Zudem werden viele der allgemeinen Programmiersprachen für die Audioprogrammierung verwendet. Das bereits genannte C++ bekommt dabei Konkurrenz von ähnlich effizienten, jedoch robusteren Sprachen wie Rust und Zig. Beliebt sind ebenfalls Python und die kommerzielle Programmiersprache und Entwicklungsumgebung Matlab. Durch das Hinzufügen von audiospezifischen Libraries und Packages lässt sich der Funktionsumfang der allgemeinen Sprachen für die Audioprogrammierung erweitern.
Bei einer digitalen Musikproduktion können mit Max Synthesizer, Effektprozessoren, Sequenzer und andere musikalische Werkzeuge erstellt werden. In der Entwicklung von interaktiven Systemen für Live-Musik- und Theateraufführungen findet Max ebenso Anwendung wie auch in der Gestaltung von interaktiven audiovisuellen Installationen für Ausstellungen oder öffentlichen Räumen.
Auch aus dem Bereich der Forschung und Entwicklung, beim Experimentieren mit neuen Technologien in Audio, Musik und interaktive Medien sowie auch bei der Vermittlung von Konzepten der Programmier- und Signalverarbeitung ist Max nicht mehr wegzudenken. In der Industrie wird Max für kundenspezifische Software primär in der Entwicklung von Prototypen eingesetzt. Im Folgenden will ich mit verschiedenen Beispielen verdeutlichen, wie vielfältig die Möglichkeiten mit Max sind:
Beim prozeduralen Sound-Design werden Klänge in Echtzeit durch Algorithmen erzeugt. Ursprung des Klangs sind beispielsweise Rauschgeneratoren oder Oszillatoren. Über Parameter können Sounddesigner den Klang interaktiv steuern und theoretisch unendliche Variationen erzeugen. Anwendung findet das prozedurale Sounddesign in Game Audio und Virtual Reality sowie bei der Erstellung von Sound-Effekten für Medienproduktionen. Zu Testzwecken und unter Verwendung des 2022 vorgestellten Max-Subsystems RNBO (gesprochen: Rainbow) habe ich einen prozeduralen Feuer-Sound-Effekt umgesetzt, basierend auf Andy Farnell: Designing Sound (siehe Ressourcen). Der Klang des Feuers besteht aus drei Komponenten: Hiss, Crackles und Lapping. Der Algorithmus setzt sich im Wesentlichen aus Rauschgeneratoren und kaskadierten Filtern zusammen. Die Interaktivität besteht aus einem Intensitäts-Slider, der das Mischverhältnis fünf unterschiedlich parametrisierter Feuer-Instanzen regelt.
RNBO verhält sich als visuelle Sprache ähnlich zu Max. Der Unterschied besteht in den Exportoptionen des gepatchten Signalflusses: Dieser kann als AU/VST3-Plug-in, für Raspberry Pi, als C++-Quelldatei sowie für Browser- Anwendungen exportiert werden. Der Plug-in-Export wird mit dem weit verbreiteten C++-Audio-Framework JUCE realisiert, das auch für die Entwicklung von Max verwendet wird.
Binaurales 3D-Audio klingt mit Head-Tracking sofort besser. Eine einfache Möglichkeit, dieses dynamische binaurale 3D-Audio- Rendering zu realisieren, besteht darin, die Webcam eines Rechners zu verwenden. 3D-Audio lässt sich in Max beispielsweise mit dem Drittanbieter Package Spat umsetzen; dieses beinhaltet Objekte zu Panoramisierung und Rendering. Mit Hilfe der in Max integrierten JavaScript-Runtime node.js kann über das Bild der Webcam die Kopfposition erfasst werden. Die Rotationsdaten werden in Form von eulerschen Winkeln als OSC (Open Sound Control)-Nachrichten formatiert über UDP (User Datagram Protocol) zum Rendering an den 3D-Audio-Patch gesandt.
Im Rahmen meiner Abschlussarbeit habe ich einen Prototypen eines 3D-Audio-Wavetable- Synthesizers entwickelt. Dabei geht es um die Erforschung des klanggestalterischen Potentials eines Software-Synthesizer-Plug- Ins, welches die Potentiale digitaler Klangsynthese für das 3D-Audio-Panning nutzt. Mittlerweile wurde von der portugiesischen Firma Sound Particles mit SkyDust 3D ein ähnliches Konzept als kommerzielle Software entwickelt. Für die Klangforschung- und Entwicklung war Max die ideale Plattform. Mit Hilfe des Exports als M4L-Device, kann der Synthesizer innerhalb der DAW Ableton Live genutzt und das Zusammenspiel mit anderen Klangelementen getestet werden.
Beim 3D-Synthesizer-Projekt bin ich an eine Grenze der Max-Objekte gestoßen: Mit dem [2d.wave~] Objekt kann man zwar durch mehrere Wavetables morphen, der im Objekt enthaltene Oszillator ist aber nicht Aliasingfrei. Glücklicherweise stellt Cycling 74‘ mit der Max API und dem min-devkit Frameworks zur Verfügung, um mit C, bzw. C++ eigene Objekte (Externals) zu schreiben. Dabei lassen sich neben Signalverarbeitungsalgorithmen auch UI-Elemente unter Verwendung der OpenGL-Spezifikation entwickeln. So war es mir möglich, ein External zur aliasing-freien, morphbaren Wavetable-Synthese inklusive Visualisierung zu schreiben.
Bleiben beim Patchen in Max Fragestellungen der Synchronisierung von Threads erspart, müssen beim Programmieren der Externals im Audio-Thread lock-freie Prinzipien beachten und Methoden zum Datenaustausch zwischen Audio- und Low-Prio-Thread angewandt werden (z.B. lockfree queues, atomare Operationen, etc.).
Pro-Audio-Software-Prototype Bei Impulse Audio Lab wurde der MVP der Fahrsound-Design-Software EVx Suite in Max gebaut. Bei der Entwicklung waren überwiegend Sound-Designer beteiligt, womit Max als zugängliche Entwicklungsumgebung eine gute Wahl darstellte. Wichtig bei komplexen Patches, an denen mehrere Personen gleichzeitig arbeiten, ist eine klare Struktur. Dabei hilft die Trennung von UI-Elementen und DSP-Blöcken sowie die Befolgung grundlegender Programmier-Prinzipien, wie die Zerlegung des Codes in kleine, einfach verständliche und wiederverwendbare Funktionseinheiten.
Die in den Beispielen beschrieben Funktionalitäten stellen nur einen Teil von dem vor, was mit Max möglich ist. Darüber hinaus können beispielsweise Arduino Boards über serielle Kommunikation angesteuert, mit Mira Benutzeroberflächen zur Steuerung von Max-Patches mit dem iPad entwickelt und mit den RAVE (Realtime Audio Variational neuralen Audiosynthese durchgeführt werden. Abbildung 8 gibt eine Übersicht zu den technologischen Möglichkeiten in der Entwicklungsumgebung Max.
Da durch das Einbinden von C++-APIs unbegrenzte Möglichkeiten zur Integration von Technologien in Max besteht, kann unmöglich der vollständige Funktionsumfang abschließend beschrieben werden.
Neben den besprochenen Vorteilen gibt es ein paar Einschränkungen, wobei diese subjektiv und auf eigener Erfahrung basierend eingeschätzt sind.
Bei der kommerziellen Verwertung von in Max entwickelten Stand-Alone-Anwendungen, stellen mangelnde Kopierschutzmöglichkeiten ein Problem dar. Kopierschutz steht, abgesehen von den technischen Hürden in der Implementierung, in einem Gegensatz zu dem von der Max-Community gelebten offenen Patch Austausch.
Die mangelnden Optimierungsoptionen machen sich v.a. bei komplexen Patches bemerkbar. Die Versionskontrolle (mit z.B. Github) ist aufgrund des visuellen Programmcodes schwer handhabbar. Automatisiertes Testing (z.B. unit tests) und automatisiertes Deployment (z.B. Git CI) ist mit Max nicht möglich. Über die Code-Export Optionen von Gen und RNBO können aber gepatchte Algorithmen in mit C++ entwickelter Software weiterverwendet werden.
Max muss sich als proprietäre Software den Vorwurf gefallen lassen, dass Objekte eine Blackbox darstellen. Durch den RNBO Code- Export sind die Algorithmen in den Objekten mittlerweile transparenter. Zudem zählt das Verarbeiten von Offline- Daten – alles, was keine Echtzeit Control-, Audio- oder Videodaten sind, z.B. Dataframes –nicht zu den Stärken von Max.
Der Einstieg in die Audioprogrammierung lohnt sich für Tonmeister in vielerlei Hinsicht – kreativer Ausdruck, technische Innovation und die Monetarisierung eigens entwickelter Software bzw. die Erweiterung des eigenen Dienstleistungsportfolios bieten Potential.
Max stellt dabei eine benutzerfreundliche Entwicklungsumgebung dar, die ein guter Ausgangspunkt für das Lernen und Entdecken weiterer Technologien und Sprachen ist.
Ressourcen für den Einstieg und zur Weiterbildung:
Jonas Kieser hat die Grundlagen der Audioprogrammierung mit Pure Data und SuperCollider am IEM in Graz erlernt und für seine Abschlussarbeit in Audiovisuelle Medien an der HdM Stuttgart den Prototyp eines 3D-Audio Wavetable-Synthesizer mit Max/MSP programmiert. Seit zwei Jahren ist er als Entwickler bei Impulse Audio Lab tätig und arbeitet dort an intelligenten Algorithmen zur Audio-Signalverarbeitung für Automobile und Elektronik.