some initial work on server timer problem

This commit is contained in:
Volker Fischer 2009-07-31 19:55:28 +00:00
parent 5052ec6f14
commit 3bd2999252
4 changed files with 68 additions and 24 deletions

View File

@ -136,7 +136,7 @@ void CChannel::SetNetwFrameSizeAndFact ( const int iNewNetwFrameSize,
ConvBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact ); ConvBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact );
// initialize and reset cycle time variance measurement // initialize and reset cycle time variance measurement
CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_BLOCK_SIZE_SAMPLES, CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_BLOCK_FRAME_SAMPLES,
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE ); SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
CycleTimeVariance.Reset(); CycleTimeVariance.Reset();
@ -157,7 +157,7 @@ bool CChannel::SetSockBufSize ( const int iNumBlocks )
// the network block size is a multiple of the internal minimal // the network block size is a multiple of the internal minimal
// block size // block size
SockBuf.Init ( SYSTEM_BLOCK_SIZE_SAMPLES, iNumBlocks ); SockBuf.Init ( SYSTEM_BLOCK_FRAME_SAMPLES, iNumBlocks );
return false; // -> no error return false; // -> no error
} }
@ -432,12 +432,12 @@ EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData )
// subtract the number of samples of the current block since the // subtract the number of samples of the current block since the
// time out counter is based on samples not on blocks (definition: // time out counter is based on samples not on blocks (definition:
// always one atomic block is get by using the GetData() function // always one atomic block is get by using the GetData() function
// where the atomic block size is "SYSTEM_BLOCK_SIZE_SAMPLES") // where the atomic block size is "SYSTEM_BLOCK_FRAME_SAMPLES")
// TODO this code only works with the above assumption -> better // TODO this code only works with the above assumption -> better
// implementation so that we are not depending on assumptions // implementation so that we are not depending on assumptions
iConTimeOut -= SYSTEM_BLOCK_SIZE_SAMPLES; iConTimeOut -= SYSTEM_BLOCK_FRAME_SAMPLES;
if ( iConTimeOut <= 0 ) if ( iConTimeOut <= 0 )
{ {
@ -490,7 +490,7 @@ CVector<uint8_t> CChannel::PrepSendPacket ( const CVector<uint8_t>& vecbyNPacket
int CChannel::GetUploadRateKbps() int CChannel::GetUploadRateKbps()
{ {
const int iAudioSizeOut = iNetwFrameSizeFact * SYSTEM_BLOCK_SIZE_SAMPLES; const int iAudioSizeOut = iNetwFrameSizeFact * SYSTEM_BLOCK_FRAME_SAMPLES;
// we assume that the UDP packet which is transported via IP has an // we assume that the UDP packet which is transported via IP has an
// additional header size of // additional header size of

View File

@ -60,10 +60,10 @@
// System block size, this is the block size on which the audio coder works. // System block size, this is the block size on which the audio coder works.
// All other block sizes must be a multiple of this size // All other block sizes must be a multiple of this size
#define SYSTEM_BLOCK_SIZE_SAMPLES 128 #define SYSTEM_BLOCK_FRAME_SAMPLES 128
#define SYSTEM_BLOCK_DURATION_MS_FLOAT \ #define SYSTEM_BLOCK_DURATION_MS_FLOAT \
( static_cast<double> ( SYSTEM_BLOCK_SIZE_SAMPLES ) / \ ( static_cast<double> ( SYSTEM_BLOCK_FRAME_SAMPLES ) / \
SYSTEM_SAMPLE_RATE * 1000 ) SYSTEM_SAMPLE_RATE * 1000 )
// define the maximum mono audio buffer size at a sample rate // define the maximum mono audio buffer size at a sample rate

View File

@ -50,15 +50,34 @@ CServer::CServer ( const QString& strLoggingFileName,
vstrChatColors[4] = "maroon"; vstrChatColors[4] = "maroon";
vstrChatColors[5] = "coral"; vstrChatColors[5] = "coral";
vecsSendData.Init ( SYSTEM_BLOCK_SIZE_SAMPLES ); vecsSendData.Init ( SYSTEM_BLOCK_FRAME_SAMPLES );
// init moving average buffer for response time evaluation // init moving average buffer for response time evaluation
CycleTimeVariance.Init ( SYSTEM_BLOCK_SIZE_SAMPLES, CycleTimeVariance.Init ( SYSTEM_BLOCK_FRAME_SAMPLES,
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE ); SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
// connect timer timeout signal // connect timer timeout signal
QObject::connect ( &Timer, SIGNAL ( timeout() ), QObject::connect ( &HighPrecisionTimer, SIGNAL ( timeout() ),
this, SLOT ( OnTimer() ) ); this, SLOT ( OnHighPrecisionTimer() ) );
/*
// init timer stuff
//vTimeOutIntervals = [0 ]
// for 128 sample frame size at 48 kHz sampling rate:
// actual intervals: 0.0 2.666 5.333 8.0
// quantized to 1 ms: 0 3 5 8 (0)
// for 256 sample frame size at 48 kHz sampling rate:
// actual intervals: 0.0 5.333 10.666 16.0
// quantized to 1 ms: 0 5 11 16 (0)
*/
// enable logging (if requested) // enable logging (if requested)
if ( !strLoggingFileName.isEmpty() ) if ( !strLoggingFileName.isEmpty() )
@ -176,10 +195,8 @@ void CServer::Start()
{ {
if ( !IsRunning() ) if ( !IsRunning() )
{ {
// start main timer // start main timer with lowest possible resolution
HighPrecisionTimer.start ( MIN_TIMER_RESOLUTION_MS );
// TEST
Timer.start ( static_cast<int> ( ceil ( SYSTEM_BLOCK_DURATION_MS_FLOAT ) ) );
// init time for response time evaluation // init time for response time evaluation
CycleTimeVariance.Reset(); CycleTimeVariance.Reset();
@ -189,16 +206,22 @@ Timer.start ( static_cast<int> ( ceil ( SYSTEM_BLOCK_DURATION_MS_FLOAT ) ) );
void CServer::Stop() void CServer::Stop()
{ {
// stop main timer // stop main timer
Timer.stop(); HighPrecisionTimer.stop();
// logging // logging
Logging.AddServerStopped(); Logging.AddServerStopped();
} }
void CServer::OnHighPrecisionTimer()
{
// TEST
OnTimer();
}
void CServer::OnTimer() void CServer::OnTimer()
{ {
CVector<int> vecChanID; CVector<int> vecChanID;
CVector<CVector<double> > vecvecdData ( SYSTEM_BLOCK_SIZE_SAMPLES ); CVector<CVector<double> > vecvecdData ( SYSTEM_BLOCK_FRAME_SAMPLES );
CVector<CVector<double> > vecvecdGains; CVector<CVector<double> > vecvecdGains;
// get data from all connected clients // get data from all connected clients
@ -240,7 +263,7 @@ void CServer::GetBlockAllConC ( CVector<int>& vecChanID,
bool bChannelIsNowDisconnected = false; bool bChannelIsNowDisconnected = false;
// init temporal data vector and clear input buffers // init temporal data vector and clear input buffers
CVector<double> vecdData ( SYSTEM_BLOCK_SIZE_SAMPLES ); CVector<double> vecdData ( SYSTEM_BLOCK_FRAME_SAMPLES );
vecChanID.Init ( 0 ); vecChanID.Init ( 0 );
vecvecdData.Init ( 0 ); vecvecdData.Init ( 0 );
@ -668,7 +691,7 @@ CVector<short> CServer::ProcessData ( CVector<CVector<double> >& vecvecdData,
int i; int i;
// init return vector with zeros since we mix all channels on that vector // init return vector with zeros since we mix all channels on that vector
CVector<short> vecsOutData ( SYSTEM_BLOCK_SIZE_SAMPLES, 0 ); CVector<short> vecsOutData ( SYSTEM_BLOCK_FRAME_SAMPLES, 0 );
const int iNumClients = vecvecdData.Size(); const int iNumClients = vecvecdData.Size();
@ -678,7 +701,7 @@ CVector<short> CServer::ProcessData ( CVector<CVector<double> >& vecvecdData,
// 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 ( vecdGains[j] == static_cast<double> ( 1.0 ) )
{ {
for ( i = 0; i < SYSTEM_BLOCK_SIZE_SAMPLES; i++ ) for ( i = 0; i < SYSTEM_BLOCK_FRAME_SAMPLES; i++ )
{ {
vecsOutData[i] = vecsOutData[i] =
Double2Short ( vecsOutData[i] + vecvecdData[j][i] ); Double2Short ( vecsOutData[i] + vecvecdData[j][i] );
@ -686,7 +709,7 @@ CVector<short> CServer::ProcessData ( CVector<CVector<double> >& vecvecdData,
} }
else else
{ {
for ( i = 0; i < SYSTEM_BLOCK_SIZE_SAMPLES; i++ ) for ( i = 0; i < SYSTEM_BLOCK_FRAME_SAMPLES; i++ )
{ {
vecsOutData[i] = vecsOutData[i] =
Double2Short ( vecsOutData[i] + Double2Short ( vecsOutData[i] +

View File

@ -29,6 +29,7 @@
#include <qtimer.h> #include <qtimer.h>
#include <qdatetime.h> #include <qdatetime.h>
#include <qhostaddress.h> #include <qhostaddress.h>
#include "celt.h"
#include "global.h" #include "global.h"
#include "socket.h" #include "socket.h"
#include "channel.h" #include "channel.h"
@ -40,6 +41,18 @@
// no valid channel number // no valid channel number
#define INVALID_CHANNEL_ID ( MAX_NUM_CHANNELS + 1 ) #define INVALID_CHANNEL_ID ( MAX_NUM_CHANNELS + 1 )
// minimum timer precision
#define MIN_TIMER_RESOLUTION_MS 1 // ms
// add some error checking, the high precision timer implementation only
// supports 128 and 256 samples frame size at 48 kHz sampling rate
#if ( ( SYSTEM_BLOCK_FRAME_SAMPLES != 128 ) && ( SYSTEM_BLOCK_FRAME_SAMPLES != 256 ) )
# error "Only system frame sizes of 128 and 256 samples are supported by this module"
#endif
#if SYSTEM_SAMPLE_RATE != 48000
# error "Only a system sample rate of 48 kHz is supported by this module"
#endif
/* Classes ********************************************************************/ /* Classes ********************************************************************/
class CServer : public QObject class CServer : public QObject
@ -56,7 +69,7 @@ public:
void Start(); void Start();
void Stop(); void Stop();
bool IsRunning() { return Timer.isActive(); } bool IsRunning() { return HighPrecisionTimer.isActive(); }
bool GetTimingStdDev ( double& dCurTiStdDev ); bool GetTimingStdDev ( double& dCurTiStdDev );
@ -100,12 +113,20 @@ protected:
CVector<double>& vecdGains ); CVector<double>& vecdGains );
virtual void customEvent ( QEvent* Event ); virtual void customEvent ( QEvent* Event );
void OnTimer();
/* 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];
QMutex Mutex; QMutex Mutex;
// audio encoder/decoder
CELTMode* CeltMode[MAX_NUM_CHANNELS];
CELTEncoder* CeltEncoder[MAX_NUM_CHANNELS];
CELTDecoder* CeltDecoder[MAX_NUM_CHANNELS];
int iCeltNumCodedBytes[MAX_NUM_CHANNELS];
CVector<unsigned char> vecCeltData[MAX_NUM_CHANNELS];
CVector<QString> vstrChatColors; CVector<QString> vstrChatColors;
// HTML file server status // HTML file server status
@ -113,7 +134,7 @@ protected:
QString strServerHTMLFileListName; QString strServerHTMLFileListName;
QString strServerNameWithPort; QString strServerNameWithPort;
QTimer Timer; QTimer HighPrecisionTimer;
CVector<short> vecsSendData; CVector<short> vecsSendData;
// actual working objects // actual working objects
@ -125,7 +146,7 @@ protected:
CServerLogging Logging; CServerLogging Logging;
public slots: public slots:
void OnTimer(); void OnHighPrecisionTimer();
void OnSendProtMessage ( int iChID, CVector<uint8_t> vecMessage ); void OnSendProtMessage ( int iChID, CVector<uint8_t> vecMessage );
// CODE TAG: MAX_NUM_CHANNELS_TAG // CODE TAG: MAX_NUM_CHANNELS_TAG