Ich denke nicht, dass es ein Bug im klassischen Sinne ist. Denke, es liegt irgendwie daran, dass das Grid von links nach rechts abgearbeitet wird und wenn die Software "plötzlich" durch ein Send/Return wieder zum Anfang springen muss, dann dauert's halt länger... könnte mir aber vorstellen, dass das irgendwie zu lösen sein wird.
…
Wobei "Nur" auch relativ ist. Alleine eine lange Signalkette mit vielen leeren Shunts kostet Prozessorleistung und trägt somit auch zur Latenz bei. Wenn man latenz-empfindlich ist, dann sollte man die Signalkette so kurz wie möglich halten – ist zumindest meine amateurhafte Meinung. Ich hab' schon viele Grid-Layouts gesehen, bei denen verschwenderisch mit Shunts umgegangen wurde, dann aber aus "Platzmangel" Send und Returns eingebaut waren.
Ich bin auch kein Programmierer, kann mir aber gut vorstellen dass es einen Unterschied macht, wenn das Grid durch einen links platzierten Return neu gescannt werden muss.
Also ich denke, hier tut Information Not…
Das Grid, auf dem Display und im Editor, ist zunächst lediglich eine grafische Benutzeroberfläche.
Es dient dazu, die Struktur, gemäß der die einzelnen Effekt-Blöcke das Eingangssignal verarbeiten, bereitzustellen.
Die Firmware, das Betriebssystem des Axe, steuert den Ablauf des Modelings auf dieser strukturellen Grundlage.
Die einzelnen Blöcke werden durch separate (Unter)Programme realisiert, in denen die jeweiligen Simulationen eines Effekts ablaufen.
Dies geschieht durch Berechnungen auf Grundlage physikalisch/mathematischer Funktionen.
Um die Reihenfolge zu ermitteln, gemäß der die zuvor von analogen in digitale Signale umgewandelten Datenströme (Zahlenwerte) verarbeitet werden sollen, wird die grafische Grid-Darstellung bspw. in eine Struktur umgeformt, die dies ermöglicht.
Das kann man zBsp. mit Matrizen umsetzen.
Dieses Konstrukt kennen wahrscheinlich die Meisten noch aus dem Mathe-Unterricht.
Keine Sorge; Vektor- und Skalarprodukte werden hier kein Thema sein ;-)
Eine 2-Dimensionale Matrix sähe dann bspw. so aus:
0 3 1 9
1 5 7 3
8 1 6 4
Diese 2D-Matrix besteht aus Zeilen und Spalten.
Jede Position in der Matrix hat einen Index, über den diese Position ansprechbar ist, um einen Zahlenwert einzutragen oder auszulesen.
Die Position (2, 3), Zeile 2, Spalte 3, besitzt hier den Wert (Inhalt) 7.
Nehmen wir nun an, das AxeFx hätte ein Grid aus 4 Zeilen und 10 Spalten.
Dann wird beim Laden eines leeren Presets eine Variable im Arbeitsspeicher erzeugt, also eine Speicherstelle im Arbeitsspeicher, die das Format Matrix besitzt, mit Nullen gefüllt wird und wie folgt dimensioniert wird:
grid = matrix(4, 10)
(grid ist der zukünftige Variablenname, unter dem man sie anspricht und manipuliert)
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Danach kann ich diese Variable nutzen, um in eine der Positionen dieser Matrix einen Wert einzugeben oder ihn auszulesen.
grid(1, 3) = 5
0 0 5 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Wenn ich nun festlege, dass alle Effekt-Blöcke, Shunts und Leerstellen eine ID bekommen, über die ich diese im Verarbeitungsprozess/Modeling später ansprechen bzw. aufrufen/starten kann, kann ich das AxeEditor-Grid auslesen und ein Abbild davon in diese Matrix einpflegen.
Bsp. für eine ID-Vergabe:
-----------------------------
0 = Leerstelle (nicht belegt)
1 = Amp-Block
2 = Chorus
9 = Shunt
Wenn der User nun eine Änderung im Grid vornimmt, registriert das System dies, passt die grafische Darstellung der Editoroberfläche an und aktualisiert die Matrix.
Ich füge einen Chorus, ein paar Shunts und einen Amp-Block in's Grid ein.
Alles wird in Zeile 1 platziert.
9 2 9 9 9 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
So bekomme ich eine Struktur, nach der ich den Modeling-Prozess ablaufen lassen kann.
Das Eingangssignal geht in den Chorus und von dort in den Amp.
Das reicht für unser Beispiel zum Verständnis aus.
Nun kann das System die Matrix auswerten und ein Unterprogramm aufrufen/starten, den Chorus. Dabei werden die Eingangsdaten, die unsere Gitarre liefert und die in Form eines kontinuierlichen Zahlenstroms vorliegen (A/D Wandler hat das analoge Signal ja umgewandelt) mit an das Chorus-Programm und dessen Berechnungen übergeben.
Gleichzeitig wurde das Unterprogramm eines Amp-Blocks gestartet.
Dieses bekommt nun kontinuierlich die Rückgabe-Daten aus der Chorus-Verarbeitung und modelliert/simuliert damit den Amp.
Was hier nicht zu finden ist, sind Shunts!
Diese existieren nicht als Effekt-Blöcke, die das Signal be/verarbeiten!
Sie haben lediglich innerhalb des Grids und der Matrix einen formalen, strukturellen Wert.
In der Datenverarbeitung werden die Signaldaten ausschließlich nacheinander durch die beteiligten Effekt-Blöcke verarbeitet.
Woher weiß das System aber, welchen Weg das Signal nehmen muss?
Dies erreicht man dadurch, dass man die Matrix zu einer 3D-Matrix umformt bzw. sie gleich so anlegt.
Hört sich kompliziert an, ist es aber nicht.
grid = matrix(4, 10, 5)
Die ersten beiden Indizes bleiben weiterhin für die Positionen von Zeile und Spalte im Grid/in der Matrix.
Nun kann ich in dieser Matrize eine Speicherstelle ansprechen, die aus 3 Indizes statt aus 2 besteht.
Also wird unsere Matrix einfach etwas anders aufgerufen, um Daten hineinzuschreiben oder auszulesen:
9 2 9 9 9 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Der Amp-Block, ID = 1, wird nun ausgelesen, wenn ich abfrage, was an Position
grid(1, 6, 1) = (Zeile, Spalte, Zusatzdimension) eingetragen ist: "1"
D.h., die ersten beiden Indizes der Matrix dienen immer dazu, Zeile und Spalte des Grids abzubilden.
Der 3. Index dient dazu, bei Index = 1 den Block-Typ gemäß ID zu speichern.
Ab Index 2 könnte man nun Positionen aus dem Grid speichern, mit denen diese aktuelle Zelle VERBUNDEN ist.
9 2 9 9 9 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Der Chorus, Position 1, 2 im Grid (Matrix) sei mit dem Shunt an Position 1, 3 auch verbunden (also die Blöcke sind nicht nur dort eingebaut ohne Verbindung).
Dann könnte ich das in der Matrix für die Speicherposition des Chorus folgendermaßen speichern:
grid(1, 2, 1) ist ja mit der ID des Chorus belegt; dort steht eine "2".
grid(1, 2, 2) = 1,03 wäre eine Angabe (Koordinaten) zu einer Verbindung
1. kleiner Trick; Die 1,03 belegt nur einen Speicherplatz in der Matrix.
Aber in Form einer Dezimalzahl kann ich 2 Koordinatenwerte im Grid gleichzeitig angeben,
Um die Zeile und Spalte zu ermitteln, bediene ich mich einfach einer Funktion, mit der ich wahlweise den Ganzzahl-Anteil oder den Dezimal-Anteil zurückbekomme.
Dann habe ich die Koordinaten 1 und 03 bzw. 3!
Zeile 1, Spalte 3.
2. kleiner Trick.
Da ich die ganzen Zwischenschritte, mit Shunts belegt, eigentlich garnicht benötige, trage ich in die Matrix stattdessen gleich
grid(1, 2, 2) = 1,06 ein!
Dann erkennt das System, dass hier der Chorus mit dem Block im Grid an Position Zeile 1, Spalte 6 verbunden ist.
Und genau diese Info benötigt das Modeling-System für die Bearbeitung.
Wieviele Shunts es braucht, um anzuzeigen, welche Blöcke miteinander verbunden sind, interessiert hier nicht.
In der Verarbeitung/Modeling werden die Signal-Daten DIREKT an die einzelnen Effekt-Blöcke übergeben und die berechneten Rückgabewerte übernommen, um sie an den nächsten Block oder die nächsten Blöcke weiterzugeben.
Die Shunts im Grid und in der Matrix dienen nur dazu, dass das System erkennen kann, welchen Weg das Signal nimmt.
D.h., immer dann, wenn ich eine weitere Verbindung zwischen zwei Zellen im Grid herstelle, wird in der Matrix (Variable grid) ein entsprechender Wert eingetragen, der bezeichnet, mit welcher Zelle die aktuelle Zelle verbunden worden ist.
Bsp.:
Matrix (Variable grid)
------------------------
9 2 9 9 9 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
grid(1, 2, 1) = 2 (ID = 2 = Chorus)
grid(1, 2, 2) = 0 (Zeile 1, Spalte 2, Chorus, ist nicht verbunden)
Der User zieht eine Verbindung zur rechts angrenzenden Zelle, in der er anfangs einen Shunt platziert hatte.
Das System registriert dies und ändert 2 Werte.
grid(1, 2, 2) = 1,03 (Zeile 1, Spalte 2, Chorus, verbunden mit Zeile 1, Spalte 3, Shunt)
grid(1, 3, 2) = 1,02 (Zeile 1, Spalte 3, Shunt, verbunden mit Zeile 1, Spalte 2, Chorus)
Das war jetzt ne Menge Stoff und ich hoffe, ihr beide seid nicht zu früh ausgestiegen…
Diese Variante ist eine Möglichkeit, die Verbindungsstruktur für das System nachvollziehbar und auswertbar zu machen.
Die grafische Darstellung des Grids ist nur das sog. User-Frontend; die Bedieneroberfläsche.
Ob das so in der Firmware umgesetzt ist, oder ggf. etwas anders, weiß ich natürlich nicht.
Das weiß nur FAS.
Aber man kann sehen, dass das Betriebssystem/die Firmware sich nicht durch das visuelle Grid von oben links nach unten rechts arbeitet.
Das Grid selbst ist ebenfalls keine verarbeitende Einheit.
Die Effekt-Blöcke bestehen aus einzelnen Programmen bzw. Unterprogrammen, die nacheinander die Daten verarbeiten.
Wenn in diesem System die Programmierer den Shunts eine zeitlich relevante Funktion zugeordnet haben sollten, halte ich dies für einen gravierenden Fehler in der Konzeption.
Diese Matrix kann man im übrigen bei der Speicherung des Presets mitspeichern.
So lässt sich einfach die Struktur eines Presets wieder aufbauen, wenn man es aufruft.
Einiges habe ich sehr rudimentär dargestellt und formuliert.
Es ging um ein Verständnis des Grundprinzips.
Nicht um eine vollständige Darstellung des Firmware-Systems.
Nun denn;
Viele Grüße an die rauchenden Köpfe ;-))
Mike