One millisecond resolution is not enough!

Posted on 1998-09-20
Last Modified: 2010-04-06
I am not very familiar with the internal workings of Windows, or the Windows API.  I know that in DOS you could easily manipulate the timer interrupt. How do you go about doing that in Delphi, or Windows in general?  Is it being unreasonable to set a timer at 1 MHz?

(note: I know about TTimer)
Question by:scrapdog

Expert Comment

ID: 1340316
Here is something(timer, I mean) with resolution 0.1 msec:
Z-timer on Delphi Super Page:
as the matter of fact I couldn't get it to work, co if you succeed, leave a comment how ;-)

Author Comment

ID: 1340317
Thanks for the tip.  I looked at the source code, and even though a lot of it confuses me (not the assembly code, but the windows functions), I will learn something by looking at it.  However, a component wasn't really what I was looking for.

I will elaborate of my question a little more.  The program PC64 for Windows emulates a Commodore 64, which is a computer that runs at about 1 MHz.  In order to execute instructions cycle-exact, some timing mechanism that runs at 1 MHz must be present in the program to carry out operations in the CPU.  

Or do emulation programs generally carry out a batch of instructions? (i.e. execute a batch of 1000 instructions every millisecond)

If the latter is the case, it is because it is not possible to set a timer to 1 MHz.  If it clearly is not possible to set a timer to that rate, I would like to know.

Other applications that use a timer with a very high resolution are applications that process sound.  Do sound applications use Timers with resolutions up to 44 KHz, or do they all use a Timer with an interval of 1 msec or more with buffers?  The question is not how to do it with buffers, the question is whether buffers MUST be used.

The main thing I am trying to get at:  is it typical for applications, including emulators and multimedia, to use timers of resolution much better than 1 msec?  And if so, how?

Thanks again to duke_n for his prompt reply.
LVL 20

Expert Comment

ID: 1340318

in windows it is dangerous to trust in lowlevel timers because windows is a multitasking system. Windows decides which application gets how much cpu time. So if Windows thinks that there is an application that is more important than yours, you'll get problems with the timers.
The better way is to use the "Application.Idle" event and asking win API "GetTickCount" in the event handler of this event.

Regards, Madshi.
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.


Expert Comment

ID: 1340319
Timers in NT and Win95+ are not a nice experience if your objective is other than to move around icons on the desktop. There is no good way to implement hires timers. Not even with kernelmode drivers.
Sound applications generally use buffers.
The multimedia timers (timeSetEvent) only have 1 millisecond resolution (not including timer latency).

Check QueryPerformanceCounter for very high granularity timers under NT.

/// John

Author Comment

ID: 1340320
So it is safe to assume that all emulation programs (such as PC64) execute instructions in a batch?

LVL 20

Expert Comment

ID: 1340321
I'm quite sure that these emulation programs does NOT install a timer at the cpu frequence of the emulated cpu. So they will have to use something like batch instructions...

Regards, Madshi.

Accepted Solution

wamoz earned 50 total points
ID: 1340322
High resolution timing under Windows is done using the Multimedia Timer Functions. If these aren't good enough then you have to build some custom hardware.

In the case of your "cycle-exact" emulator, I think you will find that it isn't cycle exact. What is most likely happening is that it is running rather faster than a C64, and every so often idles until the correct amount of time has elapsed.

Madshi sensibly warns you against trusting timers due to the pre-emptive nature of multi-tasking operating systems. There are three things you can do about this.

(1) Design your code on the expectation that it will occasionally miss a beat (literally) so that it doesn't matter. This is how streaming audio copes with packet loss and timing problems - it just drops late packets and plays whatever turns up exactly when the clock says they should be played.

(2) You can increase the priority of a thread to real-time, the purpose of which is self evident.

(3) Cut your code some slack. Size the batches of instructions (I refer to your own comment) so that their duty cycle is less than half of what is theoretically supported. When working this out, don't forget that there are other processes running.

I gather you want to do this sort of thing yourself. Boy have you jumped in at the deep end. Nevertheless, there's only one way to learn. If I wanted to do this I'd structure it as described in the previous paragraph. Controlling the wait state is most efficiently done by going into an idle loop that blocks on a simple flag. (repeat ... until bSynch).

If you want this to work under Win95 or in a multi-threaded application, don't forget to process the message queue inside the loop.

You tell the loop to exit using an event handler that you fire using timeSetEvent().

With respect to multimedia devices that require high frequency operation, they employ a similar clock synching strategy. For example, your sound card and your CPU dance an elaborate dance with the CPU bursting wave tables and and timing *descriptions* across a DMA channel in response to "more" requests expressed by the sound card using an interrupt and memory mapped I/O.

The following functions are used with multimedia timers. Most of these are documented to some degree in the Delphi help but if that's not enough I can furnish you with detailed APIs.


Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
problem when i try to pack my dll file with upx 9 76
Show Listview image from database (String field) 5 123
Delphi 2 59
Delphi and Access based Enumeration 9 59
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now