GLBasic forum

Other languages => GLBasic - de => Topic started by: Trabant 500 on 2010-Feb-07

Title: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-07
Servus.

Ich sitze oft hinter meinem Schlagzeug und spiele einfach so vor mich hin. Dabei kommt es hin und wieder vor das mir ein Rhythmus gut gefällt und ich nichts zum Aufschreiben dabeihabe. Meinen WIZ habe ich allerdings immer einstecken und deswegen habe ich mir einen kleinen Drumcomputer programmiert.
Aus der aktuellen BPM-Zahl wird die Länge eines Ticks berechnet und wenn die vergangene Zeit gleich oder größer als diese Länge ist, wird einen Tick weitergezählt und die aktuellen Sounds ausgegeben.
Die vergangene Zeit wird mit GETTIMERALL() berechnet, aber irgendwie ist das zu ungenau. Wie man sich vorstellen kann muss sowas so exakt wir ein schweizer Uhrwerk laufen. Leider tut es das aber nicht, weil die vergangene Zeit immer größer ist als die benötigte. Dadurch holpert es manchmal und läuft auch absolut nicht im Metrum.
Hat jemand eine Idee wie man dieses Problem beheben und das Programm absolut exakt machen kann ?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-07
Also ich habe ein paar Testdurchläufe auf dem PC gemacht. Dabei habe ich den Drumcomputer eine Minute durchlaufen lassen und danach hat er mir die größte benötigte Zeit pro Tick ausgegeben. Ein Tick ist übrigens die Länge einer 16tel-Note (von einem 4/4-Takt ausgehend).

Hier die Ergebnisse dieser Testläufe:
QuoteBPM   Tickzeit   benötigte Zeit(gerundet)
  60   250         269
  80   187,5      216
100   150         179
120   125         146
150   100         127
200    75          113

Die Tickzeit ist also die berechnete Dauer die eine 16tel-Note eigentlich benötigen müsste (in ms). Wie man unschwer erkennen kann, weicht die benötigte Zeit erheblich von der errechneten ab. Ein wiederkehrendes Muster lässt sich dabei leider nicht feststellen. Es kommt anscheinend darauf an, was der PC nebenbei noch zu tun hat, denn ich bekam bei mehreren Durchläufen und der selben BPM-Einstellung trotzdem unterschiedliche Werte, die aber nur marginal voneinander abwichen. Jedoch machen sich selbst ein paar Millisekunden in der Masse sehr deutlich bemerkbar.

Diese Tests liefen im Leerlauf. Das Programm musste nur zählen und keine Sounds wiedergeben oder Eingaben entgegennehmen. Ich habe in Blitzbasic auch ein Testprogramm zum Ermitteln der Zeiten geschrieben und dort sah es ähnlich aus, denn auch da gab es große Unterschiede zwischen den verschiedenen Zeiten.

Meine Vergleiche zwischen meinem Korg-Metronom und Fruityloops ergaben aber keine Abweichungen. Das lief absolut exakt. Und Fruityloops muss ja auch noch sehr viele Aufgaben neben dem zählen erfüllen. Daran erkenne ich das es machbar ist, aber leider weiß ich nicht wie die das gemacht haben. Wo liegt also mein Denkfehler ?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-07
ÃÅ"ber das was Du schreibst habe ich mir auch schon Gedanken gemacht und das ist auch die ÃÅ"berzeugung zu der ich gekommen bin. Allerdings möchte ich nochmals auf das Fruityloops-Beispiel zurückkommen. Meine Tests mit Fruityloops liefen auf dem selben Rechner wie mein Programm und die selben Prozesse wurden gleichzeitig ausgeführt. Im Prinzip sind es also die gleichen Testbedingungen, aber trotzdem läuft Fruityloops absolut exakt. Selbst dann, wenn ich noch andere Anwendungen laufen habe. Also muss es ja irgendwie exakt funktionieren, selbst wenn man kein Echtzeitsystem hat. Die Frage ist nur: Wie ?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-07
Kann man denn die Windows-API in GLBasic einbinden ?
Die ausgegebenen Werte in meiner Tabelle sind, wie gesagt, gerundet. Ich habe nie wirklich gerade Ergebnisse bekommen, sondern immer mit Dezimalstellen hinter dem Komma. Und dennoch bekomme ich es nicht hin, daß mein Programm wirklich genau läuft.
Ich habe auch schon probiert die Zeitspanne, die das Programm für einen Durchlauf mehr als berechnet gebraucht hat, vom jeweils nächsten Durchlauf abzuziehen, aber da verschluckt er noch mehr. Das funktioniert also auch nicht.
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Kitty Hello on 2010-Feb-08
Also.
Mit dem aktuellen Update verwende ich den genauesten Timer, den der Wiz anbietet.
Was macht Dein Code? Evtl. ist's ein Programmfehler?

Kann das Problem sein, dass es mit dem Screen-sync zu tun hat? LIMITFPS -1 schon mal versucht?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Schranz0r on 2010-Feb-08
Quote from: Trabant 500 on 2010-Feb-07
Kann man denn die Windows-API in GLBasic einbinden ?

sischa dat!

Ob dir das allerdings mehr hilft, wage ich zu bezweifeln...
Warten wir mal auf Gernots Kommentar!

EDIT:
Mist Gernot war schneller!
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-08
Ja. LIMITFPS -1 war mein erster Gedanke, aber das hat leider keine Änderung gebracht.

Hier mal mein Testcode:
Code (glbasic) Select
GLOBAL OneTick#=125.0    //entspricht 120 BPM
GLOBAL MaxTick#
GLOBAL Ticktime#
GLOBAL ActTicktime#


LIMITFPS -1
Ticktime#=GETTIMERALL()


WHILE KEY(15)=0

ActTicktime=GETTIMERALL()-Ticktime

IF ActTicktime>=OneTick
IF ActTicktime>MaxTick THEN MaxTick=ActTicktime
Ticktime=GETTIMERALL()
ENDIF

PRINT "Berechnete Ticklänge = "+OneTick,0,0
PRINT "Maximale Ticklänge = "+MaxTick,0,20

SHOWSCREEN
WEND
END
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-08
Wieso ? Wird denn das Win-API nicht auch kompiliert ?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-08
Na wenn es doch aber kompiliert wird, dann ist das doch am Ende alles ein (Maschinen)Code, den auch der WIZ versteht, oder !?  :blink:

Hat jemand mal das Beispielprogramm getestet und eventuell einen Denkfehler endeckt ?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Kitty Hello on 2010-Feb-08
geht unter win32
Code (glbasic) Select


AUTOPAUSE FALSE

GLOBAL OneTick#=125.0    //entspricht 120 BPM
GLOBAL MaxTick#
GLOBAL Ticktime#
GLOBAL ActTicktime#


LIMITFPS -1
Ticktime#=GETTIMERALL()


WHILE KEY(15)=0

LOCAL now = GETTIMERALL()
   ActTicktime= now -Ticktime

   IF ActTicktime>=OneTick
      IF ActTicktime>MaxTick THEN MaxTick=ActTicktime
      Ticktime=now
   ENDIF
   
   PRINT "Berechnete Ticklänge = "+OneTick,0,0
   PRINT "Maximale Ticklänge = "+MaxTick,0,20

SHOWSCREEN
WEND
END


Macht das bei Wiz Ärger?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-08
Bist Du Dir sicher ? Also bei mir zeigt das genauso Abweichungen.  :blink:
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Kitty Hello on 2010-Feb-09
Unter windows!?
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-09
Ja, unter WindowsXP Pro.
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-09
Das Problem ist, daß auch die geringste Abweichung nicht sein darf, denn auch Kleinvieh macht Mist. Und es sollte schon absolut genau sein.
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Schranz0r on 2010-Feb-09
1.6 ms schenk ich doch her... :blink:
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Kitty Hello on 2010-Feb-09
1 ms ist die Zeit, die der Code in der Schleife noch braucht.
Bei 60 Hz (die hörtst Du nicht - die siehst Du nicht mal gescheit) ist ein Frame 16.7 ms.
Title: Re: Ist zeitgenaues programmieren mit GETTIMERALL() nicht möglich ?
Post by: Trabant 500 on 2010-Feb-09
Also bei mir sind die Abweichungen größer. Bei einem gerade durchgeführten Test waren es 137,4 statt 125.  Das Problem ist ja, daß sich das aufsummiert und außerdem muss das Programm ja noch Arrays durchrattern, gegebenfalls Sounds abspielen, Benutzereingaben überwachen usw.

Wie gesagt findet bei Fruityloops keine Abweichung statt. Ich habe gerade ein Programm geschrieben, welches den Prozessor 100% auslastet. Danach hab ich zu Fruityloops gewechselt und trotz der vollen Aulastung lief es absolut im Takt.