![]() |
AW: Zwei unabhängige Zeitschleifen D7
Liste der Anhänge anzeigen (Anzahl: 1)
Stelle dir unsere Vorschläge etwa so vor:
(Jede Zeile stellt ein OnTimer-Event dar, sagen wir mal 250ms pro Zeile.)
Code:
Die DMX-Szenenanweisungen sind das, was du bereits hast. Diese sorgen dafür, dass in die Liste für den betreffenden Kanal ab Auftreten die nächsten N Zwischenwerte geschrieben werden. Dies passiert bei jedem Timer-Tick, je für eine Zeiteinheit weiter als vorher, aber eine Anweisung schreibt alle daraus resultierenden zukünftigen Werte bereits in einem Rutsch vorab in ihren Kanal. Nachdem die Szenenanweisungen fertig sind, gibst du nur noch die Werte der Kanäle aus und weiter geht's mit dem nächsten Tick. Das Geraffel mit diesem Pseudo-Delay ist ja noch viel schlimmer als mehrere Timer!
DMX-Szenenanweisung Kanal1 Kanal2 Kanal3 ... Kanal479
- 250 0 - 250 0 - 250 0 - 250 0 Fade to 90 Ch1 2sec 230 0 - 210 0 Fade to 100 Ch2 1sec 190 25 - 170 50 - 150 75 - 130 100 - 110 100 - 90 100 - 90 100 - 90 100 Bei meiner kleinen DMX-Dimmer Software habe ich es allerdings noch anders gemacht. Dort habe ich alle Funktionen (im Wesentlichen Fades, aber mit unterschiedlichen Interpolationsarten) in nette kleine Klassen verpackt, die je eine Fade-Sequenz auf einem Kanal darstellen. Jede der Instanzen kennt ihren Anfangszeitpunkt relativ zum Abspielstart der Gesamtszene, und ihre Länge sowie Start- und Endwert. Ich habe es nun so gemacht, dass ich diese Klasse fragen kann: Welchen Wert hast du denn zum Zeitpunkt X? Die Klasse gibt mir einen Wert zurück, und somit brauche ich in meinem Play-Thread nur noch Aktuelle Uhrzeit minus Startuhrzeit nehmen, habe ein exaktes Delta, und frage einfach alle gerade aktiven Sequenzen, welchen Wert sie mir den geben möchten für dieses Delta. Das hübsch in ein Array, und weg damit über DMX. Der riesen Vorteil: Ich bin komplett unabhängig vom konkreten Intervall, mit dem ich eine Szene abspiele. (Manche DMX-Konverter sind da etwas niggelich, deswegen habe ich ein SpinEdit mit dem man zwischen 5ms und 1000ms Intervallen verstellen kann - on the fly.) Weiterer Vorteil: Man kann beliebig in einer Szene hin und her springen und bekommt die für den Zeitpunkt aktuellen Werte. In dem angehängten Bild habe ich z.B. die Trackbar direkt an die Position gezogen, und die kleinen Quadrate rechts der Kanäle zeigen den korrekten Wert (die sind direkt aus dem Output-Array gefärbt). |
AW: Zwei unabhängige Zeitschleifen D7
Hi Medium,
sorry ich versteh das nicht ganz. Wie krieg ich diese 2 oder 1 Sec unter?? DMX-Szenenanweisung Kanal1 Kanal2 Kanal3 ... - 250 0 Fade to 90 Ch1 2sec 230 0 - 210 0 Fade to 100 Ch2 1sec 190 25 - 170 50 Die Scenen das hab ich nun im 250 ms Takt das geht auch ganz gut. Aber Du sagtest das geht alles ohne diesem dooofen Delay - aber wie?? Im übrigen dieses Programm (Dein bild) ist das in Delphi auch gemacht? Gruß beanbear |
AW: Zwei unabhängige Zeitschleifen D7
Sieh den gesamten zeitlichen Ablauf mal durch nur einen einzigen Taktgeber bestimmt, und sowohl deine Szene als auch einzelne Fades als Arrays, deren Index in Zeit angegeben wird (mal so hypothetisch). Die eigentliche Hauptaufgabe ist es dann zu jedem Timer Event einfach nur die Werte der einzelnen Arrays zum DMX Interface zu schicken. Ein Array mit 4 Elementen würde bei 250ms Takt einer Sekunde entsprechen. Ich versuche mal Pseudocode. (Skizze in Pascal-Art, kein C&P fähiger Code.)
Delphi-Quellcode:
Da das Szenen-Array ggf. etwas lang würde wenn man das Intervall kleiner macht (was sinnvoll wäre, da Fades mit 250ms nicht so toll aussehen), sollte man dafür vielleicht eher eine Liste nehmen, deren Index nicht der Zeit entspricht, sondern wo jeder Eintrag seine Startzeit als Feld bekommt. Dann muss man zwar pro Timer-Event alle Szenenanweisungen durchgehen, und schauen ob jetzt eine davon ansteht, aber das sollte selbst bei ein paar Tausend keine merkbare Performance kosten.
type
TFadeBlock = class private FValues: array of Byte; FStartTime: Integer; public property StartTime: Integer; property Values[index: Integer]: Byte; constructor Create(aStartTime, aLengthInSec: Integer); function GetValueAtTime(aTime: Integer): Byte; end; TMyForm = class(TForm) private Channels: array[1..479] of TFadeBlock; Scene: array of TSceneEvent; CurrentTime: Integer; end; implementation constructor TFadeBlock.Create(aStartTime, aLengthInSec: Integer); begin SetLength(FValues, aLengthInSec*(1/TimerInterval)); FStartTime := aStartTime; end; function GetValueAtTime(aTime: Integer): Byte; var i: Integer; begin i := Max(Low(FValues), Min(aTime-FStartTime, High(FValues))); result := FValues[i]; end; //-------------- procedure TMyForm.OnTimerEvent; begin // Channel-Liste anhand von Szenenanweisungen mit Fade-Blöcken versehen if Assigned(SceneEvents[CurrentTime]) then begin Event := SceneEvents[CurrentTime]; Channel := Event.Channel; Channels[Channel] := TFadeBlock.Create(CurrentTime, Event.LengthInSec); for i := 0 to High(Channels[Channel].Values) do // Internes Value-Array des Blocks mit den interpolierten Werten beschreiben, schöner wäre es noch wenn die Fade-Klasse dies selber täte Channels[Channel].Values[i] := Interpolate(Event.StartValue, Event.EndValue, i); end; // Nun einfach alle Kanäle "fragen" welchen Wert sie denn gerade haben, und den ausgeben for i := Low(Channels) to High(Channels) do begin if Assigned(Channels[i]) then OutputDMX(Channels[i].GetValueAtTime(CurrentTime), i); end; Inc(CurrentTime); end; Und ja, das ist mit Delphi geschrieben. Da ich dafür TurboPower AsyncPro (COM-Port) nutze und dies nur für Delphi 7 parat hatte, ist es sogar noch Delphi 7. |
AW: Zwei unabhängige Zeitschleifen D7
Hi Medium,
ich werd mich jetzt mal durch deinen Quellcode wursteln, kann noch nicht alles umsetzen... Aber ich versuch das mal. Vielen vielen Dank Dir gleich mal für die Postings! Wird wohl ein paar Tage dauern bis ich mich dann nochmal melde. Also vielen Dank... Gruß beanbear |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz