Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Timing problem (https://www.delphipraxis.net/159686-timing-problem.html)

EWeiss 8. Apr 2011 11:08

AW: Timing problem
 
Auf den ersten Bilck schon..
wenn dann würde ich eh meinen WaitableTimer verwenden
damit wäre es möglich solange zu warten bis der Loop nach dem übermitteln PlayingSong = False
abgearbeitet ist.

Aber dazu müßte ich einen Thread erstellen was nicht so einfach ist da viel Faktoren hier eine Rolle spielen.

gruss

Namenloser 8. Apr 2011 11:33

AW: Timing problem
 
Der (wichtige) Unterschied ist: Hagens Procedure nutzt
Delphi-Quellcode:
MsgWaitForMultipleObjects
, sodass die Anwendung schläft, solange nicht eine Input-Message hereinkommt oder die Wartezeit überschritten wird. Deshalb verbraucht sie deutlich weniger Ressourcen:
Delphi-Quellcode:
procedure Delay(Milliseconds: Integer);
var
  Tick: DWord;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := GetTickCount + DWord(Milliseconds);
    while (Milliseconds > 0) and
          (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Application.ProcessMessages;
      if Application.Terminated then Exit;
      Milliseconds := Tick - GetTickcount;
    end;
  finally
    CloseHandle(Event);
  end;
end;
Eigentlich musst du nur
Delphi-Quellcode:
Application.ProcessMessages;
durch deine eigene Message-Abarbeitungsroutine ersetzen...

EWeiss 8. Apr 2011 12:00

AW: Timing problem
 
Du meinst also quasi
Anstelle von Winprocessmessages
Delphi-Quellcode:
Delay(Milliseconds: Integer);
verwenden und damit über meine Winprocessmessage gehen..

Soweit habe ich das verstanden.
Nur was für einen Sinn macht das wenn ich beisp. den Song abspiele und dann
Delay(1000) also eine sekunde warten lasse.

Dann tut sich ja auf meinem ganzen Window nix mehr oder?

Aber wenn es was bringt um das Timing problem zu beseitigen kann ich es ja mal versuchen.

Mein Bedenken ist nur wenn sich der Loop gerade zu der Zeit
wo ich die Anwendung beende in Drawgraphics befinde hat auch das Delay zu der Zeit keine Funktion
und kann nicht eingreifen und genau dort das abspielen des Songs beenden.

Also wird sich das Window genausowenig schließen lassen.

EDIT:
Im moment ist es so das kein Interesse mehr an meinem Projekt besteht
Also Download = 0 und das obwohl jetzt fast alles fertig ist.
Sonst hätte ich den Source schon hochgeladen.
Nur was macht das für einen Sinn wenn es niemanden mehr Interessiert. ;)


gruss

Namenloser 8. Apr 2011 14:44

AW: Timing problem
 
Ich weiß nicht, wie dein PlayNotes aussieht. Ich dachte nur, wenn da z.B. eine Note ist, die für 1 Sekunde spielt, dann kann das Programm 1 Sekunde schlafen, bis es die nächste Note abspielt. So wäre das zumindest, wenn du MIDI zum Abspielen verwendest. Wie das auf dein konktretes Programm anzuwenden ist, sprich, wo es sich eine Pause gönnen kann, musst du wissen.

Wenn dein Programm tatsächlich permanent etwas tut, dann wirst du auch nicht um die 100% CPU-Auslastung herumkommen...

PS: Ich werde dein Programm erst dann wieder runterladen, wenn Grund zur Annahme besteht, dass das Problem, das bei mir den Start verhindert, behoben ist ;)

alfold 8. Apr 2011 14:47

AW: Timing problem
 
Ich weiss es ist nonVcl! Vom Prinzip her nichts anderes!
Aber warum machst du es Dir selber schwerer als es sein muss?
In VCL würde ich einen Timer nehmen und dann nicht while benutzen sondern
If songplay then usw.
Vorteil liegt klar auf der Hand, Du hast keine while schleife in der Du nun festhängst!
CPU last würde damit auch nach unten gehen.
Wie man einen Timer in nonVCL schreibt mh.. muss ich passen.

Soll ja auch nur als Anregung dienen!

alfold

DeddyH 8. Apr 2011 15:01

AW: Timing problem
 
Zitat:

Zitat von alfold (Beitrag 1093937)
Wie man einen Timer in nonVCL schreibt mh.. muss ich passen.

Das ist recht überschaubar: http://msdn.microsoft.com/de-de/library/ee503884.aspx

EWeiss 8. Apr 2011 15:02

AW: Timing problem
 
Zitat:

Zitat von alfold (Beitrag 1093937)
Ich weiss es ist nonVcl! Vom Prinzip her nichts anderes!
Aber warum machst du es Dir selber schwerer als es sein muss?
In VCL würde ich einen Timer nehmen und dann nicht while benutzen sondern
If songplay then usw.
Vorteil liegt klar auf der Hand, Du hast keine while schleife in der Du nun festhängst!
CPU last würde damit auch nach unten gehen.
Wie man einen Timer in nonVCL schreibt mh.. muss ich passen.

Soll ja auch nur als Anregung dienen!

alfold

Ich habe kein Problem einen Timer zu erstellen das sind zwei Zeilen ;)
SetTimer und KillTimer das ist alles.

Das problem ist aber nicht der Timer selbst sondern er muss auch warten wenn eine andere Aktion ausgeführt wird.
Das soll er auch .. Aber das geht nur über einen eigenen Thread bzw einer Callback.

Ich habe meinen Timer und der wartet auch..
Muss mal sehen ob ich damit bessere Karten habe.

Delphi-Quellcode:
function MySetWaitableTimer(hTimer: THandle;
                            var lpDueTime: TLargeInteger;
                            lPeriod: longint;
                            pfnCompletionRoutine: TFNTimerAPCRoutine;
                            lpArgToCompletionRoutine: Pointer;
                            fResume: BOOL): BOOL;
                            stdcall; external 'kernel32.dll' name 'SetWaitableTimer';

Zitat:

Wenn dein Programm tatsächlich permanent etwas tut, dann wirst du auch nicht um die 100% CPU-Auslastung herumkommen...
Na ja hab 25% aber dann ackert er auch..
Denke damit kann ich leben ..

Bei normalen Grafik Operationen sind es 0%

Zitat:

PS: Ich werde dein Programm erst dann wieder runterladen, wenn Grund zur Annahme besteht,
dass das Problem, das bei mir den Start verhindert, behoben ist
Kann ich ganz und voll verstehen nur wie soll ich das beheben wenn der Download gleich 0 ist.
Macht es dann Sinn den Quelltext noch hochzuladen ?

gruss

alfold 8. Apr 2011 15:44

AW: Timing problem
 
hab mich vielleicht blöd ausgedrückt: unabhängig von nonVCL oder VCl bitte. Nur im Prinzip!

Delphi-Quellcode:
TForm1.Timer1Timer(sender: Tobject)
begin
    if Playsong then
    begin
        PlayNotes;//<--wobei das evtl hier im Timer nicht wichtig ist? 
        DrawGraphics(WinHandle);
        hsi.nPos := StartX + XSizeMid;
        SetScrollInfo(WinHandle, SB_HORZ, hsi, True);
    end;
end;
Ich weiss es ist nicht so einfach wie oben geschrieben, ist ja nur ne Überlegung.
Worauf soll Dein Timer warten? WEnn ich dich richtig verstehe geht es darum Die note/Pause abzuspielen, dabei gleichzeitig die graphik zu aktuallisieren.

Zumal die Aktuallisierung der Graphic ja nur vom Tempo wichtig ist. Ob Du da 8tel 16tel oder 32tel darstellen tust ist der Graphic egal. Wichtig ist die sychronisation!
Also evtl trennen, siehe im Timer!

alfold

EWeiss 8. Apr 2011 15:50

AW: Timing problem
 
Zitat:

PlayNotes;//<--wobei das evtl hier im Timer nicht wichtig ist?
Darauf baut sich alles auf.
Wie kommst du darauf das es nicht wichtig sein soll ?
Ohne dem Spielt einfach kein Ton.

Der Grafik ist das nicht egal denn das Grid verwaltet nun mal die noten
Und diese werden eingelesen abhängig von den Balken (Abtastbar) wie lange sie sich über einer Noten befindet.
Und die kann ganz lang sein.

Also eine kombination zwichen Grafik Timing und der länge der noten (was wiederum mit dem Timing zu tun hat).
Werde es nachher mal mit meinem Timer versuchen der auf die Events wartet.

gruss

alfold 8. Apr 2011 16:10

AW: Timing problem
 
Missvertändniss! Playnotes meine ich im Timer evtl überflüssig! Weil Du damit nur "die Melodie" spielst, hat aber mit der Anzeige im eigentlichen nichts zu tun:wink:
Denn abspielen kannst Du auch ohne graphic das meint ich damit!

alfold

EWeiss 8. Apr 2011 16:27

AW: Timing problem
 
Zitat:

Zitat von alfold (Beitrag 1093968)
Missvertändniss! Playnotes meine ich im Timer evtl überflüssig! Weil Du damit nur "die Melodie" spielst, hat aber mit der Anzeige im eigentlichen nichts zu tun:wink:
Denn abspielen kannst Du auch ohne graphic das meint ich damit!

alfold

Nein .. Ohne Grafik geht gar nichts das Programm ist so aufgebaut das x,y Koordinaten mit der AbtastLeiste
aufgenommen werden und mit einem array verglichen werden wo einmal der erste eintrag für die Spur von 0..7 steht
und der zweite 0..1000 für die maximale eingabe an noten pro Spur.

gruss

alfold 8. Apr 2011 18:15

AW: Timing problem
 
Da hast Du dir aber selbst das Problem gebaut!
Nenne mal Qauntisierung, ist reine Mathematik bei MIDI.
Die Graphic selber dient mir ja nur um evtl die Note genauer zuplatzieren. Taktanfang zb. oder wenn ich sie zu kurz gespielt habe ebend mal zu verlängern von 1/8 auf 1/4 zb ist also nur Hilfsmittel bei MIDI.
Das Du das Problem Lösen wirst da hab ich volles Vertrauen, nur der Ansatz, die Graphic in den Vordergrund zu setzen, anstatt auf das Eigentlich die MIDIEEVENTS (MIDIFILE)für den Aufbau der Graphic zu nutzen, halte ich nicht für gut!

Gruss alfold

rollstuhlfahrer 8. Apr 2011 18:34

AW: Timing problem
 
Ich möchte dann doch noch mal auf #1 zurückkommen:
Zitat:

Zitat von EWeiss
Delphi-Quellcode:
  // Starte den Song
  while PlayingSong do
  begin
    //Weiterlaufen bis die 16.tel Note (Pause) abgelaufen ist
    while GetTickCount < Tick + TempoWait do
      Winprocessmessages;

    Tick := GetTickCount;
    PlayNotes;
    DrawGraphics(WinHandle);
    hsi.nPos := StartX + XSizeMid;
    SetScrollInfo(WinHandle, SB_HORZ, hsi, True);
  end;

Du versuchst also die restliche Zeit damit abzuwarten, indem du immer wieder das System frägst, ob nicht irgendwelche Fensternachrichten da sind. Hier in der Mitte dieses Threads wurde auf die "richtige" nonvcl-übersetzung des Delays hingewiesen. Jetzt kannst du ganz einfach dein ressourcenfressendes
Delphi-Quellcode:
while GetTickCount < Tick + TempoWait do Winprocessmessages;
durch ein simples
Delphi-Quellcode:
Delay(Tick + TempoWait - GetTickCount);
ersetzen. Dann sollte sich das ganze mit der Warterei gelöst haben.

Bernhard

EWeiss 8. Apr 2011 19:17

AW: Timing problem
 
Da tut sich rein gar nichts..
Das mag zwar resourcen schonender sein aber mein Window kann ich trotzdem nicht schließen während der Song
am spielen ist.

Delphi-Quellcode:
procedure TMidiTracker.Delay(Milliseconds: Integer);
var
  Tick: DWord;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := GetTickCount + DWord(Milliseconds);
    while (Milliseconds > 0) and
          (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Winprocessmessages;
      if PlayingSong = False then Exit;
      Milliseconds := Tick - GetTickcount;
    end;
  finally
    CloseHandle(Event);
  end;
end;

Delphi-Quellcode:
  // Starte den Song
  while PlayingSong do
  begin
    //Weiterlaufen bis die 16.tel Note (Pause) abgelaufen ist
    //while GetTickCount < Tick + TempoWait do
    //  Winprocessmessages;

    Delay(Tick + TempoWait - GetTickCount);

    Tick := GetTickCount;
    PlayNotes;
    DrawGraphics(WinHandle);
    hsi.nPos := StartX + XSizeMid;
    SetScrollInfo(WinHandle, SB_HORZ, hsi, True);
  end;
Danke trotzdem..

EDIT:
OH sorry doch tut sich mehr als gedacht..
Von 25% CPU runter auf 1%

Aber warum kann ich mein Window nicht schließen.
grrrrr....
gruss

rollstuhlfahrer 8. Apr 2011 19:19

AW: Timing problem
 
Und du setzt auch sobald die Schließen-Nachricht kommst dein "PlayingSong" auf FALSE?

Bernhard

ADD:
Zitat:

Zitat von EWeiss (Beitrag 1094004)
Delphi-Quellcode:
if PlayingSong = False then Exit;

Iiihhh. Da muss ein
Delphi-Quellcode:
if not PlayingSong then
hin.

EWeiss 8. Apr 2011 19:29

AW: Timing problem
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1094005)
Und du setzt auch sobald die Schließen-Nachricht kommst dein "PlayingSong" auf FALSE?

Bernhard

ADD:
Zitat:

Zitat von EWeiss (Beitrag 1094004)
Delphi-Quellcode:
if PlayingSong = False then Exit;

Iiihhh. Da muss ein
Delphi-Quellcode:
if not PlayingSong then
hin.

Jup habe es auch gerade bemerk ;)
Danke für den Hinweis.

Jo wenn der Song zu ende ist bzw der Button Stop gedrückt wird
dann wird die False gesetzt

EDIT:
Muss jetzt noch mal genau die Windows Messagen prüfen
Warum das Window nicht schließt.
Geht erst wenn der Song beendet ist (sagte ich aber schon) ;)


gruss

rollstuhlfahrer 8. Apr 2011 19:35

AW: Timing problem
 
Das war ja nicht die Frage. Die Frage war, ob PlayingSong auf FALSE gesetzt wird, wenn WM_CLOSE bei dem entsprechenden Fenster ankommt?

Bernhard

EWeiss 8. Apr 2011 19:40

AW: Timing problem
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1094010)
Das war ja nicht die Frage. Die Frage war, ob PlayingSong auf FALSE gesetzt wird, wenn WM_CLOSE bei dem entsprechenden Fenster ankommt?

Bernhard

Ach so das meinst du..
Muss das nochmal setzen gestern hat es aufgrund der langen wartezeit durch den Loop nicht funktioniert.

Gebe gleich bescheid ;)

EDIT:
Ich behandle die WM_CLOSE Message nicht.
Unter ..
Delphi-Quellcode:
    WM_DESTROY:
    begin
      if MidiTracker.PlayingSong then
        MidiTracker.PlayingSong := False;
      SaveINI;
      PostQuitMessage(0);
      Result := 1;
      Exit;
    end;
funktioniert es nicht.
Das Lied läuft noch währen PostQuitMessage(0);
ausgeführt wurde.

gruss

alfold 8. Apr 2011 20:02

AW: Timing problem
 
Du hast doch sicherlich irgendwo PLaystart und Playstop Procdure!
Du musst natürlich auch die Playstop Procedure aufrufen bevor du was beendest!:wink:

alfold

EWeiss 8. Apr 2011 20:06

AW: Timing problem
 
Zitat:

Zitat von alfold (Beitrag 1094014)
Du hast doch sicherlich irgendwo PLaystart und Playstop Procdure!
Du musst natürlich auch die Playstop Procedure aufrufen bevor du was beendest!:wink:

alfold

Jetzt ist aber gut oder ? :)
Ich habe nur eine Play Procedure welche den Status False/True setzt die kann ich aber beim beenden
der anwendung nicht verwenden weil dann ein neuer Zugriff auf meine DLL stattfindet und
das Caption des Button auf Play gesetzt wird.

Also muss ein SongPlaying = False reichen.
Da ist irgendwas anderes im Bush

Habe jetzt
Delphi-Quellcode:
    ID_CLOSE:
    begin
      // Anwendung beenden
      Sendmessage(WinHandle, WM_CLOSE, 0, 0);
      Sendmessage(WinHandle, WM_DESTROY, 0, 0);
      //PostQuitMessage(0);
      Result := True;
      Exit;
    end;
WM_CLOSE Message noch hinzugefügt was eigentlich nicht notwendig ist..
Jetzt schließt das Fenster aber die IDE von Delphi hängt.
Ist ein zeichen das irgendwas noch nicht richtig beendet wurde.
Nach PostQuitMessage

PS:
Die Probleme habe ich aber nicht wenn der Song nicht läuft.

gruss

rollstuhlfahrer 8. Apr 2011 21:21

AW: Timing problem
 
Zitat:

Zitat von EWeiss (Beitrag 1094016)
Delphi-Quellcode:
      // Anwendung beenden
      Sendmessage(WinHandle, WM_CLOSE, 0, 0);
      Sendmessage(WinHandle, WM_DESTROY, 0, 0);

Das ist jetzt auch wieder nix. Du schickst NUR WM_CLOSE an dein Fenster. In der entsprechenden Nachrichtenschleife rufst du bei einer solchen Nachricht MSDN-Library durchsuchenDestroyWindow() auf. Das bewirkt dann, dass WM_DESTROY aufgerufen wird. Außerdem solltest du in einer solchen Situation auch MSDN-Library durchsuchenPostMessage() benutzen.

Bernhard

EWeiss 8. Apr 2011 21:30

AW: Timing problem
 
Zitat:

Zitat von rollstuhlfahrer (Beitrag 1094021)
Zitat:

Zitat von EWeiss (Beitrag 1094016)
Delphi-Quellcode:
      // Anwendung beenden
      Sendmessage(WinHandle, WM_CLOSE, 0, 0);
      Sendmessage(WinHandle, WM_DESTROY, 0, 0);

Das ist jetzt auch wieder nix. Du schickst NUR WM_CLOSE an dein Fenster. In der entsprechenden Nachrichtenschleife rufst du bei einer solchen Nachricht MSDN-Library durchsuchenDestroyWindow() auf. Das bewirkt dann, dass WM_DESTROY aufgerufen wird. Außerdem solltest du in einer solchen Situation auch MSDN-Library durchsuchenPostMessage() benutzen.

Bernhard

PostMessage wird oder soll nur in der Anwendung selbst und nicht aus meiner DLL aufgerufen werden.
Diese schickt normalerweise nur ein WM_DESTROY und das ist allemal ausreichend.
WM_CLOSE habe ich nur mal Testweise eingebunden ob dies mein Problem löst.

Also das was du da ansprichst sind die Messagen die ich aus meiner DLL sende
Die verwaltet aber nur Grafische Operationen und soll nicht das Recht haben die Anwendung zu schließen.


EDIT:
opps ..
Du meinst PostMessage jo das stimmt denn beim beenden muß ich nicht mehr warten
ob eine Rückantwort kommt.
Manchmal sollte man schon richtig lesen ;)
gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:47 Uhr.
Seite 2 von 2     12   

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