change the mechanism of how the LEDs are updated -> no window event posts anymore to avoid blocking in the critical audio thread

This commit is contained in:
Volker Fischer 2014-01-03 08:54:49 +00:00
parent e9a5962ef1
commit 6e49e4e92c
16 changed files with 144 additions and 365 deletions

View file

@ -58,6 +58,7 @@ CClient::CClient ( const quint16 iPortNumber ) :
bFraSiFactSafeSupported ( false ), bFraSiFactSafeSupported ( false ),
bOpenChatOnNewMessage ( true ), bOpenChatOnNewMessage ( true ),
eGUIDesign ( GD_ORIGINAL ), eGUIDesign ( GD_ORIGINAL ),
bJitterBufferOK ( true ),
strCentralServerAddress ( "" ), strCentralServerAddress ( "" ),
bUseDefaultCentralServerAddress ( true ), bUseDefaultCentralServerAddress ( true ),
iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL ) iServerSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL )
@ -367,6 +368,29 @@ bool CClient::SetServerAddr ( QString strNAddr )
} }
} }
bool CClient::GetAndResetbJitterBufferOKFlag()
{
// get the socket buffer put status flag and reset it
const bool bSocketJitBufOKFlag = Socket.GetAndResetbJitterBufferOKFlag();
if ( !bJitterBufferOK )
{
// our jitter buffer get status is not OK so the overall status of the
// jitter buffer is also not OK (we do not have to consider the status
// of the socket buffer put status flag)
// reset flag before returning the function
bJitterBufferOK = true;
return false;
}
// the jitter buffer get (our own status flag) is OK, the final status
// now depends on the jitter buffer put status flag from the socket
// since per definition the jitter buffer status is OK if both the
// put and get status are OK
return bSocketJitBufOKFlag;
}
void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ) void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor )
{ {
// first check new input parameter // first check new input parameter
@ -659,8 +683,8 @@ void CClient::Stop()
ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() ); ConnLessProtocol.CreateCLDisconnection ( Channel.GetAddress() );
// reset current signal level and LEDs // reset current signal level and LEDs
bJitterBufferOK = true;
SignalLevelMeter.Reset(); SignalLevelMeter.Reset();
PostWinMessage ( MS_RESET_ALL, 0 );
} }
void CClient::Init() void CClient::Init()
@ -854,7 +878,7 @@ void CClient::Init()
void CClient::AudioCallback ( CVector<int16_t>& psData, void* arg ) void CClient::AudioCallback ( CVector<int16_t>& psData, void* arg )
{ {
// get the pointer to the object // get the pointer to the object
CClient* pMyClientObj = reinterpret_cast<CClient*> ( arg ); CClient* pMyClientObj = static_cast<CClient*> ( arg );
// process audio data // process audio data
pMyClientObj->ProcessSndCrdAudioData ( psData ); pMyClientObj->ProcessSndCrdAudioData ( psData );
@ -1080,13 +1104,10 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
const bool bReceiveDataOk = const bool bReceiveDataOk =
( Channel.GetData ( vecbyNetwData ) == GS_BUFFER_OK ); ( Channel.GetData ( vecbyNetwData ) == GS_BUFFER_OK );
if ( bReceiveDataOk ) // invalidate the buffer OK status flag if necessary
if ( !bReceiveDataOk )
{ {
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN ); bJitterBufferOK = false;
}
else
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED );
} }
// CELT decoding // CELT decoding

View file

@ -108,8 +108,12 @@ public:
void Stop(); void Stop();
bool IsRunning() { return Sound.IsRunning(); } bool IsRunning() { return Sound.IsRunning(); }
bool SetServerAddr ( QString strNAddr ); bool SetServerAddr ( QString strNAddr );
double MicLevelL() { return SignalLevelMeter.MicLevelLeft(); } double MicLevelL() { return SignalLevelMeter.MicLevelLeft(); }
double MicLevelR() { return SignalLevelMeter.MicLevelRight(); } double MicLevelR() { return SignalLevelMeter.MicLevelRight(); }
bool GetAndResetbJitterBufferOKFlag();
bool IsConnected() { return Channel.IsConnected(); } bool IsConnected() { return Channel.IsConnected(); }
bool GetOpenChatOnNewMessage() const { return bOpenChatOnNewMessage; } bool GetOpenChatOnNewMessage() const { return bOpenChatOnNewMessage; }
@ -353,6 +357,8 @@ void SetAudoCompressiontype ( const EAudComprType eNAudCompressionType );
bool bOpenChatOnNewMessage; bool bOpenChatOnNewMessage;
EGUIDesign eGUIDesign; EGUIDesign eGUIDesign;
bool bJitterBufferOK;
QString strCentralServerAddress; QString strCentralServerAddress;
bool bUseDefaultCentralServerAddress; bool bUseDefaultCentralServerAddress;

View file

@ -254,10 +254,10 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
lbrInputLevelR->setValue ( 0 ); lbrInputLevelR->setValue ( 0 );
// init status LEDs // init status LEDs
ledConnection->SetUpdateTime ( 2 * LED_BAR_UPDATE_TIME_MS ); ledConnection->Reset();
ledChat->SetUpdateTime ( 2 * LED_BAR_UPDATE_TIME_MS ); ledBuffers->Reset();
ledDelay->SetUpdateTime ( 2 * PING_UPDATE_TIME_MS );
ledDelay->Reset(); ledDelay->Reset();
ledChat->Reset();
// init slider controls --- // init slider controls ---
@ -435,6 +435,9 @@ CClientDlg::CClientDlg ( CClient* pNCliP,
QObject::connect ( &TimerSigMet, SIGNAL ( timeout() ), QObject::connect ( &TimerSigMet, SIGNAL ( timeout() ),
this, SLOT ( OnTimerSigMet() ) ); this, SLOT ( OnTimerSigMet() ) );
QObject::connect ( &TimerBuffersLED, SIGNAL ( timeout() ),
this, SLOT ( OnTimerBuffersLED() ) );
QObject::connect ( &TimerStatus, SIGNAL ( timeout() ), QObject::connect ( &TimerStatus, SIGNAL ( timeout() ),
this, SLOT ( OnTimerStatus() ) ); this, SLOT ( OnTimerStatus() ) );
@ -903,6 +906,25 @@ void CClientDlg::OnTimerSigMet()
lbrInputLevelR->setValue ( (int) ceil ( dCurSigLevelR ) ); lbrInputLevelR->setValue ( (int) ceil ( dCurSigLevelR ) );
} }
void CClientDlg::OnTimerBuffersLED()
{
int iCurStatus;
// get and reset current buffer state and set LED from that flag
if ( pClient->GetAndResetbJitterBufferOKFlag() )
{
iCurStatus = MUL_COL_LED_GREEN;
}
else
{
iCurStatus = MUL_COL_LED_RED;
}
// update the buffer LED and the general settings dialog, too
ledBuffers->SetLight ( iCurStatus );
ClientSettingsDlg.SetStatus ( iCurStatus );
}
void CClientDlg::OnTimerPing() void CClientDlg::OnTimerPing()
{ {
// send ping message to the server // send ping message to the server
@ -1005,6 +1027,7 @@ void CClientDlg::Connect ( const QString& strSelectedAddress,
// start timer for level meter bar and ping time measurement // start timer for level meter bar and ping time measurement
TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS ); TimerSigMet.start ( LEVELMETER_UPDATE_TIME_MS );
TimerBuffersLED.start ( BUFFER_LED_UPDATE_TIME_MS );
TimerPing.start ( PING_UPDATE_TIME_MS ); TimerPing.start ( PING_UPDATE_TIME_MS );
} }
else else
@ -1036,7 +1059,8 @@ void CClientDlg::Disconnect()
lbrInputLevelL->setValue ( 0 ); lbrInputLevelL->setValue ( 0 );
lbrInputLevelR->setValue ( 0 ); lbrInputLevelR->setValue ( 0 );
// stop ping time measurement timer // stop other timers
TimerBuffersLED.stop();
TimerPing.stop(); TimerPing.stop();
@ -1044,13 +1068,13 @@ void CClientDlg::Disconnect()
// immediately update status bar // immediately update status bar
OnTimerStatus(); OnTimerStatus();
// TODO this seems not to work, LEDs are still updated afterwards...
// reset LEDs // reset LEDs
ledConnection->Reset(); ledConnection->Reset();
ledBuffers->Reset(); ledBuffers->Reset();
ledDelay->Reset(); ledDelay->Reset();
ledChat->Reset(); ledChat->Reset();
ClientSettingsDlg.ResetStatus();
// clear mixer board (remove all faders) // clear mixer board (remove all faders)
MainMixerBoard->HideAll(); MainMixerBoard->HideAll();
@ -1168,31 +1192,3 @@ rbtReverbSelR->setStyleSheet ( "" );
// also apply GUI design to child GUI controls // also apply GUI design to child GUI controls
MainMixerBoard->SetGUIDesign ( eNewDesign ); MainMixerBoard->SetGUIDesign ( eNewDesign );
} }
void CClientDlg::customEvent ( QEvent* Event )
{
if ( Event->type() == QEvent::User + 11 )
{
const int iMessType = ( (CCustomEvent*) Event )->iMessType;
const int iStatus = ( (CCustomEvent*) Event )->iStatus;
switch ( iMessType )
{
case MS_JIT_BUF_PUT:
case MS_JIT_BUF_GET:
// buffer status -> if any buffer goes red, this LED will go red
ledBuffers->SetLight ( iStatus );
break;
case MS_RESET_ALL:
ledConnection->Reset();
ledBuffers->Reset();
ledDelay->Reset();
ledChat->Reset();
break;
}
// update general settings dialog, too
ClientSettingsDlg.SetStatus ( iMessType, iStatus );
}
}

View file

@ -52,6 +52,7 @@
// update time for GUI controls // update time for GUI controls
#define LEVELMETER_UPDATE_TIME_MS 100 // ms #define LEVELMETER_UPDATE_TIME_MS 100 // ms
#define BUFFER_LED_UPDATE_TIME_MS 300 // ms
#define LED_BAR_UPDATE_TIME_MS 1000 // ms #define LED_BAR_UPDATE_TIME_MS 1000 // ms
// range for signal level meter // range for signal level meter
@ -96,10 +97,10 @@ protected:
bool bConnected; bool bConnected;
bool bUnreadChatMessage; bool bUnreadChatMessage;
QTimer TimerSigMet; QTimer TimerSigMet;
QTimer TimerBuffersLED;
QTimer TimerStatus; QTimer TimerStatus;
QTimer TimerPing; QTimer TimerPing;
virtual void customEvent ( QEvent* Event );
virtual void closeEvent ( QCloseEvent* Event ); virtual void closeEvent ( QCloseEvent* Event );
void UpdateDisplay(); void UpdateDisplay();
@ -118,6 +119,7 @@ public slots:
void OnConnectDisconBut(); void OnConnectDisconBut();
void OnInstPictureBut(); void OnInstPictureBut();
void OnTimerSigMet(); void OnTimerSigMet();
void OnTimerBuffersLED();
void OnTimerStatus() { UpdateDisplay(); } void OnTimerStatus() { UpdateDisplay(); }

View file

@ -269,7 +269,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
#endif #endif
// init delay and other information controls // init delay and other information controls
ledOverallDelay->SetUpdateTime ( 2 * PING_UPDATE_TIME_MS ); ledNetw->Reset();
ledOverallDelay->Reset(); ledOverallDelay->Reset();
lblPingTimeValue->setText ( "---" ); lblPingTimeValue->setText ( "---" );
lblOverallDelayValue->setText ( "---" ); lblOverallDelayValue->setText ( "---" );
@ -750,19 +750,3 @@ void CClientSettingsDlg::UpdateDisplay()
QString().setNum ( pClient->GetUploadRateKbps() ) + " kbps" ); QString().setNum ( pClient->GetUploadRateKbps() ) + " kbps" );
} }
} }
void CClientSettingsDlg::SetStatus ( const int iMessType, const int iStatus )
{
switch ( iMessType )
{
case MS_JIT_BUF_PUT:
case MS_JIT_BUF_GET:
// network LED shows combined status of put and get
ledNetw->SetLight ( iStatus );
break;
case MS_RESET_ALL:
ledNetw->Reset();
break;
}
}

View file

@ -55,7 +55,9 @@ public:
QWidget* parent = 0, QWidget* parent = 0,
Qt::WindowFlags f = 0 ); Qt::WindowFlags f = 0 );
void SetStatus ( const int iMessType, const int iStatus ); void SetStatus ( const int iStatus ) { ledNetw->SetLight ( iStatus ); }
void ResetStatus() { ledNetw->Reset(); }
void SetPingTimeResult ( const int iPingTime, void SetPingTimeResult ( const int iPingTime,
const int iOverallDelayMs, const int iOverallDelayMs,
const int iOverallDelayLEDColor ); const int iOverallDelayLEDColor );

View file

@ -260,17 +260,14 @@ typedef unsigned char uint8_t;
#endif #endif
/* Definitions for window message system ------------------------------------ */ /* Pseudo enum definitions -------------------------------------------------- */
typedef unsigned int _MESSAGE_IDENT;
#define MS_RESET_ALL 0 // MS: Message
#define MS_JIT_BUF_PUT 1
#define MS_JIT_BUF_GET 2
#define MS_PACKET_RECEIVED 3
#define MUL_COL_LED_RED 0 #define MUL_COL_LED_RED 0
#define MUL_COL_LED_YELLOW 1 #define MUL_COL_LED_YELLOW 1
#define MUL_COL_LED_GREEN 2 #define MUL_COL_LED_GREEN 2
// definition for custom event
#define MS_PACKET_RECEIVED 0
/* Classes ********************************************************************/ /* Classes ********************************************************************/
class CGenErr class CGenErr
@ -337,9 +334,4 @@ bool GetNumericArgument ( QTextStream& tsConsole,
double rRangeStop, double rRangeStop,
double& rValue); double& rValue);
// posting a window message
void PostWinMessage ( const _MESSAGE_IDENT MessID,
const int iMessageParam = 0,
const int iChanNum = 0 );
#endif /* !defined ( GLOBAL_H__3B123453_4344_BB2B_23E7A0D31912__INCLUDED_ ) */ #endif /* !defined ( GLOBAL_H__3B123453_4344_BB2B_23E7A0D31912__INCLUDED_ ) */

View file

@ -639,22 +639,3 @@ bool GetNumericArgument ( QTextStream& tsConsole,
return false; return false;
} }
} }
/******************************************************************************\
* Window Message System *
\******************************************************************************/
void PostWinMessage ( const _MESSAGE_IDENT MessID,
const int iMessageParam,
const int iChanNum )
{
// first check if application is initialized
if ( pApp != NULL )
{
CCustomEvent* CustomEvent =
new CCustomEvent ( MessID, iMessageParam, iChanNum );
// Qt will delete the event object when done
QCoreApplication::postEvent ( pMainWindow, CustomEvent );
}
}

View file

@ -43,25 +43,6 @@ CMultiColorLED::CMultiColorLED ( QWidget* parent, Qt::WindowFlags f )
// set init bitmap // set init bitmap
setPixmap ( BitmCubeGrey ); setPixmap ( BitmCubeGrey );
eColorFlag = RL_GREY; eColorFlag = RL_GREY;
// init update time
SetUpdateTime ( DEFAULT_UPDATE_TIME );
// init timers -> we want to have single shot timers
TimerRedLight.setSingleShot ( true );
TimerGreenLight.setSingleShot ( true );
TimerYellowLight.setSingleShot ( true );
// connect timer events to the desired slots
connect ( &TimerRedLight, SIGNAL ( timeout() ),
this, SLOT ( OnTimerRedLight() ) );
connect ( &TimerGreenLight, SIGNAL ( timeout() ),
this, SLOT ( OnTimerGreenLight() ) );
connect ( &TimerYellowLight, SIGNAL ( timeout() ),
this, SLOT ( OnTimerYellowLight() ) );
connect ( this, SIGNAL ( newPixmap ( const QPixmap& ) ),
this, SLOT ( OnNewPixmap ( const QPixmap& ) ) );
} }
void CMultiColorLED::changeEvent ( QEvent* curEvent ) void CMultiColorLED::changeEvent ( QEvent* curEvent )
@ -71,88 +52,64 @@ void CMultiColorLED::changeEvent ( QEvent* curEvent )
{ {
if ( this->isEnabled() ) if ( this->isEnabled() )
{ {
emit newPixmap ( BitmCubeGrey ); setPixmap ( BitmCubeGrey );
eColorFlag = RL_GREY; eColorFlag = RL_GREY;
} }
else else
{ {
emit newPixmap ( BitmCubeDisabled ); setPixmap ( BitmCubeDisabled );
eColorFlag = RL_DISABLED; eColorFlag = RL_DISABLED;
} }
} }
} }
void CMultiColorLED::OnTimerRedLight() void CMultiColorLED::SetColor ( const ELightColor eNewColorFlag )
{ {
bFlagRedLi = false; switch ( eNewColorFlag )
UpdateColor();
}
void CMultiColorLED::OnTimerGreenLight()
{
bFlagGreenLi = false;
UpdateColor();
}
void CMultiColorLED::OnTimerYellowLight()
{
bFlagYellowLi = false;
UpdateColor();
}
void CMultiColorLED::UpdateColor()
{
// Red light has highest priority, then comes yellow and at the end, we
// decide to set green light. Allways check the current color of the
// control before setting the color to prevent flickering
if ( bFlagRedLi )
{ {
case RL_RED:
// red
if ( eColorFlag != RL_RED ) if ( eColorFlag != RL_RED )
{ {
emit newPixmap ( BitmCubeRed ); setPixmap ( BitmCubeRed );
eColorFlag = RL_RED; eColorFlag = RL_RED;
} }
return; break;
}
if ( bFlagYellowLi ) case RL_YELLOW:
{ // yellow
if ( eColorFlag != RL_YELLOW ) if ( eColorFlag != RL_YELLOW )
{ {
emit newPixmap ( BitmCubeYellow ); setPixmap ( BitmCubeYellow );
eColorFlag = RL_YELLOW; eColorFlag = RL_YELLOW;
} }
return; break;
}
if ( bFlagGreenLi ) case RL_GREEN:
{ // green
if ( eColorFlag != RL_GREEN ) if ( eColorFlag != RL_GREEN )
{ {
emit newPixmap ( BitmCubeGreen ); setPixmap ( BitmCubeGreen );
eColorFlag = RL_GREEN; eColorFlag = RL_GREEN;
} }
return; break;
}
default:
// if no color is active, set control to grey light // if no color is active, set control to grey light
if ( eColorFlag != RL_GREY ) if ( eColorFlag != RL_GREY )
{ {
setPixmap ( BitmCubeGrey ); setPixmap ( BitmCubeGrey );
eColorFlag = RL_GREY; eColorFlag = RL_GREY;
} }
break;
}
} }
void CMultiColorLED::Reset() void CMultiColorLED::Reset()
{ {
if ( this->isEnabled() ) if ( this->isEnabled() )
{ {
// reset color flags SetColor ( RL_GREY );
bFlagRedLi = false;
bFlagGreenLi = false;
bFlagYellowLi = false;
UpdateColor();
} }
} }
@ -163,41 +120,16 @@ void CMultiColorLED::SetLight ( const int iNewStatus )
switch ( iNewStatus ) switch ( iNewStatus )
{ {
case MUL_COL_LED_GREEN: case MUL_COL_LED_GREEN:
// green light SetColor ( RL_GREEN );
bFlagGreenLi = true;
TimerGreenLight.start();
break; break;
case MUL_COL_LED_YELLOW: case MUL_COL_LED_YELLOW:
// yellow light SetColor ( RL_YELLOW );
bFlagYellowLi = true;
TimerYellowLight.start();
break; break;
case MUL_COL_LED_RED: case MUL_COL_LED_RED:
// red light SetColor ( RL_RED );
bFlagRedLi = true;
TimerRedLight.start();
break; break;
} }
UpdateColor();
} }
} }
void CMultiColorLED::SetUpdateTime ( const int iNUTi )
{
// avoid too short intervals
if ( iNUTi < MIN_TIME_FOR_RED_LIGHT )
{
iUpdateTime = MIN_TIME_FOR_RED_LIGHT;
}
else
{
iUpdateTime = iNUTi;
}
TimerGreenLight.setInterval ( iUpdateTime );
TimerYellowLight.setInterval ( iUpdateTime );
TimerRedLight.setInterval ( iUpdateTime );
}

View file

@ -34,29 +34,17 @@
#include <QLabel> #include <QLabel>
#include <QPixmap> #include <QPixmap>
#include <QTimer>
#include <QTreeWidget>
#include <QIcon> #include <QIcon>
#include "global.h" #include "global.h"
/* Definitions ****************************************************************/
#define DEFAULT_UPDATE_TIME 300
// the red and yellow light should be on at least this interval
#define MIN_TIME_FOR_RED_LIGHT 100
/* Classes ********************************************************************/ /* Classes ********************************************************************/
class CMultiColorLED : public QLabel class CMultiColorLED : public QLabel
{ {
Q_OBJECT
public: public:
CMultiColorLED ( QWidget* parent = 0, Qt::WindowFlags f = 0 ); CMultiColorLED ( QWidget* parent = 0, Qt::WindowFlags f = 0 );
void Reset(); void Reset();
void SetUpdateTime ( const int iNUTi );
void SetLight ( const int iNewStatus ); void SetLight ( const int iNewStatus );
protected: protected:
@ -71,7 +59,7 @@ protected:
ELightColor eColorFlag; ELightColor eColorFlag;
virtual void changeEvent ( QEvent* curEvent ); virtual void changeEvent ( QEvent* curEvent );
void UpdateColor(); void SetColor ( const ELightColor eNewColorFlag );
QPixmap BitmCubeDisabled; QPixmap BitmCubeDisabled;
QPixmap BitmCubeGrey; QPixmap BitmCubeGrey;
@ -79,89 +67,11 @@ protected:
QPixmap BitmCubeYellow; QPixmap BitmCubeYellow;
QPixmap BitmCubeRed; QPixmap BitmCubeRed;
QTimer TimerRedLight;
QTimer TimerGreenLight;
QTimer TimerYellowLight;
int iUpdateTime; int iUpdateTime;
bool bFlagRedLi; bool bFlagRedLi;
bool bFlagGreenLi; bool bFlagGreenLi;
bool bFlagYellowLi; bool bFlagYellowLi;
protected slots:
void OnTimerRedLight();
void OnTimerGreenLight();
void OnTimerYellowLight();
virtual void OnNewPixmap ( const QPixmap& newPixmap ) { setPixmap ( newPixmap ); }
signals:
void newPixmap ( const QPixmap& newPixmap );
};
class CMultColLEDListViewItem : public CMultiColorLED
{
Q_OBJECT
public:
CMultColLEDListViewItem ( const int iNewCol )
: pListViewItem ( NULL ), iColumn ( iNewCol ) {}
void SetListViewItemPointer ( QTreeWidgetItem* pNewListViewItem )
{
pListViewItem = pNewListViewItem;
}
protected slots:
virtual void OnNewPixmap ( const QPixmap& newPixmap )
{
if ( pListViewItem != NULL )
{
pListViewItem->setIcon ( iColumn, QIcon ( newPixmap ) );
}
}
protected:
QTreeWidgetItem* pListViewItem;
int iColumn;
};
class CServerListViewItem : public QTreeWidgetItem
{
public:
CServerListViewItem ( QTreeWidget* parent )
: QTreeWidgetItem ( parent ), LED ( 2 )
{
LED.SetListViewItemPointer ( this );
}
void SetLight ( int iNewStatus )
{
LED.SetLight ( iNewStatus );
}
protected:
CMultColLEDListViewItem LED;
};
class CConnectionServerListViewItem : public QTreeWidgetItem
{
public:
CConnectionServerListViewItem ( QTreeWidget* parent )
: QTreeWidgetItem ( parent ), LED ( 4 )
{
LED.SetListViewItemPointer ( this );
}
void Reset() { LED.Reset(); }
void SetUpdateTime ( const int iNUTi ) { LED.SetUpdateTime ( iNUTi ); }
void SetLight ( int iNewStatus ) { LED.SetLight ( iNewStatus ); }
protected:
CMultColLEDListViewItem LED;
}; };
#endif // _MULTCOLORLED_H__FD6B49B5_87DF_48DD_A873_804E1606C2AC__INCLUDED_ #endif // _MULTCOLORLED_H__FD6B49B5_87DF_48DD_A873_804E1606C2AC__INCLUDED_

View file

@ -798,16 +798,6 @@ void CServer::OnTimer()
} }
} }
} }
// send message for get status (for GUI)
if ( eGetStat == GS_BUFFER_OK )
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN, iCurChanID );
}
else
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED, iCurChanID );
}
} }
// a channel is now disconnected, take action on it // a channel is now disconnected, take action on it
@ -1287,28 +1277,10 @@ bool CServer::PutData ( const CVector<uint8_t>& vecbyRecBuf,
if ( bChanOK ) if ( bChanOK )
{ {
// put packet in socket buffer // put packet in socket buffer
switch ( vecChannels[iCurChanID].PutData ( vecbyRecBuf, iNumBytesRead ) ) if ( vecChannels[iCurChanID].PutData ( vecbyRecBuf, iNumBytesRead ) == PS_PROT_OK_MESS_NOT_EVALUATED )
{ {
case PS_AUDIO_OK: // set flag
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN, iCurChanID ); bIsNotEvaluatedProtocolMessage = true;
break;
case PS_AUDIO_ERR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED, iCurChanID );
break;
case PS_PROT_ERR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW, iCurChanID );
break;
case PS_PROT_OK_MESS_NOT_EVALUATED:
bIsNotEvaluatedProtocolMessage = true; // set flag
break;
case PS_GEN_ERROR:
case PS_PROT_OK:
// for these cases, do nothing
break;
} }
} }

View file

@ -44,8 +44,8 @@ CServerDlg::CServerDlg ( CServer* pNServP,
// client list // client list
lvwClients->setWhatsThis ( tr ( "<b>Client List:</b> The client list " lvwClients->setWhatsThis ( tr ( "<b>Client List:</b> The client list "
"shows all clients which are currently connected to this server. Some " "shows all clients which are currently connected to this server. Some "
"informations about the clients like the IP address, name, buffer " "informations about the clients like the IP address and name are given "
"state are given for each connected client." ) ); "for each connected client." ) );
lvwClients->setAccessibleName ( tr ( "Connected clients list view" ) ); lvwClients->setAccessibleName ( tr ( "Connected clients list view" ) );
@ -161,7 +161,6 @@ CServerDlg::CServerDlg ( CServer* pNServP,
// set up list view for connected clients // set up list view for connected clients
lvwClients->setColumnWidth ( 0, 170 ); lvwClients->setColumnWidth ( 0, 170 );
lvwClients->setColumnWidth ( 1, 130 ); lvwClients->setColumnWidth ( 1, 130 );
lvwClients->setColumnWidth ( 2, 60 );
lvwClients->clear(); lvwClients->clear();
@ -175,7 +174,7 @@ lvwClients->setMinimumHeight ( 140 );
vecpListViewItems.Init ( MAX_NUM_CHANNELS ); vecpListViewItems.Init ( MAX_NUM_CHANNELS );
for ( int i = MAX_NUM_CHANNELS - 1; i >= 0; i-- ) for ( int i = MAX_NUM_CHANNELS - 1; i >= 0; i-- )
{ {
vecpListViewItems[i] = new CServerListViewItem ( lvwClients ); vecpListViewItems[i] = new QTreeWidgetItem ( lvwClients );
vecpListViewItems[i]->setHidden ( true ); vecpListViewItems[i]->setHidden ( true );
} }
@ -461,11 +460,11 @@ void CServerDlg::OnTimer()
vecpListViewItems[i]->setText ( 1, vecsName[i] ); vecpListViewItems[i]->setText ( 1, vecsName[i] );
// jitter buffer size (polling for updates) // jitter buffer size (polling for updates)
vecpListViewItems[i]->setText ( 3, vecpListViewItems[i]->setText ( 2,
QString().setNum ( veciJitBufNumFrames[i] ) ); QString().setNum ( veciJitBufNumFrames[i] ) );
// out network block size // out network block size
vecpListViewItems[i]->setText ( 4, vecpListViewItems[i]->setText ( 3,
QString().setNum ( static_cast<double> ( QString().setNum ( static_cast<double> (
veciNetwFrameSizeFact[i] * SYSTEM_BLOCK_DURATION_MS_FLOAT veciNetwFrameSizeFact[i] * SYSTEM_BLOCK_DURATION_MS_FLOAT
), 'f', 2 ) ); ), 'f', 2 ) );
@ -582,25 +581,3 @@ void CServerDlg::changeEvent ( QEvent* pEvent )
} }
} }
} }
void CServerDlg::customEvent ( QEvent* pEvent )
{
if ( pEvent->type() == QEvent::User + 11 )
{
ListViewMutex.lock();
{
const int iMessType = ( (CCustomEvent*) pEvent )->iMessType;
const int iStatus = ( (CCustomEvent*) pEvent )->iStatus;
const int iChanNum = ( (CCustomEvent*) pEvent )->iChanNum;
switch(iMessType)
{
case MS_JIT_BUF_PUT:
case MS_JIT_BUF_GET:
vecpListViewItems[iChanNum]->SetLight ( iStatus );
break;
}
}
ListViewMutex.unlock();
}
}

View file

@ -36,7 +36,6 @@
#include "global.h" #include "global.h"
#include "server.h" #include "server.h"
#include "settings.h" #include "settings.h"
#include "multicolorled.h"
#include "ui_serverdlgbase.h" #include "ui_serverdlgbase.h"
@ -58,7 +57,6 @@ public:
Qt::WindowFlags f = 0 ); Qt::WindowFlags f = 0 );
protected: protected:
virtual void customEvent ( QEvent* pEvent );
virtual void changeEvent ( QEvent* pEvent ); virtual void changeEvent ( QEvent* pEvent );
virtual void closeEvent ( QCloseEvent* Event ); virtual void closeEvent ( QCloseEvent* Event );
@ -71,7 +69,7 @@ protected:
CServer* pServer; CServer* pServer;
CSettings* pSettings; CSettings* pSettings;
CVector<CServerListViewItem*> vecpListViewItems; CVector<QTreeWidgetItem*> vecpListViewItems;
QMutex ListViewMutex; QMutex ListViewMutex;
QMenuBar* pMenu; QMenuBar* pMenu;

View file

@ -34,11 +34,6 @@
<string>Name</string> <string>Name</string>
</property> </property>
</column> </column>
<column>
<property name="text" >
<string>Buffers</string>
</property>
</column>
<column> <column>
<property name="text" > <property name="text" >
<string>Jitter Buffer Size</string> <string>Jitter Buffer Size</string>

View file

@ -117,6 +117,21 @@ void CSocket::SendPacket ( const CVector<uint8_t>& vecbySendBuf,
} }
} }
bool CSocket::GetAndResetbJitterBufferOKFlag()
{
// check jitter buffer status
if ( !bJitterBufferOK )
{
// reset flag and return "not OK" status
bJitterBufferOK = true;
return false;
}
// the buffer was OK, we do not have to reset anything and just return the
// OK status
return true;
}
void CSocket::OnDataReceived() void CSocket::OnDataReceived()
{ {
while ( SocketDevice.hasPendingDatagrams() ) while ( SocketDevice.hasPendingDatagrams() )
@ -152,21 +167,9 @@ void CSocket::OnDataReceived()
// this network packet is valid, put it in the channel // this network packet is valid, put it in the channel
switch ( pChannel->PutData ( vecbyRecBuf, iNumBytesRead ) ) switch ( pChannel->PutData ( vecbyRecBuf, iNumBytesRead ) )
{ {
case PS_AUDIO_OK:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN );
break;
case PS_AUDIO_ERR: case PS_AUDIO_ERR:
case PS_GEN_ERROR: case PS_GEN_ERROR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED ); bJitterBufferOK = false;
break;
case PS_PROT_ERR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW );
break;
default:
// other put data states need not to be considered here
break; break;
} }
} }

View file

@ -57,15 +57,21 @@ class CSocket : public QObject
public: public:
CSocket ( CChannel* pNewChannel, CSocket ( CChannel* pNewChannel,
const quint16 iPortNumber ) const quint16 iPortNumber )
: pChannel( pNewChannel ), bIsClient ( true ) { Init ( iPortNumber ); } : pChannel ( pNewChannel ),
bIsClient ( true ),
bJitterBufferOK ( true ) { Init ( iPortNumber ); }
CSocket ( CServer* pNServP, CSocket ( CServer* pNServP,
const quint16 iPortNumber ) const quint16 iPortNumber )
: pServer ( pNServP ), bIsClient ( false ) { Init ( iPortNumber ); } : pServer ( pNServP ),
bIsClient ( false ),
bJitterBufferOK ( true ) { Init ( iPortNumber ); }
void SendPacket ( const CVector<uint8_t>& vecbySendBuf, void SendPacket ( const CVector<uint8_t>& vecbySendBuf,
const CHostAddress& HostAddr ); const CHostAddress& HostAddr );
bool GetAndResetbJitterBufferOKFlag();
protected: protected:
void Init ( const quint16 iPortNumber = LLCON_DEFAULT_PORT_NUMBER ); void Init ( const quint16 iPortNumber = LLCON_DEFAULT_PORT_NUMBER );
@ -80,6 +86,8 @@ protected:
bool bIsClient; bool bIsClient;
bool bJitterBufferOK;
public slots: public slots:
void OnDataReceived(); void OnDataReceived();