- speed optimizations (removed some memory allocations in the processing routine)

- removed duplicate function
- clean up some code
This commit is contained in:
Volker Fischer 2014-01-08 21:24:37 +00:00
parent d98ac1b2af
commit 33afb04f3f
2 changed files with 138 additions and 135 deletions

View file

@ -197,7 +197,7 @@ void CHighPrecisionTimer::run()
// CServer implementation ****************************************************** // CServer implementation ******************************************************
CServer::CServer ( const int iNewNumChan, CServer::CServer ( const int iNewMaxNumChan,
const QString& strLoggingFileName, const QString& strLoggingFileName,
const quint16 iPortNumber, const quint16 iPortNumber,
const QString& strHTMLStatusFileName, const QString& strHTMLStatusFileName,
@ -207,13 +207,13 @@ CServer::CServer ( const int iNewNumChan,
const QString& strServerInfo, const QString& strServerInfo,
const QString& strNewWelcomeMessage, const QString& strNewWelcomeMessage,
const bool bNCentServPingServerInList ) : const bool bNCentServPingServerInList ) :
iNumChannels ( iNewNumChan ), iMaxNumChannels ( iNewMaxNumChan ),
Socket ( this, iPortNumber ), Socket ( this, iPortNumber ),
bWriteStatusHTMLFile ( false ), bWriteStatusHTMLFile ( false ),
ServerListManager ( iPortNumber, ServerListManager ( iPortNumber,
strCentralServer, strCentralServer,
strServerInfo, strServerInfo,
iNewNumChan, iNewMaxNumChan,
bNCentServPingServerInList, bNCentServPingServerInList,
&ConnLessProtocol ), &ConnLessProtocol ),
bAutoRunMinimized ( false ), bAutoRunMinimized ( false ),
@ -225,7 +225,7 @@ CServer::CServer ( const int iNewNumChan,
// create CELT encoder/decoder for each channel (must be done before // create CELT encoder/decoder for each channel (must be done before
// enabling the channels), create a mono and stereo encoder/decoder // enabling the channels), create a mono and stereo encoder/decoder
// for each channel // for each channel
for ( i = 0; i < iNumChannels; i++ ) for ( i = 0; i < iMaxNumChannels; i++ )
{ {
// init audio endocder/decoder (mono) // init audio endocder/decoder (mono)
CeltModeMono[i] = cc6_celt_mode_create ( CeltModeMono[i] = cc6_celt_mode_create (
@ -311,6 +311,11 @@ CServer::CServer ( const int iNewNumChan,
vstrChatColors[4] = "maroon"; vstrChatColors[4] = "maroon";
vstrChatColors[5] = "coral"; vstrChatColors[5] = "coral";
// allocate memory for the channel IDs vector for the current connected
// channels where we assume the worst case that all possible channels are
// used
vecChanIDsCurConChan.Init ( iMaxNumChannels );
// enable history graph (if requested) // enable history graph (if requested)
if ( !strHistoryFileName.isEmpty() ) if ( !strHistoryFileName.isEmpty() )
{ {
@ -351,7 +356,7 @@ CServer::CServer ( const int iNewNumChan,
// enable all channels (for the server all channel must be enabled the // enable all channels (for the server all channel must be enabled the
// entire life time of the software) // entire life time of the software)
for ( i = 0; i < iNumChannels; i++ ) for ( i = 0; i < iMaxNumChannels; i++ )
{ {
vecChannels[i].SetEnable ( true ); vecChannels[i].SetEnable ( true );
} }
@ -641,12 +646,15 @@ void CServer::OnTimer()
{ {
int i, j; int i, j;
CVector<int> vecChanID; // TODO avoid allocating memory in the time critical processing routine
CVector<CVector<double> > vecvecdGains; CVector<CVector<double> > vecvecdGains;
CVector<CVector<int16_t> > vecvecsData; CVector<CVector<int16_t> > vecvecsData;
CVector<int> vecNumAudioChannels; CVector<int> vecNumAudioChannels;
// Get data from all connected clients ------------------------------------- // Get data from all connected clients -------------------------------------
// some inits
int iNumClients = 0; // init connected client counter
bool bChannelIsNowDisconnected = false; bool bChannelIsNowDisconnected = false;
// Make put and get calls thread safe. Do not forget to unlock mutex // Make put and get calls thread safe. Do not forget to unlock mutex
@ -654,28 +662,36 @@ void CServer::OnTimer()
Mutex.lock(); Mutex.lock();
{ {
// first, get number and IDs of connected channels // first, get number and IDs of connected channels
vecChanID.Init ( 0 ); for ( i = 0; i < iMaxNumChannels; i++ )
for ( i = 0; i < iNumChannels; i++ )
{ {
if ( vecChannels[i].IsConnected() ) if ( vecChannels[i].IsConnected() )
{ {
// add ID and data // add ID and increment counter (note that the vector length is
vecChanID.Add ( i ); // according to the worst case scenario, if the number of
// connected clients is less, only a subset of elements of this
// vector are actually used and the others are dummy elements)
vecChanIDsCurConChan[iNumClients] = i;
iNumClients++;
} }
} }
// process connected channels
const int iNumCurConnChan = vecChanID.Size();
// init temporary vectors // init temporary vectors
vecvecdGains.Init ( iNumCurConnChan );
vecvecsData.Init ( iNumCurConnChan );
vecNumAudioChannels.Init ( iNumCurConnChan );
for ( i = 0; i < iNumCurConnChan; i++ ) // TODO in the entire realtime timer routine including the ProcessData no
// memory must be allocated -> use member variables for the vectors and
// only change the size on changing the number of connected clients at
// the server
// TODO avoid allocating memory in the time critical processing routine
vecvecdGains.Init ( iNumClients );
vecvecsData.Init ( iNumClients );
vecNumAudioChannels.Init ( iNumClients );
// process connected channels
for ( i = 0; i < iNumClients; i++ )
{ {
// get actual ID of current channel // get actual ID of current channel
const int iCurChanID = vecChanID[i]; const int iCurChanID = vecChanIDsCurConChan[i];
// get and store number of audio channels // get and store number of audio channels
const int iCurNumAudChan = const int iCurNumAudChan =
@ -684,17 +700,18 @@ void CServer::OnTimer()
vecNumAudioChannels[i] = iCurNumAudChan; vecNumAudioChannels[i] = iCurNumAudChan;
// init vectors storing information of all channels // init vectors storing information of all channels
vecvecdGains[i].Init ( iNumCurConnChan ); vecvecdGains[i].Init ( iNumClients );
vecvecsData[i].Init ( iCurNumAudChan * SYSTEM_FRAME_SIZE_SAMPLES ); vecvecsData[i].Init ( iCurNumAudChan * SYSTEM_FRAME_SIZE_SAMPLES );
// get gains of all connected channels // get gains of all connected channels
for ( j = 0; j < iNumCurConnChan; j++ ) for ( j = 0; j < iNumClients; j++ )
{ {
// The second index of "vecvecdGains" does not represent // The second index of "vecvecdGains" does not represent
// the channel ID! Therefore we have to use "vecChanID" to // the channel ID! Therefore we have to use
// query the IDs of the currently connected channels // "vecChanIDsCurConChan" to query the IDs of the currently
// connected channels
vecvecdGains[i][j] = vecvecdGains[i][j] =
vecChannels[iCurChanID].GetGain( vecChanID[j] ); vecChannels[iCurChanID].GetGain( vecChanIDsCurConChan[j] );
} }
// get current number of CELT coded bytes // get current number of CELT coded bytes
@ -702,7 +719,8 @@ void CServer::OnTimer()
vecChannels[iCurChanID].GetNetwFrameSize(); vecChannels[iCurChanID].GetNetwFrameSize();
// init temporal data vector and clear input buffers // init temporal data vector and clear input buffers
CVector<uint8_t> vecbyData ( iCeltNumCodedBytes ); // TODO avoid allocating memory in the time critical processing routine
CVector<uint8_t> vecbyData ( iCeltNumCodedBytes );
// get data // get data
const EGetDataStat eGetStat = const EGetDataStat eGetStat =
@ -816,8 +834,6 @@ void CServer::OnTimer()
// Process data ------------------------------------------------------------ // Process data ------------------------------------------------------------
const int iNumClients = vecChanID.Size();
// Check if at least one client is connected. If not, stop server until // Check if at least one client is connected. If not, stop server until
// one client is connected. // one client is connected.
if ( iNumClients != 0 ) if ( iNumClients != 0 )
@ -825,21 +841,34 @@ void CServer::OnTimer()
for ( int i = 0; i < iNumClients; i++ ) for ( int i = 0; i < iNumClients; i++ )
{ {
// get actual ID of current channel // get actual ID of current channel
const int iCurChanID = vecChanID[i]; const int iCurChanID = vecChanIDsCurConChan[i];
// get number of audio channels of current channel
const int iCurNumAudChan = vecNumAudioChannels[i];
// calculate the number of samples for output vector
const int iNumOutSamples =
iCurNumAudChan * SYSTEM_FRAME_SIZE_SAMPLES;
// allocate memory for the send data vector
// TODO avoid allocating memory in the time critical processing routine
CVector<int16_t> vecsSendData ( iNumOutSamples );
// generate a sparate mix for each channel // generate a sparate mix for each channel
// actual processing of audio data -> mix // actual processing of audio data -> mix
CVector<short> vecsSendData ( ProcessData ( i, ProcessData ( iCurNumAudChan,
vecvecsData, vecvecsData,
vecvecdGains[i], vecvecdGains[i],
vecNumAudioChannels ) ); vecNumAudioChannels,
vecsSendData );
// get current number of CELT coded bytes // get current number of CELT coded bytes
const int iCeltNumCodedBytes = const int iCeltNumCodedBytes =
vecChannels[iCurChanID].GetNetwFrameSize(); vecChannels[iCurChanID].GetNetwFrameSize();
// CELT encoding // CELT encoding
CVector<unsigned char> vecCeltData ( iCeltNumCodedBytes ); // TODO avoid allocating memory in the time critical processing routine
CVector<unsigned char> vecCeltData ( iCeltNumCodedBytes );
if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 ) if ( vecChannels[iCurChanID].GetNumAudioChannels() == 1 )
{ {
@ -912,40 +941,41 @@ opus_custom_encoder_ctl ( OpusEncoderStereo[iCurChanID],
} }
} }
CVector<int16_t> CServer::ProcessData ( const int iCurIndex, /// @brief Mix all audio data from all clients together.
CVector<CVector<int16_t> >& vecvecsData, void CServer::ProcessData ( const int iCurNumAudChan,
CVector<double>& vecdGains, const CVector<CVector<int16_t> >& vecvecsData,
CVector<int>& vecNumAudioChannels ) const CVector<double>& vecdGains,
const CVector<int>& vecNumAudioChannels,
CVector<int16_t>& vecsOutData )
{ {
int i, j, k; int i, j, k;
// get number of audio channels of current channel // get the number of clients
const int iCurNumAudChan = vecNumAudioChannels[iCurIndex];
// number of samples for output vector
const int iNumOutSamples = iCurNumAudChan * SYSTEM_FRAME_SIZE_SAMPLES;
// init return vector with zeros since we mix all channels on that vector
CVector<int16_t> vecsOutData ( iNumOutSamples, 0 );
const int iNumClients = vecvecsData.Size(); const int iNumClients = vecvecsData.Size();
// mix all audio data from all clients together // init return vector with zeros since we mix all channels on that vector
vecsOutData.Reset ( 0 );
// distinguish between stereo and mono mode
if ( iCurNumAudChan == 1 ) if ( iCurNumAudChan == 1 )
{ {
// Mono target channel ------------------------------------------------- // Mono target channel -------------------------------------------------
for ( j = 0; j < iNumClients; j++ ) for ( j = 0; j < iNumClients; j++ )
{ {
// get a reference to the audio data and gain of the current client
const CVector<int16_t>& vecsData = vecvecsData[j];
const double dGain = vecdGains[j];
// if channel gain is 1, avoid multiplication for speed optimization // if channel gain is 1, avoid multiplication for speed optimization
if ( vecdGains[j] == static_cast<double> ( 1.0 ) ) if ( dGain == static_cast<double> ( 1.0 ) )
{ {
if ( vecNumAudioChannels[j] == 1 ) if ( vecNumAudioChannels[j] == 1 )
{ {
// mono // mono
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ ) for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
{ {
vecsOutData[i] = vecsOutData[i] = Double2Short (
Double2Short ( vecsOutData[i] + vecvecsData[j][i] ); static_cast<double> ( vecsOutData[i] ) + vecsData[i] );
} }
} }
else else
@ -955,7 +985,7 @@ CVector<int16_t> CServer::ProcessData ( const int iCurIndex,
{ {
vecsOutData[i] = vecsOutData[i] =
Double2Short ( vecsOutData[i] + Double2Short ( vecsOutData[i] +
( vecvecsData[j][k] + vecvecsData[j][k + 1] ) / 2 ); ( static_cast<double> ( vecsData[k] ) + vecsData[k + 1] ) / 2 );
} }
} }
} }
@ -966,9 +996,8 @@ CVector<int16_t> CServer::ProcessData ( const int iCurIndex,
// mono // mono
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ ) for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
{ {
vecsOutData[i] = vecsOutData[i] = Double2Short (
Double2Short ( vecsOutData[i] + vecsOutData[i] + vecsData[i] * dGain );
vecvecsData[j][i] * vecdGains[j] );
} }
} }
else else
@ -977,8 +1006,8 @@ CVector<int16_t> CServer::ProcessData ( const int iCurIndex,
for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 ) for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 )
{ {
vecsOutData[i] = vecsOutData[i] =
Double2Short ( vecsOutData[i] + vecdGains[j] * Double2Short ( vecsOutData[i] + dGain *
( vecvecsData[j][k] + vecvecsData[j][k + 1] ) / 2 ); ( static_cast<double> ( vecsData[k] ) + vecsData[k + 1] ) / 2 );
} }
} }
} }
@ -989,8 +1018,12 @@ CVector<int16_t> CServer::ProcessData ( const int iCurIndex,
// Stereo target channel ----------------------------------------------- // Stereo target channel -----------------------------------------------
for ( j = 0; j < iNumClients; j++ ) for ( j = 0; j < iNumClients; j++ )
{ {
// get a reference to the audio data and gain of the current client
const CVector<int16_t>& vecsData = vecvecsData[j];
const double dGain = vecdGains[j];
// if channel gain is 1, avoid multiplication for speed optimization // if channel gain is 1, avoid multiplication for speed optimization
if ( vecdGains[j] == static_cast<double> ( 1.0 ) ) if ( dGain == static_cast<double> ( 1.0 ) )
{ {
if ( vecNumAudioChannels[j] == 1 ) if ( vecNumAudioChannels[j] == 1 )
{ {
@ -998,21 +1031,21 @@ CVector<int16_t> CServer::ProcessData ( const int iCurIndex,
for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 ) for ( i = 0, k = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++, k += 2 )
{ {
// left channel // left channel
vecsOutData[k] = vecsOutData[k] = Double2Short (
Double2Short ( vecsOutData[k] + vecvecsData[j][i] ); static_cast<double> ( vecsOutData[k] ) + vecsData[i] );
// right channel // right channel
vecsOutData[k + 1] = vecsOutData[k + 1] = Double2Short (
Double2Short ( vecsOutData[k + 1] + vecvecsData[j][i] ); static_cast<double> ( vecsOutData[k + 1] ) + vecsData[i] );
} }
} }
else else
{ {
// stereo // stereo
for ( i = 0; i < iNumOutSamples; i++ ) for ( i = 0; i < ( 2 * SYSTEM_FRAME_SIZE_SAMPLES ); i++ )
{ {
vecsOutData[i] = vecsOutData[i] = Double2Short (
Double2Short ( vecsOutData[i] + vecvecsData[j][i] ); static_cast<double> ( vecsOutData[i] ) + vecsData[i] );
} }
} }
} }
@ -1025,28 +1058,25 @@ CVector<int16_t> CServer::ProcessData ( const int iCurIndex,
{ {
// left channel // left channel
vecsOutData[k] = Double2Short ( vecsOutData[k] = Double2Short (
vecsOutData[k] + vecvecsData[j][i] * vecdGains[j] ); vecsOutData[k] + vecsData[i] * dGain );
// right channel // right channel
vecsOutData[k + 1] = Double2Short ( vecsOutData[k + 1] = Double2Short (
vecsOutData[k + 1] + vecvecsData[j][i] * vecdGains[j] ); vecsOutData[k + 1] + vecsData[i] * dGain );
} }
} }
else else
{ {
// stereo // stereo
for ( i = 0; i < iNumOutSamples; i++ ) for ( i = 0; i < ( 2 * SYSTEM_FRAME_SIZE_SAMPLES ); i++ )
{ {
vecsOutData[i] = vecsOutData[i] = Double2Short (
Double2Short ( vecsOutData[i] + vecsOutData[i] + vecsData[i] * dGain );
vecvecsData[j][i] * vecdGains[j] );
} }
} }
} }
} }
} }
return vecsOutData;
} }
CVector<CChannelInfo> CServer::CreateChannelList() CVector<CChannelInfo> CServer::CreateChannelList()
@ -1054,7 +1084,7 @@ CVector<CChannelInfo> CServer::CreateChannelList()
CVector<CChannelInfo> vecChanInfo ( 0 ); CVector<CChannelInfo> vecChanInfo ( 0 );
// look for free channels // look for free channels
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( vecChannels[i].IsConnected() ) if ( vecChannels[i].IsConnected() )
{ {
@ -1075,7 +1105,7 @@ void CServer::CreateAndSendChanListForAllConChannels()
CVector<CChannelInfo> vecChanInfo ( CreateChannelList() ); CVector<CChannelInfo> vecChanInfo ( CreateChannelList() );
// now send connected channels list to all connected clients // now send connected channels list to all connected clients
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( vecChannels[i].IsConnected() ) if ( vecChannels[i].IsConnected() )
{ {
@ -1129,7 +1159,7 @@ void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID
// Send chat text to all connected clients --------------------------------- // Send chat text to all connected clients ---------------------------------
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( vecChannels[i].IsConnected() ) if ( vecChannels[i].IsConnected() )
{ {
@ -1142,7 +1172,7 @@ void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID
int CServer::GetFreeChan() int CServer::GetFreeChan()
{ {
// look for a free channel // look for a free channel
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( !vecChannels[i].IsConnected() ) if ( !vecChannels[i].IsConnected() )
{ {
@ -1154,54 +1184,38 @@ int CServer::GetFreeChan()
return INVALID_CHANNEL_ID; return INVALID_CHANNEL_ID;
} }
int CServer::FindChannel ( const CHostAddress& InetAddr )
{
// look for a channel with the given internet address
for ( int i = 0; i < iNumChannels; i++ )
{
if ( vecChannels[i].GetAddress() == InetAddr )
{
return i;
}
}
// no free channel found, return invalid ID
return INVALID_CHANNEL_ID;
}
int CServer::GetNumberOfConnectedClients() int CServer::GetNumberOfConnectedClients()
{ {
int iNumConnClients = 0; int iNumConnClients = 0;
// check all possible channels for connection status // check all possible channels for connection status
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( vecChannels[i].IsConnected() ) if ( vecChannels[i].IsConnected() )
{ {
// this channel is connected, increment counter // this channel is connected, increment counter
iNumConnClients += 1; iNumConnClients++;
} }
} }
return iNumConnClients; return iNumConnClients;
} }
int CServer::CheckAddr ( const CHostAddress& Addr ) int CServer::FindChannel ( const CHostAddress& CheckAddr )
{ {
CHostAddress InetAddr; CHostAddress InetAddr;
// check for all possible channels if IP is already in use // check for all possible channels if IP is already in use
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( vecChannels[i].IsConnected() ) // the "GetAddress" gives a valid address and returns true if the
// channel is connected
if ( vecChannels[i].GetAddress ( InetAddr ) )
{ {
if ( vecChannels[i].GetAddress ( InetAddr ) ) // IP found, return channel number
if ( InetAddr == CheckAddr )
{ {
// IP found, return channel number return i;
if ( InetAddr == Addr )
{
return i;
}
} }
} }
} }
@ -1222,7 +1236,7 @@ bool CServer::PutData ( const CVector<uint8_t>& vecbyRecBuf,
{ {
// Get channel ID ------------------------------------------------------ // Get channel ID ------------------------------------------------------
// check address // check address
int iCurChanID = CheckAddr ( HostAdr ); int iCurChanID = FindChannel ( HostAdr );
if ( iCurChanID == INVALID_CHANNEL_ID ) if ( iCurChanID == INVALID_CHANNEL_ID )
{ {
@ -1246,7 +1260,7 @@ bool CServer::PutData ( const CVector<uint8_t>& vecbyRecBuf,
// reset the channel gains of current channel, at the same // reset the channel gains of current channel, at the same
// time reset gains of this channel ID for all other channels // time reset gains of this channel ID for all other channels
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
vecChannels[iCurChanID].SetGain ( i, (double) 1.0 ); vecChannels[iCurChanID].SetGain ( i, (double) 1.0 );
@ -1346,13 +1360,13 @@ void CServer::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CHostAddress InetAddr; CHostAddress InetAddr;
// init return values // init return values
vecHostAddresses.Init ( iNumChannels ); vecHostAddresses.Init ( iMaxNumChannels );
vecsName.Init ( iNumChannels ); vecsName.Init ( iMaxNumChannels );
veciJitBufNumFrames.Init ( iNumChannels ); veciJitBufNumFrames.Init ( iMaxNumChannels );
veciNetwFrameSizeFact.Init ( iNumChannels ); veciNetwFrameSizeFact.Init ( iMaxNumChannels );
// check all possible channels // check all possible channels
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( vecChannels[i].GetAddress ( InetAddr ) ) if ( vecChannels[i].GetAddress ( InetAddr ) )
{ {
@ -1381,11 +1395,9 @@ void CServer::StartStatusHTMLFileWriting ( const QString& strNewFileName,
void CServer::WriteHTMLChannelList() void CServer::WriteHTMLChannelList()
{ {
// create channel list
CVector<CChannelInfo> vecChanInfo ( CreateChannelList() );
// prepare file and stream // prepare file and stream
QFile serverFileListFile ( strServerHTMLFileListName ); QFile serverFileListFile ( strServerHTMLFileListName );
if ( !serverFileListFile.open ( QIODevice::WriteOnly | QIODevice::Text ) ) if ( !serverFileListFile.open ( QIODevice::WriteOnly | QIODevice::Text ) )
{ {
return; return;
@ -1394,18 +1406,8 @@ void CServer::WriteHTMLChannelList()
QTextStream streamFileOut ( &serverFileListFile ); QTextStream streamFileOut ( &serverFileListFile );
streamFileOut << strServerNameWithPort << endl << "<ul>" << endl; streamFileOut << strServerNameWithPort << endl << "<ul>" << endl;
// get the number of connected clients
int iNumConnClients = 0;
for ( int i = 0; i < iNumChannels; i++ )
{
if ( vecChannels[i].IsConnected() )
{
iNumConnClients++;
}
}
// depending on number of connected clients write list // depending on number of connected clients write list
if ( iNumConnClients == 0 ) if ( GetNumberOfConnectedClients() == 0 )
{ {
// no clients are connected -> empty server // no clients are connected -> empty server
streamFileOut << " No client connected" << endl; streamFileOut << " No client connected" << endl;
@ -1413,7 +1415,7 @@ void CServer::WriteHTMLChannelList()
else else
{ {
// write entry for each connected client // write entry for each connected client
for ( int i = 0; i < iNumChannels; i++ ) for ( int i = 0; i < iMaxNumChannels; i++ )
{ {
if ( vecChannels[i].IsConnected() ) if ( vecChannels[i].IsConnected() )
{ {

View file

@ -115,7 +115,7 @@ class CServer : public QObject
Q_OBJECT Q_OBJECT
public: public:
CServer ( const int iNewNumChan, CServer ( const int iNewMaxNumChan,
const QString& strLoggingFileName, const QString& strLoggingFileName,
const quint16 iPortNumber, const quint16 iPortNumber,
const QString& strHTMLStatusFileName, const QString& strHTMLStatusFileName,
@ -193,9 +193,8 @@ protected:
void StartStatusHTMLFileWriting ( const QString& strNewFileName, void StartStatusHTMLFileWriting ( const QString& strNewFileName,
const QString& strNewServerNameWithPort ); const QString& strNewServerNameWithPort );
int CheckAddr ( const CHostAddress& Addr );
int GetFreeChan(); int GetFreeChan();
int FindChannel ( const CHostAddress& InetAddr ); int FindChannel ( const CHostAddress& CheckAddr );
int GetNumberOfConnectedClients(); int GetNumberOfConnectedClients();
CVector<CChannelInfo> CreateChannelList(); CVector<CChannelInfo> CreateChannelList();
void CreateAndSendChanListForAllConChannels(); void CreateAndSendChanListForAllConChannels();
@ -204,17 +203,18 @@ protected:
const QString& strChatText ); const QString& strChatText );
void WriteHTMLChannelList(); void WriteHTMLChannelList();
CVector<int16_t> ProcessData ( const int iCurIndex, void ProcessData ( const int iCurNumAudChan,
CVector<CVector<int16_t> >& vecvecsData, const CVector<CVector<int16_t> >& vecvecsData,
CVector<double>& vecdGains, const CVector<double>& vecdGains,
CVector<int>& vecNumAudioChannels ); const CVector<int>& vecNumAudioChannels,
CVector<int16_t>& vecsOutData );
virtual void customEvent ( QEvent* pEvent ); virtual void customEvent ( QEvent* pEvent );
// do not use the vector class since CChannel does not have appropriate // do not use the vector class since CChannel does not have appropriate
// copy constructor/operator // copy constructor/operator
CChannel vecChannels[MAX_NUM_CHANNELS]; CChannel vecChannels[MAX_NUM_CHANNELS];
int iNumChannels; int iMaxNumChannels;
CProtocol ConnLessProtocol; CProtocol ConnLessProtocol;
QMutex Mutex; QMutex Mutex;
@ -232,6 +232,7 @@ protected:
OpusCustomDecoder* OpusDecoderStereo[MAX_NUM_CHANNELS]; OpusCustomDecoder* OpusDecoderStereo[MAX_NUM_CHANNELS];
CVector<QString> vstrChatColors; CVector<QString> vstrChatColors;
CVector<int> vecChanIDsCurConChan;
// actual working objects // actual working objects
CSocket Socket; CSocket Socket;