bug fixes

This commit is contained in:
Volker Fischer 2009-08-13 16:12:49 +00:00
parent 3f6cfbbaeb
commit af0b4816c3
9 changed files with 164 additions and 157 deletions

View file

@ -120,7 +120,7 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
const int iInSize = vecbyData.Size();
// check size
if ( iInSize != iBlockSize )
if ( ( iInSize == 0 ) || ( iInSize != iBlockSize ) )
{
return false;
}

View file

@ -32,7 +32,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ),
bIsEnabled ( false ),
iNetwFrameSizeFact ( FRAME_SIZE_FACTOR_DEFAULT ),
iNetwFrameSize ( 0 )
iNetwFrameSize ( 1 ) // any value > 0
{
// initial value for connection time out counter, we calculate the total
// number of samples here and subtract the number of samples of the block
@ -46,7 +46,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
SetSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL );
// initialize cycle time variance measurement with defaults
CycleTimeVariance.Init ( SYSTEM_BLOCK_FRAME_SAMPLES,
CycleTimeVariance.Init ( SYSTEM_FRAME_SIZE_SAMPLES,
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
@ -140,7 +140,7 @@ void CChannel::SetNetwFrameSizeAndFact ( const int iNewNetwFrameSize,
ConvBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact );
// initialize and reset cycle time variance measurement
CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_BLOCK_FRAME_SAMPLES,
CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_FRAME_SIZE_SAMPLES,
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
CycleTimeVariance.Reset();
@ -448,12 +448,12 @@ EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData )
// subtract the number of samples of the current block since the
// time out counter is based on samples not on blocks (definition:
// always one atomic block is get by using the GetData() function
// where the atomic block size is "SYSTEM_BLOCK_FRAME_SAMPLES")
// where the atomic block size is "SYSTEM_FRAME_SIZE_SAMPLES")
// TODO this code only works with the above assumption -> better
// implementation so that we are not depending on assumptions
iConTimeOut -= SYSTEM_BLOCK_FRAME_SAMPLES;
iConTimeOut -= SYSTEM_FRAME_SIZE_SAMPLES;
if ( iConTimeOut <= 0 )
{
@ -506,7 +506,7 @@ CVector<uint8_t> CChannel::PrepSendPacket ( const CVector<uint8_t>& vecbyNPacket
int CChannel::GetUploadRateKbps()
{
const int iAudioSizeOut = iNetwFrameSizeFact * SYSTEM_BLOCK_FRAME_SAMPLES;
const int iAudioSizeOut = iNetwFrameSizeFact * SYSTEM_FRAME_SIZE_SAMPLES;
// we assume that the UDP packet which is transported via IP has an
// additional header size of

View file

@ -40,7 +40,7 @@ CClient::CClient ( const quint16 iPortNumber ) :
{
// init audio endocder/decoder (mono)
CeltMode = celt_mode_create (
SYSTEM_SAMPLE_RATE, 1, SYSTEM_BLOCK_FRAME_SAMPLES, NULL );
SYSTEM_SAMPLE_RATE, 1, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
CeltEncoder = celt_encoder_create ( CeltMode );
CeltDecoder = celt_decoder_create ( CeltMode );
@ -272,7 +272,7 @@ void CClient::Init()
{
// translate block size index in actual block size
const int iPrefMonoFrameSize =
iSndCrdPrefMonoFrameSizeFactor * SYSTEM_BLOCK_FRAME_SAMPLES;
iSndCrdPrefMonoFrameSizeFactor * SYSTEM_FRAME_SIZE_SAMPLES;
// get actual sound card buffer size using preferred size
iMonoBlockSizeSam = Sound.Init ( iPrefMonoFrameSize );
@ -395,7 +395,7 @@ void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
{
// encode current audio frame with CELT encoder
celt_encode ( CeltEncoder,
&vecsNetwork[i * SYSTEM_BLOCK_FRAME_SAMPLES],
&vecsNetwork[i * SYSTEM_FRAME_SIZE_SAMPLES],
NULL,
&vecCeltData[0],
iCeltNumCodedBytes );
@ -431,7 +431,7 @@ void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
celt_decode ( CeltDecoder,
&vecbyNetwData[0],
iCeltNumCodedBytes,
&vecsAudioSndCrdMono[i * SYSTEM_BLOCK_FRAME_SAMPLES] );
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
}
else
{
@ -439,7 +439,7 @@ void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
celt_decode ( CeltDecoder,
NULL,
iCeltNumCodedBytes,
&vecsAudioSndCrdMono[i * SYSTEM_BLOCK_FRAME_SAMPLES] );
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
}
}

View file

@ -85,15 +85,15 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
// set text for sound card buffer delay radio buttons
rButBufferDelayPreferred->setText ( GenSndCrdBufferDelayString (
FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_BLOCK_FRAME_SAMPLES,
FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_FRAME_SIZE_SAMPLES,
", preferred" ) );
rButBufferDelayDefault->setText ( GenSndCrdBufferDelayString (
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_BLOCK_FRAME_SAMPLES,
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES,
", default" ) );
rButBufferDelaySafe->setText ( GenSndCrdBufferDelayString (
FRAME_SIZE_FACTOR_SAFE * SYSTEM_BLOCK_FRAME_SAMPLES ) );
FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) );
// sound card buffer delay inits
SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayPreferred );
@ -192,7 +192,7 @@ void CClientSettingsDlg::UpdateSoundCardFrame()
// preferred size
const int iPrefBufSize =
iCurPrefFrameSizeFactor * SYSTEM_BLOCK_FRAME_SAMPLES;
iCurPrefFrameSizeFactor * SYSTEM_FRAME_SIZE_SAMPLES;
// actual size (use yellow color if different from preferred size)
const QString strActSizeValues =

View file

@ -60,14 +60,14 @@
// 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
#define SYSTEM_BLOCK_FRAME_SAMPLES 128
#define SYSTEM_FRAME_SIZE_SAMPLES 128
#define SYSTEM_BLOCK_DURATION_MS_FLOAT \
( static_cast<double> ( SYSTEM_BLOCK_FRAME_SAMPLES ) / \
( static_cast<double> ( SYSTEM_FRAME_SIZE_SAMPLES ) / \
SYSTEM_SAMPLE_RATE * 1000 )
// define the allowed audio frame size factors (since the
// "SYSTEM_BLOCK_FRAME_SAMPLES" is quite small, it may be that on some
// "SYSTEM_FRAME_SIZE_SAMPLES" is quite small, it may be that on some
// computers a larger value is required)
#define FRAME_SIZE_FACTOR_PREFERRED 1 // 128 (for frame size 128)
#define FRAME_SIZE_FACTOR_DEFAULT 2 // 256 (for frame size 128)
@ -78,6 +78,10 @@
// of bytes to be expected from the network interface
#define MAX_MONO_AUD_BUFF_SIZE_AT_48KHZ 4096
// Maximum block size for network input buffer. Consider a maximum sample rate
// of 48 kHz and two audio channels and two bytes per sample.
#define MAX_SIZE_BYTES_NETW_BUF ( MAX_MONO_AUD_BUFF_SIZE_AT_48KHZ * 4 )
// minimum/maximum network buffer size (which can be chosen by slider)
#define MIN_NET_BUF_SIZE_NUM_BL 1 // number of blocks
#define MAX_NET_BUF_SIZE_NUM_BL 20 // number of blocks

View file

@ -878,14 +878,33 @@ bool CProtocol::EvaluateNetwTranspPropsMes ( const CVector<uint8_t>& vecData )
ReceivedNetwTranspProps.iNetworkPacketSize =
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 4 ) );
if ( ( ReceivedNetwTranspProps.iNetworkPacketSize < 1 ) ||
( ReceivedNetwTranspProps.iNetworkPacketSize > MAX_SIZE_BYTES_NETW_BUF ) )
{
return true;
}
// block size factor (2 bytes)
ReceivedNetwTranspProps.iBlockSizeFact =
static_cast<uint16_t> ( GetValFromStream ( vecData, iPos, 2 ) );
if ( ( ReceivedNetwTranspProps.iBlockSizeFact != FRAME_SIZE_FACTOR_PREFERRED ) &&
( ReceivedNetwTranspProps.iBlockSizeFact != FRAME_SIZE_FACTOR_DEFAULT ) &&
( ReceivedNetwTranspProps.iBlockSizeFact != FRAME_SIZE_FACTOR_SAFE ) )
{
return true;
}
// number of channels of the audio signal, e.g. "2" is stereo (1 byte)
ReceivedNetwTranspProps.iNumAudioChannels =
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 1 ) );
if ( ( ReceivedNetwTranspProps.iNumAudioChannels != 1 ) &&
( ReceivedNetwTranspProps.iNumAudioChannels != 2 ) )
{
return true;
}
// sample rate of the audio stream (4 bytes)
ReceivedNetwTranspProps.iSampleRate =
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 4 ) );

View file

@ -30,7 +30,7 @@ CHighPrecisionTimer::CHighPrecisionTimer()
{
// add some error checking, the high precision timer implementation only
// supports 128 samples frame size at 48 kHz sampling rate
#if ( SYSTEM_BLOCK_FRAME_SAMPLES != 128 )
#if ( SYSTEM_FRAME_SIZE_SAMPLES != 128 )
# error "Only system frame size of 128 samples is supported by this module"
#endif
#if SYSTEM_SAMPLE_RATE != 48000
@ -112,24 +112,18 @@ CServer::CServer ( const QString& strLoggingFileName,
{
int i;
// create CELT encoder/decoder for each channel
// create CELT encoder/decoder for each channel (must be done before
// enabling the channels)
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
{
// init audio endocder/decoder (mono)
CeltMode[i] = celt_mode_create (
SYSTEM_SAMPLE_RATE, 1, SYSTEM_BLOCK_FRAME_SAMPLES, NULL );
SYSTEM_SAMPLE_RATE, 1, SYSTEM_FRAME_SIZE_SAMPLES, NULL );
CeltEncoder[i] = celt_encoder_create ( CeltMode[i] );
CeltDecoder[i] = celt_decoder_create ( CeltMode[i] );
}
// enable all channels (for the server all channel must be enabled the
// entire life time of the software
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
{
vecChannels[i].SetEnable ( true );
}
// define colors for chat window identifiers
vstrChatColors.Init ( 6 );
vstrChatColors[0] = "mediumblue";
@ -139,10 +133,10 @@ CServer::CServer ( const QString& strLoggingFileName,
vstrChatColors[4] = "maroon";
vstrChatColors[5] = "coral";
vecsSendData.Init ( SYSTEM_BLOCK_FRAME_SAMPLES );
vecsSendData.Init ( SYSTEM_FRAME_SIZE_SAMPLES );
// init moving average buffer for response time evaluation
CycleTimeVariance.Init ( SYSTEM_BLOCK_FRAME_SAMPLES,
CycleTimeVariance.Init ( SYSTEM_FRAME_SIZE_SAMPLES,
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
// enable logging (if requested)
@ -175,6 +169,13 @@ CServer::CServer ( const QString& strLoggingFileName,
QString().number( static_cast<int> ( iPortNumber ) ) );
}
// enable all channels (for the server all channel must be enabled the
// entire life time of the software
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
{
vecChannels[i].SetEnable ( true );
}
// connections -------------------------------------------------------------
// connect timer timeout signal
@ -287,12 +288,112 @@ void CServer::Stop()
void CServer::OnTimer()
{
CVector<int> vecChanID;
CVector<CVector<int16_t> > vecvecsData;
CVector<CVector<double> > vecvecdGains;
int i, j;
// get data from all connected clients
GetBlockAllConC ( vecChanID, vecvecsData, vecvecdGains );
CVector<int> vecChanID;
CVector<CVector<double> > vecvecdGains;
CVector<CVector<int16_t> > vecvecsData;
// get data from all connected clients -------------------------------------
bool bChannelIsNowDisconnected = false;
// make put and get calls thread safe. Do not forget to unlock mutex
// afterwards!
Mutex.lock();
{
// first, get number and IDs of connected channels
vecChanID.Init ( 0 );
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// add ID and data
vecChanID.Add ( i );
}
}
// process connected channels
const int iNumCurConnChan = vecChanID.Size();
// init temporary vectors
vecvecdGains.Init ( iNumCurConnChan );
vecvecsData.Init ( iNumCurConnChan );
for ( i = 0; i < iNumCurConnChan; i++ )
{
// init vectors storing information of all channels
vecvecdGains[i].Init ( iNumCurConnChan );
vecvecsData[i].Init ( SYSTEM_FRAME_SIZE_SAMPLES );
// get gains of all connected channels
for ( j = 0; j < iNumCurConnChan; j++ )
{
// The second index of "vecvecdGains" does not represent
// the channel ID! Therefore we have to use "vecChanID" to
// query the IDs of the currently connected channels
vecvecdGains[i][j] =
vecChannels[vecChanID[i]].GetGain( vecChanID[j] );
}
// get current number of CELT coded bytes
const int iCeltNumCodedBytes =
vecChannels[i].GetNetwFrameSize();
// init temporal data vector and clear input buffers
CVector<uint8_t> vecbyData ( iCeltNumCodedBytes );
// get data
const EGetDataStat eGetStat = vecChannels[i].GetData ( vecbyData );
// if channel was just disconnected, set flag that connected
// client list is sent to all other clients
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
{
bChannelIsNowDisconnected = true;
}
// CELT decode received data stream
CVector<int16_t> vecsAudioMono ( SYSTEM_FRAME_SIZE_SAMPLES );
if ( eGetStat == GS_BUFFER_OK )
{
celt_decode ( CeltDecoder[i],
&vecbyData[0],
iCeltNumCodedBytes,
&vecvecsData[i][0] );
}
else
{
// lost packet
celt_decode ( CeltDecoder[i],
NULL,
iCeltNumCodedBytes,
&vecvecsData[i][0] );
}
// send message for get status (for GUI)
if ( eGetStat == GS_BUFFER_OK )
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN, i );
}
else
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED, i );
}
}
// a channel is now disconnected, take action on it
if ( bChannelIsNowDisconnected )
{
// update channel list for all currently connected clients
CreateAndSendChanListForAllConChannels();
}
}
Mutex.unlock(); // release mutex
// Process data ------------------------------------------------------------
const int iNumClients = vecChanID.Size();
// Check if at least one client is connected. If not, stop server until
@ -307,8 +408,7 @@ void CServer::OnTimer()
// get current number of CELT coded bytes
const int iCeltNumCodedBytes =
vecChannels[vecChanID[i]].GetNetwFrameSize() /
vecChannels[vecChanID[i]].GetNetwFrameSizeFact();
vecChannels[vecChanID[i]].GetNetwFrameSize();
// CELT encoding
CVector<unsigned char> vecCeltData ( iCeltNumCodedBytes );
@ -342,7 +442,7 @@ CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
int i;
// init return vector with zeros since we mix all channels on that vector
CVector<int16_t> vecsOutData ( SYSTEM_BLOCK_FRAME_SAMPLES, 0 );
CVector<int16_t> vecsOutData ( SYSTEM_FRAME_SIZE_SAMPLES, 0 );
const int iNumClients = vecvecsData.Size();
@ -352,7 +452,7 @@ CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
// if channel gain is 1, avoid multiplication for speed optimization
if ( vecdGains[j] == static_cast<double> ( 1.0 ) )
{
for ( i = 0; i < SYSTEM_BLOCK_FRAME_SAMPLES; i++ )
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
{
vecsOutData[i] =
Double2Short ( vecsOutData[i] + vecvecsData[j][i] );
@ -360,7 +460,7 @@ CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
}
else
{
for ( i = 0; i < SYSTEM_BLOCK_FRAME_SAMPLES; i++ )
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
{
vecsOutData[i] =
Double2Short ( vecsOutData[i] +
@ -372,112 +472,6 @@ CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
return vecsOutData;
}
void CServer::GetBlockAllConC ( CVector<int>& vecChanID,
CVector<CVector<int16_t> >& vecvecsData,
CVector<CVector<double> >& vecvecdGains )
{
int i, j;
bool bChannelIsNowDisconnected = false;
vecChanID.Init ( 0 );
vecvecsData.Init ( 0 );
vecvecdGains.Init ( 0 );
// make put and get calls thread safe. Do not forget to unlock mutex
// afterwards!
Mutex.lock();
{
// check all possible channels
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
{
// get current number of CELT coded bytes
const int iCeltNumCodedBytes =
vecChannels[i].GetNetwFrameSize() /
vecChannels[i].GetNetwFrameSizeFact();
// init temporal data vector and clear input buffers
CVector<uint8_t> vecbyData ( iCeltNumCodedBytes );
// read out all input buffers to decrease timeout counter on
// disconnected channels
const EGetDataStat eGetStat = vecChannels[i].GetData ( vecbyData );
// if channel was just disconnected, set flag that connected
// client list is sent to all other clients
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
{
bChannelIsNowDisconnected = true;
}
if ( vecChannels[i].IsConnected() )
{
// CELT decode received data stream
CVector<int16_t> vecsAudioMono ( SYSTEM_BLOCK_FRAME_SAMPLES );
if ( eGetStat == GS_BUFFER_OK )
{
celt_decode ( CeltDecoder[i],
&vecbyData[0],
iCeltNumCodedBytes,
&vecsAudioMono[0] );
}
else
{
// lost packet
celt_decode ( CeltDecoder[i],
NULL,
iCeltNumCodedBytes,
&vecsAudioMono[0] );
}
// add ID and data
vecChanID.Add ( i );
const int iOldSize = vecvecsData.Size();
vecvecsData.Enlarge ( 1 );
vecvecsData[iOldSize].Init ( vecsAudioMono.Size() );
vecvecsData[iOldSize] = vecsAudioMono;
// send message for get status (for GUI)
if ( eGetStat == GS_BUFFER_OK )
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN, i );
}
else
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED, i );
}
}
}
// now that we know the IDs of the connected clients, get gains
const int iNumCurConnChan = vecChanID.Size();
vecvecdGains.Init ( iNumCurConnChan );
for ( i = 0; i < iNumCurConnChan; i++ )
{
vecvecdGains[i].Init ( iNumCurConnChan );
for ( j = 0; j < iNumCurConnChan; j++ )
{
// The second index of "vecvecdGains" does not represent
// the channel ID! Therefore we have to use "vecChanID" to
// query the IDs of the currently connected channels
vecvecdGains[i][j] =
vecChannels[vecChanID[i]].GetGain( vecChanID[j] );
}
}
// a channel is now disconnected, take action on it
if ( bChannelIsNowDisconnected )
{
// update channel list for all currently connected clients
CreateAndSendChanListForAllConChannels();
}
}
Mutex.unlock(); // release mutex
}
CVector<CChannelShortInfo> CServer::CreateChannelList()
{
CVector<CChannelShortInfo> vecChanInfo ( 0 );

View file

@ -105,10 +105,6 @@ protected:
void StartStatusHTMLFileWriting ( const QString& strNewFileName,
const QString& strNewServerNameWithPort );
void GetBlockAllConC ( CVector<int>& vecChanID,
CVector<CVector<int16_t> >& vecvecsData,
CVector<CVector<double> >& vecvecdGains );
int CheckAddr ( const CHostAddress& Addr );
int GetFreeChan();
CVector<CChannelShortInfo> CreateChannelList();

View file

@ -40,12 +40,6 @@
class CServer; // forward declaration of CServer
/* Definitions ****************************************************************/
// Maximum block size for network input buffer. Consider a maximum sample rate
// of 48 kHz and two audio channels and two bytes per sample.
#define MAX_SIZE_BYTES_NETW_BUF ( MAX_MONO_AUD_BUFF_SIZE_AT_48KHZ * 4 )
/* Classes ********************************************************************/
class CSocket : public QObject
{