backup checkin, including lots of test code...
This commit is contained in:
parent
b12ee5c104
commit
d571f5328b
14 changed files with 1269 additions and 918 deletions
|
@ -1,4 +1,4 @@
|
||||||
4.0.0
|
3.2.0
|
||||||
|
|
||||||
- new GUI style of the main window, added switch for selecting the GUI style
|
- new GUI style of the main window, added switch for selecting the GUI style
|
||||||
in the settings window
|
in the settings window
|
||||||
|
|
205
src/buffer.cpp
205
src/buffer.cpp
|
@ -54,11 +54,37 @@ bool CNetBuf::Put ( const CVector<uint8_t>& vecbyData,
|
||||||
// Check if there is not enough space available -> correct
|
// Check if there is not enough space available -> correct
|
||||||
if ( GetAvailSpace() < iInSize )
|
if ( GetAvailSpace() < iInSize )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
// not enough space in buffer for put operation, correct buffer to
|
// not enough space in buffer for put operation, correct buffer to
|
||||||
// prepare for new data
|
// prepare for new data
|
||||||
Clear ( CT_PUT );
|
Clear ( CT_PUT );
|
||||||
|
|
||||||
bPutOK = false; // return error flag
|
bPutOK = false; // return error flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TEST invalidate last written block for better PLC
|
||||||
|
// ATTENTION: We assume that mem size is factor of block size here!!!!
|
||||||
|
if ( !bIsSimulation )
|
||||||
|
{
|
||||||
|
if ( iPutPos == 0 )
|
||||||
|
{
|
||||||
|
for ( int iPos = iMemSize - iInSize; iPos < iMemSize; iPos++ )
|
||||||
|
{
|
||||||
|
vecMemory[iPos] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for ( int iPos = iPutPos - iInSize; iPos < iPutPos; iPos++ )
|
||||||
|
{
|
||||||
|
vecMemory[iPos] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
// check for special case: buffer memory is not sufficient
|
// check for special case: buffer memory is not sufficient
|
||||||
if ( iInSize > iMemSize )
|
if ( iInSize > iMemSize )
|
||||||
|
@ -86,7 +112,7 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// check for invalid data in buffer
|
// check for invalid data in buffer
|
||||||
if ( iNumInvalidElements > 0 )
|
if ( iNumInvalidElements > 0 )
|
||||||
{
|
{
|
||||||
|
@ -96,15 +122,19 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
|
||||||
|
|
||||||
bGetOK = false; // return error flag
|
bGetOK = false; // return error flag
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Check if there is not enough data available -> correct
|
// Check if there is not enough data available -> correct
|
||||||
if ( GetAvailData() < iInSize )
|
if ( GetAvailData() < iInSize )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
// not enough data in buffer for get operation, correct buffer to
|
// not enough data in buffer for get operation, correct buffer to
|
||||||
// prepare for getting data
|
// prepare for getting data
|
||||||
Clear ( CT_GET );
|
Clear ( CT_GET );
|
||||||
|
|
||||||
bGetOK = false; // return error flag
|
bGetOK = false; // return error flag
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
|
||||||
// check for special case: buffer memory is not sufficient
|
// check for special case: buffer memory is not sufficient
|
||||||
if ( iInSize > iMemSize )
|
if ( iInSize > iMemSize )
|
||||||
|
@ -118,11 +148,33 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
|
||||||
// class)
|
// class)
|
||||||
CBufferBase<uint8_t>::Get ( vecbyData );
|
CBufferBase<uint8_t>::Get ( vecbyData );
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TEST check for all zero packet
|
||||||
|
bool bAllZeroPacket = true;
|
||||||
|
for ( int iPos = 0; iPos < iInSize; iPos++ )
|
||||||
|
{
|
||||||
|
if ( vecbyData[iPos] != 0 )
|
||||||
|
{
|
||||||
|
bAllZeroPacket = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bAllZeroPacket )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return bGetOK;
|
return bGetOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNetBuf::Clear ( const EClearType eClearType )
|
void CNetBuf::Clear ( const EClearType eClearType )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
CBufferBase<uint8_t>::Clear ( eClearType );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
// Define the number of blocks bound for the "random offset" (1) algorithm.
|
// Define the number of blocks bound for the "random offset" (1) algorithm.
|
||||||
// If we are above the bound, we use the "middle of buffer" (2) algorithm.
|
// If we are above the bound, we use the "middle of buffer" (2) algorithm.
|
||||||
//
|
//
|
||||||
|
@ -177,6 +229,13 @@ void CNetBuf::Clear ( const EClearType eClearType )
|
||||||
// 1: 0 / 2: 0 / 3: 1 / 4: 1 / 5: 2 ...)
|
// 1: 0 / 2: 0 / 3: 1 / 4: 1 / 5: 2 ...)
|
||||||
iNewFillLevel =
|
iNewFillLevel =
|
||||||
( ( ( iMemSize - iBlockSize) / 2 ) / iBlockSize ) * iBlockSize;
|
( ( ( iMemSize - iBlockSize) / 2 ) / iBlockSize ) * iBlockSize;
|
||||||
|
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
iNewFillLevel += static_cast<int> ( static_cast<double> ( rand() ) *
|
||||||
|
iNumBlocksBoundInclForRandom / RAND_MAX ) * iBlockSize -
|
||||||
|
iNumBlocksBoundInclForRandom / 2 * iBlockSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +243,10 @@ void CNetBuf::Clear ( const EClearType eClearType )
|
||||||
if ( eClearType == CT_GET )
|
if ( eClearType == CT_GET )
|
||||||
{
|
{
|
||||||
// clear buffer since we had a buffer underrun
|
// clear buffer since we had a buffer underrun
|
||||||
vecMemory.Reset ( 0 );
|
if ( !bIsSimulation )
|
||||||
|
{
|
||||||
|
vecMemory.Reset ( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
// reset buffer pointers so that they are at maximum distance after
|
// reset buffer pointers so that they are at maximum distance after
|
||||||
// the get operation (assign new fill level value to the get pointer)
|
// the get operation (assign new fill level value to the get pointer)
|
||||||
|
@ -233,4 +295,143 @@ void CNetBuf::Clear ( const EClearType eClearType )
|
||||||
eBufState = CNetBuf::BS_OK;
|
eBufState = CNetBuf::BS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
//iNumInvalidElements = 8 * iMemSize;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Network buffer with statistic calculations implementation ******************/
|
||||||
|
CNetBufWithStats::CNetBufWithStats() :
|
||||||
|
CNetBuf ( false ) // base class init: no simulation mode
|
||||||
|
{
|
||||||
|
// define the sizes of the simulation buffers,
|
||||||
|
// must be NUM_STAT_SIMULATION_BUFFERS elements!
|
||||||
|
viBufSizesForSim[0] = 2;
|
||||||
|
viBufSizesForSim[1] = 3;
|
||||||
|
viBufSizesForSim[2] = 4;
|
||||||
|
viBufSizesForSim[3] = 5;
|
||||||
|
viBufSizesForSim[4] = 6;
|
||||||
|
viBufSizesForSim[5] = 7;
|
||||||
|
viBufSizesForSim[6] = 8;
|
||||||
|
viBufSizesForSim[7] = 9;
|
||||||
|
viBufSizesForSim[8] = 10;
|
||||||
|
viBufSizesForSim[9] = 12;
|
||||||
|
viBufSizesForSim[10] = 14;
|
||||||
|
viBufSizesForSim[11] = 17;
|
||||||
|
viBufSizesForSim[12] = 20;
|
||||||
|
|
||||||
|
// set all simulation buffers in simulation mode
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
SimulationBuffer[i].SetIsSimulation ( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNetBufWithStats::Init ( const int iNewBlockSize,
|
||||||
|
const int iNewNumBlocks,
|
||||||
|
const bool bPreserve )
|
||||||
|
{
|
||||||
|
// call base class Init
|
||||||
|
CNetBuf::Init ( iNewBlockSize, iNewNumBlocks, bPreserve );
|
||||||
|
|
||||||
|
// inits for statistics calculation
|
||||||
|
if ( !bPreserve )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
// init simulation buffers with the correct size
|
||||||
|
SimulationBuffer[i].Init ( iNewBlockSize, viBufSizesForSim[i] );
|
||||||
|
|
||||||
|
// init statistics
|
||||||
|
ErrorRateStatistic[i].Init ( 80000, true );//TEST!!!!!//MAX_STATISTIC_COUNT );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CNetBufWithStats::Put ( const CVector<uint8_t>& vecbyData,
|
||||||
|
const int iInSize )
|
||||||
|
{
|
||||||
|
// call base class Put
|
||||||
|
const bool bPutOK = CNetBuf::Put ( vecbyData, iInSize );
|
||||||
|
|
||||||
|
// update statistics calculations
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
ErrorRateStatistic[i].Update (
|
||||||
|
!SimulationBuffer[i].Put ( vecbyData, iInSize ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return bPutOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CNetBufWithStats::Get ( CVector<uint8_t>& vecbyData )
|
||||||
|
{
|
||||||
|
// call base class Get
|
||||||
|
const bool bGetOK = CNetBuf::Get ( vecbyData );
|
||||||
|
|
||||||
|
// update statistics calculations
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
ErrorRateStatistic[i].Update (
|
||||||
|
!SimulationBuffer[i].Get ( vecbyData ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return bGetOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
int CNetBufWithStats::GetAutoSetting()
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TEST
|
||||||
|
if ( ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].GetAverage() > 0.06 )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||||
|
{
|
||||||
|
ErrorRateStatistic[i].Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS - 1; i++ )
|
||||||
|
{
|
||||||
|
if ( ErrorRateStatistic[i].GetAverage() <= 0.005)//TEST!!!!! 0.005 )
|
||||||
|
{
|
||||||
|
return viBufSizesForSim[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TEST for debugging
|
||||||
|
void CNetBufWithStats::StoreAllSimAverages()
|
||||||
|
{
|
||||||
|
|
||||||
|
FILE* pFile = fopen ( "c:\\temp\\test.dat", "w" );
|
||||||
|
|
||||||
|
|
||||||
|
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS - 1; i++ )
|
||||||
|
{
|
||||||
|
fprintf ( pFile, "%e, ", ErrorRateStatistic[i].GetAverage() );
|
||||||
|
}
|
||||||
|
fprintf ( pFile, "%e", ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].GetAverage() );
|
||||||
|
fprintf ( pFile, "\n" );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
const int iLen = ErrorRateStatistic[4].ErrorsMovAvBuf.Size();
|
||||||
|
for ( int i = 0; i < iLen; i++ )
|
||||||
|
{
|
||||||
|
fprintf ( pFile, "%e\n", ErrorRateStatistic[4].ErrorsMovAvBuf[i] );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
fclose ( pFile );
|
||||||
|
|
||||||
|
// scilab:
|
||||||
|
// close;x=read('c:/temp/test.dat',-1,13);plot2d([2,3,4,5,6,7,8,9,10,12,14,17,20], x, style=-1 , logflag = 'nl');plot2d([2 20],[1 1]*0.01);plot2d([2 20],[1 1]*0.005);x
|
||||||
}
|
}
|
||||||
|
|
175
src/buffer.h
175
src/buffer.h
|
@ -29,18 +29,37 @@
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions ****************************************************************/
|
||||||
|
// each regular buffer access lead to a count for put and get, assuming 2.33 ms
|
||||||
|
// blocks we have 30 s / 2.33 ms * 2 = 25714
|
||||||
|
//#define MAX_STATISTIC_COUNT 25714
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
// 7 / 0.00266 * 2 = 5263.1579
|
||||||
|
#define MAX_STATISTIC_COUNT 3759
|
||||||
|
|
||||||
|
|
||||||
|
// number of simulation network jitter buffers for evaluating the statistic
|
||||||
|
#define NUM_STAT_SIMULATION_BUFFERS 13
|
||||||
|
|
||||||
|
|
||||||
/* Classes ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
// Buffer base class -----------------------------------------------------------
|
// Buffer base class -----------------------------------------------------------
|
||||||
template<class TData> class CBufferBase
|
template<class TData> class CBufferBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CBufferBase() : bIsInitialized ( false ) {}
|
CBufferBase ( const bool bNIsSim = false ) :
|
||||||
|
bIsSimulation ( bNIsSim ), bIsInitialized ( false ) {}
|
||||||
|
|
||||||
|
void SetIsSimulation ( const bool bNIsSim ) { bIsSimulation = bNIsSim; }
|
||||||
|
|
||||||
virtual void Init ( const int iNewMemSize,
|
virtual void Init ( const int iNewMemSize,
|
||||||
const bool bPreserve = false )
|
const bool bPreserve = false )
|
||||||
{
|
{
|
||||||
|
// in simulation mode the size is not changed during operation -> we do
|
||||||
|
// not have to implement special code for this case
|
||||||
// only enter the "preserve" branch, if object was already initialized
|
// only enter the "preserve" branch, if object was already initialized
|
||||||
if ( bPreserve && bIsInitialized )
|
if ( bPreserve && ( !bIsSimulation ) && bIsInitialized )
|
||||||
{
|
{
|
||||||
// copy old data in new vector using get pointer as zero per
|
// copy old data in new vector using get pointer as zero per
|
||||||
// definition
|
// definition
|
||||||
|
@ -143,7 +162,10 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// allocate memory for actual data buffer
|
// allocate memory for actual data buffer
|
||||||
vecMemory.Init ( iNewMemSize );
|
if ( !bIsSimulation )
|
||||||
|
{
|
||||||
|
vecMemory.Init ( iNewMemSize );
|
||||||
|
}
|
||||||
|
|
||||||
// init buffer pointers and buffer state (empty buffer)
|
// init buffer pointers and buffer state (empty buffer)
|
||||||
iGetPos = 0;
|
iGetPos = 0;
|
||||||
|
@ -161,31 +183,44 @@ public:
|
||||||
virtual bool Put ( const CVector<TData>& vecData,
|
virtual bool Put ( const CVector<TData>& vecData,
|
||||||
const int iInSize )
|
const int iInSize )
|
||||||
{
|
{
|
||||||
// copy new data in internal buffer
|
if ( bIsSimulation )
|
||||||
int iCurPos = 0;
|
|
||||||
if ( iPutPos + iInSize > iMemSize )
|
|
||||||
{
|
{
|
||||||
// remaining space size for second block
|
// in this simulation only the buffer pointers and the buffer state
|
||||||
const int iRemSpace = iPutPos + iInSize - iMemSize;
|
// is updated, no actual data is transferred
|
||||||
|
iPutPos += iInSize;
|
||||||
// data must be written in two steps because of wrap around
|
if ( iPutPos >= iMemSize )
|
||||||
while ( iPutPos < iMemSize )
|
|
||||||
{
|
{
|
||||||
vecMemory[iPutPos++] = vecData[iCurPos++];
|
iPutPos -= iMemSize;
|
||||||
}
|
|
||||||
|
|
||||||
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
|
|
||||||
{
|
|
||||||
vecMemory[iPutPos] = vecData[iCurPos++];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// data can be written in one step
|
// copy new data in internal buffer
|
||||||
const int iEnd = iPutPos + iInSize;
|
int iCurPos = 0;
|
||||||
while ( iPutPos < iEnd )
|
if ( iPutPos + iInSize > iMemSize )
|
||||||
{
|
{
|
||||||
vecMemory[iPutPos++] = vecData[iCurPos++];
|
// remaining space size for second block
|
||||||
|
const int iRemSpace = iPutPos + iInSize - iMemSize;
|
||||||
|
|
||||||
|
// data must be written in two steps because of wrap around
|
||||||
|
while ( iPutPos < iMemSize )
|
||||||
|
{
|
||||||
|
vecMemory[iPutPos++] = vecData[iCurPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
|
||||||
|
{
|
||||||
|
vecMemory[iPutPos] = vecData[iCurPos++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// data can be written in one step
|
||||||
|
const int iEnd = iPutPos + iInSize;
|
||||||
|
while ( iPutPos < iEnd )
|
||||||
|
{
|
||||||
|
vecMemory[iPutPos++] = vecData[iCurPos++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,31 +242,44 @@ public:
|
||||||
// get size of data to be get from the buffer
|
// get size of data to be get from the buffer
|
||||||
const int iInSize = vecData.Size();
|
const int iInSize = vecData.Size();
|
||||||
|
|
||||||
// copy data from internal buffer in output buffer
|
if ( bIsSimulation )
|
||||||
int iCurPos = 0;
|
|
||||||
if ( iGetPos + iInSize > iMemSize )
|
|
||||||
{
|
{
|
||||||
// remaining data size for second block
|
// in this simulation only the buffer pointers and the buffer state
|
||||||
const int iRemData = iGetPos + iInSize - iMemSize;
|
// is updated, no actual data is transferred
|
||||||
|
iGetPos += iInSize;
|
||||||
// data must be read in two steps because of wrap around
|
if ( iGetPos >= iMemSize )
|
||||||
while ( iGetPos < iMemSize )
|
|
||||||
{
|
{
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos++];
|
iGetPos -= iMemSize;
|
||||||
}
|
|
||||||
|
|
||||||
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
|
|
||||||
{
|
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// data can be read in one step
|
// copy data from internal buffer in output buffer
|
||||||
const int iEnd = iGetPos + iInSize;
|
int iCurPos = 0;
|
||||||
while ( iGetPos < iEnd )
|
if ( iGetPos + iInSize > iMemSize )
|
||||||
{
|
{
|
||||||
vecData[iCurPos++] = vecMemory[iGetPos++];
|
// remaining data size for second block
|
||||||
|
const int iRemData = iGetPos + iInSize - iMemSize;
|
||||||
|
|
||||||
|
// data must be read in two steps because of wrap around
|
||||||
|
while ( iGetPos < iMemSize )
|
||||||
|
{
|
||||||
|
vecData[iCurPos++] = vecMemory[iGetPos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
|
||||||
|
{
|
||||||
|
vecData[iCurPos++] = vecMemory[iGetPos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// data can be read in one step
|
||||||
|
const int iEnd = iGetPos + iInSize;
|
||||||
|
while ( iGetPos < iEnd )
|
||||||
|
{
|
||||||
|
vecData[iCurPos++] = vecMemory[iGetPos++];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,12 +340,28 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
|
enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
|
||||||
|
enum EClearType { CT_PUT, CT_GET };
|
||||||
|
|
||||||
|
virtual void Clear ( const EClearType eClearType )
|
||||||
|
{
|
||||||
|
// clear memory
|
||||||
|
if ( !bIsSimulation )
|
||||||
|
{
|
||||||
|
vecMemory.Reset ( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// init buffer pointers and buffer state (empty buffer)
|
||||||
|
iGetPos = 0;
|
||||||
|
iPutPos = 0;
|
||||||
|
eBufState = CBufferBase<TData>::BS_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
CVector<TData> vecMemory;
|
CVector<TData> vecMemory;
|
||||||
int iMemSize;
|
int iMemSize;
|
||||||
int iGetPos;
|
int iGetPos;
|
||||||
int iPutPos;
|
int iPutPos;
|
||||||
EBufState eBufState;
|
EBufState eBufState;
|
||||||
|
bool bIsSimulation;
|
||||||
bool bIsInitialized;
|
bool bIsInitialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -306,6 +370,9 @@ protected:
|
||||||
class CNetBuf : public CBufferBase<uint8_t>
|
class CNetBuf : public CBufferBase<uint8_t>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CNetBuf ( const bool bNewIsSim = false ) :
|
||||||
|
CBufferBase<uint8_t> ( bNewIsSim ) {}
|
||||||
|
|
||||||
virtual void Init ( const int iNewBlockSize,
|
virtual void Init ( const int iNewBlockSize,
|
||||||
const int iNewNumBlocks,
|
const int iNewNumBlocks,
|
||||||
const bool bPreserve = false );
|
const bool bPreserve = false );
|
||||||
|
@ -316,15 +383,39 @@ public:
|
||||||
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum EClearType { CT_PUT, CT_GET };
|
virtual void Clear ( const EClearType eClearType );
|
||||||
|
|
||||||
void Clear ( const EClearType eClearType );
|
|
||||||
|
|
||||||
int iBlockSize;
|
int iBlockSize;
|
||||||
int iNumInvalidElements;
|
int iNumInvalidElements;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Network buffer (jitter buffer) with statistic calculations ------------------
|
||||||
|
class CNetBufWithStats : public CNetBuf
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CNetBufWithStats();
|
||||||
|
|
||||||
|
virtual void Init ( const int iNewBlockSize,
|
||||||
|
const int iNewNumBlocks,
|
||||||
|
const bool bPreserve = false );
|
||||||
|
|
||||||
|
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
||||||
|
virtual bool Get ( CVector<uint8_t>& vecbyData );
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
void StoreAllSimAverages();
|
||||||
|
int GetAutoSetting();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// statistic (do not use the vector class since the classes do not have
|
||||||
|
// appropriate copy constructor/operator)
|
||||||
|
CErrorRate ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
|
CNetBuf SimulationBuffer[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
|
int viBufSizesForSim[NUM_STAT_SIMULATION_BUFFERS];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Conversion buffer (very simple buffer) --------------------------------------
|
// Conversion buffer (very simple buffer) --------------------------------------
|
||||||
// For this very simple buffer no wrap around mechanism is implemented. We
|
// For this very simple buffer no wrap around mechanism is implemented. We
|
||||||
// assume here, that the applied buffers are an integer fraction of the total
|
// assume here, that the applied buffers are an integer fraction of the total
|
||||||
|
|
|
@ -611,6 +611,20 @@ void CChannel::UpdateSocketBufferSize ( const double dLocalStdDev )
|
||||||
// do nothing
|
// do nothing
|
||||||
if ( bDoAutoSockBufSize )
|
if ( bDoAutoSockBufSize )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
SetSockBufNumFrames ( SockBuf.GetAutoSetting(), true );
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef _WIN32
|
||||||
|
// TEST
|
||||||
|
static FILE* pFile = fopen ( "c:\\temp\\test.dat", "w" );
|
||||||
|
fprintf ( pFile, "%d\n", SockBuf.GetAutoSetting() );
|
||||||
|
fflush ( pFile );
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
// We use the time response measurement for the automatic setting.
|
// We use the time response measurement for the automatic setting.
|
||||||
// Assumptions:
|
// Assumptions:
|
||||||
// - the audio interface/network jitter is assumed to be Gaussian
|
// - the audio interface/network jitter is assumed to be Gaussian
|
||||||
|
@ -633,7 +647,7 @@ void CChannel::UpdateSocketBufferSize ( const double dLocalStdDev )
|
||||||
const double dEstCurBufSet = ( SYSTEM_BLOCK_DURATION_MS_FLOAT +
|
const double dEstCurBufSet = ( SYSTEM_BLOCK_DURATION_MS_FLOAT +
|
||||||
3.3 * ( CycleTimeVariance.GetStdDev() + dLocalStdDev ) ) /
|
3.3 * ( CycleTimeVariance.GetStdDev() + dLocalStdDev ) ) /
|
||||||
SYSTEM_BLOCK_DURATION_MS_FLOAT + 0.5;
|
SYSTEM_BLOCK_DURATION_MS_FLOAT + 0.5;
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
// TEST
|
// TEST
|
||||||
//if (bIsServer) {
|
//if (bIsServer) {
|
||||||
|
@ -643,7 +657,7 @@ fflush ( pFile );
|
||||||
// close;x=read('c:/temp/test.dat',-1,3);plot(x)
|
// close;x=read('c:/temp/test.dat',-1,3);plot(x)
|
||||||
//}
|
//}
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
// upper/lower hysteresis decision
|
// upper/lower hysteresis decision
|
||||||
const int iUpperHystDec = LlconMath().round ( dEstCurBufSet - dHysteresis );
|
const int iUpperHystDec = LlconMath().round ( dEstCurBufSet - dHysteresis );
|
||||||
const int iLowerHystDec = LlconMath().round ( dEstCurBufSet + dHysteresis );
|
const int iLowerHystDec = LlconMath().round ( dEstCurBufSet + dHysteresis );
|
||||||
|
@ -667,5 +681,6 @@ fflush ( pFile );
|
||||||
SetSockBufNumFrames ( iUpperHystDec, true );
|
SetSockBufNumFrames ( iUpperHystDec, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,11 @@ public:
|
||||||
|
|
||||||
void CreateNetTranspPropsMessFromCurrentSettings();
|
void CreateNetTranspPropsMessFromCurrentSettings();
|
||||||
|
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
void StoreAllSimAverages() { SockBuf.StoreAllSimAverages(); }
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ProtocolIsEnabled();
|
bool ProtocolIsEnabled();
|
||||||
|
|
||||||
|
@ -145,7 +150,7 @@ protected:
|
||||||
CVector<double> vecdGains;
|
CVector<double> vecdGains;
|
||||||
|
|
||||||
// network jitter-buffer
|
// network jitter-buffer
|
||||||
CNetBuf SockBuf;
|
CNetBufWithStats SockBuf;
|
||||||
int iCurSockBufNumFrames;
|
int iCurSockBufNumFrames;
|
||||||
bool bDoAutoSockBufSize;
|
bool bDoAutoSockBufSize;
|
||||||
|
|
||||||
|
|
|
@ -924,6 +924,21 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TEST
|
||||||
|
// fid=fopen('v.dat','r');x=fread(fid,'int16');fclose(fid);
|
||||||
|
static FILE* pFileDelay = fopen("c:\\temp\\test2.dat", "wb");
|
||||||
|
short sData[2];
|
||||||
|
for (i = 0; i < iMonoBlockSizeSam; i++)
|
||||||
|
{
|
||||||
|
sData[0] = (short) vecsAudioSndCrdMono[i];
|
||||||
|
fwrite(&sData, size_t(2), size_t(1), pFileDelay);
|
||||||
|
}
|
||||||
|
fflush(pFileDelay);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// check if channel is connected
|
// check if channel is connected
|
||||||
if ( Channel.IsConnected() )
|
if ( Channel.IsConnected() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,8 +92,6 @@ public:
|
||||||
double MicLevelR() { return SignalLevelMeter.MicLevelRight(); }
|
double MicLevelR() { return SignalLevelMeter.MicLevelRight(); }
|
||||||
bool IsConnected() { return Channel.IsConnected(); }
|
bool IsConnected() { return Channel.IsConnected(); }
|
||||||
|
|
||||||
double GetTimingStdDev() { return CycleTimeVariance.GetStdDev(); }
|
|
||||||
|
|
||||||
bool GetOpenChatOnNewMessage() const { return bOpenChatOnNewMessage; }
|
bool GetOpenChatOnNewMessage() const { return bOpenChatOnNewMessage; }
|
||||||
void SetOpenChatOnNewMessage ( const bool bNV ) { bOpenChatOnNewMessage = bNV; }
|
void SetOpenChatOnNewMessage ( const bool bNV ) { bOpenChatOnNewMessage = bNV; }
|
||||||
|
|
||||||
|
|
|
@ -271,9 +271,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
||||||
// init delay and other information controls
|
// init delay and other information controls
|
||||||
ledOverallDelay->SetUpdateTime ( 2 * PING_UPDATE_TIME_MS );
|
ledOverallDelay->SetUpdateTime ( 2 * PING_UPDATE_TIME_MS );
|
||||||
ledOverallDelay->Reset();
|
ledOverallDelay->Reset();
|
||||||
lblPingTimeValue->setText ( "" );
|
lblPingTimeValue->setText ( "---" );
|
||||||
lblOverallDelayValue->setText ( "" );
|
lblOverallDelayValue->setText ( "---" );
|
||||||
lblUpstreamValue->setText ( "" );
|
lblUpstreamValue->setText ( "---" );
|
||||||
|
|
||||||
|
|
||||||
// init slider controls ---
|
// init slider controls ---
|
||||||
|
@ -350,8 +350,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
||||||
", preferred" ) );
|
", preferred" ) );
|
||||||
|
|
||||||
rbtBufferDelayDefault->setText ( GenSndCrdBufferDelayString (
|
rbtBufferDelayDefault->setText ( GenSndCrdBufferDelayString (
|
||||||
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES,
|
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES ) );
|
||||||
", default" ) );
|
|
||||||
|
|
||||||
rbtBufferDelaySafe->setText ( GenSndCrdBufferDelayString (
|
rbtBufferDelaySafe->setText ( GenSndCrdBufferDelayString (
|
||||||
FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) );
|
FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) );
|
||||||
|
@ -741,9 +740,9 @@ void CClientSettingsDlg::UpdateDisplay()
|
||||||
if ( !pClient->IsRunning() )
|
if ( !pClient->IsRunning() )
|
||||||
{
|
{
|
||||||
// clear text labels with client parameters
|
// clear text labels with client parameters
|
||||||
lblPingTimeValue->setText ( "" );
|
lblPingTimeValue->setText ( "---" );
|
||||||
lblOverallDelayValue->setText ( "" );
|
lblOverallDelayValue->setText ( "---" );
|
||||||
lblUpstreamValue->setText ( "" );
|
lblUpstreamValue->setText ( "---" );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -564,6 +564,30 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblUpstream" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Audio Stream Rate</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lblUpstreamValue" >
|
||||||
|
<property name="minimumSize" >
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string>val</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" >
|
<layout class="QHBoxLayout" >
|
||||||
<item>
|
<item>
|
||||||
|
@ -622,12 +646,6 @@
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="font" >
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>val</string>
|
<string>val</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -659,36 +677,6 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" >
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblUpstream" >
|
|
||||||
<property name="text" >
|
|
||||||
<string>Audio Stream Rate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblUpstreamValue" >
|
|
||||||
<property name="minimumSize" >
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="font" >
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text" >
|
|
||||||
<string>val</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -60,7 +60,7 @@ LED bar: lbr
|
||||||
|
|
||||||
// version and application name (always use this version)
|
// version and application name (always use this version)
|
||||||
#undef VERSION
|
#undef VERSION
|
||||||
#define VERSION "4.0.0cvs"
|
#define VERSION "3.2.0cvs"
|
||||||
#define APP_NAME "llcon"
|
#define APP_NAME "llcon"
|
||||||
|
|
||||||
// Windows registry key name of auto run entry for the server
|
// Windows registry key name of auto run entry for the server
|
||||||
|
|
|
@ -943,6 +943,11 @@ void CLlconClientDlg::UpdateDisplay()
|
||||||
chbChat->setChecked ( true );
|
chbChat->setChecked ( true );
|
||||||
chbChat->blockSignals ( false );
|
chbChat->blockSignals ( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TEST
|
||||||
|
pClient->GetChannel()->StoreAllSimAverages();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLlconClientDlg::SetGUIDesign ( const EGUIDesign eNewDesign )
|
void CLlconClientDlg::SetGUIDesign ( const EGUIDesign eNewDesign )
|
||||||
|
|
|
@ -1218,25 +1218,6 @@ void CServer::WriteHTMLChannelList()
|
||||||
streamFileOut << "</ul>" << endl;
|
streamFileOut << "</ul>" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CServer::GetTimingStdDev ( double& dCurTiStdDev )
|
|
||||||
{
|
|
||||||
dCurTiStdDev = 0.0; // init return value
|
|
||||||
|
|
||||||
// only return value if server is active and the actual measurement is
|
|
||||||
// updated
|
|
||||||
if ( IsRunning() )
|
|
||||||
{
|
|
||||||
// return the standard deviation
|
|
||||||
dCurTiStdDev = CycleTimeVariance.GetStdDev();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CServer::customEvent ( QEvent* pEvent )
|
void CServer::customEvent ( QEvent* pEvent )
|
||||||
{
|
{
|
||||||
if ( pEvent->type() == QEvent::User + 11 )
|
if ( pEvent->type() == QEvent::User + 11 )
|
||||||
|
|
|
@ -116,8 +116,6 @@ public:
|
||||||
void Stop();
|
void Stop();
|
||||||
bool IsRunning() { return HighPrecisionTimer.isActive(); }
|
bool IsRunning() { return HighPrecisionTimer.isActive(); }
|
||||||
|
|
||||||
bool GetTimingStdDev ( double& dCurTiStdDev );
|
|
||||||
|
|
||||||
bool PutData ( const CVector<uint8_t>& vecbyRecBuf,
|
bool PutData ( const CVector<uint8_t>& vecbyRecBuf,
|
||||||
const int iNumBytesRead,
|
const int iNumBytesRead,
|
||||||
const CHostAddress& HostAdr );
|
const CHostAddress& HostAdr );
|
||||||
|
|
113
src/util.h
113
src/util.h
|
@ -255,20 +255,25 @@ template<class TData> void CFIFO<TData>::Add ( const TData tNewD )
|
||||||
template<class TData> class CMovingAv : public CVector<TData>
|
template<class TData> class CMovingAv : public CVector<TData>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMovingAv() : CVector<TData>(), iCurIdx ( 0 ), iNorm ( 0 ),
|
CMovingAv() :
|
||||||
tCurAvResult ( TData ( 0 ) ) {}
|
CVector<TData>(),
|
||||||
CMovingAv ( const int iNeSi ) : CVector<TData> ( iNeSi ), iCurIdx ( 0 ),
|
iCurIdx ( 0 ),
|
||||||
iNorm ( 0 ), tCurAvResult ( TData ( 0 ) ) {}
|
iNorm ( 0 ),
|
||||||
CMovingAv ( const int iNeSi, const TData tInVa ) :
|
tCurAvResult ( TData ( 0 ) ),
|
||||||
CVector<TData> ( iNeSi, tInVa ), iCurIdx ( 0 ), iNorm ( 0 ),
|
tNoDataResult ( TData ( 0 ) ) {}
|
||||||
tCurAvResult ( TData ( 0 ) ) {}
|
|
||||||
|
|
||||||
void Add ( const TData tNewD );
|
void Add ( const TData tNewD );
|
||||||
|
|
||||||
|
void Init ( const int iNewSize,
|
||||||
|
const TData tNNoDRes = TData ( 0 ) );
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
inline TData GetAverage()
|
inline TData GetAverage()
|
||||||
{
|
{
|
||||||
if ( this->iNorm == 0 )
|
if ( this->iNorm == 0 )
|
||||||
{
|
{
|
||||||
return TData ( 0 );
|
return tNoDataResult;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -276,22 +281,22 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Init ( const int iNewSize );
|
|
||||||
void InitVec ( const int iNewSize, const int iNewVecSize );
|
|
||||||
void Reset();
|
|
||||||
bool IsInitialized() { return ( this->iNorm == this->iVectorSize ); }
|
bool IsInitialized() { return ( this->iNorm == this->iVectorSize ); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int iCurIdx;
|
int iCurIdx;
|
||||||
int iNorm;
|
int iNorm;
|
||||||
TData tCurAvResult;
|
TData tCurAvResult;
|
||||||
|
TData tNoDataResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class TData> void CMovingAv<TData>::Init ( const int iNewSize )
|
template<class TData> void CMovingAv<TData>::Init ( const int iNewSize,
|
||||||
|
const TData tNNoDRes )
|
||||||
{
|
{
|
||||||
iNorm = 0;
|
iNorm = 0;
|
||||||
iCurIdx = 0;
|
iCurIdx = 0;
|
||||||
tCurAvResult = TData ( 0 ); // only for scalars!
|
tCurAvResult = TData ( 0 ); // only for scalars!
|
||||||
|
tNoDataResult = tNNoDRes;
|
||||||
CVector<TData>::Init ( iNewSize );
|
CVector<TData>::Init ( iNewSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,18 +773,11 @@ fflush ( pFile );
|
||||||
// close;x=read('c:/temp/test.dat',-1,2);plot(x)
|
// close;x=read('c:/temp/test.dat',-1,2);plot(x)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( iNewValueBoundFactor > 0 )
|
// check if new value is in range (lower and upper bound)
|
||||||
|
if ( ( fabs ( dCurAddVal ) <= ( iNewValueBoundFactor * dIntervalTime ) ) )// &&
|
||||||
|
// ( fabs ( dCurAddVal ) >= dIntervalTime ) )
|
||||||
{
|
{
|
||||||
// check if new value is in range
|
// add squared value
|
||||||
if ( fabs ( dCurAddVal ) < ( iNewValueBoundFactor * dIntervalTime ) )
|
|
||||||
{
|
|
||||||
// add squared value
|
|
||||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// new value bound is not used, add new value (add squared value)
|
|
||||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal );
|
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,4 +802,61 @@ protected:
|
||||||
int iNewValueBoundFactor;
|
int iNewValueBoundFactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Error rate measurement ------------------------------------------------------
|
||||||
|
class CErrorRate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CErrorRate() {}
|
||||||
|
|
||||||
|
void Init ( const int iHistoryLength,
|
||||||
|
const bool bNBlockOnDoubleErr = false )
|
||||||
|
{
|
||||||
|
// initialize buffer (use "no data result" of 1.0 which stands for the
|
||||||
|
// worst error rate possible)
|
||||||
|
ErrorsMovAvBuf.Init ( iHistoryLength, 1.0f );
|
||||||
|
|
||||||
|
bPreviousState = true;
|
||||||
|
|
||||||
|
// store setting
|
||||||
|
bBlockOnDoubleErrors = bNBlockOnDoubleErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
ErrorsMovAvBuf.Reset();
|
||||||
|
bPreviousState = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update ( const bool bState )
|
||||||
|
{
|
||||||
|
// if two states were false, do not use the new value
|
||||||
|
if ( bBlockOnDoubleErrors && bPreviousState && bState )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add errors as values 0 and 1 to get correct error rate average
|
||||||
|
if ( bState )
|
||||||
|
{
|
||||||
|
ErrorsMovAvBuf.Add ( 1.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorsMovAvBuf.Add ( 0.0f );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// store state
|
||||||
|
bPreviousState = bState;
|
||||||
|
}
|
||||||
|
|
||||||
|
double GetAverage() { return ErrorsMovAvBuf.GetAverage(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CMovingAv<float> ErrorsMovAvBuf;
|
||||||
|
bool bBlockOnDoubleErrors;
|
||||||
|
bool bPreviousState;
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* !defined ( UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */
|
#endif /* !defined ( UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */
|
||||||
|
|
Loading…
Reference in a new issue