bug fixes
This commit is contained in:
parent
3f6cfbbaeb
commit
af0b4816c3
9 changed files with 164 additions and 157 deletions
|
@ -120,7 +120,7 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
|
||||||
const int iInSize = vecbyData.Size();
|
const int iInSize = vecbyData.Size();
|
||||||
|
|
||||||
// check size
|
// check size
|
||||||
if ( iInSize != iBlockSize )
|
if ( ( iInSize == 0 ) || ( iInSize != iBlockSize ) )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
|
||||||
vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ),
|
vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ),
|
||||||
bIsEnabled ( false ),
|
bIsEnabled ( false ),
|
||||||
iNetwFrameSizeFact ( FRAME_SIZE_FACTOR_DEFAULT ),
|
iNetwFrameSizeFact ( FRAME_SIZE_FACTOR_DEFAULT ),
|
||||||
iNetwFrameSize ( 0 )
|
iNetwFrameSize ( 1 ) // any value > 0
|
||||||
{
|
{
|
||||||
// initial value for connection time out counter, we calculate the total
|
// initial value for connection time out counter, we calculate the total
|
||||||
// number of samples here and subtract the number of samples of the block
|
// 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 );
|
SetSockBufNumFrames ( DEF_NET_BUF_SIZE_NUM_BL );
|
||||||
|
|
||||||
// initialize cycle time variance measurement with defaults
|
// 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 );
|
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,7 +140,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_FRAME_SAMPLES,
|
CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_FRAME_SIZE_SAMPLES,
|
||||||
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
||||||
|
|
||||||
CycleTimeVariance.Reset();
|
CycleTimeVariance.Reset();
|
||||||
|
@ -448,12 +448,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_FRAME_SAMPLES")
|
// where the atomic block size is "SYSTEM_FRAME_SIZE_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_FRAME_SAMPLES;
|
iConTimeOut -= SYSTEM_FRAME_SIZE_SAMPLES;
|
||||||
|
|
||||||
if ( iConTimeOut <= 0 )
|
if ( iConTimeOut <= 0 )
|
||||||
{
|
{
|
||||||
|
@ -506,7 +506,7 @@ CVector<uint8_t> CChannel::PrepSendPacket ( const CVector<uint8_t>& vecbyNPacket
|
||||||
|
|
||||||
int CChannel::GetUploadRateKbps()
|
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
|
// we assume that the UDP packet which is transported via IP has an
|
||||||
// additional header size of
|
// additional header size of
|
||||||
|
|
|
@ -40,7 +40,7 @@ CClient::CClient ( const quint16 iPortNumber ) :
|
||||||
{
|
{
|
||||||
// init audio endocder/decoder (mono)
|
// init audio endocder/decoder (mono)
|
||||||
CeltMode = celt_mode_create (
|
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 );
|
CeltEncoder = celt_encoder_create ( CeltMode );
|
||||||
CeltDecoder = celt_decoder_create ( CeltMode );
|
CeltDecoder = celt_decoder_create ( CeltMode );
|
||||||
|
@ -272,7 +272,7 @@ void CClient::Init()
|
||||||
{
|
{
|
||||||
// translate block size index in actual block size
|
// translate block size index in actual block size
|
||||||
const int iPrefMonoFrameSize =
|
const int iPrefMonoFrameSize =
|
||||||
iSndCrdPrefMonoFrameSizeFactor * SYSTEM_BLOCK_FRAME_SAMPLES;
|
iSndCrdPrefMonoFrameSizeFactor * SYSTEM_FRAME_SIZE_SAMPLES;
|
||||||
|
|
||||||
// get actual sound card buffer size using preferred size
|
// get actual sound card buffer size using preferred size
|
||||||
iMonoBlockSizeSam = Sound.Init ( iPrefMonoFrameSize );
|
iMonoBlockSizeSam = Sound.Init ( iPrefMonoFrameSize );
|
||||||
|
@ -395,7 +395,7 @@ void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
|
||||||
{
|
{
|
||||||
// encode current audio frame with CELT encoder
|
// encode current audio frame with CELT encoder
|
||||||
celt_encode ( CeltEncoder,
|
celt_encode ( CeltEncoder,
|
||||||
&vecsNetwork[i * SYSTEM_BLOCK_FRAME_SAMPLES],
|
&vecsNetwork[i * SYSTEM_FRAME_SIZE_SAMPLES],
|
||||||
NULL,
|
NULL,
|
||||||
&vecCeltData[0],
|
&vecCeltData[0],
|
||||||
iCeltNumCodedBytes );
|
iCeltNumCodedBytes );
|
||||||
|
@ -431,7 +431,7 @@ void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
|
||||||
celt_decode ( CeltDecoder,
|
celt_decode ( CeltDecoder,
|
||||||
&vecbyNetwData[0],
|
&vecbyNetwData[0],
|
||||||
iCeltNumCodedBytes,
|
iCeltNumCodedBytes,
|
||||||
&vecsAudioSndCrdMono[i * SYSTEM_BLOCK_FRAME_SAMPLES] );
|
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -439,7 +439,7 @@ void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
|
||||||
celt_decode ( CeltDecoder,
|
celt_decode ( CeltDecoder,
|
||||||
NULL,
|
NULL,
|
||||||
iCeltNumCodedBytes,
|
iCeltNumCodedBytes,
|
||||||
&vecsAudioSndCrdMono[i * SYSTEM_BLOCK_FRAME_SAMPLES] );
|
&vecsAudioSndCrdMono[i * SYSTEM_FRAME_SIZE_SAMPLES] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,15 +85,15 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
||||||
|
|
||||||
// set text for sound card buffer delay radio buttons
|
// set text for sound card buffer delay radio buttons
|
||||||
rButBufferDelayPreferred->setText ( GenSndCrdBufferDelayString (
|
rButBufferDelayPreferred->setText ( GenSndCrdBufferDelayString (
|
||||||
FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_BLOCK_FRAME_SAMPLES,
|
FRAME_SIZE_FACTOR_PREFERRED * SYSTEM_FRAME_SIZE_SAMPLES,
|
||||||
", preferred" ) );
|
", preferred" ) );
|
||||||
|
|
||||||
rButBufferDelayDefault->setText ( GenSndCrdBufferDelayString (
|
rButBufferDelayDefault->setText ( GenSndCrdBufferDelayString (
|
||||||
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_BLOCK_FRAME_SAMPLES,
|
FRAME_SIZE_FACTOR_DEFAULT * SYSTEM_FRAME_SIZE_SAMPLES,
|
||||||
", default" ) );
|
", default" ) );
|
||||||
|
|
||||||
rButBufferDelaySafe->setText ( GenSndCrdBufferDelayString (
|
rButBufferDelaySafe->setText ( GenSndCrdBufferDelayString (
|
||||||
FRAME_SIZE_FACTOR_SAFE * SYSTEM_BLOCK_FRAME_SAMPLES ) );
|
FRAME_SIZE_FACTOR_SAFE * SYSTEM_FRAME_SIZE_SAMPLES ) );
|
||||||
|
|
||||||
// sound card buffer delay inits
|
// sound card buffer delay inits
|
||||||
SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayPreferred );
|
SndCrdBufferDelayButtonGroup.addButton ( rButBufferDelayPreferred );
|
||||||
|
@ -192,7 +192,7 @@ void CClientSettingsDlg::UpdateSoundCardFrame()
|
||||||
|
|
||||||
// preferred size
|
// preferred size
|
||||||
const int iPrefBufSize =
|
const int iPrefBufSize =
|
||||||
iCurPrefFrameSizeFactor * SYSTEM_BLOCK_FRAME_SAMPLES;
|
iCurPrefFrameSizeFactor * SYSTEM_FRAME_SIZE_SAMPLES;
|
||||||
|
|
||||||
// actual size (use yellow color if different from preferred size)
|
// actual size (use yellow color if different from preferred size)
|
||||||
const QString strActSizeValues =
|
const QString strActSizeValues =
|
||||||
|
|
10
src/global.h
10
src/global.h
|
@ -60,14 +60,14 @@
|
||||||
|
|
||||||
// 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_FRAME_SAMPLES 128
|
#define SYSTEM_FRAME_SIZE_SAMPLES 128
|
||||||
|
|
||||||
#define SYSTEM_BLOCK_DURATION_MS_FLOAT \
|
#define SYSTEM_BLOCK_DURATION_MS_FLOAT \
|
||||||
( static_cast<double> ( SYSTEM_BLOCK_FRAME_SAMPLES ) / \
|
( static_cast<double> ( SYSTEM_FRAME_SIZE_SAMPLES ) / \
|
||||||
SYSTEM_SAMPLE_RATE * 1000 )
|
SYSTEM_SAMPLE_RATE * 1000 )
|
||||||
|
|
||||||
// define the allowed audio frame size factors (since the
|
// 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)
|
// computers a larger value is required)
|
||||||
#define FRAME_SIZE_FACTOR_PREFERRED 1 // 128 (for frame size 128)
|
#define FRAME_SIZE_FACTOR_PREFERRED 1 // 128 (for frame size 128)
|
||||||
#define FRAME_SIZE_FACTOR_DEFAULT 2 // 256 (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
|
// of bytes to be expected from the network interface
|
||||||
#define MAX_MONO_AUD_BUFF_SIZE_AT_48KHZ 4096
|
#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)
|
// minimum/maximum network buffer size (which can be chosen by slider)
|
||||||
#define MIN_NET_BUF_SIZE_NUM_BL 1 // number of blocks
|
#define MIN_NET_BUF_SIZE_NUM_BL 1 // number of blocks
|
||||||
#define MAX_NET_BUF_SIZE_NUM_BL 20 // number of blocks
|
#define MAX_NET_BUF_SIZE_NUM_BL 20 // number of blocks
|
||||||
|
|
|
@ -878,14 +878,33 @@ bool CProtocol::EvaluateNetwTranspPropsMes ( const CVector<uint8_t>& vecData )
|
||||||
ReceivedNetwTranspProps.iNetworkPacketSize =
|
ReceivedNetwTranspProps.iNetworkPacketSize =
|
||||||
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 4 ) );
|
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)
|
// block size factor (2 bytes)
|
||||||
ReceivedNetwTranspProps.iBlockSizeFact =
|
ReceivedNetwTranspProps.iBlockSizeFact =
|
||||||
static_cast<uint16_t> ( GetValFromStream ( vecData, iPos, 2 ) );
|
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)
|
// number of channels of the audio signal, e.g. "2" is stereo (1 byte)
|
||||||
ReceivedNetwTranspProps.iNumAudioChannels =
|
ReceivedNetwTranspProps.iNumAudioChannels =
|
||||||
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 1 ) );
|
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)
|
// sample rate of the audio stream (4 bytes)
|
||||||
ReceivedNetwTranspProps.iSampleRate =
|
ReceivedNetwTranspProps.iSampleRate =
|
||||||
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 4 ) );
|
static_cast<uint32_t> ( GetValFromStream ( vecData, iPos, 4 ) );
|
||||||
|
|
250
src/server.cpp
250
src/server.cpp
|
@ -30,7 +30,7 @@ CHighPrecisionTimer::CHighPrecisionTimer()
|
||||||
{
|
{
|
||||||
// add some error checking, the high precision timer implementation only
|
// add some error checking, the high precision timer implementation only
|
||||||
// supports 128 samples frame size at 48 kHz sampling rate
|
// 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"
|
# error "Only system frame size of 128 samples is supported by this module"
|
||||||
#endif
|
#endif
|
||||||
#if SYSTEM_SAMPLE_RATE != 48000
|
#if SYSTEM_SAMPLE_RATE != 48000
|
||||||
|
@ -112,24 +112,18 @@ CServer::CServer ( const QString& strLoggingFileName,
|
||||||
{
|
{
|
||||||
int i;
|
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++ )
|
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||||
{
|
{
|
||||||
// init audio endocder/decoder (mono)
|
// init audio endocder/decoder (mono)
|
||||||
CeltMode[i] = celt_mode_create (
|
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] );
|
CeltEncoder[i] = celt_encoder_create ( CeltMode[i] );
|
||||||
CeltDecoder[i] = celt_decoder_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
|
// define colors for chat window identifiers
|
||||||
vstrChatColors.Init ( 6 );
|
vstrChatColors.Init ( 6 );
|
||||||
vstrChatColors[0] = "mediumblue";
|
vstrChatColors[0] = "mediumblue";
|
||||||
|
@ -139,10 +133,10 @@ CServer::CServer ( const QString& strLoggingFileName,
|
||||||
vstrChatColors[4] = "maroon";
|
vstrChatColors[4] = "maroon";
|
||||||
vstrChatColors[5] = "coral";
|
vstrChatColors[5] = "coral";
|
||||||
|
|
||||||
vecsSendData.Init ( SYSTEM_BLOCK_FRAME_SAMPLES );
|
vecsSendData.Init ( SYSTEM_FRAME_SIZE_SAMPLES );
|
||||||
|
|
||||||
// init moving average buffer for response time evaluation
|
// 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 );
|
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
||||||
|
|
||||||
// enable logging (if requested)
|
// enable logging (if requested)
|
||||||
|
@ -175,6 +169,13 @@ CServer::CServer ( const QString& strLoggingFileName,
|
||||||
QString().number( static_cast<int> ( iPortNumber ) ) );
|
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 -------------------------------------------------------------
|
// connections -------------------------------------------------------------
|
||||||
// connect timer timeout signal
|
// connect timer timeout signal
|
||||||
|
@ -287,12 +288,112 @@ void CServer::Stop()
|
||||||
|
|
||||||
void CServer::OnTimer()
|
void CServer::OnTimer()
|
||||||
{
|
{
|
||||||
CVector<int> vecChanID;
|
int i, j;
|
||||||
CVector<CVector<int16_t> > vecvecsData;
|
|
||||||
CVector<CVector<double> > vecvecdGains;
|
|
||||||
|
|
||||||
// get data from all connected clients
|
CVector<int> vecChanID;
|
||||||
GetBlockAllConC ( vecChanID, vecvecsData, vecvecdGains );
|
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();
|
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
|
||||||
|
@ -307,8 +408,7 @@ void CServer::OnTimer()
|
||||||
|
|
||||||
// get current number of CELT coded bytes
|
// get current number of CELT coded bytes
|
||||||
const int iCeltNumCodedBytes =
|
const int iCeltNumCodedBytes =
|
||||||
vecChannels[vecChanID[i]].GetNetwFrameSize() /
|
vecChannels[vecChanID[i]].GetNetwFrameSize();
|
||||||
vecChannels[vecChanID[i]].GetNetwFrameSizeFact();
|
|
||||||
|
|
||||||
// CELT encoding
|
// CELT encoding
|
||||||
CVector<unsigned char> vecCeltData ( iCeltNumCodedBytes );
|
CVector<unsigned char> vecCeltData ( iCeltNumCodedBytes );
|
||||||
|
@ -342,7 +442,7 @@ CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
|
||||||
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<int16_t> vecsOutData ( SYSTEM_BLOCK_FRAME_SAMPLES, 0 );
|
CVector<int16_t> vecsOutData ( SYSTEM_FRAME_SIZE_SAMPLES, 0 );
|
||||||
|
|
||||||
const int iNumClients = vecvecsData.Size();
|
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 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_FRAME_SAMPLES; i++ )
|
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
|
||||||
{
|
{
|
||||||
vecsOutData[i] =
|
vecsOutData[i] =
|
||||||
Double2Short ( vecsOutData[i] + vecvecsData[j][i] );
|
Double2Short ( vecsOutData[i] + vecvecsData[j][i] );
|
||||||
|
@ -360,7 +460,7 @@ CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( i = 0; i < SYSTEM_BLOCK_FRAME_SAMPLES; i++ )
|
for ( i = 0; i < SYSTEM_FRAME_SIZE_SAMPLES; i++ )
|
||||||
{
|
{
|
||||||
vecsOutData[i] =
|
vecsOutData[i] =
|
||||||
Double2Short ( vecsOutData[i] +
|
Double2Short ( vecsOutData[i] +
|
||||||
|
@ -372,112 +472,6 @@ CVector<int16_t> CServer::ProcessData ( CVector<CVector<int16_t> >& vecvecsData,
|
||||||
return vecsOutData;
|
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> CServer::CreateChannelList()
|
||||||
{
|
{
|
||||||
CVector<CChannelShortInfo> vecChanInfo ( 0 );
|
CVector<CChannelShortInfo> vecChanInfo ( 0 );
|
||||||
|
|
|
@ -105,10 +105,6 @@ protected:
|
||||||
void StartStatusHTMLFileWriting ( const QString& strNewFileName,
|
void StartStatusHTMLFileWriting ( const QString& strNewFileName,
|
||||||
const QString& strNewServerNameWithPort );
|
const QString& strNewServerNameWithPort );
|
||||||
|
|
||||||
void GetBlockAllConC ( CVector<int>& vecChanID,
|
|
||||||
CVector<CVector<int16_t> >& vecvecsData,
|
|
||||||
CVector<CVector<double> >& vecvecdGains );
|
|
||||||
|
|
||||||
int CheckAddr ( const CHostAddress& Addr );
|
int CheckAddr ( const CHostAddress& Addr );
|
||||||
int GetFreeChan();
|
int GetFreeChan();
|
||||||
CVector<CChannelShortInfo> CreateChannelList();
|
CVector<CChannelShortInfo> CreateChannelList();
|
||||||
|
|
|
@ -40,12 +40,6 @@
|
||||||
class CServer; // forward declaration of CServer
|
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 ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
class CSocket : public QObject
|
class CSocket : public QObject
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue