Development news...
hatte gestern mal wieder nen inspirationsreichen Tag, mein Code funktionierte auf Anhieb, und als dann mal was zickte - stehen lassen, ins Bett, heute Morgen zum Frühstück dann gschwind gefixt. Irgendwie ist diese Entwicklungsphilosophie stressfreier
Gestriges Schraubthema - die Basis meines Modulationsroutings. Das Controller-Management. Funktioniert einwandfrei, da ist mir dann auch gleich aufgefallen, daß der AN1x ein 7bit Modwheel hat, ansonsten läuft der Krempel so, wie ich das geplant hab, muß nur noch für NRPNs/RPNs ein 7bit-Handling einbauen, die würden im Moment wohl 14bit-Werte in 7bit-Auflösung ausspucken, und damit von den normalen Controllern abweichen, was ich ja nicht will.
Insgesamt ist dieses Modulationsrouting für den User ein sehr fieses Gewirr an Zahlen, Berechnungen und noch viel mehr. Vorstellen kann man sich das, was ich da in der Engine zusammen baue, als ein Synth, wo man "mittendrin" rumbaut, sich also quasi die Steuerung noch selber programmiert. Für den Einsteiger wirklich völlig ungeeignet, aber ich werde auch diese Schicht nach außen legen. Da der Begriff "modeling" ja grad so hip ist - es gibt eigentlich nen "modeling synthesizer", aber auf analoger Basis. Und so wirds dann auch abgebildet. Wie gesagt, Expert Mode, User Mode, vielleicht noch nen Advanced Mode dazwischen, weil die Unterschiede zwischen den beiden Betriebarten extrem groß sind. Jetzt mal zum Expert Mode:
Der Synthesizer an für sich ist strunzdumm und kann gar nix, wenn man ihn einschaltet. Der weiß nichtmal, was er mit nem Note-On anfangen soll. Und genau das ist gut so:
Am Anfang stehen Controller. Im Moment sind es 40 Slots. 8 davon sind "Systemcontroller", die fest verdrahtet sind und Dinge abbilden, die nicht als MIDI-Controller rüberkommen. Da gibt es:
0 - Trigger/Gate
Der beinhaltet die Werte -32768 für "alles aus", 0 für "da spielt was, und das Event dazu ist verarbeitet worden", 16383 für "da kam ein Note-On, während eine Note spielte" und 32767 für "da kam ein Note-On, während nichts spielte"
1 - Pitch
Hier wird der schon quasi in CV umgerechnete Notenwert hingekippt. Da kommt eventuell mal was Anderes als das momentane notenwert * 256 rein, um unterschiedliche Stimmungen zu erreichen.
Neben diesen beiden wichtigen Dingern kommen dann noch Pitchbender, Velocity, Release Velocity und Pressure mit rein. Sind 6 Stück, 2 halte ich mal frei, wenn mir noch was einfällt.
Nach diesen 8 Systemcontrollern kommen im Moment 32 frei definierbare Controller, wo normale MIDI-Controller hin kommen, die 7bit sein können (GPS1-4, Attack, Decay und was es da so alles gibt), 14bit (Modwheel, Balance, Pan usw), außerdem kann man da RPNs und NRPNs hinschicken, ebenfalls 7bit oder 14bit, außerdem wird DBDEC und DBINC unterstützt, also die volle MIDI-Spezifikation ist drin. Die Slots enthalten neben den Verwaltungsinformationen, wie die Werte gesetzt werden, noch einen Default-Wert mit einem Flag, das entscheidet, ob bei der MIDI-Message zum resetten aller Controller dieser auf den Default-Wert gesetzt werden soll (z.B. Modwheel auf 0), im Moment ist auch noch neuer/alter Wert drin, das diente zur Entscheidung, ob Routingeinträge, die den Slot benutzen, neu berechnet werden müssen, möglicherweise berechne ich aber eh alles neu - mir gehen nämlich meine 2KB RAM langsam aus
Dann gibts die Register, das sind quasi Variablen. Alle auf 32bit ausgelegt, während gerechnet wird, und nach Berechnung auf 16bit "geclippt". Man kann so sogar den Output seiner Hüllkurven mit einem anderen Controller "mischen" und eine gewisse Form der "Übersteuerung" einbauen. Oder wie wärs mit nem übersteuerten LFO? Geht alles. Übrigens auch im Analogteil
Dazu gibts dann noch die Controls, das sind einerseits die Steuerspannungen, und man kann in restlos alle reinschrauben. Auch die internen Kalibrierungswerte kann man überschreiben. Einschränken werde ich nur die ersten beiden, die die Referenzwerte für Nullpunkt und Amplitude aller CVs darstellen. Wenn mans mit denen übertreibt, kann man die Elektronik nämlich zerstören. Aber ich lasse sie in kleinen Grenzen modulierbar, dann kann man einen "Störfaktor" auf die gesamte analoge Steuerung einbringen, und damit einen sehr wartungsbedürftigen alten Analogsynth modulieren, bei dem z.B. das Netzteil kaputt ist und schwankt (Ja, ich bin in dieser Beziehung pervers
.
Außerdem - ich bin ja Unix-Freund, und unter Unix ist alles eine Datei, egal, obs eine Tastatur, der Drucker oder wirklich eine Datei ist - findet sich hier auch der komplette Rest der Steuerung wieder. Neben den 64 Steuerspannungen, die es gibt, sind dann noch bis zu 128 andere Steuerwerte vorhanden, die z.B. die Wellenformen auswählen, die Sync ein/ausschalten, Trigger/Gate für die Modulationsprozessoren, Gate für den Sample&Hold, die ganzen Quellen/Zielauswahlen der analogen Modulationsmatrix, und diverser anderer Kram. Sicherlich macht es nicht bei Allem Sinn, da Wild zahlen reinziwerfen, aber alles ist so ausgelegt, daß man mit Zahlen arbeiten kann. Man muß nur viel nachdenken, wie man rechnen muß, damit das gewünschte Ergebnis rauskommt.
Diese Werte bekommen alle Defaults, können also vom User mit entsprechenden Daten vorbelegt werden (oder werden vom System schon durch das Tuning vorbelegt), wenn sie nicht durch die Modulationen verändert werden sollen. Gerade die Modulationsmatrix, also was wohin und was woher kommt, kann man zwar modulieren, muß man aber nicht.
Soviel also zu Input/Output. Das steht einfach mal alles so im Raum, und drumrum hängt ein Modulationsrouter. Dieser besitzt 128 (im Moment) Einträge mit den folgenden Daten:
- Quelle (Controller oder Register)
- Ziel (Register oder Control)
- Modifikator (entweder ein 7bit-Zahlenwert oder eine Registernummer/Controllernummer)
- Benutzung des Modifikators (ignorieren, addieren, multiplizieren, dividieren)
- Typ des Modifikators (mit/ohne Vorzeichen)
Und hier ist jetzt die eigentliche Logik von der ganzen Kiste abgebildet. Wenn hier nix drin steht, kommt kein Ton raus.
Im einfachsten Fall, um einfach einen Orgelpatch, keine Hüllkurven, monophon, zu bauen, muß man also etwa folgendes verdrahten:
- Controller 0 über einige Register mit den vorhandenen Rechenoperationen so hinbiegen, daß hinten im Endeffekt 0 und 1 rauskommen -> damit ist quasi ein einfaches Gate isoliert
- Das Register, was ganz am Ende der Berechnungen von Controller 0 steht, mit dem Wert des Vertrauens multiplizieren und auf den VCA-Pegel für Haupt-Osc und evtl. Sub-Osc schreiben
- Controller 1 auf Pitch des VCOs schreiben
- Controller für Pitch-Wheel durch 16 teilen und auf Pitch des VCOs schreiben
"das war ja einfach" - wir haben einen einfachen Patch ala Orgel. Der erste Schritt ist übrigens mit Hüllkurven deutlich einfacher, weil Trigger und Gate Werte sind, die einfach nach größer oder kleiner 0 entscheiden. Der VCA-Wert, der hier kompliziert berechnet werden muß durch Übersteuerung, kommt dann ja aus einem Modulationsprozessor. Und mit einigen simplen Berechnungen kann man entsprechend den Trigger auch trennen in Note nach Leerlauf und Note nach Note, um im Legato-Spiel z.B. die Hüllkurve nicht nach überlappend gespielten Noten neu zu triggern, oder z.B. um den Glide nur beim Legato-Spiel zu benutzen, während eine neue Note nach Leerlauf den Glide umgeht.
Die Modulationsprozessoren können alle auf die ersten 32 Register zugreifen, wobei die insgesamt 24 Modulationsprozessoren in 3 8er-Gruppen unterteilt sind, und nur beim ersten sind Register 0-7 auch wirklich Register 0-7. Die anderen beiden können zwar in sich auch auf 0-7 zugreifen, aber nur von den Nachbarn in der Gruppe. Diese beiden MP-Gruppen werden dann in den Registern 32-47 abgelegt. Aber mehr als 8 Modulationsprozessoren (die ja Hüllkurven und LFOs und noch mehr darstellen) muß man ja vermutlich auch nicht gegenseitig modulieren. Register 8-15 werden mit den digitalisierten Daten der 8 Modulationsbusleitungen bestückt, 16-31 sind frei, 48-63 sind frei.
Das klingt alles jetzt unendlich kompliziert für nicht-Computer-Entwickler, denke ich, entsprechend umfangreich wird auch die Anleitung für den Expert-Mode, aber das User Interface wird hier vermutlich die meiste Entwicklungsarbeit kosten, denn es soll einem am Ende die Arbeit mit dieser Höllenkonstruktion so einfach wie möglich machen. Möglicherweise ist aufgrund der Komplexität für den Expert Mode eine Bedienung nur über einen Computer extern möglich, aber im Expert Mode kann man ja schließlich seinen Synth "zusammenbauen", wie man ihn will, und damit ein Modell für den User-Mode bereit stellen, bei dem dann, wie man es von handelsüblichen Geräten kennt, nur noch die freigegebenen Parameter eingestellt werden können, die auch nicht zwingend was mit den vorhandenen Controls zu tun haben müssen, es können ja schließlich Werte direkt in der Routingtabelle, in Registern oder Controllern sein. Und die Controller kann man auch alle live bedienen. Also 32 Knobs in parallel.
Obigen Orgelpatch in leicht erweiterter Version hatte ich gestern mal am Laufen, 5 User-Controller, mit denen ich detune von VCO2 gesteuert hab, ein wenig waveforms, ein wenig sync ein/aus, alles recht rudimentär, und noch ohne den Router, das war noch hardcoded. Ich musste feststellen, ich bin in Sachen fette Sounds glaub auf dem richtigen Weg. Die Konstruktion hat mit 2 VCOs und daran angebundenen 5 Sub-Oscs (VCO1 mit Subosc auf 1, 2, 3 und 4 Oktaven tiefer, VCO2 mit Subosc auf 2 Oktaven tiefer), nem Detune um etwa eine Oktave auf VCO2 und Sync VCO1->VCO2 derart brachiale Geräusche hervorgebracht, sowas motiviert dann wieder, da schnell weiter zu machen, daß da noch Filter dahinter kommen und so Zeug. Außerdem brauch ich ein zweites Voice-Brett für noch mehr Chaos