Replicant A, Teil 3
Kapitel 9: Die Modulationsmischer
Damit sie nicht so viel Fläche in Anspruch nehmen wie ein mittlerer Kleinstaat, greifen wir hier wieder zu Stacked Macros. Die Umschalter dafür sollen waagerecht auf das Panel – nicht einfach in Reaktor, der ja nur über senkrechte Schalterreihen verfügt. Wir realisieren das mit Mouse Areas, die wir über einen Merger und ein Snap Value in den Panel Index routen (das Snap ist nötig, damit der aktuelle Wert mit einem Snapshot gespeichert wird).
Darüber legen wir eine Beschriftung mit Text-Modulen und hinterleuchten die Areas mit Lamps, die wir in ein Macro schachteln, damit sie im Hintergrund bleiben. Das hat sogar einen leichten 3D-Look, den ich für die Wellenform-Schalter bei den Oszis abgekupfert habe (dort ist die Beschriftung in den Lamp-Skins enthalten):
Die Mischer kann man nun verschieden gestalten, ich habe vier Eingangszüge für jeden vorgesehen und zu gänzlich unanalogen rein numerischen Intensitätsreglern gegriffen, optisch nicht sehr ansprechend, aber platzsparend. Man kann natürlich auch die Regler der Zahlenfelder wieder einblenden, aber das ist nicht unbedingt übersichtlicher und braucht viel mehr Fläche.
Das Routing der Modulatoren zu den Mischereingängen realisieren wir mit Sends und Receives. Die Send-Ausgänge erscheinen automatisch und drahtlos in allen gesetzten Receives. Das erspart viel Strippenzieherei, und die Receives können gleich als Auswahlmenüs auf dem Panel dienen. Nur die Audio-Modulationsquellen routen wir nicht so, denn sonst schalten alle an ein Receive angeschlossenen Module in den Audio-Modus und treiben die Prozessorlast gewaltig nach oben, die reinen Event-Module quittieren den Dienst.
Die Receives haben ebenso wie die Schalter den Vorteil, dass sie die hinter ihnen liegenden Module nur einschalten, wenn sie diese anwählen. Nicht angewählte sind dann inaktiv und brauchen auch keine Rechenleistung.
Wir brauchen für jeden Mischerzug drei Receives, die jeweils die unipolaren, bipolaren und invertierten Signale liefern. Nur eines ist sichtbar und Master der anderen zwei, schaltet sie also mit um. Die Sortierung ist natürlich etwas mühsam, aber das ist in der aktuellen Version 5.5.1 entscheidend verbessert worden, man kann nun per Doppelklick und Zahleneingabe die Reihenfolge festlegen. Um ein Send in der Receive-Liste zu deaktivieren, muss man das „Use“-Feld gänzlich löschen.
Man muss das nur einmal machen und kann die Receives dann kopieren. Dabei ist es zwingend notwendig, Masters und Slaves zusammen und mit abgeschalteten „automatic use of new sends“ zu kopieren, sonst ist die Koppelung futsch und/oder man hat man alle in den Listen deaktivierten Sends wieder aktiv.
In der aktuellen Version ist Reaktor leider recht zickig und verabschiedet sich manchmal kommentarlos, wenn man die Receives/Sends anschließt. Vorher speichern hilft, die Selbstbeherrschung zu wahren. Am Besten sogar mit fortlaufenden Nummern – ich hatte bei den Arbeiten an diesem Synth beim Laden einmal die herzerfrischende Meldung: Not a valid File. Stundenlanges Gebastel dahin, danke auch …
Kopiert man Macros mit vielen Receives, kann der Vorgang auch schon mal ein paar Minuten dauern, das ist leider immer noch so und Reaktor zeigt dabei nicht einmal eine Sanduhr, sondern ist völlig eingefroren. Nicht abschießen, sondern warten.
Noch ein kleiner Tipp: Der eklige kleine Versatz zwischen gesetzten und kopierten Modulen, der sich manchmal ergibt, lässt sich dadurch beseitigen, dass man alle Module in einem Macro mit Strg-A selektiert und dann mit den Pfeiltasten der PC-Tastatur ein Stückchen verschiebt. Das ist reine Kosmetik, aber es sieht dann ordentlicher und übersichtlicher aus.
Der Umschalter für Unipolar/Invertiert/Bipolar ist als unsichtbarer Slave eines Reglers eingerichtet, und für den Regler habe ich eine platzsparende dreistufige Bitmap gebastelt, so dass er als per Mausschub bedienbarer Schalter funktioniert. Bei solch einer Koppelung von Reglern und Schaltern ist darauf zu achten, dass die Umschaltung von Bitmap und Schalterstellung übereinstimmt.
Die Skin-Funktion ist gar nicht so kompliziert, man muss lediglich mit irgendeinem Grafikprogramm die Bilder für die Schalter/Reglerstellungen neben- oder untereinander pinseln und das dann als Bitmap abspeichern (Vorlagen kann man mit Alt-Druck aus Reaktor kopieren). Beim Import legt man mit der Höhen/Breitenangabe fest, wie viele Stellungen es sein sollen und ggf. die sonstigen Parameter. Für Regler ist das sehr aufwändig, da man ja alle Reglerpositionen abbilden muss, aber für Schalter ist eine zweistufige Bitmap schnell gezaubert und meistens auch schicker als das bordeigene Design. Außerdem kann man die Beschriftung platzsparend auf die Schaltflächen setzen. Bei mehrstufigen Schaltern geht das leider nicht, da muss man zu Regler-Schalter-Kopplung greifen und wie oben beschrieben verfahren bzw. Mouse Areas wie bei den Modmixer-Umschaltern verwenden.
Nach dem Umschalter für die drei Modulator-Amplituden folgt der Intensitätsregler, bei Tonhöhe mit einem Einstellbereich von plus/minus 12,7 Halbtönen, dazu kommt noch ein x-Button, der die Modulation verzehnfacht. Bei der Tonhöhenmodulation gibt es so zwei Einstellbereiche von 12,7 und 127 Halbtönen, einen Fein- und einen Maximalbereich.
Andere Parameter werden mit +/- 100% angesteuert und mit dem x-Button verdoppelt, damit man bipolare Parameter mit einem unipolaren Modulator komplett durchfahren kann wenn gewünscht.
Manche sind entsprechend der speziellen Zielparameter skaliert, wie z.B. der dB-Regler des 24dB-Filters, dort sind es 18dB (6dB ist der „Nullwert“, 24 das Maximum). Der x2-Schalter ist da natürlich redundant, aber ich habe ihn einfach mal dringelassen.
Die einzelnen Modulationen und die Gesamtmodulation für jeden Parameter machen wir abschaltbar, das ist für Kontrollzwecke sehr praktisch. Den Hauptschalter gibt es zweimal, einmal im Mischer selbst und zum anderen bedienfreundlich direkt neben dem Parameter-Regler, auf dem Panel sind das die Achteckigen mit + und x – Symbol (+ für additive, x für multiplikative Mischer). Die zwei sind über Kreuz gekoppelt, jeder ist des anderen Master und Slave. So kann man die Modulation schnell mal abschalten, wo man gerade herumregelt, und auch, wenn der Mischer gerade ausgeblendet ist.
Den restlichen Platz belegen wir mit einer anschaulichen Grafik und ein paar Kontroll-LEDs, die anzeigen, ob der Mischerkanal ein positives, negatives oder gar kein Signal ausgibt. Blinkende Lämpchen machen sich immer gut und sind auch nützlich bei komplexen Modulationen.
Beim Amplifier verwenden wir einen unipolaren multiplikativen Mischer mit Top-Down-Intensitätsregelung. Hier wäre eine Skalierung in dB angebracht, aber da wir das überblendbar von linear zu exponentiell haben (in jedem Mischerzug separat), bleiben wir bei Prozenten.
Das ist etwas komplexer, denn hinter dem Wahlmenüs und -schaltern wird erst mal Top-Down-geregelt mit von 1 subtrahierten unipolaren Signalen bzw. invertierten bipolaren für negative Modulation (sie sind also gegenphasig, nicht negativ), dann geht es durch einen einstellbaren Exponentiator.
Die ON-Schalter für die Kanäle und den Mischerausgang schalten im OFF-Zustand eine 1 auf den Multiplier, denn bei einer 0 wäre ja sonst alles auf Null gesetzt. Die LEDs geben wieder den Ausgangszustand an, hier ist aber zusätzlich die 1 als weiß definiert. Damit man die Modulationen mitsamt Exponentialisierung besser im Blick hat, habe ich noch eine kleine Pegelanzeige eingebaut.
Um den Mischer zu durchschauen, spielt man am Besten eine Weile damit herum und probiert verschiedene Einstellungen aus. Fast jede Modulation ist machbar, nur über 0 dB bzw. Faktor 1 hinaus kann man nicht modulieren. Dafür muss man Modulation und Level miteinander abgleichen. Und: Bipolare Modulationen werden durch den Limiter abgeschnitten, wenn ihre Amplitude größer ist als der Modulationsbereich, also bei maximaler Auslenkung ab 50% Intensität.
Die frei belegbaren Mod Mixer sind so ausgelegt, dass man bei jedem Mischerzug wählen kann, ob er addieren oder multiplizieren soll. Der Ausgang eines Zuges wird mit dem nächsten verrechnet, und wie bei einer Rechenaufgabe ergibt sich von oben nach unten das Endergebnis. Wird ein multiplikativer Zug abgeschaltet, hat er als Output eine 1, damit er die vorigen nicht nullt.
Hier gibt es auch Aussteuerungsanzeigen statt der einfachen LEDs, um die Berechnung ein wenig anschaulicher zu machen.
Die vielen Anzeigen im Instrument haben einen Nachteil: Sie verursachen kurze Prozessorlastspitzen beim Notenwechsel. Das kann sich bei hoher Last in Form von Aussetzern bemerkbar machen, vor allem bei sehr niedrigen Latenzen. Deshalb machen wir sie zentral abschaltbar, indem wir die Voice Number auf Null setzen. Dann sind alle Anzeigen auf dem letzten Wert eingefroren bis auf die Scopes, die separat schaltbar sind.
Die Prozessorlast, die durch Events erzeugt wird, zeigt Reaktor mit der gestrichelten Linie im CPU-Display rechts oben an. Wenn sie mehr als 50% erreicht, kann es schon knacksen.
Mein Büro-PC mit einfachem Prozessor fängt da früh an zu knistern, auch wenn die eigentliche Last noch moderat ist. Mein Laptop mit Dual-Core Prozessor meistert das souveräner, offensichtlich hat NI darauf geachtet, auf solchen Rechnern die Event- und Audioberechnungen auf die Kerne zu verteilen.
Hallo Holger,
vielen Dank für deine sehr umfangreiche Reihe über Reaktor. Ich habe bisher nur quer lesen können und einen kurzen Blick in die Struktur geworfen; trotzdem kann man unschwer erkennen, dass viel Arbeit dahinter steckt. Ich werde noch intensiv nachlesen.
Mir ist aufgefallen, dass du an genau den Stellen über REAKTOR Kritik äußerst, an denen es um Event-Verarbeitung geht.
Dies ist kein Wunder, da du, so weit ich das überblicke, ausschließlich auf dem Primary-Level arbeitest.
Hier ist die Reihenfolge der Events nun mal nicht (logisch) gleichzeitig, sondern „nur” sequentiell.
Die Reihenfolge, mit der Events verarbeitet werden, ist hoch komplex und auf der primary-Ebene nur schwer und umständlich zu kontrollieren.
Nicht alles, was logisch hintereinander ausgeführt erscheint, hat auch genau diese Reihenfolge.
Zu unterscheiden sind GUI-events, die völlig unabhängig zu jeder Zeit geschehen, audio-basierte Events (meist getaktet mit 400Hz) und natürlich audio-getaktete events mit sample-Rate 44100Hz z.B.
Wenn man absolute (und eher einfache) Kontrolle über die Reihenfolge von Events haben möchte, muss man meiner Ansicht nach auf die Core-Ebene übergehen.
Nichtsdestotrotz ist dein Ensemble sehr interessant und gibt viel Freiraum für Experimente.
Danke!
herw
@herw Hi herw, Dank zurück für das Feedback. Jep, da steckt die Freizeit von drei Monaten drin…
Für Core-Ebene braucht man solide DSP-Kenntnisse, oder halt viel Einarbeitungszeit. Als eigentlich-Musiker möchte ich da nicht Jahre mit verbringen, und ich denke, viele Andere auch nicht. Das ist eher die Domäne von Programmierern. Wenn man sich die Events mit dem „Event History“ genau anguckt, dann kann man auch auf dem Primary Level gezielt einzelne Daten filtern, verzögern usw. Aber alles kriegt man da nicht gebacken, das stimmt. Umso dankbarer bin ich für Macros wie das „Mono GP“, das hat ein Riesenproblem beseitigt. Und es zeigt, wie knifflig scheinbar einfache Prozesse sein können…
Dann noch viel Spaß beim Lesen, im letzten Teil kommt die Wavetable- und Phase Distortion- Abteilung dran.
kleiner Nachtrag zu den Send-Reiceive-Verbindungen:
dies wird leider ein schon seit Jahren vernachlässigt.
Sie sind vom Konzept her völlig falsch implemetiert, insbesondere das Kopieren liefert keine Kopie, sondern ein Durcheinander in den receive-Listen.
Schade, ein sehr mächtiges Werkzeug wird hier stiefmütterlich behandelt.
So hilft es nur, wie du beschreibst, selbst Hand anzulegen, oder höchste Disziplin beim Kopieren, Einfügen und Nichtlöschen einmal eingesetzter Send-Module.
herw
@herw Immerhin sind die Send/Receive jetzt einigermaßen editierbar, das war in der letzten Version ja eine Katastrophe. Und wenn man das Häkchen entfernt bei „automatic use of new sends“, dann klappt auch das Kopieren. Bleibt zu hoffen, dass NI das noch verbessert und weiterentwickelt, so dass man auch Events zusammen mit Audio damit routen kann, ohne den Overload zu verursachen.