PARTIALS FRAMEWORK (multiplexing)
Moderator: herw
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Beispiel 2: einfacher Eventblock
Beispiel 2: einfacher Eventblock (Teil 1)
Nun, das Übersenden von einfachen Eventquellen ist sicherlich schon sehr nützlich, wenn man wie im Beispiel 1 viele Quellen zum Beispiel in eine CoreCell übertragen möchte.
Es gibt aber auch Eventquellen, die mehrere miteinander verknüpfte Daten senden und empfangen:
MouseArea, XY, EventTable, SnapValueArray, SystemInfo. Natürlich kann man jeden Ausgang und Eingang als eigenständige Eventquelle bzw. eigenständiges Eventziel sehen und wie im ersten Beispiel beschrieben mit verschiedenen identifiers verwalten. Eleganter kann es aber sein, wenn man solche Daten zu einem Block zusammenfasst, zum Beispiel um beim routing sie unter einem identifier laufen zu lassen.
Das Beispiel 2 beginnt zunächst mal völlig harmlos. Durch kleine Veränderungen kommen wir hoffentlich den Geheimnissen des frameworks etwas näher.
Wir wollen durch einen Triggerevent fünf Werte in einem Block übertragen. Diese sollen innerhalb der erzeugenden CoreCell den Status der Gleichzeitigkeit haben. Es ist weniger erstaunlich, dass man diesen Status innerhalb der CoreCell erreichen kann; umsomehr erstaunlich ist es aber, dass dieser Status über einen sequentiellen Bus in primary zu einer anschließenden CoreCell übertragen wird, so dass diese in der empfangenden CoreCell wiederum den Status der Gleichzeitigkeit haben.
Zunächst beschäftigen wir uns aber nur mit der Sendeseite.
Die Daten selbst lauten zum Beispiel (1, 1.1, 1.2, -1.3, 2.4). Ich nehme an, dass ihr mittlerweile das Skript über multiplexing zum vierten Mal durchgelesen habt und schon wisst, dass man dem Bus irgendwie den identifier id und die Anzahl # der Daten mitteilen muss. Also im Prinzip lautet der gesamte Datensatz (id, 5, 1, 1.1, 1.2, -1.3, 2.4). Dies ist nicht ganz richtig, wie wir noch sehen werden, aber lassen wir uns überraschen.
Hier ist der grundsätzliche Aufbau von der Primary-Seite: Ein Button als Trigger, die EventCoreCell, die die Werte festlegt und der Eventmonitor zur Kontrolle des Busses.
Wir bemerken, dass an die EventCoreCell ein chainIterator angeschlossen ist, d.h. innerhalb der CoreCell läuft also ein Iterationsprozess ab.
Der Trigger wird zweifach benutzt: zunächst innerhalb der CoreCell und dann noch im chainiterator. Etwas komisch, wo man doch annehmen könnte, dass man nur durch einen Event den chainiterator anstoßen müsste.
Schauen wir uns mit dem Eventmonitor den Datenblock an, so erkennen wir erstaunt, dass dieser länger ist und einen zusätzlich Event mit dem Wert 31 mitführt.
Fortsetzung folgt
ciao herw
Nun, das Übersenden von einfachen Eventquellen ist sicherlich schon sehr nützlich, wenn man wie im Beispiel 1 viele Quellen zum Beispiel in eine CoreCell übertragen möchte.
Es gibt aber auch Eventquellen, die mehrere miteinander verknüpfte Daten senden und empfangen:
MouseArea, XY, EventTable, SnapValueArray, SystemInfo. Natürlich kann man jeden Ausgang und Eingang als eigenständige Eventquelle bzw. eigenständiges Eventziel sehen und wie im ersten Beispiel beschrieben mit verschiedenen identifiers verwalten. Eleganter kann es aber sein, wenn man solche Daten zu einem Block zusammenfasst, zum Beispiel um beim routing sie unter einem identifier laufen zu lassen.
Das Beispiel 2 beginnt zunächst mal völlig harmlos. Durch kleine Veränderungen kommen wir hoffentlich den Geheimnissen des frameworks etwas näher.
Wir wollen durch einen Triggerevent fünf Werte in einem Block übertragen. Diese sollen innerhalb der erzeugenden CoreCell den Status der Gleichzeitigkeit haben. Es ist weniger erstaunlich, dass man diesen Status innerhalb der CoreCell erreichen kann; umsomehr erstaunlich ist es aber, dass dieser Status über einen sequentiellen Bus in primary zu einer anschließenden CoreCell übertragen wird, so dass diese in der empfangenden CoreCell wiederum den Status der Gleichzeitigkeit haben.
Zunächst beschäftigen wir uns aber nur mit der Sendeseite.
Die Daten selbst lauten zum Beispiel (1, 1.1, 1.2, -1.3, 2.4). Ich nehme an, dass ihr mittlerweile das Skript über multiplexing zum vierten Mal durchgelesen habt und schon wisst, dass man dem Bus irgendwie den identifier id und die Anzahl # der Daten mitteilen muss. Also im Prinzip lautet der gesamte Datensatz (id, 5, 1, 1.1, 1.2, -1.3, 2.4). Dies ist nicht ganz richtig, wie wir noch sehen werden, aber lassen wir uns überraschen.
Hier ist der grundsätzliche Aufbau von der Primary-Seite: Ein Button als Trigger, die EventCoreCell, die die Werte festlegt und der Eventmonitor zur Kontrolle des Busses.
Wir bemerken, dass an die EventCoreCell ein chainIterator angeschlossen ist, d.h. innerhalb der CoreCell läuft also ein Iterationsprozess ab.
Der Trigger wird zweifach benutzt: zunächst innerhalb der CoreCell und dann noch im chainiterator. Etwas komisch, wo man doch annehmen könnte, dass man nur durch einen Event den chainiterator anstoßen müsste.
Schauen wir uns mit dem Eventmonitor den Datenblock an, so erkennen wir erstaunt, dass dieser länger ist und einen zusätzlich Event mit dem Wert 31 mitführt.
Fortsetzung folgt
ciao herw
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
-
- user
- Beiträge: 27
- Registriert: 27. März 2011, 12:42
Re: OT : ADSR
Danke. Kurz noch zu dem LFO/ ADSR Demo von Seite 1, ...hatte ich auch so. Mein Fehler war aber das Ich den Haken beim Meter für "Show Value" nicht aktiviert hatte und nur den wert des Kabels mit dem Mauszeiger ausgelesen hab.
So geht es jetzt und ich kann mich weiter mit der Library und dem Beispiel 2 beschäftigen.
So geht es jetzt und ich kann mich weiter mit der Library und dem Beispiel 2 beschäftigen.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: OT: ADSR
das Kabel wird nur mit der displayFrequenz von 25 Hz abgelesen. Nach einiger Zeit müsste aber trotzdem 0 erscheinen.macrospank hat geschrieben:Danke. Kurz noch zu dem LFO/ ADSR Demo von Seite 1, ...hatte ich auch so. Mein Fehler war aber das Ich den Haken beim Meter für "Show Value" nicht aktiviert hatte und nur den wert des Kabels mit dem Mauszeiger ausgelesen hab.
So geht es jetzt und ich kann mich weiter mit der Library und dem Beispiel 2 beschäftigen.
-
- user
- Beiträge: 27
- Registriert: 27. März 2011, 12:42
Re: OT: ADSR
mhhh nichso ganz.
Das ADSR zeigt im "Meter" schon korrekt den Wert 0 an
aber wenn du mal mit dem Mauszeiger auf das Kabel vor dem Meter gehst siehst du einen wert wie z.b 1.2334E-08 (auch direkt nach der Initialisierung).
Hab irgendwo gelesen das solche werte mit wissenschaftl Notation zu tun haben und zugegeben versteh ichs nicht wirklich.
Ich vermute wegen den vielen stellen nach dem Komma. Aber wenn der wert ausgelesen wird zeigt er im Meter ja 0 an. Also passt ja alles.
Wir müssen uns aber wegen mir nicht damit aufhalten und können gerne zu deinem Eventblock zurückkehren. Ist viel spannender.
Das ADSR zeigt im "Meter" schon korrekt den Wert 0 an
aber wenn du mal mit dem Mauszeiger auf das Kabel vor dem Meter gehst siehst du einen wert wie z.b 1.2334E-08 (auch direkt nach der Initialisierung).
Hab irgendwo gelesen das solche werte mit wissenschaftl Notation zu tun haben und zugegeben versteh ichs nicht wirklich.
Ich vermute wegen den vielen stellen nach dem Komma. Aber wenn der wert ausgelesen wird zeigt er im Meter ja 0 an. Also passt ja alles.
Wir müssen uns aber wegen mir nicht damit aufhalten und können gerne zu deinem Eventblock zurückkehren. Ist viel spannender.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: Beispiel 2: einfacher Eventblock
Beispiel 2: einfacher Eventblock (Teil 2)
31, wieso 31?
Das hat mich seinerzeit fast zum Wahnsinn getrieben. Irgendwelche zusätzlichen Daten, die nirgendwo erklärt werden und wie soll ich, bitte schön, diese verarbeiten? Ich muss dazu sagen, dass Max (bzw. Stephan Schmidt) mir partials framework schon sehr früh zugeschickt hat und dann nur zwei der Skripten vorlagen, ich mir also das irgendwie zusammen reimen musste bzw. dann Max gelöchert habe.
Also: irgendwie muss ja dem Bus mitgegeben werden, dass 1. eine bestimmte Anzahl von Daten zugeschickt werden und 2. dann auch noch eventuell nur eine Auswahl davon ????
Ihr versteht nur „Bahnhof”? Jaaaaaa, ich lange Zeit auch!
Dies ist eine der spannendsten Stellen bisher im Bereich Multiplexing. Im Skript werden ja einige verschiedene Anwendungen, besser gesagt „Verschlüsselungsmethoden” genannt, die auch einleuchtend sind, aber doch irgendwie im theoretischen Raum liegen.
Die 31, ja manchmal auch 255 oder 1023 oder 7 oder 63. ?!? Dämmert es? Nein! Doch, da war doch was mit Binärzahlen!!
Hmm: 31 ist 32-1 und das sind 2^5-1 und 255 ist 256-1=2^8-1 usw..
Wir schauen mal in die CoreCell hinein: Links offenbar Mehrfach-value-Module, die alle (gleichzeitig) vom Trigger getriggert werden (was auch sonst?). Wir sehen dort unsere Daten, die wir übertragen wollen, als Konstante.
Danach das Makro id-send-synchronous (nicht verwechseln mit dem verkleinerten send-synchronous, das den identifier nicht mitschickt, falls nicht nötig; Achtung: Name der Makros ist derselbe).
Wir sehen die typische Ankopplung des chain-Iterators (-+, +- und outputfilter) an das Makro.
Ja gut: testen wir doch einfach mal:
Wir löschen die unterste Verbindung, so dass die 2.4 nicht gesendet werden soll ... ... und vergleichen die Ausgabe: Ja! 15=2^4-1!
Alles klar? Das id-send-synchronous-Makro zählt die benutzen Eingänge und verschlüsselt sie binär: 4 Eingänge -> 2^4-1, 5 Eingänge ->2^5-1 usw.
Gleich mal austesten (mehr oder weniger Ausgänge).
Erfolg! ja, ABER Zweifel!
Was soll das Ganze? Ich kann doch auch an der Anzahl der Daten in der zweiten Komponente # erkennen, wie viele Daten gesendet werden, also was soll das Ganze und wieso 2^n-1 für n Eingänge und nicht 2^n ??? Das ist doch Redundanz pur!
Großes Nachdenken über Binärverschlüsselung liefert folgende Überlegung:
2^0-1=0 ist binär 0, 2^1-1=1 ist binär 01, 2^3-1=7 ist binär 0111, 2^5-1=31 ist binär 011111.
Ja! Offenbar zählt das Makro anhand der Binärzahl, wie viele Quellen tatsächlich angeschlossen sind. Aber das ist doch trotzdem redundant!
Hmm: probieren geht über studieren. Wir schließen den fünften Wert (2.4) wieder an und löschen dafür den 3. Anschluss: Mal sehen, was passiert: 27 ! 27 ist binär 011011 (=2^0+2^1+2^3+2^4=1+2+8+16=27).
Alles klar! Die Verschlüsselungzahl vermittelt sogar, welche Anschlüsse zum Triggerzeitpunkt verwendet werden.
Jetzt ist auch klar, warum man die Daten triggern muss: alle Eingänge, die gerade einen Event zeitgleich erhalten, werden registriert und so verschlüsselt, dass sie durch die Verschlüsselungszahl angeben, wo solche Event gerade auftraten.
D.h. man könnte also sogar verschiedene Trigger hier verwenden, um andere Kombination aktiver zeitgleicher Events zu übermitteln!
Das ist genial und sicherlich in primary nur äußerst schwer zu realisieren. Hier schlägt das Paradigma der Gleichzeitigkeit voll durch!
Also zusammenfassend:
Das id-send-snychronous entsendet neben den eigentlichen Daten auch eventuelle Teildaten und kann diese so versenden, dass sie auf der Empfängerseite wieder entschlüsselt werden können.
In keinem Fall sollte man also Spezialmakros mit weniger Eingängen erstellen. Das Makro kann sich selbst verwalten! Es gibt im partials framework schon Varianten für zwei, vier, acht, 16 und 32 Eingänge. Ein ganz dickes Lob an Max, überhaupt auf solch eine Idee zu kommen.
Unser Eventblock lautet also:
(id,#,or,<data 1>, <data 2>, ... , <data #-1>),
id gibt den identifier , # die Anzahl der folgenden Daten, or ist die verschlüsselte Auswahl der zeitgleichen Events an den Eingängen („port flags”) und danach folgen die eigentlichen Daten.
Das lässt uns schon erwartungsvoll auf die nächste Folge hoffen.
Ich gebe mal ein wenig Zeit, um damit selbst zu experimentieren und das Ganze zu verdauen.
ciao herw
31, wieso 31?
Das hat mich seinerzeit fast zum Wahnsinn getrieben. Irgendwelche zusätzlichen Daten, die nirgendwo erklärt werden und wie soll ich, bitte schön, diese verarbeiten? Ich muss dazu sagen, dass Max (bzw. Stephan Schmidt) mir partials framework schon sehr früh zugeschickt hat und dann nur zwei der Skripten vorlagen, ich mir also das irgendwie zusammen reimen musste bzw. dann Max gelöchert habe.
Also: irgendwie muss ja dem Bus mitgegeben werden, dass 1. eine bestimmte Anzahl von Daten zugeschickt werden und 2. dann auch noch eventuell nur eine Auswahl davon ????
Ihr versteht nur „Bahnhof”? Jaaaaaa, ich lange Zeit auch!
Dies ist eine der spannendsten Stellen bisher im Bereich Multiplexing. Im Skript werden ja einige verschiedene Anwendungen, besser gesagt „Verschlüsselungsmethoden” genannt, die auch einleuchtend sind, aber doch irgendwie im theoretischen Raum liegen.
Die 31, ja manchmal auch 255 oder 1023 oder 7 oder 63. ?!? Dämmert es? Nein! Doch, da war doch was mit Binärzahlen!!
Hmm: 31 ist 32-1 und das sind 2^5-1 und 255 ist 256-1=2^8-1 usw..
Wir schauen mal in die CoreCell hinein: Links offenbar Mehrfach-value-Module, die alle (gleichzeitig) vom Trigger getriggert werden (was auch sonst?). Wir sehen dort unsere Daten, die wir übertragen wollen, als Konstante.
Danach das Makro id-send-synchronous (nicht verwechseln mit dem verkleinerten send-synchronous, das den identifier nicht mitschickt, falls nicht nötig; Achtung: Name der Makros ist derselbe).
Wir sehen die typische Ankopplung des chain-Iterators (-+, +- und outputfilter) an das Makro.
Ja gut: testen wir doch einfach mal:
Wir löschen die unterste Verbindung, so dass die 2.4 nicht gesendet werden soll ... ... und vergleichen die Ausgabe: Ja! 15=2^4-1!
Alles klar? Das id-send-synchronous-Makro zählt die benutzen Eingänge und verschlüsselt sie binär: 4 Eingänge -> 2^4-1, 5 Eingänge ->2^5-1 usw.
Gleich mal austesten (mehr oder weniger Ausgänge).
Erfolg! ja, ABER Zweifel!
Was soll das Ganze? Ich kann doch auch an der Anzahl der Daten in der zweiten Komponente # erkennen, wie viele Daten gesendet werden, also was soll das Ganze und wieso 2^n-1 für n Eingänge und nicht 2^n ??? Das ist doch Redundanz pur!
Großes Nachdenken über Binärverschlüsselung liefert folgende Überlegung:
2^0-1=0 ist binär 0, 2^1-1=1 ist binär 01, 2^3-1=7 ist binär 0111, 2^5-1=31 ist binär 011111.
Ja! Offenbar zählt das Makro anhand der Binärzahl, wie viele Quellen tatsächlich angeschlossen sind. Aber das ist doch trotzdem redundant!
Hmm: probieren geht über studieren. Wir schließen den fünften Wert (2.4) wieder an und löschen dafür den 3. Anschluss: Mal sehen, was passiert: 27 ! 27 ist binär 011011 (=2^0+2^1+2^3+2^4=1+2+8+16=27).
Alles klar! Die Verschlüsselungzahl vermittelt sogar, welche Anschlüsse zum Triggerzeitpunkt verwendet werden.
Jetzt ist auch klar, warum man die Daten triggern muss: alle Eingänge, die gerade einen Event zeitgleich erhalten, werden registriert und so verschlüsselt, dass sie durch die Verschlüsselungszahl angeben, wo solche Event gerade auftraten.
D.h. man könnte also sogar verschiedene Trigger hier verwenden, um andere Kombination aktiver zeitgleicher Events zu übermitteln!
Das ist genial und sicherlich in primary nur äußerst schwer zu realisieren. Hier schlägt das Paradigma der Gleichzeitigkeit voll durch!
Also zusammenfassend:
Das id-send-snychronous entsendet neben den eigentlichen Daten auch eventuelle Teildaten und kann diese so versenden, dass sie auf der Empfängerseite wieder entschlüsselt werden können.
In keinem Fall sollte man also Spezialmakros mit weniger Eingängen erstellen. Das Makro kann sich selbst verwalten! Es gibt im partials framework schon Varianten für zwei, vier, acht, 16 und 32 Eingänge. Ein ganz dickes Lob an Max, überhaupt auf solch eine Idee zu kommen.
Unser Eventblock lautet also:
(id,#,or,<data 1>, <data 2>, ... , <data #-1>),
id gibt den identifier , # die Anzahl der folgenden Daten, or ist die verschlüsselte Auswahl der zeitgleichen Events an den Eingängen („port flags”) und danach folgen die eigentlichen Daten.
Das lässt uns schon erwartungsvoll auf die nächste Folge hoffen.
Ich gebe mal ein wenig Zeit, um damit selbst zu experimentieren und das Ganze zu verdauen.
ciao herw
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: Beispiel 2: einfacher Eventblock
Beispiel 2: einfacher Eventblock (Teil 3)
kleine Ergänzung zum Knobeln und Spielen: Als kleine Übungsaufgabe sollte man jede der in den Eventblöcken enthaltenen Zahlen genau interpretieren können. Interessant ist übrigens die „Denkweise” des Interpreters von REAKTOR. Von der Struktur her könnte man annehmen, dass die violetten Events vor den grünen Events angezeigt werden müssen, da der Trigger im chain iterator ja schließlich die Iteration auslöst.
REAKTOR geht in seiner Interpretation aber von den so genannten „sinks” (Verbrauchern) aus und verfolgt den Signalweg rückwärts. Der am weitesten entfernte Verbraucher der CoreCell ist die grüne Monitoranzeige.
Falls ich etwas falsch interpretiere, möge bitte einer der Experten von NI hier mich gerne korrigieren!
Das ist manchmal sehr verwirrend, wenn beispielsweise der Trigger nicht nur aus einem einzelnen Wert besteht, sondern etwa aus einen Eventblock extrahiert wird. Das werde ich eventuell mal in einem der nächsten Abschnitte kurz anreißen.
Viel Spaß mit dem Beispiel herw
kleine Ergänzung zum Knobeln und Spielen: Als kleine Übungsaufgabe sollte man jede der in den Eventblöcken enthaltenen Zahlen genau interpretieren können. Interessant ist übrigens die „Denkweise” des Interpreters von REAKTOR. Von der Struktur her könnte man annehmen, dass die violetten Events vor den grünen Events angezeigt werden müssen, da der Trigger im chain iterator ja schließlich die Iteration auslöst.
REAKTOR geht in seiner Interpretation aber von den so genannten „sinks” (Verbrauchern) aus und verfolgt den Signalweg rückwärts. Der am weitesten entfernte Verbraucher der CoreCell ist die grüne Monitoranzeige.
Falls ich etwas falsch interpretiere, möge bitte einer der Experten von NI hier mich gerne korrigieren!
Das ist manchmal sehr verwirrend, wenn beispielsweise der Trigger nicht nur aus einem einzelnen Wert besteht, sondern etwa aus einen Eventblock extrahiert wird. Das werde ich eventuell mal in einem der nächsten Abschnitte kurz anreißen.
Viel Spaß mit dem Beispiel herw
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
-
- user
- Beiträge: 27
- Registriert: 27. März 2011, 12:42
Re: Beispiel 2: einfacher Eventblock
von der Zusamenfassung Teil 2:
Bezieht sich das auf alle Macros ? Oder welche Macros sind davon nicht betroffen?
z.b. das LFO Demo ganz unten auf Seite 1. enthält ein {e} mux bei dem ich die Eingänge reduziert hatte. Ich dachte ich kann die Eingänge beliebig erweitern oder reduzieren?
herw hat geschrieben: In keinem Fall sollte man also Spezialmakros mit weniger Eingängen erstellen. Das Makro kann sich selbst verwalten! Es gibt im partials framework schon Varianten für zwei, vier, acht, 16 und 32 Eingänge. Ein ganz dickes Lob an Max, überhaupt auf solch eine Idee zu kommen.
Bezieht sich das auf alle Macros ? Oder welche Macros sind davon nicht betroffen?
z.b. das LFO Demo ganz unten auf Seite 1. enthält ein {e} mux bei dem ich die Eingänge reduziert hatte. Ich dachte ich kann die Eingänge beliebig erweitern oder reduzieren?
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: Beispiel 2: einfacher Eventblock
ja natürlich kannst du das reduzieren, ich wollte nur damit sagen, dass es einfach nicht nötig ist. Die Makros sind so gestaltet, dass unbenutzte Eingänge auch wirklich ungenutzt bleiben; wenn du in manche Makros hineinschaust, dann haben die relevanten Eingänge einen quickbus „suppress init” der zuverlässig verhindert, dass das Core-Makro Initialisierungsevents eines offenen Eingangs erzeugt und benutzt.macrospank hat geschrieben:von der Zusamenfassung Teil 2:Bezieht sich das auf alle Macros ? Oder welche Macros sind davon nicht betroffen?herw hat geschrieben: In keinem Fall sollte man also Spezialmakros mit weniger Eingängen erstellen. Das Makro kann sich selbst verwalten! Es gibt im partials framework schon Varianten für zwei, vier, acht, 16 und 32 Eingänge. Ein ganz dickes Lob an Max, überhaupt auf solch eine Idee zu kommen.
z.b. das LFO Demo ganz unten auf Seite 1. enthält ein {e} mux bei dem ich die Eingänge reduziert hatte. Ich dachte ich kann die Eingänge beliebig erweitern oder reduzieren?
Als ich das framework zum ersten Mal sah, dachte ich auch: ok du passt es nach deinem Gutdünken an (Erweiterung oder Reduzierung der Ein- und Ausgänge, Namensänderung der Ports etc.)
Das habe ich dann auch teilweise durchgeführt, einfach weil ich mir zunächst die vorgegebenen Bezeichnungen nicht merken konnte oder nicht aussagekräftig genug waren.
Nach ein paar Tagen merkte ich aber, dass das wirklich in fiesester Kleinarbeit ausartet und die eigentliche Arbeit völlig zum Erliegen kommt.
Es ist wirklich egal, ob man zum Beispiel ein 16er-send synchronous für neun Eingänge benutzt oder ob man sich die Mühe macht und ein Spezial-Modul für neun Eingänge aus diesem erstellt.
Ich nehme das framework einfach so, wie es ist, und versuche mich in die Logik hineinzudenken, um dann eventuell kombinierte Makros zu erstellen, die dann mir die Arbeit erleichtern.
Abgesehen davon wird das framework auch hoffentlich erweitert werden von findigen Entwicklern. Dann müssen zum allgemeinen Verständnis ja auch die vorgegebenen Makros benutzt werden; wollte man dann da wieder herangehen und alles ändern?
Max hat zwei Prinzipien eingehalten: für den Anschluss von Eventquellen benutzt er die Einteilung in Zehnerschritten (mux und demux). Ansonsten geht er binär vor und erstellt Makros für zwei, vier, acht, 16 und 32 Ein- und Ausgänge oder Operatoren. Dadurch hat er viel Programmierarbeit gespart.
Ja es ist zunächst schwierig, sich auf einen fremden Programmierstil einzulassen und zu akzeptieren, aber seine Arbeit dient unserer Arbeitserleichterung.
Wichtig ist eigentlich nur, dass die Schnittstellen zu den persönlichen Strukturen voll verstanden sind und eingehalten werden.
In diesem Sinne war mein Einwand gedacht; vielleicht habe ich ihn etwas zu rabiat formuliert; wenn es deiner Arbeit oder deinem ästhetischen Empfinden nutzt, kannst Du ja Spezialmakros erstellen, sie werden auch voll funktionieren, notwendig ist es aber nicht.
Ich bin froh, dass du diese Zweifel hier erwähnst, genauso habe ich auch vor einigen Monaten gedacht und gemerkt, dass man sich einfach auf das framework einlassen sollte.
ciao herw
PS: es freut mich, dass du so aufmerksam mitliest; es spornt mich an, noch vor dem wohl verdienten Urlaub ein paar posts in den nächsten Tagen hier zu schreiben ehe es in die totale Funkstille geht (kein Telefon- und Internetnetz, weit ab in der Abgeschiedenheit).
Dem Modular wird es hoffentlich nützen.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: Beispiel 2: einfacher Eventblock
Beispiel 2: einfacher Eventblock (Teil 4)
gut - die Sendeseite ist einigermaßen geklärt, nun zur Empfangsseite.
Beschäftigen wir uns zunächst mal einfach mit der Bereitstellung der Daten des Eventblocks: Ich habe das letzte Ensemble um einen Empfänger erweitert. Es ist das Gegenstück zum Sender: Wir betrachten das Ergebnis nach der Initialisierung und stellen befriedigt fest, dass unsere Daten ordnungsgemäß im Empfänger ankommen. Innen passiert nicht viel; standardmäßig wird der Bus zunächst wieder aufgelöst durch den raw receiver, der die Identität, die Anzahl der Daten, die Indizes und die Daten erzeugt bzw. abliest. Das Makro receive_synchronous leitet daraus dann die eigentlichen Daten wieder her, die dann an den entsprechenden Ausgängen zur Verfügung stehen.
gut - die Sendeseite ist einigermaßen geklärt, nun zur Empfangsseite.
Beschäftigen wir uns zunächst mal einfach mit der Bereitstellung der Daten des Eventblocks: Ich habe das letzte Ensemble um einen Empfänger erweitert. Es ist das Gegenstück zum Sender: Wir betrachten das Ergebnis nach der Initialisierung und stellen befriedigt fest, dass unsere Daten ordnungsgemäß im Empfänger ankommen. Innen passiert nicht viel; standardmäßig wird der Bus zunächst wieder aufgelöst durch den raw receiver, der die Identität, die Anzahl der Daten, die Indizes und die Daten erzeugt bzw. abliest. Das Makro receive_synchronous leitet daraus dann die eigentlichen Daten wieder her, die dann an den entsprechenden Ausgängen zur Verfügung stehen.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: Beispiel 2: einfacher Eventblock
Beispiel 2: einfacher Eventblock (Teil 5)
Die Verarbeitung der herausgefilterten Daten ist in der Regel nicht ein bloßes Abrufen; natürlich möchte man in der empfangenden CoreCell diese Daten auch direkt verwenden, umändern, verknüpfen etc..
Hierbei muss man aber eines bedenken: die Daten gelten trotz des sequentiellen Busses sowohl beim Senden als auch beim Empfangen als synchron.
Das hat zum Beispiel zur Folge, dass rein logisch die fünf Zahlen insgesamt nur einen Event auslösen können und nicht mehrere hintereinander. Das ist praktisch, da man nicht extra auf bestimmte Daten „warten” muss und ein Zugriff gleichzeitig erfolgt. Wenn man das nicht wünscht, dann kann man auch das receive_synchronous etwas vereinfachen, aber warum sollte man einen Luxus aufgeben?
Dass die Daten innerhalb der CoreCell tatsächlich logisch zeitgleich sind, kann man durch eine kleine Veränderung beweisen: Wir führen die Ausgänge des Makros mit Hilfe eines Mergers zusammen und beobachten nun den gemeinsamen Ausgang. Wir sehen, dass nur der letzte Wert ausgegeben wird. Zeitgleiche Events werden von einem Merger immer so behandelt, dass nur der unterste Wert weitergereicht wird. Wären die Events nicht zeitgleich, würden mehrere Events ausgegeben.
Zum Abschluss dieses Abschnittes wollen wir noch mal einen Blick in das Makro receive_synchronous werfen: Ich bin immer wieder fasziniert davon, wie klar und strukturiert der Aufbau ist; ein relativ kurzer Blick genügt schon, um die Hauptidee zu verstehen:
Wir dürfen bei der Interpretation dieses Makros nicht vergessen, dass die Daten zunächst sequentiell ankommen. Damit sie als zeitgleich gelten, werden sie am Schluss (ganz rechts) durch einen gemeinsamen Trigger weitergeleitet. Dieser Trigger wartet den letzten Index ab ([]=#-1). Dazwischen werden die Daten mit Hilfe eines Decodierers und einens Routers verteilt. Der Decodierer ist einfach gestaltet, mit der Logik habe ich mich noch nicht vertraut gemacht; da warte ich ab, wenn ich mal nichts zu tun haben sollte. Ich nehme das Makro als Blackbox hin wie so viele kleine Helfer.
Wenn man übrigens den Trigger und die Value-Makros entfernt, erhielte man alle Daten sequentiell, aber wer will das schon?
Die Verarbeitung der herausgefilterten Daten ist in der Regel nicht ein bloßes Abrufen; natürlich möchte man in der empfangenden CoreCell diese Daten auch direkt verwenden, umändern, verknüpfen etc..
Hierbei muss man aber eines bedenken: die Daten gelten trotz des sequentiellen Busses sowohl beim Senden als auch beim Empfangen als synchron.
Das hat zum Beispiel zur Folge, dass rein logisch die fünf Zahlen insgesamt nur einen Event auslösen können und nicht mehrere hintereinander. Das ist praktisch, da man nicht extra auf bestimmte Daten „warten” muss und ein Zugriff gleichzeitig erfolgt. Wenn man das nicht wünscht, dann kann man auch das receive_synchronous etwas vereinfachen, aber warum sollte man einen Luxus aufgeben?
Dass die Daten innerhalb der CoreCell tatsächlich logisch zeitgleich sind, kann man durch eine kleine Veränderung beweisen: Wir führen die Ausgänge des Makros mit Hilfe eines Mergers zusammen und beobachten nun den gemeinsamen Ausgang. Wir sehen, dass nur der letzte Wert ausgegeben wird. Zeitgleiche Events werden von einem Merger immer so behandelt, dass nur der unterste Wert weitergereicht wird. Wären die Events nicht zeitgleich, würden mehrere Events ausgegeben.
Zum Abschluss dieses Abschnittes wollen wir noch mal einen Blick in das Makro receive_synchronous werfen: Ich bin immer wieder fasziniert davon, wie klar und strukturiert der Aufbau ist; ein relativ kurzer Blick genügt schon, um die Hauptidee zu verstehen:
Wir dürfen bei der Interpretation dieses Makros nicht vergessen, dass die Daten zunächst sequentiell ankommen. Damit sie als zeitgleich gelten, werden sie am Schluss (ganz rechts) durch einen gemeinsamen Trigger weitergeleitet. Dieser Trigger wartet den letzten Index ab ([]=#-1). Dazwischen werden die Daten mit Hilfe eines Decodierers und einens Routers verteilt. Der Decodierer ist einfach gestaltet, mit der Logik habe ich mich noch nicht vertraut gemacht; da warte ich ab, wenn ich mal nichts zu tun haben sollte. Ich nehme das Makro als Blackbox hin wie so viele kleine Helfer.
Wenn man übrigens den Trigger und die Value-Makros entfernt, erhielte man alle Daten sequentiell, aber wer will das schon?
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: Beispiel 2: einfacher Eventblock
Beispiel 2: einfacher Eventblock (Teil 6)
Senden und Empfangen sind jetzt klar. Was könnte man damit anfangen?
Innerhalb der Core-Cell kann man z.B. den Identifier, die Werte, die Anzahl der Daten und die Reihenfolge verändern.
Ändern des Identifiers
Ausgangspunkt ist eine einfache Sende-Empfangs-Struktur. Ich verzichte hier mal zunächst auf das synchrone Empfangen und wende mal nur die Abfrage des Identifiers an. Wir erinnern uns, dass der Sender mit dem Identifier 0 sendet (erster roter Event). Im Empfangsmodul wird nun der Identifier 0 abgefragt und entsprechend der Gleichheit auch durchgelassen. Hier beachtet wieder die Reihenfolge, wie REAKTOR die Events anzeigt. Jeder einzelne Event wird hier getrennt von hinten nach vorne abgearbeitet und somit als einzelner Verbraucher (sink) angesehen.
Setzt man den Abfrage-Identifier auf einen anderen Wert als 0, wird der Bus nicht durchgelassen. Leitet man den Bus auf mehrere raw_receive_gate-Module könnte man so verschiedene Datensätze (messages) umleiten und unterschiedlich behandeln.
Wir können natürlich den Identifier auch direkt ändern. Das funktioniert (man erhält das Ergebnis der 2. Abbildung mit dem geänderten Identifier), aber so richtig befriedigend ist das nicht, da man in einer längeren Kette von Sende - und Empfangsmodulen doch den Verdacht hat, dass bei dem wechselseitigen Auftreten der Events doch etwas schief gehen könnte; wenn schon Block, dann auch ein richtiger Block!
Senden und Empfangen sind jetzt klar. Was könnte man damit anfangen?
Innerhalb der Core-Cell kann man z.B. den Identifier, die Werte, die Anzahl der Daten und die Reihenfolge verändern.
Ändern des Identifiers
Ausgangspunkt ist eine einfache Sende-Empfangs-Struktur. Ich verzichte hier mal zunächst auf das synchrone Empfangen und wende mal nur die Abfrage des Identifiers an. Wir erinnern uns, dass der Sender mit dem Identifier 0 sendet (erster roter Event). Im Empfangsmodul wird nun der Identifier 0 abgefragt und entsprechend der Gleichheit auch durchgelassen. Hier beachtet wieder die Reihenfolge, wie REAKTOR die Events anzeigt. Jeder einzelne Event wird hier getrennt von hinten nach vorne abgearbeitet und somit als einzelner Verbraucher (sink) angesehen.
Setzt man den Abfrage-Identifier auf einen anderen Wert als 0, wird der Bus nicht durchgelassen. Leitet man den Bus auf mehrere raw_receive_gate-Module könnte man so verschiedene Datensätze (messages) umleiten und unterschiedlich behandeln.
Wir können natürlich den Identifier auch direkt ändern. Das funktioniert (man erhält das Ergebnis der 2. Abbildung mit dem geänderten Identifier), aber so richtig befriedigend ist das nicht, da man in einer längeren Kette von Sende - und Empfangsmodulen doch den Verdacht hat, dass bei dem wechselseitigen Auftreten der Events doch etwas schief gehen könnte; wenn schon Block, dann auch ein richtiger Block!
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: Beispiel 2: einfacher Eventblock
Beispiel 2: einfacher Eventblock (Teil 7)
Wenn schon Block, dann auch richtiger Block!
Da hilft natürlich das synchrone Empfangen und Senden. Wir verweilen hier ein wenig, da dieses Beispiel weitere Einblicke in die Funktionsweise vom framework gibt: Beim Starten des Ensembles wird übrigens nichts gesendet, da ich einen Unterbrecher hinter den 1. Sendebutton gesetzt habe. Wir sehen weiterhin nun zwei Trigger-Buttons, der erste sendet den Block aus, der zweite empfängt, bearbeitet und sendet den veränderten Block.
Wir drücken zunächst Sende 1, die roten Events erscheinen, danach Sende 2, die grünen Events erscheinen.
Wir drücken nochmals Sende 2 - nichts passiert! Wer sich dafür interessiert, sollte einen Blick bis ins tiefste Innere werfen und sich mit dem Iterator singleshot beschäftigen. Er benötigt an seinem Eingang # (Anzahl der events, die er einmal senden soll) einen Event. Der singleshot reduziert während seiner Arbeit die Anzahl intern auf 0. Somit bewirkt ein weiterer Triggerimpuls außen am chain_iterator nichts.
Das heißt, wir benötigen nicht nur einen Trigger, um den chain_iterator zu starten, sondern auch einen Event über die Anzahl der Daten die gesendet werden müssen.
Hmm, das ist umständlich; wir können doch nicht jedesmal zwei Button drücken, nur um einen Eventblock weiter leiten zu können?
Das muss automatisch erfolgen!
Das tut's auch, wenn wir einfach überlegen, was nötig ist: wir wollen, dass ein beliebiger Eventblock ausgelesen wird und die Daten zeitgleich zur Verfügung stehen; gleichzeitig soll die Anzahl der Daten an den SingleShot übergeben werden und dann noch der chain_iterator getriggert werden.
Da die Daten ja sequentiell eintreffen, konzentrieren wir uns auf den letzten Wert; er muss der Auslöser sein.
Es gibt ein solches Makro, das den letzten Wert als Trigger ausgibt: trigger_on_last zu finden in der primary-Abteilung des multiplexing-Ordners. An den Ausgängen des Makros erkennt man, dass er den Bus {b} weiterleitet und eben auch den Trigger mit dem letzten Wert an den chain Iterator übergibt. Nun liefert ein Druck auf Sende 1 wie gewünscht das Übertragen des roten Eventblocks zum grünen Eventblock.
Wenn schon Block, dann auch richtiger Block!
Da hilft natürlich das synchrone Empfangen und Senden. Wir verweilen hier ein wenig, da dieses Beispiel weitere Einblicke in die Funktionsweise vom framework gibt: Beim Starten des Ensembles wird übrigens nichts gesendet, da ich einen Unterbrecher hinter den 1. Sendebutton gesetzt habe. Wir sehen weiterhin nun zwei Trigger-Buttons, der erste sendet den Block aus, der zweite empfängt, bearbeitet und sendet den veränderten Block.
Wir drücken zunächst Sende 1, die roten Events erscheinen, danach Sende 2, die grünen Events erscheinen.
Wir drücken nochmals Sende 2 - nichts passiert! Wer sich dafür interessiert, sollte einen Blick bis ins tiefste Innere werfen und sich mit dem Iterator singleshot beschäftigen. Er benötigt an seinem Eingang # (Anzahl der events, die er einmal senden soll) einen Event. Der singleshot reduziert während seiner Arbeit die Anzahl intern auf 0. Somit bewirkt ein weiterer Triggerimpuls außen am chain_iterator nichts.
Das heißt, wir benötigen nicht nur einen Trigger, um den chain_iterator zu starten, sondern auch einen Event über die Anzahl der Daten die gesendet werden müssen.
Hmm, das ist umständlich; wir können doch nicht jedesmal zwei Button drücken, nur um einen Eventblock weiter leiten zu können?
Das muss automatisch erfolgen!
Das tut's auch, wenn wir einfach überlegen, was nötig ist: wir wollen, dass ein beliebiger Eventblock ausgelesen wird und die Daten zeitgleich zur Verfügung stehen; gleichzeitig soll die Anzahl der Daten an den SingleShot übergeben werden und dann noch der chain_iterator getriggert werden.
Da die Daten ja sequentiell eintreffen, konzentrieren wir uns auf den letzten Wert; er muss der Auslöser sein.
Es gibt ein solches Makro, das den letzten Wert als Trigger ausgibt: trigger_on_last zu finden in der primary-Abteilung des multiplexing-Ordners. An den Ausgängen des Makros erkennt man, dass er den Bus {b} weiterleitet und eben auch den Trigger mit dem letzten Wert an den chain Iterator übergibt. Nun liefert ein Druck auf Sende 1 wie gewünscht das Übertragen des roten Eventblocks zum grünen Eventblock.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
-
- user
- Beiträge: 27
- Registriert: 27. März 2011, 12:42
Re: PARTIALS FRAMEWORK (multiplexing)
Eventblock5.ens darf sich jeder aus dem Bild "Beispiel 2-20.jpg" selbstbauen ?
Nett das du uns auchnochwas übriglässt herw
Edit:
Verstehe das jetzt so das EventBlock 5 fehlt da EventBlock 6 & 7 die Korrekte ausführung beinhalten und 5 somit überflüssig wird.
Nett das du uns auchnochwas übriglässt herw
Edit:
Verstehe das jetzt so das EventBlock 5 fehlt da EventBlock 6 & 7 die Korrekte ausführung beinhalten und 5 somit überflüssig wird.
- herw
- moderator
- Beiträge: 3123
- Registriert: 13. März 2006, 18:28
- Wohnort: Dortmund
Re: PARTIALS FRAMEWORK (multiplexing)
ja, ich hatte eine falsche Nummerierung gewählt: Eventblock 5.ens = eventblock 6.ens.macrospank hat geschrieben:Eventblock5.ens darf sich jeder aus dem Bild "Beispiel 2-20.jpg" selbstbauen ?
Nett das du uns auchnochwas übriglässt herw
Edit:
Verstehe das jetzt so das EventBlock 5 fehlt da EventBlock 6 & 7 die Korrekte ausführung beinhalten und 5 somit überflüssig wird.
Ich habe es nun korrigiert. In deinem Download musst du nur 6 in 5 und 7 in 6 umbenennen.
War wohl ein bisschen zu viel Schreiberei heute; aber das wunderschöne Herbstwetter verführte dazu.
Jetzt muss erstmal gut sein. Morgen geht's weiter mit Änderung von Werten und der Reihenfolge.
Ich möchte auch noch das Einlesen in eine EventTable und in ein SnapValueArray und das Auslesen beiden behandeln, bevor ich dann erst mal für einige Zeit offline bin. Damit lässt sich dann schon viel anfangen.
ciao herw
-
- user
- Beiträge: 27
- Registriert: 27. März 2011, 12:42
Re: PARTIALS FRAMEWORK (multiplexing)
Ok gut. Hast wirklich ordentlich was vermittelt heute. Vielen Dank dafür.
Ich wünsch dir noch nen Schönen Sonntagabend und freu mich schon auf die nächsten Teile.
Ich wünsch dir noch nen Schönen Sonntagabend und freu mich schon auf die nächsten Teile.