backup checkin, including lots of test code...

This commit is contained in:
Volker Fischer 2011-06-11 05:19:48 +00:00
parent b12ee5c104
commit d571f5328b
14 changed files with 1269 additions and 918 deletions

View file

@ -1,4 +1,4 @@
4.0.0
3.2.0
- new GUI style of the main window, added switch for selecting the GUI style
in the settings window

View file

@ -54,11 +54,37 @@ bool CNetBuf::Put ( const CVector<uint8_t>& vecbyData,
// Check if there is not enough space available -> correct
if ( GetAvailSpace() < iInSize )
{
/*
// not enough space in buffer for put operation, correct buffer to
// prepare for new data
Clear ( CT_PUT );
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
if ( iInSize > iMemSize )
@ -86,7 +112,7 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
{
return false;
}
/*
// check for invalid data in buffer
if ( iNumInvalidElements > 0 )
{
@ -96,15 +122,19 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
bGetOK = false; // return error flag
}
*/
// Check if there is not enough data available -> correct
if ( GetAvailData() < iInSize )
{
/*
// not enough data in buffer for get operation, correct buffer to
// prepare for getting data
Clear ( CT_GET );
bGetOK = false; // return error flag
*/
return false;
// check for special case: buffer memory is not sufficient
if ( iInSize > iMemSize )
@ -118,11 +148,33 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
// class)
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;
}
void CNetBuf::Clear ( const EClearType eClearType )
{
// TEST
CBufferBase<uint8_t>::Clear ( eClearType );
/*
// 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.
//
@ -177,6 +229,13 @@ void CNetBuf::Clear ( const EClearType eClearType )
// 1: 0 / 2: 0 / 3: 1 / 4: 1 / 5: 2 ...)
iNewFillLevel =
( ( ( 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 )
{
// 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
// 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;
}
}
// 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
}

View file

@ -29,18 +29,37 @@
#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 ********************************************************************/
// Buffer base class -----------------------------------------------------------
template<class TData> class CBufferBase
{
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,
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
if ( bPreserve && bIsInitialized )
if ( bPreserve && ( !bIsSimulation ) && bIsInitialized )
{
// copy old data in new vector using get pointer as zero per
// definition
@ -143,7 +162,10 @@ public:
else
{
// allocate memory for actual data buffer
vecMemory.Init ( iNewMemSize );
if ( !bIsSimulation )
{
vecMemory.Init ( iNewMemSize );
}
// init buffer pointers and buffer state (empty buffer)
iGetPos = 0;
@ -161,31 +183,44 @@ public:
virtual bool Put ( const CVector<TData>& vecData,
const int iInSize )
{
// copy new data in internal buffer
int iCurPos = 0;
if ( iPutPos + iInSize > iMemSize )
if ( bIsSimulation )
{
// 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 )
// in this simulation only the buffer pointers and the buffer state
// is updated, no actual data is transferred
iPutPos += iInSize;
if ( iPutPos >= iMemSize )
{
vecMemory[iPutPos++] = vecData[iCurPos++];
}
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
{
vecMemory[iPutPos] = vecData[iCurPos++];
iPutPos -= iMemSize;
}
}
else
{
// data can be written in one step
const int iEnd = iPutPos + iInSize;
while ( iPutPos < iEnd )
// copy new data in internal buffer
int iCurPos = 0;
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
const int iInSize = vecData.Size();
// copy data from internal buffer in output buffer
int iCurPos = 0;
if ( iGetPos + iInSize > iMemSize )
if ( bIsSimulation )
{
// 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 )
// in this simulation only the buffer pointers and the buffer state
// is updated, no actual data is transferred
iGetPos += iInSize;
if ( iGetPos >= iMemSize )
{
vecData[iCurPos++] = vecMemory[iGetPos++];
}
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
{
vecData[iCurPos++] = vecMemory[iGetPos];
iGetPos -= iMemSize;
}
}
else
{
// data can be read in one step
const int iEnd = iGetPos + iInSize;
while ( iGetPos < iEnd )
// copy data from internal buffer in output buffer
int iCurPos = 0;
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:
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;
int iMemSize;
int iGetPos;
int iPutPos;
EBufState eBufState;
bool bIsSimulation;
bool bIsInitialized;
};
@ -306,6 +370,9 @@ protected:
class CNetBuf : public CBufferBase<uint8_t>
{
public:
CNetBuf ( const bool bNewIsSim = false ) :
CBufferBase<uint8_t> ( bNewIsSim ) {}
virtual void Init ( const int iNewBlockSize,
const int iNewNumBlocks,
const bool bPreserve = false );
@ -316,15 +383,39 @@ public:
virtual bool Get ( CVector<uint8_t>& vecbyData );
protected:
enum EClearType { CT_PUT, CT_GET };
void Clear ( const EClearType eClearType );
virtual void Clear ( const EClearType eClearType );
int iBlockSize;
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) --------------------------------------
// 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

View file

@ -611,6 +611,20 @@ void CChannel::UpdateSocketBufferSize ( const double dLocalStdDev )
// do nothing
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.
// Assumptions:
// - 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 +
3.3 * ( CycleTimeVariance.GetStdDev() + dLocalStdDev ) ) /
SYSTEM_BLOCK_DURATION_MS_FLOAT + 0.5;
*/
/*
// TEST
//if (bIsServer) {
@ -643,7 +657,7 @@ fflush ( pFile );
// close;x=read('c:/temp/test.dat',-1,3);plot(x)
//}
*/
/*
// upper/lower hysteresis decision
const int iUpperHystDec = LlconMath().round ( dEstCurBufSet - dHysteresis );
const int iLowerHystDec = LlconMath().round ( dEstCurBufSet + dHysteresis );
@ -667,5 +681,6 @@ fflush ( pFile );
SetSockBufNumFrames ( iUpperHystDec, true );
}
}
*/
}
}

View file

@ -132,6 +132,11 @@ public:
void CreateNetTranspPropsMessFromCurrentSettings();
// TEST
void StoreAllSimAverages() { SockBuf.StoreAllSimAverages(); }
protected:
bool ProtocolIsEnabled();
@ -145,7 +150,7 @@ protected:
CVector<double> vecdGains;
// network jitter-buffer
CNetBuf SockBuf;
CNetBufWithStats SockBuf;
int iCurSockBufNumFrames;
bool bDoAutoSockBufSize;

View file

@ -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
if ( Channel.IsConnected() )
{

View file

@ -92,8 +92,6 @@ public:
double MicLevelR() { return SignalLevelMeter.MicLevelRight(); }
bool IsConnected() { return Channel.IsConnected(); }
double GetTimingStdDev() { return CycleTimeVariance.GetStdDev(); }
bool GetOpenChatOnNewMessage() const { return bOpenChatOnNewMessage; }
void SetOpenChatOnNewMessage ( const bool bNV ) { bOpenChatOnNewMessage = bNV; }

View file

@ -271,9 +271,9 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
// init delay and other information controls
ledOverallDelay->SetUpdateTime ( 2 * PING_UPDATE_TIME_MS );
ledOverallDelay->Reset();
lblPingTimeValue->setText ( "" );
lblOverallDelayValue->setText ( "" );
lblUpstreamValue->setText ( "" );
lblPingTimeValue->setText ( "---" );
lblOverallDelayValue->setText ( "---" );
lblUpstreamValue->setText ( "---" );
// init slider controls ---
@ -350,8 +350,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
", preferred" ) );
rbtBufferDelayDefault->setText ( GenSndCrdBufferDelayString (
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES,
", default" ) );
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES ) );
rbtBufferDelaySafe->setText ( GenSndCrdBufferDelayString (
FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) );
@ -741,9 +740,9 @@ void CClientSettingsDlg::UpdateDisplay()
if ( !pClient->IsRunning() )
{
// clear text labels with client parameters
lblPingTimeValue->setText ( "" );
lblOverallDelayValue->setText ( "" );
lblUpstreamValue->setText ( "" );
lblPingTimeValue->setText ( "---" );
lblOverallDelayValue->setText ( "---" );
lblUpstreamValue->setText ( "---" );
}
else
{

View file

@ -564,6 +564,30 @@
</property>
</spacer>
</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>
<layout class="QHBoxLayout" >
<item>
@ -622,12 +646,6 @@
<height>20</height>
</size>
</property>
<property name="font" >
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text" >
<string>val</string>
</property>
@ -659,36 +677,6 @@
</item>
</layout>
</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>
</widget>
</item>

View file

@ -60,7 +60,7 @@ LED bar: lbr
// version and application name (always use this version)
#undef VERSION
#define VERSION "4.0.0cvs"
#define VERSION "3.2.0cvs"
#define APP_NAME "llcon"
// Windows registry key name of auto run entry for the server

View file

@ -943,6 +943,11 @@ void CLlconClientDlg::UpdateDisplay()
chbChat->setChecked ( true );
chbChat->blockSignals ( false );
}
// TEST
pClient->GetChannel()->StoreAllSimAverages();
}
void CLlconClientDlg::SetGUIDesign ( const EGUIDesign eNewDesign )

View file

@ -1218,25 +1218,6 @@ void CServer::WriteHTMLChannelList()
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 )
{
if ( pEvent->type() == QEvent::User + 11 )

View file

@ -116,8 +116,6 @@ public:
void Stop();
bool IsRunning() { return HighPrecisionTimer.isActive(); }
bool GetTimingStdDev ( double& dCurTiStdDev );
bool PutData ( const CVector<uint8_t>& vecbyRecBuf,
const int iNumBytesRead,
const CHostAddress& HostAdr );

1659
src/util.h

File diff suppressed because it is too large Load diff