Entwickler-Ecke
Sonstiges (Delphi) - Timer und Midi
ssb-blume - Di 28.07.15 09:38
Titel: Timer und Midi
Hallo,
Ich habe ein merkwürdiges Verhalten eines Timers:
Der Timer wird in einer Procedur mit einem Parameter erlaubt/verboten.
Wird diese Procedur über einen Button-Click aufgerufen, funktioniert der Timer.
Wird aber über die Midi-Schnittstelle ein On/Off (9n note off, 9n note on) empfangen
und damit diese Procedur aufgerufen, wird zwar der Timer angesprochen, aber er läuft nicht.
Auch ein Break an dieser Stelle zeigt, obwohl ein enabled gesetzt wurde, dieses
nicht den Timer einschaltet!
Ich bin ratlos. Habe auch in dieser Procedur den Timer selbst erzeugt, kein Unterschied.
Kann es sein, daß die Midischnittstelle (über BASS.DLL) -Callback- der Timer nicht angesprochen wird?
Danke für eine Erklärung und evtl. eine Möglichkeit, wie ich es machen muß.
Hansi
baumina - Di 28.07.15 09:49
Könntest du evtl. den relevanten Code (wo was deklariert ist und wo/wie der Timer gestartet wird) hier posten.
Nersgatt - Di 28.07.15 09:56
Wenn ich das richtig im Kopf habe, arbeitet der TTimer mit der WM_TIMER Message von Windows. Das ist ein Low-Priority-Message. Das heißt, das wird nur ausgeführt, solange die Anwendung nichts besseres zu tun hat. Nu weiß ich nicht, wie die MIDI-Schnittstelle arbeitet, könnte mir aber vorstellen, dass da noch was anderes abläuft.
Ich verwende eigentlich nie mehr den TTimer. Ich schreib mir da lieber einen Thread, dem ich im Bedarfsfall die Arbeit übergeben kann. Eine einfache Threadschleife
Delphi-Quelltext
1: 2: 3: 4: 5:
| while not terminated do begin MachArbeit; Sleep(1000); end; |
ist ja schon ein simpler Timer, wenn man so will.
ssb-blume - Di 28.07.15 10:41
Hier etwas Code:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| public void MyMidiInProc(IntPtr handle, MIDIMessage msg, IntPtr instance, IntPtr param1, IntPtr param2) { v = Convert.ToInt32(b3, 16); mode = Convert.ToByte(b1, 16); key = Convert.ToByte(b2, 16); channel = Convert.ToByte(b0, 16); pressed = (b1 == "9") & (b3 != "00"); vel = (float)Convert.ToDouble(v); .... if ((channel == 4) & (key == 17)) { starteTimer(pressed) } }
private void starteTimer(bool on) { timer3 = new Timer(); if (on) { int f = Convert.ToInt32(vibF.Value); timer3.Interval = 500; timer3.Tick += timer3_Tick; timer3.Enabled = true; timer3.Start(); } else { timer3.Stop(); timer3.Enabled = false; timer3.Dispose(); } } |
:baumina: kannst Du damit was anfangen? Ich habe Unwesentliches weggelassen.
hansi
baumina - Di 28.07.15 10:44
Ups, irgendwie hatte ich mit Delphicode gerechnet, sry ich passe.
Nersgatt - Di 28.07.15 10:47
Dem schließe ich mich an.... :lol:
jaenicke - Di 28.07.15 10:52
Kann es sein, dass du an der Stelle in einem Thread bist?
ssb-blume - Di 28.07.15 11:01
Hallo jaenicke,
ja, denn es ist ja ein Callback!
Trotzdem sind noch viele weitere Funktionen, die abgearbeitet werden, in diesem Kontext ok.
Nur der Timer wird ja erzeugt, ist auch vorhanden, aber macht nix. Die Kontrolle im Break,
ergab, das der Timer zwar existierte, der aber das Enable nicht entgegen nimmt.
Hansi
jaenicke - Di 28.07.15 11:08
Der Timer funktioniert bei C# auch nur im Hauptthread soweit ich weiß.
// EDIT:
Scheint doch zu gehen. Aber vielleicht wird der Thread z.B. wieder beendet und es geht deshalb nicht.
Hier gibt es ein Beispiel explizit für Threads:
https://msdn.microsoft.com/de-de/library/swx5easy(v=VS.120).aspx
ssb-blume - Di 28.07.15 15:49
Danke jaenicke, werd es mal probieren...
Hansi
ssb-blume - Di 28.07.15 17:23
Danke nochmals. Es geht jetzt genau so, wie ich es wollte.
Das Beispiel konnte ich sogar noch etwas verkleinern.
Hansi
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!