🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #15392

Re: SetEventTimer routine holds TThread task?

#15392
From: Phuoc Can HUA
Date: Tue, 08 Jul 2003 23:13
396 lines
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-mail
References: <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