Page 1 of 2

Delay problem

Posted: Wed Aug 26, 2015 9:06 am
by SeregaZ
i have one small problem with Delay. i try to read midi file and play it from array. in this array stores "time" of midi. it is a very big array some times. so when play this array - i used delay, but some times Delay(1) is too big. it is in millisec - but i need microsec. have some one same like problem and how you solved it?

Re: Delay problem

Posted: Wed Aug 26, 2015 9:09 am
by RSBasic

Re: Delay problem

Posted: Wed Aug 26, 2015 9:11 am
by SeregaZ
thanks, will try it :)

Re: Delay problem

Posted: Thu Dec 10, 2015 12:18 am
by SeregaZ

Code: Select all

Global QueryPerformanceFrequency.q, QueryPerformanceFactor.f
QueryPerformanceFrequency_(@QueryPerformanceFrequency)
QueryPerformanceFactor = 1e6/QueryPerformanceFrequency

Procedure DelayMicroSeconds(Time.q)
   Protected StartTime.q, EndTime.q
   QueryPerformanceCounter_(@StartTime)
   Repeat
      Delay(0)
      QueryPerformanceCounter_(@EndTime)
   Until (EndTime-StartTime)*QueryPerformanceFactor > Time
EndProcedure



a = ElapsedMilliseconds()
For n = 1 To 1000
   DelayMicroSeconds(300)
Next
Debug ElapsedMilliseconds()-a
this code from german forum is super, but it can be changed to more small pause? i need 1/44100 some kind of:
0. 000 022 675s

Re: Delay problem

Posted: Thu Dec 10, 2015 7:09 am
by Danilo
You should remove the Delay(0) from the loop.

A delay of 0 doesn't make sense. Because of that, at least in Windows
a delay of 0 has a special meaning, see Sleep function.
Sleep() was used for Delay on Windows, but I have something in mind
that it was changed some versions ago. Not sure how PB handles a Delay of 0 now.
Maybe it just does nothing, so a delay of 0 wouldn't make sense.

Anyway, with so high precision you don't want any delay.

Under heavy OS load (many running applications and all cores and CPU's busy),
you will probably get timing problems because of task switching.
Setting a higher priority for the thread that runs the timing and MIDI output code
could at least help a little bit. See also this discussion at StackOverflow
and Microsecond Resolution Time Services for Windows.

Re: Delay problem

Posted: Thu Dec 10, 2015 8:13 am
by infratec
Hi,

I optimized it a bit (I hope):

Code: Select all

Procedure DelayMicroSeconds(Time.q)
  
  Protected StartTime.q, EndTime.q
  
  QueryPerformanceCounter_(@StartTime)
  Time / QueryPerformanceFactor
  Repeat
    QueryPerformanceCounter_(@EndTime)
  Until EndTime - StartTime >= Time
  
EndProcedure
Bernd

Re: Delay problem

Posted: Thu Dec 10, 2015 9:54 am
by Danilo
By the way, does anybody know if calling QueryPerformanceFrequency() only once (at application start)
could make problems?
Modern processors often provide a way to change CPU frequency while running, AFAIK.
Lower Frequency for power saving in Notebooks, or higher frequency for a limited time to boost performance.

Could this influence high precision timer codes?

Re: Delay problem

Posted: Thu Dec 10, 2015 10:06 am
by CELTIC88
try this 8)

Code: Select all

Procedure DelayEx(timeMicroSeconds.q)
  ; Name...........: DelayEx()
  ; Description ...: Sleeps down to 0.1 microseconds
  ; Parameters ....:  timeMicroSeconds      - Amount of microseconds to sleep
  ; Author ........: Celtic88
  timeMicroSeconds=-1*(timeMicroSeconds*10)
  ProcedureReturn ZwDelayExecution_(0,@timeMicroSeconds)
EndProcedure

Test= ElapsedMilliseconds()
DelayEx(1000000)
Debug Str(ElapsedMilliseconds()-Test) + " Ms"

Re: Delay problem

Posted: Thu Dec 10, 2015 10:50 am
by Dude
infratec wrote:Time / QueryPerformanceFactor
Division by zero error. :shock:

Re: Delay problem

Posted: Thu Dec 10, 2015 11:28 am
by Helle
@Danilo: For modern CPUs: Invariant TSC/TscInvariant!
Intel wrote:
CPUID 80000007H, EDX Bit8 Invariant TSC
The invariant TSC will run at a constant rate in all ACPI P-, C-, and T-states. This is the architectural behavior
moving forward. On processors with invariant TSC support, the OS may use the TSC for wall clock timer services
(instead of ACPI or HPET timers). TSC reads are much more efficient and do not incur the overhead associated with
a ring transition or access to a platform resource.
AMD wrote:
CPUID 80000007H, EDX Bit8 TscInvariant
TscInvariant: TSC invariant. The TSC rate is ensured to be invariant across all P-States, C-States,
and stop grant transitions (such as STPCLK Throttling); therefore the TSC is suitable for use as a
source of time.

Re: Delay problem

Posted: Thu Dec 10, 2015 11:38 am
by Danilo
Thanks, Helle!

- Time Stamp Counter

Re: Delay problem

Posted: Thu Dec 10, 2015 2:00 pm
by SeregaZ
thanks for a lot answers :) i have no succes...
0. 000 022 675s
delay millisec that DelayMicroSeconds proc microsec even dont know

problem is - when i play sound - tempo is drunk. delay pause count is a little wrong. i make attach to illustrate this drunk tempo. you will need to fix path to Array.txt and choice one of three method of pause by comment and uncomment in code: delay(1), infratec and CELTIC88 (how work CELTIC88's variant i am even dont understand)

for compare with correct tempo i add winamp plugin and that original melody.

https://www.dropbox.com/s/sdvel9hsu6yq9 ... r.zip?dl=1

can you help?

Re: Delay problem

Posted: Thu Dec 10, 2015 2:54 pm
by infratec
Dude wrote:Time / QueryPerformanceFactor
Division by zero error. :shock:
Try to replace QueryPerformanceFactor.f with
QueryPerformanceFactor.d

Bernd

Re: Delay problem

Posted: Thu Dec 10, 2015 3:27 pm
by infratec
And

Code: Select all

DelayMicroSeconds(MusArr(i)\pause * 22.675)
Bernd

Re: Delay problem

Posted: Thu Dec 10, 2015 3:42 pm
by SeregaZ
and with .f and with .d and with 22.675 and with 22 and with 23 - same drunk tempo :(((