2006-12-18 15:39:33 +01:00
|
|
|
/******************************************************************************\
|
2009-02-22 12:07:18 +01:00
|
|
|
* Copyright (c) 2004-2009
|
2006-12-18 15:39:33 +01:00
|
|
|
*
|
|
|
|
* Author(s):
|
|
|
|
* Volker Fischer
|
|
|
|
*
|
|
|
|
******************************************************************************
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
|
|
* the terms of the GNU General Public License as published by the Free Software
|
|
|
|
* Foundation; either version 2 of the License, or (at your option) any later
|
|
|
|
* version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
* details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
\******************************************************************************/
|
|
|
|
|
|
|
|
#include "channel.h"
|
|
|
|
|
|
|
|
|
2009-07-28 09:17:04 +02:00
|
|
|
/* Implementation *************************************************************/
|
2009-03-17 07:50:00 +01:00
|
|
|
CChannel::CChannel ( const bool bNIsServer ) :
|
|
|
|
bIsServer ( bNIsServer ),
|
|
|
|
sName ( "" ),
|
|
|
|
vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ),
|
|
|
|
bIsEnabled ( false ),
|
2009-07-28 22:31:23 +02:00
|
|
|
iNetwFrameSizeFact ( 0 ),
|
|
|
|
iNetwFrameSize ( 0 )
|
2006-03-13 20:32:23 +01:00
|
|
|
{
|
2009-03-03 09:35:28 +01:00
|
|
|
// initial value for connection time out counter, we calculate the total
|
|
|
|
// number of samples here and subtract the number of samples of the block
|
|
|
|
// which we take out of the buffer to be independent of block sizes
|
|
|
|
iConTimeOutStartVal = CON_TIME_OUT_SEC_MAX * SYSTEM_SAMPLE_RATE;
|
|
|
|
|
|
|
|
// init time-out for the buffer with zero -> no connection
|
|
|
|
iConTimeOut = 0;
|
|
|
|
|
2006-12-06 22:10:24 +01:00
|
|
|
// init the socket buffer
|
2006-11-25 15:46:57 +01:00
|
|
|
SetSockBufSize ( DEF_NET_BUF_SIZE_NUM_BL );
|
2006-01-28 12:29:22 +01:00
|
|
|
|
2009-03-05 21:07:41 +01:00
|
|
|
|
2006-12-06 22:10:24 +01:00
|
|
|
// connections -------------------------------------------------------------
|
2006-11-25 15:46:57 +01:00
|
|
|
QObject::connect ( &Protocol,
|
|
|
|
SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ),
|
|
|
|
this, SLOT ( OnSendProtMessage ( CVector<uint8_t> ) ) );
|
2006-02-27 20:45:27 +01:00
|
|
|
|
2006-12-06 21:22:41 +01:00
|
|
|
QObject::connect ( &Protocol,
|
|
|
|
SIGNAL ( ChangeJittBufSize ( int ) ),
|
2006-11-25 15:46:57 +01:00
|
|
|
this, SLOT ( OnJittBufSizeChange ( int ) ) );
|
2006-03-07 22:26:40 +01:00
|
|
|
|
2006-12-06 21:22:41 +01:00
|
|
|
QObject::connect ( &Protocol,
|
|
|
|
SIGNAL ( ReqJittBufSize() ),
|
2006-11-25 15:46:57 +01:00
|
|
|
SIGNAL ( ReqJittBufSize() ) );
|
2006-03-12 12:50:35 +01:00
|
|
|
|
2006-12-06 21:22:41 +01:00
|
|
|
QObject::connect ( &Protocol,
|
2006-12-08 19:19:16 +01:00
|
|
|
SIGNAL ( ReqConnClientsList() ),
|
|
|
|
SIGNAL ( ReqConnClientsList() ) );
|
|
|
|
|
|
|
|
QObject::connect ( &Protocol,
|
2006-12-06 21:22:41 +01:00
|
|
|
SIGNAL ( ConClientListMesReceived ( CVector<CChannelShortInfo> ) ),
|
2006-11-26 22:25:56 +01:00
|
|
|
SIGNAL ( ConClientListMesReceived ( CVector<CChannelShortInfo> ) ) );
|
|
|
|
|
2006-12-09 16:00:24 +01:00
|
|
|
QObject::connect( &Protocol, SIGNAL ( ChangeChanGain ( int, double ) ),
|
|
|
|
this, SLOT ( OnChangeChanGain ( int, double ) ) );
|
2006-12-10 12:06:14 +01:00
|
|
|
|
2008-01-22 22:15:04 +01:00
|
|
|
QObject::connect( &Protocol, SIGNAL ( ChangeChanName ( QString ) ),
|
|
|
|
this, SLOT ( OnChangeChanName ( QString ) ) );
|
2008-07-24 08:53:07 +02:00
|
|
|
|
|
|
|
QObject::connect( &Protocol, SIGNAL ( ChatTextReceived ( QString ) ),
|
|
|
|
this, SIGNAL ( ChatTextReceived ( QString ) ) );
|
2008-08-02 09:28:21 +02:00
|
|
|
|
2008-08-10 23:56:03 +02:00
|
|
|
QObject::connect( &Protocol, SIGNAL ( PingReceived ( int ) ),
|
|
|
|
this, SIGNAL ( PingReceived ( int ) ) );
|
2009-03-01 12:17:35 +01:00
|
|
|
|
|
|
|
QObject::connect ( &Protocol,
|
|
|
|
SIGNAL ( NetTranspPropsReceived ( CNetworkTransportProps ) ),
|
|
|
|
this, SLOT ( OnNetTranspPropsReceived ( CNetworkTransportProps ) ) );
|
2009-03-01 21:53:12 +01:00
|
|
|
|
|
|
|
QObject::connect ( &Protocol,
|
|
|
|
SIGNAL ( ReqNetTranspProps() ),
|
|
|
|
this, SLOT ( OnReqNetTranspProps() ) );
|
2009-05-09 10:22:09 +02:00
|
|
|
|
|
|
|
QObject::connect ( &Protocol, SIGNAL ( Disconnection() ),
|
|
|
|
this, SLOT ( OnDisconnection() ) );
|
2009-03-01 12:17:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CChannel::ProtocolIsEnabled()
|
|
|
|
{
|
|
|
|
// for the server, only enable protocol if the channel is connected, i.e.,
|
|
|
|
// successfully audio packets are received from a client
|
|
|
|
// for the client, enable protocol if the channel is enabled, i.e., the
|
|
|
|
// connection button was hit by the user
|
|
|
|
if ( bIsServer )
|
|
|
|
{
|
|
|
|
return IsConnected();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return bIsEnabled;
|
|
|
|
}
|
2006-02-26 11:50:47 +01:00
|
|
|
}
|
2006-03-04 11:24:40 +01:00
|
|
|
|
2006-12-09 11:04:27 +01:00
|
|
|
void CChannel::SetEnable ( const bool bNEnStat )
|
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
|
|
|
|
2006-12-09 11:04:27 +01:00
|
|
|
// set internal parameter
|
|
|
|
bIsEnabled = bNEnStat;
|
|
|
|
|
2009-03-01 12:17:35 +01:00
|
|
|
// if channel is not enabled, reset time out count and protocol
|
2006-12-09 11:04:27 +01:00
|
|
|
if ( !bNEnStat )
|
|
|
|
{
|
|
|
|
iConTimeOut = 0;
|
2009-03-01 12:17:35 +01:00
|
|
|
Protocol.Reset();
|
2006-12-09 11:04:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-28 22:31:23 +02:00
|
|
|
void CChannel::SetNetwFrameSizeAndFact ( const int iNewNetwFrameSize,
|
|
|
|
const int iNewNetwFrameSizeFact )
|
2006-03-11 21:35:38 +01:00
|
|
|
{
|
2009-03-01 12:17:35 +01:00
|
|
|
// this function is intended for the server (not the client)
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
2006-03-13 21:23:05 +01:00
|
|
|
|
2009-07-28 22:31:23 +02:00
|
|
|
// store new values
|
|
|
|
iNetwFrameSize = iNewNetwFrameSize;
|
|
|
|
iNetwFrameSizeFact = iNewNetwFrameSizeFact;
|
2008-08-15 08:56:49 +02:00
|
|
|
|
2009-07-24 16:31:25 +02:00
|
|
|
// init conversion buffer
|
2009-07-28 22:31:23 +02:00
|
|
|
ConvBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact );
|
|
|
|
|
|
|
|
// initialize and reset cycle time variance measurement
|
|
|
|
CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_BLOCK_SIZE_SAMPLES,
|
|
|
|
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
|
|
|
|
|
|
|
CycleTimeVariance.Reset();
|
2009-07-30 20:36:37 +02:00
|
|
|
|
|
|
|
// tell the server that audio coding has changed
|
|
|
|
CreateNetTranspPropsMessFromCurrentSettings();
|
2006-03-13 21:23:05 +01:00
|
|
|
}
|
|
|
|
|
2009-05-13 09:14:08 +02:00
|
|
|
bool CChannel::SetSockBufSize ( const int iNumBlocks )
|
2008-08-14 21:12:23 +02:00
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex ); // this opperation must be done with mutex
|
|
|
|
|
2009-05-13 09:14:08 +02:00
|
|
|
// first check for valid input parameter range
|
|
|
|
if ( ( iNumBlocks >= MIN_NET_BUF_SIZE_NUM_BL ) &&
|
|
|
|
( iNumBlocks <= MAX_NET_BUF_SIZE_NUM_BL ) )
|
|
|
|
{
|
|
|
|
iCurSockBufSize = iNumBlocks;
|
|
|
|
|
|
|
|
// the network block size is a multiple of the internal minimal
|
|
|
|
// block size
|
2009-07-24 22:17:01 +02:00
|
|
|
SockBuf.Init ( SYSTEM_BLOCK_SIZE_SAMPLES, iNumBlocks );
|
2009-05-13 09:14:08 +02:00
|
|
|
|
|
|
|
return false; // -> no error
|
|
|
|
}
|
2008-08-14 21:12:23 +02:00
|
|
|
|
2009-05-13 09:14:08 +02:00
|
|
|
return true; // set error flag
|
2008-08-14 21:12:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CChannel::SetGain ( const int iChanID, const double dNewGain )
|
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
|
|
|
|
|
|
|
// set value (make sure channel ID is in range)
|
2009-03-01 12:17:35 +01:00
|
|
|
if ( ( iChanID >= 0 ) && ( iChanID < USED_NUM_CHANNELS ) )
|
2008-08-14 21:12:23 +02:00
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
vecdGains[iChanID] = dNewGain;
|
2008-08-14 21:12:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
double CChannel::GetGain ( const int iChanID )
|
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
2008-08-14 21:12:23 +02:00
|
|
|
|
2008-08-15 08:56:49 +02:00
|
|
|
// get value (make sure channel ID is in range)
|
2009-03-01 12:17:35 +01:00
|
|
|
if ( ( iChanID >= 0 ) && ( iChanID < USED_NUM_CHANNELS ) )
|
2008-08-14 21:12:23 +02:00
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
return vecdGains[iChanID];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
2008-08-14 21:12:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CChannel::SetName ( const QString strNewName )
|
|
|
|
{
|
|
|
|
bool bNameHasChanged = false;
|
|
|
|
|
|
|
|
Mutex.lock();
|
|
|
|
{
|
|
|
|
// apply value (if different from previous name)
|
|
|
|
if ( sName.compare ( strNewName ) )
|
|
|
|
{
|
|
|
|
sName = strNewName;
|
|
|
|
bNameHasChanged = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Mutex.unlock();
|
|
|
|
|
|
|
|
// fire message that name has changed
|
|
|
|
if ( bNameHasChanged )
|
|
|
|
{
|
|
|
|
// the "emit" has to be done outside the mutexed region
|
|
|
|
emit NameHasChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
QString CChannel::GetName()
|
|
|
|
{
|
|
|
|
// make sure the string is not written at the same time when it is
|
|
|
|
// read here -> use mutex to secure access
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
2008-08-14 21:12:23 +02:00
|
|
|
|
2008-08-15 08:56:49 +02:00
|
|
|
return sName;
|
2008-08-14 21:12:23 +02:00
|
|
|
}
|
|
|
|
|
2006-03-04 11:24:40 +01:00
|
|
|
void CChannel::OnSendProtMessage ( CVector<uint8_t> vecMessage )
|
|
|
|
{
|
2009-03-01 12:17:35 +01:00
|
|
|
// only send messages if protocol is enabled, otherwise delete complete
|
|
|
|
// queue
|
|
|
|
if ( ProtocolIsEnabled() )
|
2006-11-25 15:46:57 +01:00
|
|
|
{
|
|
|
|
// emit message to actually send the data
|
|
|
|
emit MessReadyForSending ( vecMessage );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// delete send message queue
|
2009-03-01 12:17:35 +01:00
|
|
|
Protocol.Reset();
|
2006-11-25 15:46:57 +01:00
|
|
|
}
|
2006-03-04 11:24:40 +01:00
|
|
|
}
|
2006-03-12 12:50:35 +01:00
|
|
|
|
2006-02-27 20:45:27 +01:00
|
|
|
void CChannel::OnJittBufSizeChange ( int iNewJitBufSize )
|
|
|
|
{
|
2006-11-25 15:46:57 +01:00
|
|
|
SetSockBufSize ( iNewJitBufSize );
|
2006-02-27 20:45:27 +01:00
|
|
|
}
|
2006-03-12 12:50:35 +01:00
|
|
|
|
2006-12-06 21:22:41 +01:00
|
|
|
void CChannel::OnChangeChanGain ( int iChanID, double dNewGain )
|
|
|
|
{
|
2008-08-14 21:12:23 +02:00
|
|
|
SetGain ( iChanID, dNewGain );
|
2006-12-06 21:22:41 +01:00
|
|
|
}
|
|
|
|
|
2008-01-22 22:15:04 +01:00
|
|
|
void CChannel::OnChangeChanName ( QString strName )
|
2006-12-10 12:06:14 +01:00
|
|
|
{
|
2008-08-14 21:12:23 +02:00
|
|
|
SetName ( strName );
|
2006-12-10 12:06:14 +01:00
|
|
|
}
|
|
|
|
|
2009-07-28 22:31:23 +02:00
|
|
|
bool CChannel::GetAddress ( CHostAddress& RetAddr )
|
2009-03-01 21:53:12 +01:00
|
|
|
{
|
|
|
|
QMutexLocker locker ( &Mutex );
|
|
|
|
|
|
|
|
if ( IsConnected() )
|
|
|
|
{
|
|
|
|
RetAddr = InetAddr;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RetAddr = CHostAddress();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-01 12:17:35 +01:00
|
|
|
void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps )
|
|
|
|
{
|
2009-07-28 22:31:23 +02:00
|
|
|
// only the server shall act on network transport properties message
|
2009-07-25 22:54:57 +02:00
|
|
|
if ( bIsServer )
|
|
|
|
{
|
2009-07-28 22:31:23 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
2009-07-25 22:54:57 +02:00
|
|
|
|
2009-07-28 22:31:23 +02:00
|
|
|
// store received parameters
|
|
|
|
iNetwFrameSizeFact = NetworkTransportProps.iBlockSizeFact;
|
|
|
|
iNetwFrameSize =
|
|
|
|
NetworkTransportProps.iNetworkPacketSize /
|
|
|
|
NetworkTransportProps.iBlockSizeFact;
|
2009-07-25 22:54:57 +02:00
|
|
|
}
|
2009-03-01 12:17:35 +01:00
|
|
|
}
|
|
|
|
|
2009-03-01 21:53:12 +01:00
|
|
|
void CChannel::OnReqNetTranspProps()
|
|
|
|
{
|
|
|
|
CreateNetTranspPropsMessFromCurrentSettings();
|
|
|
|
}
|
2009-03-01 12:17:35 +01:00
|
|
|
|
2009-03-01 21:53:12 +01:00
|
|
|
void CChannel::CreateNetTranspPropsMessFromCurrentSettings()
|
|
|
|
{
|
|
|
|
CNetworkTransportProps NetworkTransportProps (
|
2009-07-28 22:31:23 +02:00
|
|
|
iNetwFrameSize * iNetwFrameSizeFact,
|
|
|
|
iNetwFrameSizeFact,
|
2009-03-01 21:53:12 +01:00
|
|
|
1, // right now we only use mono
|
2009-07-25 23:42:02 +02:00
|
|
|
SYSTEM_SAMPLE_RATE,
|
2009-07-24 16:31:25 +02:00
|
|
|
CT_CELT, // always CELT coding
|
2009-07-25 07:57:27 +02:00
|
|
|
0,
|
2009-03-01 21:53:12 +01:00
|
|
|
0 );
|
|
|
|
|
|
|
|
// send current network transport properties
|
|
|
|
Protocol.CreateNetwTranspPropsMes ( NetworkTransportProps );
|
|
|
|
}
|
2009-03-01 12:17:35 +01:00
|
|
|
|
2009-05-09 10:22:09 +02:00
|
|
|
void CChannel::OnDisconnection()
|
|
|
|
{
|
|
|
|
// set time out counter to a small value > 0 so that the next time a
|
|
|
|
// received audio block is queried, the disconnection is performed
|
|
|
|
// (assuming that no audio packet is received in the meantime)
|
|
|
|
iConTimeOut = 1; // a small number > 0
|
|
|
|
}
|
|
|
|
|
2009-03-28 21:02:21 +01:00
|
|
|
EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
|
2006-12-18 15:39:33 +01:00
|
|
|
int iNumBytes )
|
|
|
|
{
|
2006-12-09 11:04:27 +01:00
|
|
|
EPutDataStat eRet = PS_GEN_ERROR;
|
2006-11-25 15:46:57 +01:00
|
|
|
|
2006-12-10 13:02:28 +01:00
|
|
|
// init flags
|
|
|
|
bool bIsProtocolPacket = false;
|
|
|
|
bool bIsAudioPacket = false;
|
2009-03-02 21:11:24 +01:00
|
|
|
bool bNewConnection = false;
|
2006-12-10 13:02:28 +01:00
|
|
|
|
2006-12-09 11:04:27 +01:00
|
|
|
if ( bIsEnabled )
|
2006-11-25 15:46:57 +01:00
|
|
|
{
|
2006-12-10 13:02:28 +01:00
|
|
|
// first check if this is protocol data
|
2009-03-01 12:17:35 +01:00
|
|
|
// only use protocol data if protocol mechanism is enabled
|
|
|
|
if ( ProtocolIsEnabled() )
|
2006-12-09 11:04:27 +01:00
|
|
|
{
|
2008-08-05 20:55:40 +02:00
|
|
|
// parse the message assuming this is a protocol message
|
2008-08-11 19:21:09 +02:00
|
|
|
if ( !Protocol.ParseMessage ( vecbyData, iNumBytes ) )
|
2006-11-25 15:46:57 +01:00
|
|
|
{
|
2006-12-10 13:02:28 +01:00
|
|
|
// set status flags
|
|
|
|
eRet = PS_PROT_OK;
|
|
|
|
bIsProtocolPacket = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// only try to parse audio if it was not a protocol packet
|
|
|
|
if ( !bIsProtocolPacket )
|
2009-03-02 21:11:24 +01:00
|
|
|
{
|
2009-03-01 12:17:35 +01:00
|
|
|
Mutex.lock();
|
2006-12-18 15:39:33 +01:00
|
|
|
{
|
2009-07-28 09:17:04 +02:00
|
|
|
|
|
|
|
|
|
|
|
// TODO only process data if network properties protocol message has been arrived
|
|
|
|
|
|
|
|
|
2009-03-01 12:17:35 +01:00
|
|
|
// only process audio if packet has correct size
|
2009-07-28 22:31:23 +02:00
|
|
|
if ( iNumBytes == ( iNetwFrameSize * iNetwFrameSizeFact ) )
|
2006-12-10 13:02:28 +01:00
|
|
|
{
|
2009-07-24 16:31:25 +02:00
|
|
|
// set audio packet flag
|
|
|
|
bIsAudioPacket = true;
|
2006-12-18 15:39:33 +01:00
|
|
|
|
2009-07-24 16:31:25 +02:00
|
|
|
// store new packet in jitter buffer
|
2009-07-31 20:53:40 +02:00
|
|
|
if ( SockBuf.Put ( vecbyData, iNumBytes ) )
|
2006-12-10 13:02:28 +01:00
|
|
|
{
|
|
|
|
eRet = PS_AUDIO_OK;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
eRet = PS_AUDIO_ERR;
|
|
|
|
}
|
2009-03-17 07:50:00 +01:00
|
|
|
|
2009-07-24 16:31:25 +02:00
|
|
|
// update cycle time variance measurement
|
2009-03-17 07:50:00 +01:00
|
|
|
|
|
|
|
// TODO only update if time difference of received packets is below
|
|
|
|
// a limit to avoid having short network troubles incorporated in the
|
|
|
|
// statistic
|
|
|
|
|
2009-07-24 16:31:25 +02:00
|
|
|
CycleTimeVariance.Update();
|
2009-03-01 12:17:35 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// the protocol parsing failed and this was no audio block,
|
|
|
|
// we treat this as protocol error (unkown packet)
|
|
|
|
eRet = PS_PROT_ERR;
|
|
|
|
}
|
2006-11-25 15:46:57 +01:00
|
|
|
|
2009-03-01 12:17:35 +01:00
|
|
|
// all network packets except of valid llcon protocol messages
|
|
|
|
// regardless if they are valid or invalid audio packets lead to
|
|
|
|
// a state change to a connected channel
|
|
|
|
// this is because protocol messages can only be sent on a
|
|
|
|
// connected channel and the client has to inform the server
|
|
|
|
// about the audio packet properties via the protocol
|
2006-12-18 15:39:33 +01:00
|
|
|
|
2009-03-01 12:17:35 +01:00
|
|
|
// check if channel was not connected, this is a new connection
|
|
|
|
bNewConnection = !IsConnected();
|
|
|
|
|
|
|
|
// reset time-out counter
|
|
|
|
iConTimeOut = iConTimeOutStartVal;
|
2006-11-25 15:46:57 +01:00
|
|
|
}
|
2009-03-01 12:17:35 +01:00
|
|
|
Mutex.unlock();
|
2006-11-25 15:46:57 +01:00
|
|
|
}
|
|
|
|
|
2006-12-09 11:04:27 +01:00
|
|
|
if ( bNewConnection )
|
|
|
|
{
|
2009-03-01 21:53:12 +01:00
|
|
|
// if this is a new connection and the current network packet is
|
|
|
|
// neither an audio or protocol packet, we have to query the
|
|
|
|
// network transport properties for the audio packets
|
2009-07-28 22:31:23 +02:00
|
|
|
// (this is only required for server since we defined that the
|
|
|
|
// server has to send with the same properties as sent by
|
|
|
|
// the client)
|
|
|
|
if ( bIsServer && ( !bIsProtocolPacket ) && ( !bIsAudioPacket ) )
|
2009-03-01 21:53:12 +01:00
|
|
|
{
|
|
|
|
Protocol.CreateReqNetwTranspPropsMes();
|
|
|
|
}
|
|
|
|
|
2009-03-17 07:50:00 +01:00
|
|
|
// reset cycle time variance measurement
|
|
|
|
CycleTimeVariance.Reset();
|
|
|
|
|
2009-03-01 21:53:12 +01:00
|
|
|
// inform other objects that new connection was established
|
2006-12-09 11:04:27 +01:00
|
|
|
emit NewConnection();
|
|
|
|
}
|
2006-11-25 15:46:57 +01:00
|
|
|
}
|
2006-12-18 15:39:33 +01:00
|
|
|
|
|
|
|
return eRet;
|
|
|
|
}
|
|
|
|
|
2009-07-24 16:31:25 +02:00
|
|
|
EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData )
|
2006-03-06 18:04:07 +01:00
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
|
|
|
|
2009-03-03 09:35:28 +01:00
|
|
|
EGetDataStat eGetStatus;
|
|
|
|
|
2009-07-24 16:31:25 +02:00
|
|
|
const bool bSockBufState = SockBuf.Get ( vecbyData );
|
2006-12-18 15:39:33 +01:00
|
|
|
|
2009-03-03 09:35:28 +01:00
|
|
|
// decrease time-out counter
|
|
|
|
if ( iConTimeOut > 0 )
|
2006-12-18 15:39:33 +01:00
|
|
|
{
|
2009-03-03 09:35:28 +01:00
|
|
|
// subtract the number of samples of the current block since the
|
2009-07-25 23:42:02 +02:00
|
|
|
// 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_SIZE_SAMPLES")
|
2009-07-26 09:29:32 +02:00
|
|
|
|
|
|
|
// TODO this code only works with the above assumption -> better
|
|
|
|
// implementation so that we are not depending on assumptions
|
|
|
|
|
2009-07-25 23:42:02 +02:00
|
|
|
iConTimeOut -= SYSTEM_BLOCK_SIZE_SAMPLES;
|
2006-12-09 11:40:18 +01:00
|
|
|
|
2009-03-03 09:35:28 +01:00
|
|
|
if ( iConTimeOut <= 0 )
|
|
|
|
{
|
|
|
|
// channel is just disconnected
|
|
|
|
eGetStatus = GS_CHAN_NOW_DISCONNECTED;
|
|
|
|
iConTimeOut = 0; // make sure we do not have negative values
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( bSockBufState )
|
2008-08-15 08:56:49 +02:00
|
|
|
{
|
2009-03-03 09:35:28 +01:00
|
|
|
// everything is ok
|
|
|
|
eGetStatus = GS_BUFFER_OK;
|
2006-12-09 11:40:18 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
// channel is not yet disconnected but no data in buffer
|
|
|
|
eGetStatus = GS_BUFFER_UNDERRUN;
|
2006-12-18 15:39:33 +01:00
|
|
|
}
|
2006-12-09 11:40:18 +01:00
|
|
|
}
|
2009-03-03 09:35:28 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// channel is disconnected
|
|
|
|
eGetStatus = GS_CHAN_NOT_CONNECTED;
|
2006-12-18 15:39:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return eGetStatus;
|
|
|
|
}
|
|
|
|
|
2009-07-28 22:31:23 +02:00
|
|
|
CVector<uint8_t> CChannel::PrepSendPacket ( const CVector<uint8_t>& vecbyNPacket )
|
2006-01-28 12:29:22 +01:00
|
|
|
{
|
2008-08-15 08:56:49 +02:00
|
|
|
QMutexLocker locker ( &Mutex );
|
|
|
|
|
2006-12-06 22:10:24 +01:00
|
|
|
// if the block is not ready we have to initialize with zero length to
|
|
|
|
// tell the following network send routine that nothing should be sent
|
2009-03-28 21:02:21 +01:00
|
|
|
CVector<uint8_t> vecbySendBuf ( 0 );
|
2006-11-25 15:46:57 +01:00
|
|
|
|
2009-07-28 09:17:04 +02:00
|
|
|
// use conversion buffer to convert sound card block size in network
|
|
|
|
// block size
|
2009-07-28 22:31:23 +02:00
|
|
|
if ( ConvBuf.Put ( vecbyNPacket ) )
|
2006-12-18 15:39:33 +01:00
|
|
|
{
|
2009-07-28 22:31:23 +02:00
|
|
|
// a packet is ready
|
|
|
|
vecbySendBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact );
|
|
|
|
vecbySendBuf = ConvBuf.Get();
|
2006-11-25 15:46:57 +01:00
|
|
|
}
|
2006-12-18 15:39:33 +01:00
|
|
|
|
|
|
|
return vecbySendBuf;
|
|
|
|
}
|
2009-03-03 23:46:36 +01:00
|
|
|
|
|
|
|
int CChannel::GetUploadRateKbps()
|
|
|
|
{
|
2009-07-28 22:31:23 +02:00
|
|
|
const int iAudioSizeOut = iNetwFrameSizeFact * SYSTEM_BLOCK_SIZE_SAMPLES;
|
2009-03-03 23:46:36 +01:00
|
|
|
|
|
|
|
// we assume that the UDP packet which is transported via IP has an
|
|
|
|
// additional header size of
|
|
|
|
// 8 (UDP) + 20 (IP without optional fields) = 28 bytes
|
2009-07-28 22:31:23 +02:00
|
|
|
return ( iNetwFrameSize * iNetwFrameSizeFact + 28 /* header */ ) *
|
|
|
|
8 /* bits per byte */ *
|
2009-03-03 23:46:36 +01:00
|
|
|
SYSTEM_SAMPLE_RATE / iAudioSizeOut / 1000;
|
|
|
|
}
|