Article View: borland.public.cppbuilder.nativeapi
Article #15392Re: SetEventTimer routine holds TThread task?
From: Phuoc Can HUA
Date: Tue, 08 Jul 2003 23:13
Date: Tue, 08 Jul 2003 23:13
396 lines
14233 bytes
14233 bytes
Gambit,
Here is my codes. Please ignore the part with MsgGet/Put() because it's
working fine without any delay in the TThread. The problem comes with This-
>ShowLyrLine() in LocalDisplay::Refresh. It's calling some 'heavy' graphic
operations (takes ~20ms). Since the MIDI is running in a seperate thread
I'm hoping that the graphic operations won't hold the song. I guess it
might be the system screen refresh is holding it.
thanks in advance
Phuoc Can HUA
//--------------------------------------------------------------------------
-
__fastcall LocalDisplay::LocalDisplay( KaraokeNet *KNet, TFmScreen *S)
//: TThread( TRUE)
{
...
Timer0= timeSetEvent( WIPEINTERVAL, 0, (LPTIMECALLBACK)Refresh,(DWORD)this,
TIME_PERIODIC);
...
}
//--------------------------------------------------------------------------
-
void CALLBACK LocalDisplay::Refresh( UINT uID, UINT uMsg, DWORD
dwUser, DWORD dw1, DWORD dw2)
{
// Some variable declarations
...
for(;;)
{ This->MsgCtrl->MsgGet( M);
if( M->Cmd== MSG_NULL)
break;
switch( M->Cmd)
{ case MSG_LOADIMGALL:
This->ImgsAll->Load( IMGS_ALL);
break;
// Some other cases
...
}
} // End for(;;)
if( !(This->Mode &MD_SUSPFLAG))// && !FCtrl->SearchCnt)
{ Runtime= timeGetTime()-This->TmOffset;
M->P0= Runtime;
This->SetPos();
This->WipeText(); // Draw litte thing (not causing problem)
if(!(++This->TickCount% SHOWLINEFRQ))
This->ShowLyrLine( Runtime); // **** Draw a text line
(holding the TThread) ****
}
}
//--------------------------------------------------------------------------
-
void LocalDisplay::ShowLyrLine( int Runtime)
//inline void LocalDisplay::ShowLyrLine( int Runtime)
{
int Before= (SINGBEFORE *60000)/ Song->Tempo,
Gap= SINGGAP,
After= SINGAFTER;
Runtime= Runtime+ MusicDelay;
//--------------------------------- Select Line ----
int ShowLn;
LyrLnType* LyrLn;
for( int I= 0; I< 2; I++)
if( Runtime > FScr->LineOut[ I] +After)
FScr->LnStatus[ I]= LYR_SUNG;
if( LyrLinePtr < LyrLines)
{ LyrLn= (LyrLnType*)LyrTrack->LyrLine->Items[ LyrLinePtr];
// Some calculations
...
if( ShowLn!= -1
// Time gap between 2 lines is small enough
&& ( LyrLn->In -FScr->LineOut[( ShowLn+1)%2] -After -Before < Gap
|| Runtime > (int)LyrLn->In -Before))
{ FScr->CurLyrLine= LyrLn;
FScr->CurLine= ShowLn;
FScr->DrawLyricsLn(); // **** Draw a text line (holding the
TThread) ****
++LyrLinePtr;
}
}
....
}
=====================================================================================
Graphic routines
=====================================================================================
//--------------------------------------------------------------------------
-
void __fastcall TFmScreen::DrawLyricsLn( void)
{
// Some variable declarations
...
if( CurLyrLine->Txt.data()== NULL) // Ignore line with empty
words
{ // Mark the words with line LYR_CANTSEE
for( int I= 0; I < CurLyrLine->Len; I++)
((TxtEvtType*)
Lyrics->Items[ CurLyrLine->Index+I])->ScrLine= LYR_CANTSEE;
return;
}
LyrText->Width= LyrText->Canvas->TextWidth( LyrTxt);
LyrText->Canvas->TextOut(0,0, LyrTxt);
if( LyrText->Width <= LyrWidth) // Line fits in
{ LyrLnFact[ CurLine]= 1;
TextMask->Width= LyrText->Width +2;
TextMask->Canvas->CopyRect( TRect( 1,1, LyrText->Width+1, LyrText-
>Height+1),
LyrText->Canvas, TRect( 0,0, LyrText->Width, LyrText-
>Height));
TextMask->Canvas->FillRect // Clean the last pixel for Outline
( TRect( TextMask->Width -1,0, TextMask->Width, TextMask-
>Height));
Offset=(LyrWidth-LyrText->Width)/2;
}
else
{ LyrLnFact[ CurLine]=(float)LyrWidth/ LyrText->Width;
TextMask->Width= LyrWidth;
TextMask->Canvas->StretchDraw(
Rect( 1,1, TextMask->Width -1, TextMask->Height), LyrText);
Offset= 0;
}
LyrRect.Right= TextMask->Width;
Outline->Width= TextMask->Width;
Outline->Canvas->FillRect( TRect( 0,0, Outline->Width, Outline->Height));
Outline->Canvas->CopyMode= cmSrcPaint; // OR
Outline->Canvas->CopyRect( TRect( 0,-1, LyrRect.Right, LyrRect.Bottom-1),
TextMask->Canvas, LyrRect);
Outline->Canvas->CopyRect( TRect( 1,0, LyrRect.Right+1, LyrRect.Bottom),
TextMask->Canvas, LyrRect);
Outline->Canvas->CopyRect( TRect( 0,1, LyrRect.Right, LyrRect.Bottom+1),
TextMask->Canvas, LyrRect);
Outline->Canvas->CopyRect( TRect( -1,0, LyrRect.Right-1, LyrRect.Bottom),
TextMask->Canvas, LyrRect);
LyrLnTxt->Width= TextMask->Width;
LyrLnTxt->Canvas->FillRect( LyrRect);
LyrLnHil->Width= TextMask->Width;
LyrLnHil->Canvas->FillRect( LyrRect);
// Draw text outline
ColorMask->Width= TextMask->Width;
ColorMask->Canvas->Brush->Color=(TColor)(OutlineColor0 ^0xffffff);
ColorMask->Canvas->FillRect( Rect( 0,0, ColorMask->Width, ColorMask-
>Height));
ColorMask->Canvas->CopyMode= cmSrcAnd;
ColorMask->Canvas->CopyRect( LyrRect, Outline->Canvas, LyrRect);
LyrLnTxt->Canvas->CopyMode= cmNotSrcErase;
LyrLnTxt->Canvas->CopyRect( LyrRect, ColorMask->Canvas, LyrRect);
// [ white [ C0 [] ] ]
// Draw text
ColorMask->Canvas->Brush->Color=(TColor)(TextColor0 ^0xffffff);
ColorMask->Canvas->FillRect( Rect( 0,0, ColorMask->Width, ColorMask-
>Height));
ColorMask->Canvas->CopyMode= cmSrcAnd;
ColorMask->Canvas->CopyRect( LyrRect, TextMask->Canvas, LyrRect);
LyrLnTxt->Canvas->CopyRect( LyrRect, TextMask->Canvas, LyrRect);
// [ black [ ^C0 [ black] ] ]
LyrLnTxt->Canvas->CopyMode= cmSrcPaint;
LyrLnTxt->Canvas->CopyRect( LyrRect, ColorMask->Canvas, LyrRect);
// [ black [^C0 [ ^C1] ] ]
TRect LnRect= Rect( LyrLeft +Offset, LyrLnRect[ CurLine].Top,
LyrLeft +Offset +LyrRect.Right,
LyrLnRect[ CurLine].Top +LyrRect.Bottom);
// ---- Draw WorkSpace ----
if( LnStatus[ CurLine]!= LYR_EMPTY) // Clear line if not
empty
{ WorkSpace->Canvas->CopyMode= cmSrcCopy;
WorkSpace->Canvas->CopyRect(
LyrLnRect[ CurLine], Layer0->Canvas, LyrLnRect[ CurLine]);
}
WorkSpace->Canvas->CopyMode= cmNotSrcErase;
WorkSpace->Canvas->CopyRect( LnRect, Outline->Canvas, LyrRect);
WorkSpace->Canvas->CopyRect( LnRect, LyrLnTxt->Canvas, LyrRect);
//********************************************************************
// ---- Draw PaintBox1 ---- (output to screen)
if( PaintScr) // ---- DRAW TEXT ----
if( LnRect.Right > LyrLnRect[ CurLine].Right) // New line longer
PaintBox1->Canvas->CopyRect(
LnRect, WorkSpace->Canvas, LnRect);
else
PaintBox1->Canvas->CopyRect(
LyrLnRect[ CurLine], WorkSpace->Canvas, LyrLnRect[
CurLine]);
//********************************************************************
LyrLnRect[ CurLine].Left= WipeStart[ CurLine]= LnRect.Left;
LyrLnRect[ CurLine].Right= LnRect.Right;
LnStatus[ CurLine]= LYR_READY;
LineOut[ CurLine]= CurLyrLine->Out;
// Mark the words with line location
for( int I= 0; I < CurLyrLine->Len; I++)
// ((TxtEvtType*)LyrTrack->Lyrics->Items[ CurLyrLine->Index+I])-
>ScrLine= CurLine;
((TxtEvtType*)Lyrics->Items[ CurLyrLine->Index+I])->ScrLine=
CurLine;
// Mark the 1st word of next line
int L= CurLyrLine->Index +CurLyrLine->Len;
//if( L < LyrTrack->Lyrics->Count)
// ((TxtEvtType*)LyrTrack->Lyrics->Items[ L])->ScrLine=
LYR_WILLSHOW;
if( L < Lyrics->Count)
((TxtEvtType*)Lyrics->Items[ L])->ScrLine= LYR_WILLSHOW;
// ---- DRAW HIGHTED TEXT --
--
// Draw highlighted text outline
ColorMask->Canvas->Brush->Color=(TColor)(OutlineColor1 ^0xffffff);
ColorMask->Canvas->FillRect( Rect( 0,0, ColorMask->Width, ColorMask-
>Height));
ColorMask->Canvas->CopyMode= cmSrcAnd;
ColorMask->Canvas->CopyRect( LyrRect, Outline->Canvas, LyrRect);
LyrLnHil->Canvas->CopyMode= cmNotSrcErase;
LyrLnHil->Canvas->CopyRect( LyrRect, ColorMask->Canvas, LyrRect);
// [ white [ C0 [] ] ]
// Draw hightlighted text
ColorMask->Canvas->Brush->Color=(TColor)(TextColor1 ^0xffffff);
ColorMask->Canvas->FillRect( Rect( 0,0, ColorMask->Width, ColorMask-
>Height));
ColorMask->Canvas->CopyMode= cmSrcAnd;
ColorMask->Canvas->CopyRect( LyrRect, TextMask->Canvas, LyrRect);
LyrLnHil->Canvas->CopyRect( LyrRect, TextMask->Canvas, LyrRect);
// [ black [ ^C0 [ black] ] ]
LyrLnHil->Canvas->CopyMode= cmSrcPaint;
LyrLnHil->Canvas->CopyRect( LyrRect, ColorMask->Canvas, LyrRect);
// [ black [^C0 [ ^C1] ] ]
}
=====================================================================================
TThread for MIDI
=====================================================================================
//--------------------------------------------------------------------------
-
void __fastcall KarMidi::Execute()
{
//MsgCtrl->MsgPut( MSG_LOADIMGALL, 0, NULL);
Suspend();
// Some variable declarations
...
MsgCtrl->MsgPut( MSG_RESET, TEMPO, NULL);
MsgCtrl->MsgPut( MSG_SYNC, Runtime, NULL);
Mode= MD_PLAYING;
do
{
do
{ Runtime=(int)timeGetTime() -TmOffset;
do
{ if( Mode== MD_PAUSED)
{ midiOutReset( hMidiOut);
Suspend();
TmOffset= timeGetTime() -CurEvent->MSec;
Runtime= CurEvent->MSec;
MsgCtrl->MsgPut( MSG_SYNC, Runtime, NULL);
Mode= MD_PLAYING;
}
if( Runtime -LastTick >= SYNC_INTERV)
{ LastTick= Runtime;
MsgCtrl->MsgPut( MSG_SYNC, Runtime, NULL);
}
if( Runtime -LastPic >= ( CHANGEPIC *60000/ Tempo))
{ LastPic= Runtime;
MsgCtrl->MsgPut( MSG_PIC, 0, NULL);
}
Runtime=(int)timeGetTime() -TmOffset;
}
while(((int)CurEvent->MSec -Runtime > 0) && Mode!= MD_STOPPED && Mode!=
MD_END);
Status= CurEvent->status;
switch( Status)
{ case 0xf0: // SysEx
MidiHdr->lpData=(LPSTR)CurEvent->extraData;
MidiHdr->dwBufferLength= CurEvent->extraLen;
MidiHdr->dwFlags= 0;
if( midiOutPrepareHeader( hMidiOut, MidiHdr, sizeof(
MIDIHDR))
== MMSYSERR_NOERROR)
{ midiOutLongMsg( hMidiOut, MidiHdr, sizeof( MIDIHDR))
;
while(
midiOutUnprepareHeader( hMidiOut, MidiHdr, sizeof(
MIDIHDR))
== MIDIERR_STILLPLAYING);
}
break;
case 0xff: // Tempo
if( CurEvent->data[0]== 0x51 && CurEvent->extraLen== 3)
{ Tempo= 60000000/ ( CurEvent->extraData[0] << 16
| CurEvent->extraData[1] << 8
| CurEvent->extraData[2]);
MsgCtrl->MsgPut( MSG_TEMPO, Tempo, NULL);
}
break;
default:
if( Status >= 0x80 && Status < 0xf0
&& !( !PlayMelody && CurEvent->Chn== MelodyChn &&
CurEvent->Dist < DIST_MAX))
{ MidiEvt.Dat[0]= Status;
MidiEvt.Dat[1]= CurEvent->data[0];
MidiEvt.Dat[2]= CurEvent->data[1];
midiOutShortMsg( hMidiOut, MidiEvt.Msg);
}
} // End switch
CurEvent= CurEvent->next;
}
while( CurEvent && Mode!= MD_STOPPED && Mode!= MD_END);
MsgCtrl->MsgPut( MSG_RESET, TEMPO, NULL);
if( CurEvent== NULL || Mode== MD_END) // Song played to end
{ MsgCtrl->MsgPut( MSG_PLAYMODE, MD_END, NULL);
Mode= MD_STOPPED;
}
Runtime= LastTick= 0;
CurEvent= EventList;
Suspend();
if( Mode== MD_PAUSED) // In case: search after stopped
{ TmOffset= timeGetTime() -CurEvent->MSec;
Runtime= LastTick= CurEvent->MSec;
}
else
{ TmOffset= timeGetTime();
}
Mode= MD_PLAYING;
MsgCtrl->MsgPut( MSG_SYNC, Runtime, NULL);
}
while( !Terminated);
}
On Mon, 7 Jul 2003 01:08:28 -0700, Remy Lebeau (TeamB) <gambit47@yahoo.com>
wrote:
> Again, I have to ask what your thread and timer are actually doing. If
> youe
> timer is doing something that is CPU-intense and not yielding control
> back
> to the rest of the system periodically, then yes, it is conceivable for
> your
> timer to block your worker thread. Which OS are you using for this? Do
> you
> know what the overall CPU usage is during the blockage? If you're using
> WinNT/2K/XP, you can view the usage via the Task Manager.
>
>
> Gambit
>
>
>
--
_/\__/\__/\__/\__/\__/\_
www.huaonline.com
My Homepage is my Castle
Technical Details
Message-ID:
<oprr0lg5y5bq7az6@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-04!sn-xit-01!sn-xit-09!supernews.com!diablo.theplanet.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<oprrwu2pcgbq7az6@newsgroups.borland.com> <3f08d164@newsgroups.borland.com> <oprrxfa6dpbq7az6@newsgroups.borland.com> <3f09295c@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10cc67,a436a021eb0521f3
X-Google-Attributes: gid10cc67,public
X-Google-ArrivalTime: 2003-07-08 16:40:04 PST
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: Re: SetEventTimer routine holds TThread task?
References: <oprrwu2pcgbq7az6@newsgroups.borland.com> <3f08d164@newsgroups.borland.com> <oprrxfa6dpbq7az6@newsgroups.borland.com> <3f09295c@newsgroups.borland.com>
Message-ID: <oprr0lg5y5bq7az6@newsgroups.borland.com>
Content-Type: text/plain; charset=iso-8859-15; format=flowed
From: Phuoc Can HUA <home}a+t{huaonline.com>
MIME-Version: 1.0
Date: Wed, 09 Jul 2003 09:13:43 +1000
User-Agent: Opera7.10/Win32 M2 build 2840
NNTP-Posting-Host: 210.9.89.210
X-Trace: newsgroups.borland.com 1057706215 210.9.89.210 (8 Jul 2003 16:16:55 -0700)
Lines: 396
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-04!sn-xit-01!sn-xit-09!supernews.com!diablo.theplanet.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail