MIDI Timecode

Hardware- und Elektronikbasteleien, Ansteuerung von Schnittstellen und Peripherie.
Fragen zu "Consumer"-Problemen kommen in Offtopic.
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Sorry, ich habe vergessen den Link zu dem, was ich meinte, oben einzutragen.

http://www.purebasic.fr/german/viewtopi ... 127#167127

Wenn also der QueryPerformanceCounter in Deinem Rechner funktioniert,
müsste man aus dieser Procedure ein Signal/Frame schicken, welcher dann alle 33333 Micosekunden (Ticks) sendet, oder? Leider habe ich damit noch
nicht viel gemacht, aber Theoretisch müsste es in dieser Richtung laufen, was
andere Programme auch machen.

Eine höhere Auflösung ist wohl ohne zusätzliche externe Timerhardware nicht möglich.

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Sorn
Beiträge: 17
Registriert: 13.02.2008 17:30

Beitrag von Sorn »

Danke Falko :allright:

Hatte ich mir schon mal angeschaut.
Muss es nur noch ausprobieren.
Soweit ich es aber bis jetzt verstanden habe, muss ich
diesen Wert abfragen, um zu sehen wie viel Zeit
vergangen ist. Heißt das nun, dass ich die Abfrage in einen
eigenen Thread machen muss/kann?
Also so zu sagen eine Schleife, die den (delta)Wert abfragt und
sobal der (delta)Wert >= 33333µsek ist, eine Meldung an
eine Framesenderoutine schickt?
Wäre das der richtige Weg, ist das mit PB lösbar?

Habe bis jetzt noch nichts mit Threads gemacht. Ich nehme an,
ich brauche dann auch eine Abfrage im Thread, ob der Thread beendet werden soll.
Das darf dann aber nicht meine Synchronisierung durcheinander bringen. :roll:
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Hi Sorn,

wie das mit den Threads laufen wird und wie schnell die reagieren, kann ich leider nicht sagen, weil es vom PC abhängt.

Du lässt diese Ticks bis 33333 Microsekunden laufen und wenn diese erreicht
sind kannst du den Anfangswert auf #Null setzen und eine Ausgabe machen, Als auch jeweils das Folgesample ausgeben lassen usw.

Wie gesagt, wie man das mit den Samples machen muss, dazu habe ich noch zu wenig Infos.

So kann ich mir das vielen Programmen nur erklären.

Weil diese Programme und DLLS z.B. beim Abbrechen auch später
reagieren, als du klickst, gehe ich davon aus, das diese als Thread laufen.
Ich würde in dieser Richtung einfach mal die Möglichkeiten ausprobieren
und wenn es dann klappt, kann man es weiter verfeinern.

Da Du Threads einen Wert Schicken musst, kannst du diesen Thread anhand dieser Werte Steuern, wenn Dein Programm den Thread anspricht.

@all
Ich hoffe, ich habe in dieser Richtung das nicht falsch beschrieben, und wenn ja, dann könnt ihr mich gerne berichtigen. :wink:

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Ich habe mal einen Versuch gemacht, mit dem Code von hier

http://www.purebasic.fr/english/viewtop ... icrosecond

1000 ms für 30 Bilder zu simulieren. Leider kriege ich bei dem Wert und
dieser Procedure beim Wert von 31 Frames dann 336ms heraus. Wenn ich
auf 32 erhöhe, dann komme ich über 1400ms. Genauer kriege ich das nicht angezeigt. Ich habe versucht die nachfolgenden codes mit dem ASM-Befehlen in einer Procedure zu packen. Nur klappt das so nicht und ich kriege eine ASM-Fehlermeldung. Vielleicht kann ja wer, der sich mit ASM auskennt, aus der obigen Seite das mit den ns angucken und es in eine Procedure packen.

So hier mal das Beispiel aus dem Link von oben mit simulierten Frames. Ob es geht kann ich nicht garantieren.

Gruß Falko


Code: Alles auswählen

;http://www.purebasic.fr/english/viewtopic.php?t=13410&highlight=timer+microsecond
Procedure.s HiResTimer(xNum)
  Ctr1.LARGE_INTEGER
  Ctr2.LARGE_INTEGER
  Freq.LARGE_INTEGER
  Overhead.LARGE_INTEGER
  A.l
  i.l
  If QueryPerformanceFrequency_(Freq)
    QueryPerformanceCounter_(Ctr1)
    QueryPerformanceCounter_(Ctr2)
    Overhead\lowpart = Ctr2\lowpart - Ctr1\lowpart  ; determine API overhead
    QueryPerformanceCounter_(Ctr1)                  ; start time loop
    Delay(xNum)
    QueryPerformanceCounter_(Ctr2)                  ; end time loop
    TimerInfo$ = "Delay(" + Str(xNum) + ") took " + StrF((Ctr2\lowpart - Ctr1\lowpart - Overhead\lowpart) / Freq\lowpart) + " seconds"
    result$ = TimerInfo$
  Else
    result$ = "Error occured"
  EndIf
  ProcedureReturn result$
EndProcedure

;----- Main --------
StartTime = ElapsedMilliseconds() 
For i=0 To 29
 ;MessageRequester("Hi_Res Timer", HiResTimer(0.001))
 Debug "Frame: " +Str(i)+": Hi_Res Timer"+HiResTimer(31); Times in 
Next 
Endtime=ElapsedMilliseconds()-StartTime 
Debug "---------------------------------"
Debug Str(Endtime) + "ms"
;Debug Str(1000/Endtime) + " pro " +"1000ms"
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Sorn
Beiträge: 17
Registriert: 13.02.2008 17:30

Beitrag von Sorn »

Muss ich mir mal in Ruhe anschauen...

Machst dir ja echt schon Arbeit damit. :o

Scheint aber auch wirklich ein interessantes Problem zu sein,
da einen stabilen Timer zu bauen.
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Ich probiere gern was aus. Das macht mir keine Arbeit und ich hab ja Urlaub <)

Hier noch ein Beispiel, woanders abgeschaut. Mit den Werten kann ich leider so nichts anfangen. Aber das wären dann wohl in 1000ms 30Frames mit einer Abweichung (bei mir) um 0,02ms. Wenn dieser Wert also hinkommt, wobei man bedenken muss, das von ElapsedMilliseconds() die Ungenauigkeit herkommen kann, wäre dieses Ergebnis wohl geeigneter.

Die Zwischenwerte sind dann wohl Frequenz/Zeit was sich auf den jeweiligen Computer beschränkt. Vielleicht muss man diesen zur Kalibrierung in eine Gleichung setzen, sodass der Kalibrierwert dann automatisch angepasst werden kann.

Ich hoffe Du kannst hiermit was anfangen.

Code: Alles auswählen

;http://www.purebasic.fr/german/viewtopic.php?t=18091&postdays=0&postorder=asc&highlight=queryperformancefrequency&start=10
;Dieses Beispiel, um annähernd 30 Frames pro 1000ms zu schicken. 

Procedure.f DelayTimer(tdelay.f)
  TIMER.LARGE_INTEGER
  If QueryPerformanceCounter_(@TIMER)
    start = TIMER\lowpart  ;alten Low-wert sichern
    Repeat
      If QueryPerformanceCounter_(@TIMER)
        Zeit.f = TIMER\lowpart - start
      EndIf
    Until Zeit >= tdelay
    ProcedureReturn Zeit.f
  Else
    ProcedureReturn 0  ;kein Hardware-Timer
  EndIf
EndProcedure

Procedure.f InitTimer()
  FREQ.LARGE_INTEGER
  If QueryPerformanceFrequency_(@FREQ)  ;Bestimmen der frequenz
    Zeit.f = (FREQ\lowpart) / 30  ;Kalibrierwert hier die Counts z.B. 30 anpassen bis man auf 1000ms kommt
    ProcedureReturn Zeit.f
  Else
    ProcedureReturn 0  ;kein Hardware-Timer
  EndIf
EndProcedure

; If InitTimer()
;  Debug DelayTimer(30)
; EndIf

t1us = InitTimer() 

StartTime = ElapsedMilliseconds() 
  For i=1 To 30
    Debug "Frame "+Str(i)+":  "+Str(DelayTimer(t1us))
  Next i
Endtime=ElapsedMilliseconds()-StartTime   
Debug "---------------------------------"
Debug Str(Endtime) + "ms"
Das Ergebnis auf meinem Rechner sieht dann wie folgt aus:
Frame 1: 477276
Frame 2: 477284
Frame 3: 477273
Frame 4: 477317
Frame 5: 477297
Frame 6: 477278
Frame 7: 477293
Frame 8: 477276
Frame 9: 477275
Frame 10: 477278
Frame 11: 477282
Frame 12: 477284
Frame 13: 477285
Frame 14: 477281
Frame 15: 477287
Frame 16: 477290
Frame 17: 477293
Frame 18: 477281
Frame 19: 477280
Frame 20: 477283
Frame 21: 477282
Frame 22: 477301
Frame 23: 477279
Frame 24: 477276
Frame 25: 477285
Frame 26: 477290
Frame 27: 477279
Frame 28: 477293
Frame 29: 477282
Frame 30: 477290
---------------------------------
999ms
Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Sorn
Beiträge: 17
Registriert: 13.02.2008 17:30

Beitrag von Sorn »

So habe noch etwas herum probiert.
Muss aber zu meiner Schande bekennen, dass ich erst mal
mit VB6 getestet habe :oops: da kenne ich mich halt etwas besser aus.
Wenn es dann einigermaßen klappt, wollte ich es aber doch in PB machen.

Soweit ich bisher heraus gefunden habe ist es mit QueryPerformance doch so,
dass man die Werte in einer Schleife ausliest und sobald der Wert >= dem
gewünschten zeitlichen Abstand liegt das tut was man zu diesem Zeitpunkt
tun wollte. also z.B. MIDI Zeitkode ausgeben.
Das hat nun auch geklappt. Ich konnte Wavelab synchron mitlaufen lassen.
Da ich aber laufend auch abfragen muss, ob jemand eine Taste zum Anhalten
gedrückt hat, oder auch nur um die Zahlen in einer Form darzustellen, kommt
meine Ausgabe aus dem Takt, sobald ich das Form bewege, oder
sonst etwas mache.

Würde ich mit einem unabhängigen Thread diese Probleme nicht haben?
Ich müsste einen gemeinsamen Speicherbereich haben, in den ich meine
momentanen Zeitwerte eintrage damit das Hauptprogramm diese lesen
und anzeigen kann, sobald es mal Zeit dazu hat. Mein Thread müsste
vollkommen zeitlich unabhängig weiterlaufen. Und das mit einer
Millisekundengenauigkeit.

Ich habe noch nie mit Threads programmiert.
Sind Threads dafür geeignet?
Benutzeravatar
Falko
Admin
Beiträge: 3531
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.0
Kontaktdaten:

Beitrag von Falko »

Zum Punkt Thread. Vielleicht sowas?

http://www.purebasic.fr/german/viewtopi ... 449#250449

Gruß Falko
Bild
Win10 Pro 64-Bit, PB_5.4,GFA-WinDOS, Powerbasic9.05-Windows, NSBasic/CE, NSBasic/Desktop, NSBasic4APP, EmergenceBasic
Antworten