Re: Multimedia Timer

Tech-Archive recommends: Fix windows errors by optimizing your registry



See below...
On Mon, 11 Feb 2008 08:46:51 -0800 (PST), clinisbut <clinisbut@xxxxxxxxx> wrote:

I need to execute some code every 20ms. This code is just send some
data through serial port, so I think it's not heavy.

At first I was using SetTimer function and OnTimer event, but with no
good results: seems that not sending every 20ms, instead is sending 3
or so consecutive frames at same time.

Today I tried the multimedia timers, and seems that does the same.
Inside my TimeEventHandler, I trace:

TRACE( "Time:%d\n", GetTickCount() );
****
And how long does it take a TRACE statement to execute? If you are working with tight
timings like 20ms, you simply cannot afford to use TRACE. Also, GetTickCount is pointless
to use; it is not very accurate, being limited by the motherboard clock tick frequency,
which is lower resolution than the multimedia timer, so the data you are showing bears
zero correlation to any form of reality that might be happening.
****

And I see that sometimes event handler fires up more than one time at
same time, look:

Time:30664983
Time:30664983
Time:30664983
Time:30664993
Time:30665013
Time:30665033
Time:30665054
Time:30665074

I'm measuring correctly the time elapsed between calls?
****
No. There is no way to get really good numbers here. QueryPerformanceTimer might work.
****
This is the code to create a multimedia timer I'm using:

void CMyAppDlg::SomeFunctio()
{
TIMECAPS tc;
timeGetDevCaps( &tc, sizeof(TIMECAPS) );
DWORD resolution = min( max( tc.wPeriodMin, 0 ),
tc.wPeriodMax );
timeBeginPeriod( resolution );

m_Timer = timeSetEvent( TIME_ELAPSE, resolution, StartTimer,
DWORD(this), TIME_PERIODIC );
}

void CALLBACK CMyAppDlgDlg::StartTimer( UINT wTimerID, UINT msg, DWORD
dwUser, DWORD dw1, DWORD dw2 )
{
CMyAppDlg* obj = (CMyAppDlgDlg*) dwUser;
****
You might be in deep trouble here, depending on what Timer_SendData does; note that you
cannot access the HWND of the dialog because StartTimer is running in a different thread
than your main GUI thread. Also, you will need to worry about interthread
synchronization.
*****
obj->Timer_SendData( wTimerID );

}

void CMyAppDlg::Timer_SendData( UINT nIDEvent )
{
TRACE( "Time:%d\n", GetTickCount() );
****
GetTickCount is going to give you bad data, so you can ignore anything it is telling you

See my essay "Time is the Simplest Thing" on my MVP Tips site.
joe
****
}


The TIMECAPS.wPeriodMin on my system is '1', so I don't think that's
the problem...
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Multimedia Timer
    ... void CMyAppDlg::SomeFunctio ... DWORD resolution = min, ... void CALLBACK CMyAppDlgDlg::StartTimer(UINT wTimerID, UINT msg, DWORD ...
    (microsoft.public.vc.mfc)
  • Re: Multimedia Timer
    ... Today I tried the multimedia timers, and seems that does the same. ... DWORD resolution = min, ... void CALLBACK CMyAppDlgDlg::StartTimer(UINT wTimerID, UINT msg, DWORD ...
    (microsoft.public.vc.mfc)
  • Re: Camera resolution settings
    ... sample code. ... Cutting the resolution by half should be ... for each media sample just skip every ... RGB565 uses 1 WORD/pixel, not 1 DWORD. ...
    (microsoft.public.win32.programmer.directx.video)