big changes on software structure, intermediate backup checkin -> NOT WORKING correctly right now
This commit is contained in:
parent
8843e94822
commit
91071384d2
26 changed files with 557 additions and 1236 deletions
|
@ -48,12 +48,12 @@ class CSound : public CSoundBase
|
|||
public:
|
||||
CSound ( void (*fpNewCallback) ( CVector<short>& psData, void* arg ), void* arg ) :
|
||||
#if WITH_SOUND
|
||||
CSoundBase ( fpNewCallback, arg ), rhandle ( NULL ),
|
||||
CSoundBase ( false, fpNewCallback, arg ), rhandle ( NULL ),
|
||||
phandle ( NULL ), iCurPeriodSizeIn ( NUM_PERIOD_BLOCKS_IN ),
|
||||
iCurPeriodSizeOut ( NUM_PERIOD_BLOCKS_OUT ), bChangParamIn ( true ),
|
||||
bChangParamOut ( true ) {}
|
||||
#else
|
||||
CSoundBase ( fpNewCallback, arg ) {}
|
||||
CSoundBase ( false, fpNewCallback, arg ) {}
|
||||
#endif
|
||||
virtual ~CSound() { Close(); }
|
||||
|
||||
|
|
|
@ -134,13 +134,6 @@ protected:
|
|||
class CAudioCompression
|
||||
{
|
||||
public:
|
||||
enum EAudComprType
|
||||
{
|
||||
CT_NONE = 0,
|
||||
CT_IMAADPCM = 1,
|
||||
CT_MSADPCM = 2
|
||||
};
|
||||
|
||||
CAudioCompression() {}
|
||||
virtual ~CAudioCompression() {}
|
||||
|
||||
|
|
|
@ -128,18 +128,22 @@ CAudioMixerBoard::CAudioMixerBoard ( QWidget* parent, Qt::WindowFlags f ) : QFra
|
|||
// connections -------------------------------------------------------------
|
||||
// CODE TAG: MAX_NUM_CHANNELS_TAG
|
||||
// make sure we have MAX_NUM_CHANNELS connections!!!
|
||||
QObject::connect(vecpChanFader[0],SIGNAL(valueChanged(double)),this,SLOT(OnValueChangedCh0(double)));
|
||||
QObject::connect(vecpChanFader[1],SIGNAL(valueChanged(double)),this,SLOT(OnValueChangedCh1(double)));
|
||||
QObject::connect(vecpChanFader[2],SIGNAL(valueChanged(double)),this,SLOT(OnValueChangedCh2(double)));
|
||||
QObject::connect(vecpChanFader[3],SIGNAL(valueChanged(double)),this,SLOT(OnValueChangedCh3(double)));
|
||||
QObject::connect(vecpChanFader[4],SIGNAL(valueChanged(double)),this,SLOT(OnValueChangedCh4(double)));
|
||||
QObject::connect(vecpChanFader[5],SIGNAL(valueChanged(double)),this,SLOT(OnValueChangedCh5(double)));
|
||||
QObject::connect ( vecpChanFader[0], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh0 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[1], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh1 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[2], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh2 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[3], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh3 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[4], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh4 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[5], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh5 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[6], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh6 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[7], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh7 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[8], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh8 ( double ) ) );
|
||||
QObject::connect ( vecpChanFader[9], SIGNAL ( valueChanged ( double ) ), this, SLOT ( OnValueChangedCh9 ( double ) ) );
|
||||
}
|
||||
|
||||
void CAudioMixerBoard::HideAll()
|
||||
{
|
||||
// make old controls invisible
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
vecpChanFader[i]->Hide();
|
||||
}
|
||||
|
@ -149,7 +153,7 @@ void CAudioMixerBoard::ApplyNewConClientList ( CVector<CChannelShortInfo>& vecCh
|
|||
{
|
||||
// search for channels with are already present and preserver their gain
|
||||
// setting, for all other channels, reset gain
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
bool bFaderIsUsed = false;
|
||||
|
||||
|
|
|
@ -105,6 +105,10 @@ public slots:
|
|||
void OnValueChangedCh3 ( double dValue ) { emit ChangeChanGain ( 3, dValue ); }
|
||||
void OnValueChangedCh4 ( double dValue ) { emit ChangeChanGain ( 4, dValue ); }
|
||||
void OnValueChangedCh5 ( double dValue ) { emit ChangeChanGain ( 5, dValue ); }
|
||||
void OnValueChangedCh6 ( double dValue ) { emit ChangeChanGain ( 6, dValue ); }
|
||||
void OnValueChangedCh7 ( double dValue ) { emit ChangeChanGain ( 7, dValue ); }
|
||||
void OnValueChangedCh8 ( double dValue ) { emit ChangeChanGain ( 8, dValue ); }
|
||||
void OnValueChangedCh9 ( double dValue ) { emit ChangeChanGain ( 9, dValue ); }
|
||||
|
||||
signals:
|
||||
void ChangeChanGain ( int iId, double dGain );
|
||||
|
|
346
src/channel.cpp
346
src/channel.cpp
|
@ -32,10 +32,9 @@ CChannelSet::CChannelSet ( const bool bForceLowUploadRate ) :
|
|||
bWriteStatusHTMLFile ( false )
|
||||
{
|
||||
// enable all channels and set server flag
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
vecChannels[i].SetEnable ( true );
|
||||
vecChannels[i].SetIsServer ( true );
|
||||
vecChannels[i].SetForceLowUploadRate ( bForceLowUploadRate );
|
||||
}
|
||||
|
||||
|
@ -57,6 +56,10 @@ CChannelSet::CChannelSet ( const bool bForceLowUploadRate ) :
|
|||
QObject::connect ( &vecChannels[3], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh3 ( CVector<uint8_t> ) ) );
|
||||
QObject::connect ( &vecChannels[4], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh4 ( CVector<uint8_t> ) ) );
|
||||
QObject::connect ( &vecChannels[5], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh5 ( CVector<uint8_t> ) ) );
|
||||
QObject::connect ( &vecChannels[6], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh6 ( CVector<uint8_t> ) ) );
|
||||
QObject::connect ( &vecChannels[7], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh7 ( CVector<uint8_t> ) ) );
|
||||
QObject::connect ( &vecChannels[8], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh8 ( CVector<uint8_t> ) ) );
|
||||
QObject::connect ( &vecChannels[9], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh9 ( CVector<uint8_t> ) ) );
|
||||
|
||||
// request jitter buffer size
|
||||
QObject::connect ( &vecChannels[0], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh0() ) );
|
||||
|
@ -65,6 +68,10 @@ CChannelSet::CChannelSet ( const bool bForceLowUploadRate ) :
|
|||
QObject::connect ( &vecChannels[3], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh3() ) );
|
||||
QObject::connect ( &vecChannels[4], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh4() ) );
|
||||
QObject::connect ( &vecChannels[5], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh5() ) );
|
||||
QObject::connect ( &vecChannels[6], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh6() ) );
|
||||
QObject::connect ( &vecChannels[7], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh7() ) );
|
||||
QObject::connect ( &vecChannels[8], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh8() ) );
|
||||
QObject::connect ( &vecChannels[9], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh9() ) );
|
||||
|
||||
// request connected clients list
|
||||
QObject::connect ( &vecChannels[0], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh0() ) );
|
||||
|
@ -73,6 +80,10 @@ CChannelSet::CChannelSet ( const bool bForceLowUploadRate ) :
|
|||
QObject::connect ( &vecChannels[3], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh3() ) );
|
||||
QObject::connect ( &vecChannels[4], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh4() ) );
|
||||
QObject::connect ( &vecChannels[5], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh5() ) );
|
||||
QObject::connect ( &vecChannels[6], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh6() ) );
|
||||
QObject::connect ( &vecChannels[7], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh7() ) );
|
||||
QObject::connect ( &vecChannels[8], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh8() ) );
|
||||
QObject::connect ( &vecChannels[9], SIGNAL ( ReqConnClientsList() ), this, SLOT ( OnReqConnClientsListCh9() ) );
|
||||
|
||||
// channel name has changed
|
||||
QObject::connect ( &vecChannels[0], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh0() ) );
|
||||
|
@ -81,6 +92,10 @@ CChannelSet::CChannelSet ( const bool bForceLowUploadRate ) :
|
|||
QObject::connect ( &vecChannels[3], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh3() ) );
|
||||
QObject::connect ( &vecChannels[4], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh4() ) );
|
||||
QObject::connect ( &vecChannels[5], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh5() ) );
|
||||
QObject::connect ( &vecChannels[6], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh6() ) );
|
||||
QObject::connect ( &vecChannels[7], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh7() ) );
|
||||
QObject::connect ( &vecChannels[8], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh8() ) );
|
||||
QObject::connect ( &vecChannels[9], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh9() ) );
|
||||
|
||||
// chat text received
|
||||
QObject::connect ( &vecChannels[0], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh0 ( QString ) ) );
|
||||
|
@ -89,6 +104,10 @@ CChannelSet::CChannelSet ( const bool bForceLowUploadRate ) :
|
|||
QObject::connect ( &vecChannels[3], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh3 ( QString ) ) );
|
||||
QObject::connect ( &vecChannels[4], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh4 ( QString ) ) );
|
||||
QObject::connect ( &vecChannels[5], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh5 ( QString ) ) );
|
||||
QObject::connect ( &vecChannels[6], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh6 ( QString ) ) );
|
||||
QObject::connect ( &vecChannels[7], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh7 ( QString ) ) );
|
||||
QObject::connect ( &vecChannels[8], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh8 ( QString ) ) );
|
||||
QObject::connect ( &vecChannels[9], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh9 ( QString ) ) );
|
||||
|
||||
// ping message received
|
||||
QObject::connect ( &vecChannels[0], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh0 ( int ) ) );
|
||||
|
@ -97,6 +116,10 @@ CChannelSet::CChannelSet ( const bool bForceLowUploadRate ) :
|
|||
QObject::connect ( &vecChannels[3], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh3 ( int ) ) );
|
||||
QObject::connect ( &vecChannels[4], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh4 ( int ) ) );
|
||||
QObject::connect ( &vecChannels[5], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh5 ( int ) ) );
|
||||
QObject::connect ( &vecChannels[6], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh6 ( int ) ) );
|
||||
QObject::connect ( &vecChannels[7], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh7 ( int ) ) );
|
||||
QObject::connect ( &vecChannels[8], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh8 ( int ) ) );
|
||||
QObject::connect ( &vecChannels[9], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh9 ( int ) ) );
|
||||
}
|
||||
|
||||
CVector<CChannelShortInfo> CChannelSet::CreateChannelList()
|
||||
|
@ -104,7 +127,7 @@ CVector<CChannelShortInfo> CChannelSet::CreateChannelList()
|
|||
CVector<CChannelShortInfo> vecChanInfo ( 0 );
|
||||
|
||||
// look for free channels
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( vecChannels[i].IsConnected() )
|
||||
{
|
||||
|
@ -125,7 +148,7 @@ void CChannelSet::CreateAndSendChanListForAllConChannels()
|
|||
CVector<CChannelShortInfo> vecChanInfo ( CChannelSet::CreateChannelList() );
|
||||
|
||||
// now send connected channels list to all connected clients
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( vecChannels[i].IsConnected() )
|
||||
{
|
||||
|
@ -148,7 +171,7 @@ void CChannelSet::CreateAndSendChanListForAllExceptThisChan ( const int iCurChan
|
|||
|
||||
// now send connected channels list to all connected clients except for
|
||||
// the channel with the ID "iCurChanID"
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( ( vecChannels[i].IsConnected() ) && ( i != iCurChanID ) )
|
||||
{
|
||||
|
@ -196,7 +219,7 @@ void CChannelSet::CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
|
|||
|
||||
|
||||
// send chat text to all connected clients ---------------------------------
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( vecChannels[i].IsConnected() )
|
||||
{
|
||||
|
@ -209,7 +232,7 @@ void CChannelSet::CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
|
|||
int CChannelSet::GetFreeChan()
|
||||
{
|
||||
// look for a free channel
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( !vecChannels[i].IsConnected() )
|
||||
{
|
||||
|
@ -226,7 +249,7 @@ int CChannelSet::CheckAddr ( const CHostAddress& Addr )
|
|||
CHostAddress InetAddr;
|
||||
|
||||
// check for all possible channels if IP is already in use
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( vecChannels[i].GetAddress ( InetAddr ) )
|
||||
{
|
||||
|
@ -246,8 +269,8 @@ bool CChannelSet::PutData ( const CVector<unsigned char>& vecbyRecBuf,
|
|||
const int iNumBytesRead,
|
||||
const CHostAddress& HostAdr )
|
||||
{
|
||||
bool bRet = false;
|
||||
bool bCreateChanList = false;
|
||||
bool bAudioOK = false;
|
||||
bool bNewChannelReserved = false;
|
||||
|
||||
Mutex.lock();
|
||||
{
|
||||
|
@ -270,7 +293,7 @@ bool CChannelSet::PutData ( const CVector<unsigned char>& vecbyRecBuf,
|
|||
|
||||
// reset the channel gains of current channel, at the same
|
||||
// time reset gains of this channel ID for all other channels
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
vecChannels[iCurChanID].SetGain ( i, (double) 1.0 );
|
||||
|
||||
|
@ -279,14 +302,8 @@ bool CChannelSet::PutData ( const CVector<unsigned char>& vecbyRecBuf,
|
|||
vecChannels[i].SetGain ( iCurChanID, (double) 1.0 );
|
||||
}
|
||||
|
||||
// a new client connected to the server, set flag to create and
|
||||
// send all clients the updated channel list, we cannot create
|
||||
// the message here since the received data has to be put to the
|
||||
// channel first so that this channel is marked as connected
|
||||
bCreateChanList = true;
|
||||
|
||||
// send message about new channel
|
||||
emit ChannelConnected ( HostAdr );
|
||||
// set flag for new reserved channel
|
||||
bNewChannelReserved = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -309,25 +326,36 @@ bool CChannelSet::PutData ( const CVector<unsigned char>& vecbyRecBuf,
|
|||
{
|
||||
case PS_AUDIO_OK:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN, iCurChanID );
|
||||
bRet = true; // in case we have an audio packet, return true
|
||||
bAudioOK = true; // in case we have an audio packet, return true
|
||||
break;
|
||||
|
||||
case PS_AUDIO_ERR:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED, iCurChanID );
|
||||
bRet = true; // in case we have an audio packet, return true
|
||||
bAudioOK = true; // in case we have an audio packet, return true
|
||||
break;
|
||||
|
||||
case PS_PROT_ERR:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW, iCurChanID );
|
||||
|
||||
// TEST
|
||||
bAudioOK = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// after data is put in channel buffer, create channel list message if
|
||||
// requested
|
||||
if ( bCreateChanList )
|
||||
if ( bNewChannelReserved && bAudioOK )
|
||||
{
|
||||
// send message about new channel
|
||||
emit ChannelConnected ( HostAdr );
|
||||
|
||||
// A new client connected to the server, create and
|
||||
// send all clients the updated channel list (the list has to
|
||||
// be created after the received data has to be put to the
|
||||
// channel first so that this channel is marked as connected)
|
||||
//
|
||||
// connected clients list is only send for new connected clients after
|
||||
// request, only the already connected clients get the list
|
||||
// automatically, because they don't know when new clients connect
|
||||
|
@ -336,7 +364,7 @@ bool CChannelSet::PutData ( const CVector<unsigned char>& vecbyRecBuf,
|
|||
}
|
||||
Mutex.unlock();
|
||||
|
||||
return bRet;
|
||||
return bAudioOK;
|
||||
}
|
||||
|
||||
void CChannelSet::GetBlockAllConC ( CVector<int>& vecChanID,
|
||||
|
@ -347,7 +375,7 @@ void CChannelSet::GetBlockAllConC ( CVector<int>& vecChanID,
|
|||
bool bCreateChanList = false;
|
||||
|
||||
// init temporal data vector and clear input buffers
|
||||
CVector<double> vecdData ( MIN_BLOCK_SIZE_SAMPLES );
|
||||
CVector<double> vecdData ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
|
||||
|
||||
vecChanID.Init ( 0 );
|
||||
vecvecdData.Init ( 0 );
|
||||
|
@ -358,7 +386,7 @@ void CChannelSet::GetBlockAllConC ( CVector<int>& vecChanID,
|
|||
Mutex.lock();
|
||||
{
|
||||
// check all possible channels
|
||||
for ( i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
// read out all input buffers to decrease timeout counter on
|
||||
// disconnected channels
|
||||
|
@ -424,20 +452,18 @@ void CChannelSet::GetBlockAllConC ( CVector<int>& vecChanID,
|
|||
void CChannelSet::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
|
||||
CVector<QString>& vecsName,
|
||||
CVector<int>& veciJitBufSize,
|
||||
CVector<int>& veciNetwOutBlSiFact,
|
||||
CVector<int>& veciNetwInBlSiFact )
|
||||
CVector<int>& veciNetwOutBlSiFact )
|
||||
{
|
||||
CHostAddress InetAddr;
|
||||
|
||||
// init return values
|
||||
vecHostAddresses.Init ( MAX_NUM_CHANNELS );
|
||||
vecsName.Init ( MAX_NUM_CHANNELS );
|
||||
veciJitBufSize.Init ( MAX_NUM_CHANNELS );
|
||||
veciNetwOutBlSiFact.Init ( MAX_NUM_CHANNELS );
|
||||
veciNetwInBlSiFact.Init ( MAX_NUM_CHANNELS );
|
||||
vecHostAddresses.Init ( USED_NUM_CHANNELS );
|
||||
vecsName.Init ( USED_NUM_CHANNELS );
|
||||
veciJitBufSize.Init ( USED_NUM_CHANNELS );
|
||||
veciNetwOutBlSiFact.Init ( USED_NUM_CHANNELS );
|
||||
|
||||
// check all possible channels
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( vecChannels[i].GetAddress ( InetAddr ) )
|
||||
{
|
||||
|
@ -446,7 +472,6 @@ void CChannelSet::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
|
|||
vecsName[i] = vecChannels[i].GetName();
|
||||
veciJitBufSize[i] = vecChannels[i].GetSockBufSize();
|
||||
veciNetwOutBlSiFact[i] = vecChannels[i].GetNetwBufSizeFactOut();
|
||||
veciNetwInBlSiFact[i] = vecChannels[i].GetNetwBufSizeFactIn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,7 +507,7 @@ void CChannelSet::WriteHTMLChannelList()
|
|||
|
||||
// get the number of connected clients
|
||||
int iNumConnClients = 0;
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( vecChannels[i].IsConnected() )
|
||||
{
|
||||
|
@ -499,7 +524,7 @@ void CChannelSet::WriteHTMLChannelList()
|
|||
else
|
||||
{
|
||||
// write entry for each connected client
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( vecChannels[i].IsConnected() )
|
||||
{
|
||||
|
@ -530,13 +555,10 @@ void CChannelSet::WriteHTMLChannelList()
|
|||
/******************************************************************************\
|
||||
* CChannel *
|
||||
\******************************************************************************/
|
||||
CChannel::CChannel() : sName ( "" ),
|
||||
vecdGains ( MAX_NUM_CHANNELS, (double) 1.0 ), bIsServer ( false ),
|
||||
bForceLowUploadRate ( false ),
|
||||
// it is important to give the following parameters meaningful initial
|
||||
// values because they are dependend on each other
|
||||
iCurSockBufSize ( DEF_NET_BUF_SIZE_NUM_BL ),
|
||||
iCurNetwInBlSiFact ( DEF_NET_BLOCK_SIZE_FACTOR )
|
||||
CChannel::CChannel ( const bool bNIsServer ) : bIsServer ( bNIsServer ),
|
||||
sName ( "" ), vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ),
|
||||
bIsEnabled ( false ), bForceLowUploadRate ( false ),
|
||||
iCurNetwOutBlSiFact ( DEF_NET_BLOCK_SIZE_FACTOR )
|
||||
{
|
||||
// query all possible network in buffer sizes for determining if an
|
||||
// audio packet was received (the following code only works if all
|
||||
|
@ -549,11 +571,11 @@ CChannel::CChannel() : sName ( "" ),
|
|||
|
||||
// init special mode
|
||||
|
||||
// TEST -> 64
|
||||
vecNetwBufferInProps[0].iBlockSizeFactor = 1;
|
||||
vecNetwBufferInProps[0].eAudComprType = CAudioCompression::CT_NONE;
|
||||
// TEST -> 128
|
||||
vecNetwBufferInProps[0].iAudioBlockSize = 128;
|
||||
vecNetwBufferInProps[0].eAudComprType = CT_NONE;
|
||||
vecNetwBufferInProps[0].iNetwInBufSize = AudioCompressionIn.Init (
|
||||
vecNetwBufferInProps[0].iBlockSizeFactor * 64,
|
||||
vecNetwBufferInProps[0].iAudioBlockSize,
|
||||
vecNetwBufferInProps[0].eAudComprType );
|
||||
|
||||
|
||||
|
@ -567,26 +589,26 @@ vecNetwBufferInProps[0].iNetwInBufSize = AudioCompressionIn.Init (
|
|||
|
||||
// network block size factor must start from 1 -> i + 1
|
||||
const int iCurNetBlockSizeFact = i + 1;
|
||||
vecNetwBufferInProps[iNoneIdx].iBlockSizeFactor = iCurNetBlockSizeFact;
|
||||
vecNetwBufferInProps[iIMAIdx].iBlockSizeFactor = iCurNetBlockSizeFact;
|
||||
vecNetwBufferInProps[iMSIdx].iBlockSizeFactor = iCurNetBlockSizeFact;
|
||||
vecNetwBufferInProps[iNoneIdx].iAudioBlockSize = iCurNetBlockSizeFact * MIN_SERVER_BLOCK_SIZE_SAMPLES;
|
||||
vecNetwBufferInProps[iIMAIdx].iAudioBlockSize = iCurNetBlockSizeFact * MIN_SERVER_BLOCK_SIZE_SAMPLES;
|
||||
vecNetwBufferInProps[iMSIdx].iAudioBlockSize = iCurNetBlockSizeFact * MIN_SERVER_BLOCK_SIZE_SAMPLES;
|
||||
|
||||
// None (no audio compression)
|
||||
vecNetwBufferInProps[iNoneIdx].eAudComprType = CAudioCompression::CT_NONE;
|
||||
vecNetwBufferInProps[iNoneIdx].eAudComprType = CT_NONE;
|
||||
vecNetwBufferInProps[iNoneIdx].iNetwInBufSize = AudioCompressionIn.Init (
|
||||
vecNetwBufferInProps[iNoneIdx].iBlockSizeFactor * MIN_BLOCK_SIZE_SAMPLES,
|
||||
vecNetwBufferInProps[iNoneIdx].iAudioBlockSize,
|
||||
vecNetwBufferInProps[iNoneIdx].eAudComprType );
|
||||
|
||||
// IMA ADPCM
|
||||
vecNetwBufferInProps[iIMAIdx].eAudComprType = CAudioCompression::CT_IMAADPCM;
|
||||
vecNetwBufferInProps[iIMAIdx].eAudComprType = CT_IMAADPCM;
|
||||
vecNetwBufferInProps[iIMAIdx].iNetwInBufSize = AudioCompressionIn.Init (
|
||||
vecNetwBufferInProps[iIMAIdx].iBlockSizeFactor * MIN_BLOCK_SIZE_SAMPLES,
|
||||
vecNetwBufferInProps[iIMAIdx].iAudioBlockSize,
|
||||
vecNetwBufferInProps[iIMAIdx].eAudComprType );
|
||||
|
||||
// MS ADPCM
|
||||
vecNetwBufferInProps[iMSIdx].eAudComprType = CAudioCompression::CT_MSADPCM;
|
||||
vecNetwBufferInProps[iMSIdx].eAudComprType = CT_MSADPCM;
|
||||
vecNetwBufferInProps[iMSIdx].iNetwInBufSize = AudioCompressionIn.Init (
|
||||
vecNetwBufferInProps[iMSIdx].iBlockSizeFactor * MIN_BLOCK_SIZE_SAMPLES,
|
||||
vecNetwBufferInProps[iMSIdx].iAudioBlockSize,
|
||||
vecNetwBufferInProps[iMSIdx].eAudComprType );
|
||||
}
|
||||
|
||||
|
@ -594,11 +616,14 @@ vecNetwBufferInProps[0].iNetwInBufSize = AudioCompressionIn.Init (
|
|||
SetSockBufSize ( DEF_NET_BUF_SIZE_NUM_BL );
|
||||
|
||||
// set initial input and output block size factors
|
||||
SetNetwInBlSiFactAndCompr ( DEF_NET_BLOCK_SIZE_FACTOR, CAudioCompression::CT_MSADPCM );
|
||||
SetNetwBufSizeFactOut ( DEF_NET_BLOCK_SIZE_FACTOR );
|
||||
SetAudioBlockSizeAndComprIn (
|
||||
MIN_SERVER_BLOCK_SIZE_SAMPLES * DEF_NET_BLOCK_SIZE_FACTOR,
|
||||
CT_MSADPCM );
|
||||
|
||||
SetNetwBufSizeFactOut ( DEF_NET_BLOCK_SIZE_FACTOR );
|
||||
|
||||
// set initial audio compression format for output
|
||||
SetAudioCompressionOut ( CAudioCompression::CT_MSADPCM );
|
||||
SetAudioCompressionOut ( CT_MSADPCM );
|
||||
|
||||
// init time-out for the buffer with zero -> no connection
|
||||
iConTimeOut = 0;
|
||||
|
@ -640,6 +665,26 @@ vecNetwBufferInProps[0].iNetwInBufSize = AudioCompressionIn.Init (
|
|||
|
||||
QObject::connect( &Protocol, SIGNAL ( PingReceived ( int ) ),
|
||||
this, SIGNAL ( PingReceived ( int ) ) );
|
||||
|
||||
QObject::connect ( &Protocol,
|
||||
SIGNAL ( NetTranspPropsReceived ( CNetworkTransportProps ) ),
|
||||
this, SLOT ( OnNetTranspPropsReceived ( CNetworkTransportProps ) ) );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void CChannel::SetEnable ( const bool bNEnStat )
|
||||
|
@ -649,10 +694,11 @@ void CChannel::SetEnable ( const bool bNEnStat )
|
|||
// set internal parameter
|
||||
bIsEnabled = bNEnStat;
|
||||
|
||||
// if channel is not enabled, reset time out count
|
||||
// if channel is not enabled, reset time out count and protocol
|
||||
if ( !bNEnStat )
|
||||
{
|
||||
iConTimeOut = 0;
|
||||
Protocol.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,55 +715,73 @@ void CChannel::SetForceLowUploadRate ( const bool bNFoLoUpRat )
|
|||
bForceLowUploadRate = bNFoLoUpRat;
|
||||
}
|
||||
|
||||
void CChannel::SetNetwInBlSiFactAndCompr ( const int iNewBlockSizeFactor,
|
||||
const CAudioCompression::EAudComprType eNewAudComprType )
|
||||
void CChannel::SetAudioBlockSizeAndComprIn ( const int iNewBlockSize,
|
||||
const EAudComprType eNewAudComprType )
|
||||
{
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// store new value
|
||||
iCurNetwInBlSiFact = iNewBlockSizeFactor;
|
||||
// store block size value
|
||||
iCurAudioBlockSizeIn = iNewBlockSize;
|
||||
|
||||
// init audio compression unit
|
||||
AudioCompressionIn.Init ( iNewBlockSizeFactor * MIN_BLOCK_SIZE_SAMPLES,
|
||||
eNewAudComprType );
|
||||
AudioCompressionIn.Init ( iNewBlockSize, eNewAudComprType );
|
||||
|
||||
// initial value for connection time out counter
|
||||
iConTimeOutStartVal = ( CON_TIME_OUT_SEC_MAX * 1000 ) /
|
||||
( iNewBlockSizeFactor * MIN_BLOCK_DURATION_MS );
|
||||
iConTimeOutStartVal =
|
||||
( CON_TIME_OUT_SEC_MAX * SYSTEM_SAMPLE_RATE ) / iNewBlockSize;
|
||||
}
|
||||
|
||||
// socket buffer must be adjusted
|
||||
SetSockBufSizeIntern ( GetSockBufSize() );
|
||||
void CChannel::SetNetwBufSizeOut ( const int iNewAudioBlockSizeOut )
|
||||
{
|
||||
// this function is intended for the client (not the server)
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// store new value
|
||||
iCurAudioBlockSizeOut = iNewAudioBlockSizeOut;
|
||||
|
||||
iAudComprSizeOut =
|
||||
AudioCompressionOut.Init ( iNewAudioBlockSizeOut, eAudComprTypeOut );
|
||||
}
|
||||
|
||||
void CChannel::SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut )
|
||||
{
|
||||
// this function is intended for the server (not the client)
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
if ( !bForceLowUploadRate )
|
||||
// use the network block size factor only for the server
|
||||
if ( ( !bForceLowUploadRate ) && bIsServer )
|
||||
{
|
||||
// store new value
|
||||
iCurNetwOutBlSiFact = iNewNetwBlSiFactOut;
|
||||
|
||||
// init audio compression and get audio compression block size
|
||||
iAudComprSizeOut = AudioCompressionOut.Init (
|
||||
iNewNetwBlSiFactOut * MIN_BLOCK_SIZE_SAMPLES, eAudComprTypeOut );
|
||||
iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES, eAudComprTypeOut );
|
||||
|
||||
// init conversion buffer
|
||||
ConvBuf.Init ( iNewNetwBlSiFactOut * MIN_BLOCK_SIZE_SAMPLES );
|
||||
ConvBuf.Init ( iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES );
|
||||
}
|
||||
}
|
||||
|
||||
void CChannel::SetAudioCompressionOut ( const CAudioCompression::EAudComprType eNewAudComprTypeOut )
|
||||
void CChannel::SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut )
|
||||
{
|
||||
if ( !bForceLowUploadRate )
|
||||
{
|
||||
// store new value
|
||||
eAudComprTypeOut = eNewAudComprTypeOut;
|
||||
|
||||
// call "set network buffer size factor" function because its initialization
|
||||
// depends on the audio compression format and implicitely, the audio compression
|
||||
// is initialized
|
||||
SetNetwBufSizeFactOut ( iCurNetwOutBlSiFact );
|
||||
if ( bIsServer )
|
||||
{
|
||||
// call "set network buffer size factor" function because its
|
||||
// initialization depends on the audio compression format and
|
||||
// implicitely, the audio compression is initialized
|
||||
SetNetwBufSizeFactOut ( iCurNetwOutBlSiFact );
|
||||
}
|
||||
else
|
||||
{
|
||||
// for client set arbitrary block size
|
||||
SetNetwBufSizeOut ( iCurAudioBlockSizeOut );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -725,21 +789,11 @@ void CChannel::SetSockBufSize ( const int iNumBlocks )
|
|||
{
|
||||
QMutexLocker locker ( &Mutex ); // this opperation must be done with mutex
|
||||
|
||||
SetSockBufSizeIntern ( iNumBlocks );
|
||||
}
|
||||
|
||||
void CChannel::SetSockBufSizeIntern ( const int iNumBlocks )
|
||||
{
|
||||
iCurSockBufSize = iNumBlocks;
|
||||
|
||||
// the idea of setting the jitter buffer is as follows:
|
||||
// The network block size is a multiple of the internal minimal
|
||||
// block size. Therefore, the minimum jitter buffer size must be
|
||||
// so that it can take one network buffer -> NET_BLOCK_SIZE_FACTOR.
|
||||
// The actual jitter compensation are then the additional blocks of
|
||||
// the internal block size, which is set with SetSockBufSize
|
||||
SockBuf.Init ( MIN_BLOCK_SIZE_SAMPLES,
|
||||
iNumBlocks + iCurNetwInBlSiFact );
|
||||
// the network block size is a multiple of the internal minimal
|
||||
// block size
|
||||
SockBuf.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES, iNumBlocks );
|
||||
}
|
||||
|
||||
void CChannel::SetGain ( const int iChanID, const double dNewGain )
|
||||
|
@ -747,7 +801,7 @@ void CChannel::SetGain ( const int iChanID, const double dNewGain )
|
|||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// set value (make sure channel ID is in range)
|
||||
if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) )
|
||||
if ( ( iChanID >= 0 ) && ( iChanID < USED_NUM_CHANNELS ) )
|
||||
{
|
||||
vecdGains[iChanID] = dNewGain;
|
||||
}
|
||||
|
@ -758,7 +812,7 @@ double CChannel::GetGain ( const int iChanID )
|
|||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// get value (make sure channel ID is in range)
|
||||
if ( ( iChanID >= 0 ) && ( iChanID < MAX_NUM_CHANNELS ) )
|
||||
if ( ( iChanID >= 0 ) && ( iChanID < USED_NUM_CHANNELS ) )
|
||||
{
|
||||
return vecdGains[iChanID];
|
||||
}
|
||||
|
@ -801,8 +855,9 @@ QString CChannel::GetName()
|
|||
|
||||
void CChannel::OnSendProtMessage ( CVector<uint8_t> vecMessage )
|
||||
{
|
||||
// only send messages if we are connected, otherwise delete complete queue
|
||||
if ( IsConnected() )
|
||||
// only send messages if protocol is enabled, otherwise delete complete
|
||||
// queue
|
||||
if ( ProtocolIsEnabled() )
|
||||
{
|
||||
// emit message to actually send the data
|
||||
emit MessReadyForSending ( vecMessage );
|
||||
|
@ -810,7 +865,7 @@ void CChannel::OnSendProtMessage ( CVector<uint8_t> vecMessage )
|
|||
else
|
||||
{
|
||||
// delete send message queue
|
||||
Protocol.DeleteSendMessQueue();
|
||||
Protocol.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -834,6 +889,26 @@ void CChannel::OnChangeChanName ( QString strName )
|
|||
SetName ( strName );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps )
|
||||
{
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// TEST
|
||||
// TODO use mutex in Put function
|
||||
// TODO check possiblity of received parameter -> error checking
|
||||
vecNetwBufferInProps[0].iAudioBlockSize = NetworkTransportProps.iMonoAudioBlockSize;
|
||||
vecNetwBufferInProps[0].eAudComprType = NetworkTransportProps.eAudioCodingType;
|
||||
vecNetwBufferInProps[0].iNetwInBufSize = AudioCompressionIn.Init (
|
||||
vecNetwBufferInProps[0].iAudioBlockSize,
|
||||
vecNetwBufferInProps[0].eAudComprType );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool CChannel::GetAddress(CHostAddress& RetAddr)
|
||||
{
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
@ -863,8 +938,8 @@ EPutDataStat CChannel::PutData ( const CVector<unsigned char>& vecbyData,
|
|||
if ( bIsEnabled )
|
||||
{
|
||||
// first check if this is protocol data
|
||||
// only use protocol data if channel is connected
|
||||
if ( IsConnected() )
|
||||
// only use protocol data if protocol mechanism is enabled
|
||||
if ( ProtocolIsEnabled() )
|
||||
{
|
||||
// parse the message assuming this is a protocol message
|
||||
if ( !Protocol.ParseMessage ( vecbyData, iNumBytes ) )
|
||||
|
@ -889,18 +964,18 @@ EPutDataStat CChannel::PutData ( const CVector<unsigned char>& vecbyData,
|
|||
bIsAudioPacket = true;
|
||||
|
||||
// check if we are correctly initialized
|
||||
const int iNewNetwInBlSiFact =
|
||||
vecNetwBufferInProps[i].iBlockSizeFactor;
|
||||
const int iNewAudioBlockSize =
|
||||
vecNetwBufferInProps[i].iAudioBlockSize;
|
||||
|
||||
const CAudioCompression::EAudComprType eNewAudComprType =
|
||||
const EAudComprType eNewAudComprType =
|
||||
vecNetwBufferInProps[i].eAudComprType;
|
||||
|
||||
if ( ( iNewNetwInBlSiFact != iCurNetwInBlSiFact ) ||
|
||||
if ( ( iNewAudioBlockSize != iCurAudioBlockSizeIn ) ||
|
||||
( eNewAudComprType != AudioCompressionIn.GetType() ) )
|
||||
{
|
||||
// re-initialize to new value
|
||||
SetNetwInBlSiFactAndCompr ( iNewNetwInBlSiFact,
|
||||
eNewAudComprType );
|
||||
SetAudioBlockSizeAndComprIn (
|
||||
iNewAudioBlockSize, eNewAudComprType );
|
||||
}
|
||||
|
||||
// in case of a server channel, use the same audio
|
||||
|
@ -915,17 +990,18 @@ EPutDataStat CChannel::PutData ( const CVector<unsigned char>& vecbyData,
|
|||
}
|
||||
}
|
||||
|
||||
// only process if packet has correct size
|
||||
if ( bIsAudioPacket )
|
||||
Mutex.lock();
|
||||
{
|
||||
Mutex.lock();
|
||||
// only process audio if packet has correct size
|
||||
if ( bIsAudioPacket )
|
||||
{
|
||||
// decompress audio
|
||||
CVector<short> vecsDecomprAudio ( AudioCompressionIn.Decode ( vecbyData ) );
|
||||
|
||||
// convert received data from short to double
|
||||
CVector<double> vecdDecomprAudio ( iCurNetwInBlSiFact * MIN_BLOCK_SIZE_SAMPLES );
|
||||
for ( int i = 0; i < iCurNetwInBlSiFact * MIN_BLOCK_SIZE_SAMPLES; i++ )
|
||||
const int iAudioSize = vecsDecomprAudio.Size();
|
||||
CVector<double> vecdDecomprAudio ( iAudioSize );
|
||||
for ( int i = 0; i < iAudioSize; i++ )
|
||||
{
|
||||
vecdDecomprAudio[i] = static_cast<double> ( vecsDecomprAudio[i] );
|
||||
}
|
||||
|
@ -938,21 +1014,28 @@ EPutDataStat CChannel::PutData ( const CVector<unsigned char>& vecbyData,
|
|||
{
|
||||
eRet = PS_AUDIO_ERR;
|
||||
}
|
||||
|
||||
// check if channel was not connected, this is a new connection
|
||||
bNewConnection = !IsConnected();
|
||||
|
||||
// reset time-out counter
|
||||
iConTimeOut = iConTimeOutStartVal;
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// the protocol parsing failed and this was no audio block,
|
||||
// we treat this as protocol error (unkown packet)
|
||||
eRet = PS_PROT_ERR;
|
||||
else
|
||||
{
|
||||
// the protocol parsing failed and this was no audio block,
|
||||
// we treat this as protocol error (unkown packet)
|
||||
eRet = PS_PROT_ERR;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// check if channel was not connected, this is a new connection
|
||||
bNewConnection = !IsConnected();
|
||||
|
||||
// reset time-out counter
|
||||
iConTimeOut = iConTimeOutStartVal;
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
// inform other objects that new connection was established
|
||||
|
@ -1008,13 +1091,22 @@ CVector<unsigned char> CChannel::PrepSendPacket ( const CVector<short>& vecsNPac
|
|||
// tell the following network send routine that nothing should be sent
|
||||
CVector<unsigned char> vecbySendBuf ( 0 );
|
||||
|
||||
// use conversion buffer to convert sound card block size in network
|
||||
// block size
|
||||
if ( ConvBuf.Put ( vecsNPacket ) )
|
||||
if ( bIsServer )
|
||||
{
|
||||
// use conversion buffer to convert sound card block size in network
|
||||
// block size
|
||||
if ( ConvBuf.Put ( vecsNPacket ) )
|
||||
{
|
||||
// a packet is ready, compress audio
|
||||
vecbySendBuf.Init ( iAudComprSizeOut );
|
||||
vecbySendBuf = AudioCompressionOut.Encode ( ConvBuf.Get() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// a packet is ready, compress audio
|
||||
vecbySendBuf.Init ( iAudComprSizeOut );
|
||||
vecbySendBuf = AudioCompressionOut.Encode ( ConvBuf.Get() );
|
||||
vecbySendBuf = AudioCompressionOut.Encode ( vecsNPacket );
|
||||
}
|
||||
|
||||
return vecbySendBuf;
|
||||
|
|
|
@ -64,7 +64,7 @@ enum EGetDataStat
|
|||
};
|
||||
|
||||
// low upload data rate settings
|
||||
#define LOW_UPL_SET_AUDIO_COMPRESSION CAudioCompression::CT_MSADPCM
|
||||
#define LOW_UPL_SET_AUDIO_COMPRESSION CT_MSADPCM
|
||||
#define LOW_UPL_SET_BLOCK_SIZE_FACTOR_OUT MAX_NET_BLOCK_SIZE_FACTOR
|
||||
|
||||
|
||||
|
@ -75,7 +75,9 @@ class CChannel : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CChannel();
|
||||
// we have to make "server" the default since I do not see a chance to
|
||||
// use constructor initialization in the server for a vector of channels
|
||||
CChannel ( const bool bNIsServer = true );
|
||||
virtual ~CChannel() {}
|
||||
|
||||
EPutDataStat PutData ( const CVector<unsigned char>& vecbyData,
|
||||
|
@ -87,7 +89,6 @@ public:
|
|||
bool IsConnected() const { return iConTimeOut > 0; }
|
||||
|
||||
void SetEnable ( const bool bNEnStat );
|
||||
void SetIsServer ( const bool bNIsServer ) { bIsServer = bNIsServer; }
|
||||
void SetForceLowUploadRate ( const bool bNFoLoUpRat );
|
||||
|
||||
void SetAddress ( const CHostAddress NAddr ) { InetAddr = NAddr; }
|
||||
|
@ -109,18 +110,19 @@ public:
|
|||
void SetSockBufSize ( const int iNumBlocks );
|
||||
int GetSockBufSize() { return iCurSockBufSize; }
|
||||
|
||||
// TEST
|
||||
void SetNetwBufSizeOut ( const int iNewAudioBlockSizeOut );
|
||||
|
||||
void SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut );
|
||||
int GetNetwBufSizeFactOut() { return iCurNetwOutBlSiFact; }
|
||||
|
||||
int GetNetwBufSizeFactIn() { return iCurNetwInBlSiFact; }
|
||||
|
||||
void SetAudioCompressionOut ( const CAudioCompression::EAudComprType eNewAudComprTypeOut );
|
||||
CAudioCompression::EAudComprType GetAudioCompressionOut() { return eAudComprTypeOut; }
|
||||
void SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut );
|
||||
EAudComprType GetAudioCompressionOut() { return eAudComprTypeOut; }
|
||||
|
||||
// network protocol interface
|
||||
void CreateJitBufMes ( const int iJitBufSize )
|
||||
{
|
||||
if ( IsConnected() )
|
||||
if ( ProtocolIsEnabled() )
|
||||
{
|
||||
Protocol.CreateJitBufMes ( iJitBufSize );
|
||||
}
|
||||
|
@ -132,7 +134,7 @@ public:
|
|||
|
||||
void CreateNetwBlSiFactMes ( const int iNetwBlSiFact )
|
||||
{
|
||||
if ( IsConnected() )
|
||||
if ( ProtocolIsEnabled() )
|
||||
{
|
||||
Protocol.CreateNetwBlSiFactMes ( iNetwBlSiFact );
|
||||
}
|
||||
|
@ -144,10 +146,10 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void SetNetwInBlSiFactAndCompr ( const int iNewBlockSizeFactor,
|
||||
const CAudioCompression::EAudComprType eNewAudComprType );
|
||||
void SetAudioBlockSizeAndComprIn ( const int iNewBlockSize,
|
||||
const EAudComprType eNewAudComprType );
|
||||
|
||||
void SetSockBufSizeIntern ( const int iNumBlocks );
|
||||
bool ProtocolIsEnabled();
|
||||
|
||||
// audio compression
|
||||
CAudioCompression AudioCompressionIn;
|
||||
|
@ -180,20 +182,21 @@ protected:
|
|||
bool bIsServer;
|
||||
bool bForceLowUploadRate;
|
||||
|
||||
int iCurNetwInBlSiFact;
|
||||
int iCurAudioBlockSizeIn;
|
||||
int iCurNetwOutBlSiFact;
|
||||
int iCurAudioBlockSizeOut;
|
||||
|
||||
QMutex Mutex;
|
||||
|
||||
struct sNetwBufferInProps
|
||||
{
|
||||
int iNetwInBufSize;
|
||||
int iBlockSizeFactor;
|
||||
CAudioCompression::EAudComprType eAudComprType;
|
||||
int iNetwInBufSize;
|
||||
int iAudioBlockSize;
|
||||
EAudComprType eAudComprType;
|
||||
};
|
||||
CVector<sNetwBufferInProps> vecNetwBufferInProps;
|
||||
|
||||
CAudioCompression::EAudComprType eAudComprTypeOut;
|
||||
EAudComprType eAudComprTypeOut;
|
||||
|
||||
public slots:
|
||||
void OnSendProtMessage ( CVector<uint8_t> vecMessage );
|
||||
|
@ -201,6 +204,7 @@ public slots:
|
|||
void OnNetwBlSiFactChange ( int iNewNetwBlSiFact );
|
||||
void OnChangeChanGain ( int iChanID, double dNewGain );
|
||||
void OnChangeChanName ( QString strName );
|
||||
void OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTransportProps );
|
||||
|
||||
signals:
|
||||
void MessReadyForSending ( CVector<uint8_t> vecMessage );
|
||||
|
@ -237,8 +241,7 @@ public:
|
|||
void GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
|
||||
CVector<QString>& vecsName,
|
||||
CVector<int>& veciJitBufSize,
|
||||
CVector<int>& veciNetwOutBlSiFact,
|
||||
CVector<int>& veciNetwInBlSiFact );
|
||||
CVector<int>& veciNetwOutBlSiFact );
|
||||
|
||||
// access functions for actual channels
|
||||
bool IsConnected ( const int iChanNum )
|
||||
|
@ -284,6 +287,10 @@ public slots:
|
|||
void OnSendProtMessCh3 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 3, mess ); }
|
||||
void OnSendProtMessCh4 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 4, mess ); }
|
||||
void OnSendProtMessCh5 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 5, mess ); }
|
||||
void OnSendProtMessCh6 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 6, mess ); }
|
||||
void OnSendProtMessCh7 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 7, mess ); }
|
||||
void OnSendProtMessCh8 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 8, mess ); }
|
||||
void OnSendProtMessCh9 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 9, mess ); }
|
||||
|
||||
void OnNewConnectionCh0() { vecChannels[0].CreateReqJitBufMes(); }
|
||||
void OnNewConnectionCh1() { vecChannels[1].CreateReqJitBufMes(); }
|
||||
|
@ -291,6 +298,10 @@ public slots:
|
|||
void OnNewConnectionCh3() { vecChannels[3].CreateReqJitBufMes(); }
|
||||
void OnNewConnectionCh4() { vecChannels[4].CreateReqJitBufMes(); }
|
||||
void OnNewConnectionCh5() { vecChannels[5].CreateReqJitBufMes(); }
|
||||
void OnNewConnectionCh6() { vecChannels[6].CreateReqJitBufMes(); }
|
||||
void OnNewConnectionCh7() { vecChannels[7].CreateReqJitBufMes(); }
|
||||
void OnNewConnectionCh8() { vecChannels[8].CreateReqJitBufMes(); }
|
||||
void OnNewConnectionCh9() { vecChannels[9].CreateReqJitBufMes(); }
|
||||
|
||||
void OnReqConnClientsListCh0() { CreateAndSendChanListForThisChan ( 0 ); }
|
||||
void OnReqConnClientsListCh1() { CreateAndSendChanListForThisChan ( 1 ); }
|
||||
|
@ -298,6 +309,10 @@ public slots:
|
|||
void OnReqConnClientsListCh3() { CreateAndSendChanListForThisChan ( 3 ); }
|
||||
void OnReqConnClientsListCh4() { CreateAndSendChanListForThisChan ( 4 ); }
|
||||
void OnReqConnClientsListCh5() { CreateAndSendChanListForThisChan ( 5 ); }
|
||||
void OnReqConnClientsListCh6() { CreateAndSendChanListForThisChan ( 6 ); }
|
||||
void OnReqConnClientsListCh7() { CreateAndSendChanListForThisChan ( 7 ); }
|
||||
void OnReqConnClientsListCh8() { CreateAndSendChanListForThisChan ( 8 ); }
|
||||
void OnReqConnClientsListCh9() { CreateAndSendChanListForThisChan ( 9 ); }
|
||||
|
||||
void OnNameHasChangedCh0() { CreateAndSendChanListForAllConChannels(); }
|
||||
void OnNameHasChangedCh1() { CreateAndSendChanListForAllConChannels(); }
|
||||
|
@ -305,6 +320,10 @@ public slots:
|
|||
void OnNameHasChangedCh3() { CreateAndSendChanListForAllConChannels(); }
|
||||
void OnNameHasChangedCh4() { CreateAndSendChanListForAllConChannels(); }
|
||||
void OnNameHasChangedCh5() { CreateAndSendChanListForAllConChannels(); }
|
||||
void OnNameHasChangedCh6() { CreateAndSendChanListForAllConChannels(); }
|
||||
void OnNameHasChangedCh7() { CreateAndSendChanListForAllConChannels(); }
|
||||
void OnNameHasChangedCh8() { CreateAndSendChanListForAllConChannels(); }
|
||||
void OnNameHasChangedCh9() { CreateAndSendChanListForAllConChannels(); }
|
||||
|
||||
void OnChatTextReceivedCh0 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 0, strChatText ); }
|
||||
void OnChatTextReceivedCh1 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 1, strChatText ); }
|
||||
|
@ -312,6 +331,10 @@ public slots:
|
|||
void OnChatTextReceivedCh3 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 3, strChatText ); }
|
||||
void OnChatTextReceivedCh4 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 4, strChatText ); }
|
||||
void OnChatTextReceivedCh5 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 5, strChatText ); }
|
||||
void OnChatTextReceivedCh6 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 6, strChatText ); }
|
||||
void OnChatTextReceivedCh7 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 7, strChatText ); }
|
||||
void OnChatTextReceivedCh8 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 8, strChatText ); }
|
||||
void OnChatTextReceivedCh9 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 9, strChatText ); }
|
||||
|
||||
void OnPingReceivedCh0 ( int iMs ) { vecChannels[0].CreatePingMes ( iMs ); }
|
||||
void OnPingReceivedCh1 ( int iMs ) { vecChannels[1].CreatePingMes ( iMs ); }
|
||||
|
@ -319,6 +342,10 @@ public slots:
|
|||
void OnPingReceivedCh3 ( int iMs ) { vecChannels[3].CreatePingMes ( iMs ); }
|
||||
void OnPingReceivedCh4 ( int iMs ) { vecChannels[4].CreatePingMes ( iMs ); }
|
||||
void OnPingReceivedCh5 ( int iMs ) { vecChannels[5].CreatePingMes ( iMs ); }
|
||||
void OnPingReceivedCh6 ( int iMs ) { vecChannels[6].CreatePingMes ( iMs ); }
|
||||
void OnPingReceivedCh7 ( int iMs ) { vecChannels[7].CreatePingMes ( iMs ); }
|
||||
void OnPingReceivedCh8 ( int iMs ) { vecChannels[8].CreatePingMes ( iMs ); }
|
||||
void OnPingReceivedCh9 ( int iMs ) { vecChannels[9].CreatePingMes ( iMs ); }
|
||||
|
||||
signals:
|
||||
void MessReadyForSending ( int iChID, CVector<uint8_t> vecMessage );
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
/* Implementation *************************************************************/
|
||||
CClient::CClient ( const quint16 iPortNumber ) :
|
||||
Channel ( false ), /* we need a client channel -> "false" */
|
||||
Sound ( AudioCallback, this ),
|
||||
Socket ( &Channel, iPortNumber ),
|
||||
iAudioInFader ( AUD_FADER_IN_MIDDLE ),
|
||||
|
@ -111,7 +112,7 @@ void CClient::OnReceivePingMessage ( int iMs )
|
|||
bool CClient::SetServerAddr ( QString strNAddr )
|
||||
{
|
||||
QHostAddress InetAddr;
|
||||
quint16 iNetPort = LLCON_PORT_NUMBER;
|
||||
quint16 iNetPort = LLCON_DFAULT_PORT_NUMBER;
|
||||
|
||||
// parse input address for the type [IP address]:[port number]
|
||||
QString strPort = strNAddr.section ( ":", 1, 1 );
|
||||
|
@ -189,10 +190,13 @@ void CClient::AudioCallback ( CVector<short>& psData, void* arg )
|
|||
void CClient::Init()
|
||||
{
|
||||
// set block size (in samples)
|
||||
iMonoBlockSizeSam = MIN_BLOCK_SIZE_SAMPLES;
|
||||
|
||||
// TEST
|
||||
iMonoBlockSizeSam = 128;//64;//MIN_SERVER_BLOCK_SIZE_SAMPLES;
|
||||
|
||||
iStereoBlockSizeSam = 2 * iMonoBlockSizeSam;
|
||||
|
||||
iSndCrdMonoBlockSizeSam = MIN_BLOCK_DURATION_MS * SND_CRD_SAMPLE_RATE / 1000;
|
||||
iSndCrdMonoBlockSizeSam = iMonoBlockSizeSam * SND_CRD_SAMPLE_RATE / SYSTEM_SAMPLE_RATE;
|
||||
iSndCrdStereoBlockSizeSam = 2 * iSndCrdMonoBlockSizeSam;
|
||||
|
||||
vecsAudioSndCrdStereo.Init ( iSndCrdStereoBlockSizeSam );
|
||||
|
@ -203,6 +207,11 @@ void CClient::Init()
|
|||
|
||||
Sound.Init ( iSndCrdStereoBlockSizeSam );
|
||||
|
||||
|
||||
// TEST
|
||||
Channel.SetNetwBufSizeOut ( iMonoBlockSizeSam );
|
||||
|
||||
|
||||
// resample objects are always initialized with the input block size
|
||||
// record
|
||||
ResampleObjDown.Init ( iSndCrdMonoBlockSizeSam, SND_CRD_SAMPLE_RATE, SYSTEM_SAMPLE_RATE );
|
||||
|
@ -362,7 +371,7 @@ void CClient::UpdateTimeResponseMeasurement()
|
|||
// we want to calculate the standard deviation (we assume that the mean
|
||||
// is correct at the block period time)
|
||||
const double dCurAddVal =
|
||||
( (double) ( CurTime - TimeLastBlock ) - MIN_BLOCK_DURATION_MS );
|
||||
( (double) ( CurTime - TimeLastBlock ) - MIN_SERVER_BLOCK_DURATION_MS );
|
||||
|
||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
||||
|
||||
|
|
|
@ -101,7 +101,8 @@ public:
|
|||
if ( Channel.GetSockBufSize() != iNumBlocks )
|
||||
{
|
||||
// check for valid values
|
||||
if ( ( iNumBlocks >= 0 ) && ( iNumBlocks <= MAX_NET_BUF_SIZE_NUM_BL ) )
|
||||
if ( ( iNumBlocks >= MIN_NET_BUF_SIZE_NUM_BL ) &&
|
||||
( iNumBlocks <= MAX_NET_BUF_SIZE_NUM_BL ) )
|
||||
{
|
||||
// set the new socket size
|
||||
Channel.SetSockBufSize ( iNumBlocks );
|
||||
|
@ -125,9 +126,9 @@ public:
|
|||
{ Channel.SetNetwBufSizeFactOut ( iNetNetwBlSiFact ); }
|
||||
int GetNetwBufSizeFactOut() { return Channel.GetNetwBufSizeFactOut(); }
|
||||
|
||||
void SetAudioCompressionOut ( const CAudioCompression::EAudComprType eNewAudComprTypeOut )
|
||||
void SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut )
|
||||
{ Channel.SetAudioCompressionOut ( eNewAudComprTypeOut ); }
|
||||
CAudioCompression::EAudComprType GetAudioCompressionOut() { return Channel.GetAudioCompressionOut(); }
|
||||
EAudComprType GetAudioCompressionOut() { return Channel.GetAudioCompressionOut(); }
|
||||
|
||||
void SetRemoteChanGain ( const int iId, const double dGain )
|
||||
{ Channel.SetRemoteChanGain ( iId, dGain ); }
|
||||
|
|
|
@ -52,9 +52,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
|||
"for the audio stream bandwidth, audio dropouts occur and the "
|
||||
"ping time will increase significantly (the connection is stodged)." );
|
||||
SliderNetBufSiFactIn->setWhatsThis ( strNetwBlockSize );
|
||||
SliderNetBufSiFactOut->setWhatsThis ( strNetwBlockSize );
|
||||
TextNetBufSiFactIn->setWhatsThis ( strNetwBlockSize );
|
||||
TextNetBufSiFactOut->setWhatsThis ( strNetwBlockSize );
|
||||
GroupBoxNetwBuf->setWhatsThis ( strNetwBlockSize );
|
||||
|
||||
// init delay information controls
|
||||
|
@ -65,24 +63,8 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
|||
TextLabelOverallDelay->setText ( "" );
|
||||
|
||||
// init slider controls ---
|
||||
// sound buffer in
|
||||
#ifdef _WIN32
|
||||
SliderSndBufIn->setRange ( 1, AUD_SLIDER_LENGTH ); // for ASIO we only need one buffer
|
||||
#else
|
||||
SliderSndBufIn->setRange ( 2, AUD_SLIDER_LENGTH );
|
||||
#endif
|
||||
UpdateSndBufInSlider ( pClient->GetSndInterface()->GetInNumBuf() );
|
||||
|
||||
// sound buffer out
|
||||
#ifdef _WIN32
|
||||
SliderSndBufOut->setRange ( 1, AUD_SLIDER_LENGTH ); // for ASIO we only need one buffer
|
||||
#else
|
||||
SliderSndBufOut->setRange ( 2, AUD_SLIDER_LENGTH );
|
||||
#endif
|
||||
UpdateSndBufOutSlider ( pClient->GetSndInterface()->GetOutNumBuf() );
|
||||
|
||||
// network buffer
|
||||
SliderNetBuf->setRange ( 0, MAX_NET_BUF_SIZE_NUM_BL );
|
||||
SliderNetBuf->setRange ( MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL );
|
||||
UpdateJitterBufferFrame();
|
||||
|
||||
// network buffer size factor in
|
||||
|
@ -90,15 +72,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
|||
const int iCurNetBufSiFactIn = pClient->GetNetwBufSizeFactIn();
|
||||
SliderNetBufSiFactIn->setValue ( iCurNetBufSiFactIn );
|
||||
TextNetBufSiFactIn->setText ( "In:\n" + QString().setNum (
|
||||
double ( iCurNetBufSiFactIn * MIN_BLOCK_DURATION_MS ), 'f', 2 ) +
|
||||
" ms" );
|
||||
|
||||
// network buffer size factor out
|
||||
SliderNetBufSiFactOut->setRange ( 1, MAX_NET_BLOCK_SIZE_FACTOR );
|
||||
const int iCurNetBufSiFactOut = pClient->GetNetwBufSizeFactOut();
|
||||
SliderNetBufSiFactOut->setValue ( iCurNetBufSiFactOut );
|
||||
TextNetBufSiFactOut->setText ( "Out:\n" + QString().setNum (
|
||||
double ( iCurNetBufSiFactOut * MIN_BLOCK_DURATION_MS), 'f', 2 ) +
|
||||
double ( iCurNetBufSiFactIn * MIN_SERVER_BLOCK_DURATION_MS ), 'f', 2 ) +
|
||||
" ms" );
|
||||
|
||||
// init combo box containing all available sound cards in the system
|
||||
|
@ -122,15 +96,15 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
|||
// audio compression type
|
||||
switch ( pClient->GetAudioCompressionOut() )
|
||||
{
|
||||
case CAudioCompression::CT_NONE:
|
||||
case CT_NONE:
|
||||
radioButtonNoAudioCompr->setChecked ( true );
|
||||
break;
|
||||
|
||||
case CAudioCompression::CT_IMAADPCM:
|
||||
case CT_IMAADPCM:
|
||||
radioButtonIMA_ADPCM->setChecked ( true );
|
||||
break;
|
||||
|
||||
case CAudioCompression::CT_MSADPCM:
|
||||
case CT_MSADPCM:
|
||||
radioButtonMS_ADPCM->setChecked ( true );
|
||||
break;
|
||||
}
|
||||
|
@ -146,19 +120,11 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
|||
QObject::connect ( &TimerPing, SIGNAL ( timeout() ),
|
||||
this, SLOT ( OnTimerPing() ) );
|
||||
|
||||
// sliders
|
||||
QObject::connect ( SliderSndBufIn, SIGNAL ( valueChanged ( int ) ),
|
||||
this, SLOT ( OnSliderSndBufInChange ( int ) ) );
|
||||
QObject::connect ( SliderSndBufOut, SIGNAL ( valueChanged ( int ) ),
|
||||
this, SLOT ( OnSliderSndBufOutChange ( int ) ) );
|
||||
|
||||
QObject::connect ( SliderNetBuf, SIGNAL ( valueChanged ( int ) ),
|
||||
this, SLOT ( OnSliderNetBuf ( int ) ) );
|
||||
|
||||
QObject::connect ( SliderNetBufSiFactIn, SIGNAL ( valueChanged ( int ) ),
|
||||
this, SLOT ( OnSliderNetBufSiFactIn ( int ) ) );
|
||||
QObject::connect ( SliderNetBufSiFactOut, SIGNAL ( valueChanged ( int ) ),
|
||||
this, SLOT ( OnSliderNetBufSiFactOut ( int ) ) );
|
||||
|
||||
// check boxes
|
||||
QObject::connect ( cbOpenChatOnNewMessage, SIGNAL ( stateChanged ( int ) ),
|
||||
|
@ -196,18 +162,6 @@ void CClientSettingsDlg::UpdateJitterBufferFrame()
|
|||
TextNetBuf->setEnabled ( !pClient->GetDoAutoSockBufSize() );
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::UpdateSndBufInSlider ( const int iCurNumInBuf )
|
||||
{
|
||||
SliderSndBufIn->setValue ( iCurNumInBuf );
|
||||
TextSndBufIn->setText ( "In: " + QString().setNum ( iCurNumInBuf ) );
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::UpdateSndBufOutSlider ( const int iCurNumOutBuf )
|
||||
{
|
||||
SliderSndBufOut->setValue ( iCurNumOutBuf );
|
||||
TextSndBufOut->setText ( "Out: " + QString().setNum ( iCurNumOutBuf ) );
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::showEvent ( QShowEvent* showEvent )
|
||||
{
|
||||
// only activate ping timer if window is actually shown
|
||||
|
@ -220,20 +174,6 @@ void CClientSettingsDlg::hideEvent ( QHideEvent* hideEvent )
|
|||
TimerPing.stop();
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::OnSliderSndBufInChange ( int value )
|
||||
{
|
||||
pClient->GetSndInterface()->SetInNumBuf ( value );
|
||||
TextSndBufIn->setText ( "In: " + QString().setNum ( value ) );
|
||||
UpdateDisplay();
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::OnSliderSndBufOutChange ( int value )
|
||||
{
|
||||
pClient->GetSndInterface()->SetOutNumBuf ( value );
|
||||
TextSndBufOut->setText ( "Out: " + QString().setNum ( value ) );
|
||||
UpdateDisplay();
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::OnSliderNetBuf ( int value )
|
||||
{
|
||||
pClient->SetSockBufSize ( value );
|
||||
|
@ -245,16 +185,7 @@ void CClientSettingsDlg::OnSliderNetBufSiFactIn ( int value )
|
|||
{
|
||||
pClient->SetNetwBufSizeFactIn ( value );
|
||||
TextNetBufSiFactIn->setText ( "In:\n" + QString().setNum (
|
||||
double ( value * MIN_BLOCK_DURATION_MS ), 'f', 2 ) +
|
||||
" ms" );
|
||||
UpdateDisplay();
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::OnSliderNetBufSiFactOut ( int value )
|
||||
{
|
||||
pClient->SetNetwBufSizeFactOut ( value );
|
||||
TextNetBufSiFactOut->setText ( "Out:\n" + QString().setNum (
|
||||
double ( value * MIN_BLOCK_DURATION_MS ), 'f', 2 ) +
|
||||
double ( value * MIN_SERVER_BLOCK_DURATION_MS ), 'f', 2 ) +
|
||||
" ms" );
|
||||
UpdateDisplay();
|
||||
}
|
||||
|
@ -294,17 +225,17 @@ void CClientSettingsDlg::OnAudioCompressionButtonGroupClicked ( QAbstractButton*
|
|||
{
|
||||
if ( button == radioButtonNoAudioCompr )
|
||||
{
|
||||
pClient->SetAudioCompressionOut ( CAudioCompression::CT_NONE );
|
||||
pClient->SetAudioCompressionOut ( CT_NONE );
|
||||
}
|
||||
|
||||
if ( button == radioButtonIMA_ADPCM )
|
||||
{
|
||||
pClient->SetAudioCompressionOut ( CAudioCompression::CT_IMAADPCM );
|
||||
pClient->SetAudioCompressionOut ( CT_IMAADPCM );
|
||||
}
|
||||
|
||||
if ( button == radioButtonMS_ADPCM )
|
||||
{
|
||||
pClient->SetAudioCompressionOut ( CAudioCompression::CT_MSADPCM );
|
||||
pClient->SetAudioCompressionOut ( CT_MSADPCM );
|
||||
}
|
||||
UpdateDisplay();
|
||||
}
|
||||
|
@ -322,17 +253,17 @@ void CClientSettingsDlg::OnPingTimeResult ( int iPingTime )
|
|||
- the mean delay of a cyclic buffer is half the buffer size (since
|
||||
for the average it is assumed that the buffer is half filled)
|
||||
- consider the jitter buffer on the server side, too
|
||||
- assume that the sound card introduces an additional delay of 2 * MIN_BLOCK_DURATION_MS
|
||||
- assume that the sound card introduces an additional delay of 2 * MIN_SERVER_BLOCK_DURATION_MS
|
||||
*/
|
||||
const int iTotalJitterBufferDelayMS = MIN_BLOCK_DURATION_MS *
|
||||
const int iTotalJitterBufferDelayMS = MIN_SERVER_BLOCK_DURATION_MS *
|
||||
( 2 * pClient->GetSockBufSize() + pClient->GetNetwBufSizeFactIn() +
|
||||
pClient->GetNetwBufSizeFactOut() ) / 2;
|
||||
|
||||
const int iTotalSoundCardDelayMS = 2 * MIN_BLOCK_DURATION_MS +
|
||||
MIN_BLOCK_DURATION_MS * ( pClient->GetSndInterface()->GetInNumBuf() +
|
||||
const int iTotalSoundCardDelayMS = 2 * MIN_SERVER_BLOCK_DURATION_MS +
|
||||
MIN_SERVER_BLOCK_DURATION_MS * ( pClient->GetSndInterface()->GetInNumBuf() +
|
||||
pClient->GetSndInterface()->GetOutNumBuf() ) / 2;
|
||||
|
||||
const int iDelayToFillNetworkPackets = MIN_BLOCK_DURATION_MS *
|
||||
const int iDelayToFillNetworkPackets = MIN_SERVER_BLOCK_DURATION_MS *
|
||||
( pClient->GetNetwBufSizeFactIn() + pClient->GetNetwBufSizeFactOut() );
|
||||
|
||||
const int iTotalBufferDelay = iDelayToFillNetworkPackets +
|
||||
|
@ -375,9 +306,7 @@ void CClientSettingsDlg::OnPingTimeResult ( int iPingTime )
|
|||
|
||||
void CClientSettingsDlg::UpdateDisplay()
|
||||
{
|
||||
// update slider controls (settings might have been changed by sound interface)
|
||||
UpdateSndBufInSlider ( pClient->GetSndInterface()->GetInNumBuf() );
|
||||
UpdateSndBufOutSlider ( pClient->GetSndInterface()->GetOutNumBuf() );
|
||||
// update slider controls (settings might have been changed)
|
||||
UpdateJitterBufferFrame();
|
||||
|
||||
if ( !pClient->IsRunning() )
|
||||
|
@ -393,6 +322,7 @@ void CClientSettingsDlg::SetStatus ( const int iMessType, const int iStatus )
|
|||
{
|
||||
switch ( iMessType )
|
||||
{
|
||||
/*
|
||||
case MS_SOUND_IN:
|
||||
CLEDSoundIn->SetLight ( iStatus );
|
||||
break;
|
||||
|
@ -400,6 +330,7 @@ void CClientSettingsDlg::SetStatus ( const int iMessType, const int iStatus )
|
|||
case MS_SOUND_OUT:
|
||||
CLEDSoundOut->SetLight ( iStatus );
|
||||
break;
|
||||
*/
|
||||
|
||||
case MS_JIT_BUF_PUT:
|
||||
CLEDNetwPut->SetLight ( iStatus );
|
||||
|
@ -410,8 +341,10 @@ void CClientSettingsDlg::SetStatus ( const int iMessType, const int iStatus )
|
|||
break;
|
||||
|
||||
case MS_RESET_ALL:
|
||||
/*
|
||||
CLEDSoundIn->Reset();
|
||||
CLEDSoundOut->Reset();
|
||||
*/
|
||||
CLEDNetwPut->Reset();
|
||||
CLEDNetwGet->Reset();
|
||||
break;
|
||||
|
|
|
@ -72,18 +72,13 @@ protected:
|
|||
virtual void showEvent ( QShowEvent* showEvent );
|
||||
virtual void hideEvent ( QHideEvent* hideEvent );
|
||||
|
||||
void UpdateSndBufInSlider ( const int iCurNumInBuf );
|
||||
void UpdateSndBufOutSlider ( const int iCurNumOutBuf );
|
||||
void UpdateJitterBufferFrame();
|
||||
|
||||
public slots:
|
||||
void OnTimerStatus() { UpdateDisplay(); }
|
||||
void OnTimerPing();
|
||||
void OnSliderSndBufInChange ( int value );
|
||||
void OnSliderSndBufOutChange ( int value );
|
||||
void OnSliderNetBuf ( int value );
|
||||
void OnSliderNetBufSiFactIn ( int value );
|
||||
void OnSliderNetBufSiFactOut ( int value );
|
||||
void OnAutoJitBuf ( int value );
|
||||
void OnOpenChatOnNewMessageStateChanged ( int value );
|
||||
void OnAudioCompressionButtonGroupClicked ( QAbstractButton* button );
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>544</width>
|
||||
<height>306</height>
|
||||
<width>421</width>
|
||||
<height>313</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
|
@ -286,426 +286,6 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="TextNetBufSiFactOut" >
|
||||
<property name="text" >
|
||||
<string>Size</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="SliderNetBufSiFactOut" >
|
||||
<property name="pageStep" >
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="tickPosition" >
|
||||
<enum>QSlider::TicksBothSides</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="TextLabel2_2" >
|
||||
<property name="text" >
|
||||
<string>Check Ping</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="TextLabel2_3" >
|
||||
<property name="text" >
|
||||
<string>Time!</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="GroupBoxSoundCardBuffers" >
|
||||
<property name="title" >
|
||||
<string>Soundcard Buffers</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="TextSndBufOut" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Out</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="SliderSndBufOut" >
|
||||
<property name="pageStep" >
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="tickPosition" >
|
||||
<enum>QSlider::TicksBothSides</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="TextSndBufIn" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Minimum" hsizetype="MinimumExpanding" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>In</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="SliderSndBufIn" >
|
||||
<property name="pageStep" >
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="tickPosition" >
|
||||
<enum>QSlider::TicksBothSides</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="TextLabel1" >
|
||||
<property name="text" >
|
||||
<string>Out / In:</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="CMultiColorLED" native="1" name="CLEDSoundOut" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="CMultiColorLED" native="1" name="CLEDSoundIn" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>13</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
35
src/global.h
35
src/global.h
|
@ -43,7 +43,7 @@
|
|||
|
||||
// version and application name (always use this version)
|
||||
#undef VERSION
|
||||
#define VERSION "2.1.5cvs"
|
||||
#define VERSION "2.2.0cvs"
|
||||
#define APP_NAME "llcon"
|
||||
|
||||
// file name for logging file
|
||||
|
@ -53,7 +53,7 @@
|
|||
#define DEFAULT_SERVER_ADDRESS "llcon.dyndns.org"
|
||||
|
||||
// defined port number for client and server
|
||||
#define LLCON_PORT_NUMBER 22122
|
||||
#define LLCON_DFAULT_PORT_NUMBER 22122
|
||||
|
||||
// system sample rate
|
||||
#define SYSTEM_SAMPLE_RATE 24000
|
||||
|
@ -62,11 +62,18 @@
|
|||
// internal sample rate conversion which might be buggy
|
||||
#define SND_CRD_SAMPLE_RATE 48000
|
||||
|
||||
// minimum block duration - all other buffer durations must be a multiple
|
||||
// minimum server block duration - all other buffer durations must be a multiple
|
||||
// of this duration
|
||||
#define MIN_BLOCK_DURATION_MS 2 // ms
|
||||
#define MIN_SERVER_BLOCK_DURATION_MS 2 // ms
|
||||
|
||||
#define MIN_BLOCK_SIZE_SAMPLES ( MIN_BLOCK_DURATION_MS * SYSTEM_SAMPLE_RATE / 1000 )
|
||||
#define MIN_SERVER_BLOCK_SIZE_SAMPLES ( MIN_SERVER_BLOCK_DURATION_MS * SYSTEM_SAMPLE_RATE / 1000 )
|
||||
|
||||
// define the maximum mono audio buffer size at a sample rate
|
||||
// of 48 kHz, this is important for defining the maximum number
|
||||
// of bytes to be expected from the network interface (we assume
|
||||
// here that "MAX_NET_BLOCK_SIZE_FACTOR * MIN_SERVER_BLOCK_SIZE_SAMPLES"
|
||||
// is smaller than this value here)
|
||||
#define MAX_MONO_AUD_BUFF_SIZE_AT_48KHZ 4096
|
||||
|
||||
// maximum value of factor for network block size
|
||||
#define MAX_NET_BLOCK_SIZE_FACTOR 3
|
||||
|
@ -74,8 +81,9 @@
|
|||
// default network block size factor
|
||||
#define DEF_NET_BLOCK_SIZE_FACTOR 3
|
||||
|
||||
// maximum network buffer size (which can be chosen by slider)
|
||||
#define MAX_NET_BUF_SIZE_NUM_BL 12 // number of blocks
|
||||
// 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
|
||||
|
||||
// default network buffer size
|
||||
#define DEF_NET_BUF_SIZE_NUM_BL 6 // number of blocks
|
||||
|
@ -88,17 +96,22 @@
|
|||
#define MAX_NUMBER_SOUND_CARDS 10
|
||||
#define INVALID_SNC_CARD_DEVICE -1
|
||||
|
||||
|
||||
// maximum number of internet connections (channels)
|
||||
// if you want to change this paramter, there has to be done code modifications
|
||||
// on other places, too! The code tag "MAX_NUM_CHANNELS_TAG" shows these places
|
||||
// (just search for the tag in the entire code)
|
||||
// note: since in the protocol messages the channel ID is only a byte, a
|
||||
// maximum of 8 channels are possible, see e.g. "PROTMESSID_CHANNEL_GAIN"!
|
||||
#define MAX_NUM_CHANNELS 6 // max number channels for server
|
||||
#define MAX_NUM_CHANNELS 10 // max number channels for server
|
||||
|
||||
// actual number of used channels in the server
|
||||
// this parameter can safely be changed from 1 to MAX_NUM_CHANNELS
|
||||
// without any other changes in the code
|
||||
#define USED_NUM_CHANNELS 6 // used number channels for server
|
||||
|
||||
|
||||
// length of the moving average buffer for response time measurement
|
||||
#define TIME_MOV_AV_RESPONSE 30 // seconds
|
||||
#define LEN_MOV_AV_RESPONSE ( TIME_MOV_AV_RESPONSE * 1000 / MIN_BLOCK_DURATION_MS )
|
||||
#define LEN_MOV_AV_RESPONSE ( TIME_MOV_AV_RESPONSE * 1000 / MIN_SERVER_BLOCK_DURATION_MS )
|
||||
|
||||
// GUI definition: width/heigth size of LED pixmaps
|
||||
#define LED_WIDTH_HEIGHT_SIZE_PIXEL 13
|
||||
|
|
|
@ -45,22 +45,13 @@ CLlconServerDlg::CLlconServerDlg ( CServer* pNServP, QWidget* parent )
|
|||
|
||||
// set up list view for connected clients
|
||||
ListViewClients->setColumnWidth ( 0, 170 );
|
||||
|
||||
// TODO QT4
|
||||
|
||||
// ListViewClients->setColumnAlignment ( 1, Qt::AlignLeft );
|
||||
ListViewClients->setColumnWidth ( 1, 150 );
|
||||
// ListViewClients->setColumnAlignment ( 2, Qt::AlignCenter );
|
||||
// ListViewClients->setColumnAlignment ( 3, Qt::AlignCenter );
|
||||
// ListViewClients->setColumnAlignment ( 4, Qt::AlignRight );
|
||||
// ListViewClients->setColumnAlignment ( 5, Qt::AlignRight );
|
||||
// ListViewClients->setColumnAlignment ( 6, Qt::AlignRight );
|
||||
ListViewClients->clear();
|
||||
|
||||
/* insert items in reverse order because in Windows all of them are
|
||||
always visible -> put first item on the top */
|
||||
vecpListViewItems.Init(MAX_NUM_CHANNELS);
|
||||
for ( int i = MAX_NUM_CHANNELS - 1; i >= 0; i-- )
|
||||
// insert items in reverse order because in Windows all of them are
|
||||
// always visible -> put first item on the top
|
||||
vecpListViewItems.Init ( USED_NUM_CHANNELS );
|
||||
for ( int i = USED_NUM_CHANNELS - 1; i >= 0; i-- )
|
||||
{
|
||||
vecpListViewItems[i] = new CServerListViewItem ( ListViewClients );
|
||||
vecpListViewItems[i]->setHidden ( true );
|
||||
|
@ -94,16 +85,15 @@ void CLlconServerDlg::OnTimer()
|
|||
CVector<QString> vecsName;
|
||||
CVector<int> veciJitBufSize;
|
||||
CVector<int> veciNetwOutBlSiFact;
|
||||
CVector<int> veciNetwInBlSiFact;
|
||||
double dCurTiStdDev;
|
||||
|
||||
ListViewMutex.lock();
|
||||
|
||||
pServer->GetConCliParam ( vecHostAddresses, vecsName, veciJitBufSize,
|
||||
veciNetwOutBlSiFact, veciNetwInBlSiFact );
|
||||
veciNetwOutBlSiFact );
|
||||
|
||||
// fill list with connected clients
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
|
||||
{
|
||||
if ( !( vecHostAddresses[i].InetAddr == QHostAddress ( (quint32) 0 ) ) )
|
||||
{
|
||||
|
@ -119,13 +109,10 @@ void CLlconServerDlg::OnTimer()
|
|||
vecpListViewItems[i]->setText ( 4,
|
||||
QString().setNum ( veciJitBufSize[i] ) );
|
||||
|
||||
// in/out network block sizes
|
||||
// out network block size
|
||||
vecpListViewItems[i]->setText ( 5,
|
||||
QString().setNum (
|
||||
double ( veciNetwInBlSiFact[i] * MIN_BLOCK_DURATION_MS ), 'f', 2 ) );
|
||||
vecpListViewItems[i]->setText ( 6,
|
||||
QString().setNum (
|
||||
double ( veciNetwOutBlSiFact[i] * MIN_BLOCK_DURATION_MS ), 'f', 2 ) );
|
||||
double ( veciNetwOutBlSiFact[i] * MIN_SERVER_BLOCK_DURATION_MS ), 'f', 2 ) );
|
||||
|
||||
vecpListViewItems[i]->setHidden ( false );
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>699</width>
|
||||
<height>291</height>
|
||||
<width>767</width>
|
||||
<height>280</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
|
@ -19,12 +19,21 @@
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="ListViewClients" >
|
||||
<property name="rootIsDecorated" >
|
||||
|
@ -55,11 +64,6 @@
|
|||
<string>Jitter buffer size</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text" >
|
||||
<string>Block Size In</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text" >
|
||||
<string>Block Size Out</string>
|
||||
|
@ -69,12 +73,21 @@
|
|||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="TextLabelNameVersion" >
|
||||
<property name="text" >
|
||||
|
|
22
src/main.cpp
22
src/main.cpp
|
@ -46,7 +46,7 @@ int main ( int argc, char** argv )
|
|||
bool bIsClient = true;
|
||||
bool bUseGUI = true;
|
||||
bool bForceLowUploadRate = false;
|
||||
quint16 iPortNumber = LLCON_PORT_NUMBER;
|
||||
quint16 iPortNumber = LLCON_DFAULT_PORT_NUMBER;
|
||||
std::string strIniFileName = "";
|
||||
std::string strHTMLStatusFileName = "";
|
||||
std::string strServerName = "";
|
||||
|
@ -61,7 +61,7 @@ int main ( int argc, char** argv )
|
|||
if ( GetFlagArgument ( argc, argv, i, "-s", "--server" ) )
|
||||
{
|
||||
bIsClient = false;
|
||||
cerr << "server mode chosen" << std::endl;
|
||||
cout << "server mode chosen" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ int main ( int argc, char** argv )
|
|||
if ( GetFlagArgument ( argc, argv, i, "-n", "--nogui" ) )
|
||||
{
|
||||
bUseGUI = false;
|
||||
cerr << "no GUI mode chosen" << std::endl;
|
||||
cout << "no GUI mode chosen" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ int main ( int argc, char** argv )
|
|||
if ( GetStringArgument ( argc, argv, i, "-l", "--log", strArgument ) )
|
||||
{
|
||||
strLoggingFileName = strArgument;
|
||||
cerr << "logging file name: " << strLoggingFileName << std::endl;
|
||||
cout << "logging file name: " << strLoggingFileName << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ int main ( int argc, char** argv )
|
|||
if ( GetFlagArgument ( argc, argv, i, "-u", "--lowuploadrate" ) )
|
||||
{
|
||||
bForceLowUploadRate = true;
|
||||
cerr << "force low upload rate" << std::endl;
|
||||
cout << "force low upload rate" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ int main ( int argc, char** argv )
|
|||
0, 65535, rDbleArgument ) )
|
||||
{
|
||||
iPortNumber = static_cast<quint16> ( rDbleArgument );
|
||||
cerr << "selected port number: " << iPortNumber << std::endl;
|
||||
cout << "selected port number: " << iPortNumber << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -102,14 +102,14 @@ int main ( int argc, char** argv )
|
|||
if ( GetStringArgument ( argc, argv, i, "-m", "--htmlstatus", strArgument ) )
|
||||
{
|
||||
strHTMLStatusFileName = strArgument;
|
||||
cerr << "HTML status file name: " << strHTMLStatusFileName << std::endl;
|
||||
cout << "HTML status file name: " << strHTMLStatusFileName << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( GetStringArgument ( argc, argv, i, "-a", "--servername", strArgument ) )
|
||||
{
|
||||
strServerName = strArgument;
|
||||
cerr << "server name for HTML status file: " << strServerName << std::endl;
|
||||
cout << "server name for HTML status file: " << strServerName << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ int main ( int argc, char** argv )
|
|||
if ( GetStringArgument ( argc, argv, i, "-i", "--inifile", strArgument ) )
|
||||
{
|
||||
strIniFileName = strArgument;
|
||||
cerr << "initialization file name: " << strIniFileName << std::endl;
|
||||
cout << "initialization file name: " << strIniFileName << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ int main ( int argc, char** argv )
|
|||
( !strcmp ( argv[i], "-h" ) ) || ( !strcmp ( argv[i], "-?" ) ) )
|
||||
{
|
||||
const std::string strHelp = UsageArguments(argv);
|
||||
cerr << strHelp;
|
||||
cout << strHelp;
|
||||
exit ( 1 );
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,7 @@ int main ( int argc, char** argv )
|
|||
else
|
||||
{
|
||||
// only start application without using the GUI
|
||||
qDebug() << CAboutDlg::GetVersionAndNameStr ( false );
|
||||
cout << CAboutDlg::GetVersionAndNameStr ( false ).toStdString();
|
||||
app.exec();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,16 +147,28 @@ MESSAGES
|
|||
|
||||
|
||||
/* Implementation *************************************************************/
|
||||
CProtocol::CProtocol() : iCounter ( 0 ), iOldRecID ( PROTMESSID_ILLEGAL ),
|
||||
iOldRecCnt ( 0 )
|
||||
CProtocol::CProtocol()
|
||||
{
|
||||
SendMessQueue.clear();
|
||||
Reset();
|
||||
|
||||
// connections
|
||||
QObject::connect ( &TimerSendMess, SIGNAL ( timeout() ),
|
||||
this, SLOT ( OnTimerSendMess() ) );
|
||||
}
|
||||
|
||||
void CProtocol::Reset()
|
||||
{
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// prepare internal variables for initial protocol transfer
|
||||
iCounter = 0;
|
||||
iOldRecID = PROTMESSID_ILLEGAL;
|
||||
iOldRecCnt = 0;
|
||||
|
||||
// delete complete "send message queue"
|
||||
SendMessQueue.clear();
|
||||
}
|
||||
|
||||
void CProtocol::EnqueueMessage ( CVector<uint8_t>& vecMessage,
|
||||
const int iCnt,
|
||||
const int iID )
|
||||
|
@ -259,14 +271,6 @@ void CProtocol::CreateAndSendAcknMess ( const int& iID, const int& iCnt )
|
|||
emit MessReadyForSending ( vecAcknMessage );
|
||||
}
|
||||
|
||||
void CProtocol::DeleteSendMessQueue()
|
||||
{
|
||||
QMutexLocker locker ( &Mutex );
|
||||
|
||||
// delete complete "send message queue"
|
||||
SendMessQueue.clear();
|
||||
}
|
||||
|
||||
bool CProtocol::ParseMessage ( const CVector<unsigned char>& vecbyData,
|
||||
const int iNumBytes )
|
||||
{
|
||||
|
@ -315,18 +319,18 @@ for ( int i = 0; i < iNumBytes; i++ ) {
|
|||
Mutex.lock();
|
||||
{
|
||||
// check if this is the correct acknowledgment
|
||||
if ( ( SendMessQueue.front().iCnt == iRecCounter ) &&
|
||||
( SendMessQueue.front().iID == iData ) )
|
||||
bSendNextMess = false;
|
||||
if ( !SendMessQueue.empty() )
|
||||
{
|
||||
// message acknowledged, remove from queue
|
||||
SendMessQueue.pop_front();
|
||||
if ( ( SendMessQueue.front().iCnt == iRecCounter ) &&
|
||||
( SendMessQueue.front().iID == iData ) )
|
||||
{
|
||||
// message acknowledged, remove from queue
|
||||
SendMessQueue.pop_front();
|
||||
|
||||
// send next message in queue
|
||||
bSendNextMess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendNextMess = false;
|
||||
// send next message in queue
|
||||
bSendNextMess = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
@ -878,9 +882,9 @@ bool CProtocol::EvaluateNetwTranspPropsMes ( const CVector<uint8_t>& vecData )
|
|||
const int iRecCodingType =
|
||||
static_cast<unsigned short> ( GetValFromStream ( vecData, iPos, 2 ) );
|
||||
|
||||
if ( ( iRecCodingType != CNetworkTransportProps::ACT_NONE ) &&
|
||||
( iRecCodingType != CNetworkTransportProps::ACT_IMA_ADPCM ) &&
|
||||
( iRecCodingType != CNetworkTransportProps::ACT_MS_ADPCM ) )
|
||||
if ( ( iRecCodingType != CT_NONE ) &&
|
||||
( iRecCodingType != CT_IMAADPCM ) &&
|
||||
( iRecCodingType != CT_MSADPCM ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ class CProtocol : public QObject
|
|||
public:
|
||||
CProtocol();
|
||||
|
||||
void Reset();
|
||||
|
||||
void CreateJitBufMes ( const int iJitBufSize );
|
||||
void CreateReqJitBufMes();
|
||||
void CreateNetwBlSiFactMes ( const int iNetwBlSiFact );
|
||||
|
@ -86,8 +88,6 @@ public:
|
|||
bool ParseMessage ( const CVector<unsigned char>& vecbyData,
|
||||
const int iNumBytes );
|
||||
|
||||
void DeleteSendMessQueue();
|
||||
|
||||
protected:
|
||||
class CSendMessage
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ CServer::CServer ( const QString& strLoggingFileName,
|
|||
Socket ( &ChannelSet, this, iPortNumber ),
|
||||
ChannelSet ( bForceLowUploadRate )
|
||||
{
|
||||
vecsSendData.Init ( MIN_BLOCK_SIZE_SAMPLES );
|
||||
vecsSendData.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
|
||||
|
||||
// init moving average buffer for response time evaluation
|
||||
RespTimeMoAvBuf.Init ( LEN_MOV_AV_RESPONSE );
|
||||
|
@ -103,7 +103,7 @@ void CServer::Start()
|
|||
if ( !IsRunning() )
|
||||
{
|
||||
// start main timer
|
||||
Timer.start ( MIN_BLOCK_DURATION_MS );
|
||||
Timer.start ( MIN_SERVER_BLOCK_DURATION_MS );
|
||||
|
||||
// init time for response time evaluation
|
||||
TimeLastBlock = PreciseTime.elapsed();
|
||||
|
@ -137,7 +137,7 @@ void CServer::OnNewChannel ( CHostAddress ChanAddr )
|
|||
void CServer::OnTimer()
|
||||
{
|
||||
CVector<int> vecChanID;
|
||||
CVector<CVector<double> > vecvecdData ( MIN_BLOCK_SIZE_SAMPLES );
|
||||
CVector<CVector<double> > vecvecdData ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
|
||||
CVector<CVector<double> > vecvecdGains;
|
||||
|
||||
// get data from all connected clients
|
||||
|
@ -178,7 +178,7 @@ void CServer::OnTimer()
|
|||
// we want to calculate the standard deviation (we assume that the mean
|
||||
// is correct at the block period time)
|
||||
const double dCurAddVal =
|
||||
( (double) ( CurTime - TimeLastBlock ) - MIN_BLOCK_DURATION_MS );
|
||||
( (double) ( CurTime - TimeLastBlock ) - MIN_SERVER_BLOCK_DURATION_MS );
|
||||
|
||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
||||
|
||||
|
@ -189,7 +189,7 @@ void CServer::OnTimer()
|
|||
CVector<short> CServer::ProcessData ( CVector<CVector<double> >& vecvecdData,
|
||||
CVector<double>& vecdGains )
|
||||
{
|
||||
CVector<short> vecsOutData ( MIN_BLOCK_SIZE_SAMPLES );
|
||||
CVector<short> vecsOutData ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
|
||||
|
||||
const int iNumClients = vecvecdData.Size();
|
||||
|
||||
|
@ -197,7 +197,7 @@ CVector<short> CServer::ProcessData ( CVector<CVector<double> >& vecvecdData,
|
|||
const double dNorm = (double) 2.0;
|
||||
|
||||
// mix all audio data from all clients together
|
||||
for ( int i = 0; i < MIN_BLOCK_SIZE_SAMPLES; i++ )
|
||||
for ( int i = 0; i < MIN_SERVER_BLOCK_SIZE_SAMPLES; i++ )
|
||||
{
|
||||
double dMixedData = 0.0;
|
||||
|
||||
|
|
|
@ -54,11 +54,10 @@ public:
|
|||
|
||||
void GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
|
||||
CVector<QString>& vecsName,
|
||||
CVector<int>& veciJitBufSize, CVector<int>& veciNetwOutBlSiFact,
|
||||
CVector<int>& veciNetwInBlSiFact )
|
||||
CVector<int>& veciJitBufSize, CVector<int>& veciNetwOutBlSiFact )
|
||||
{
|
||||
ChannelSet.GetConCliParam ( vecHostAddresses, vecsName,
|
||||
veciJitBufSize, veciNetwOutBlSiFact, veciNetwInBlSiFact );
|
||||
veciJitBufSize, veciNetwOutBlSiFact );
|
||||
}
|
||||
|
||||
bool GetTimingStdDev ( double& dCurTiStdDev );
|
||||
|
|
|
@ -112,7 +112,7 @@ void CSettings::ReadIniFile ( const QString& sFileName )
|
|||
}
|
||||
|
||||
// network jitter buffer size
|
||||
if ( GetNumericIniSet ( IniXMLDocument, "client", "jitbuf", 0, MAX_NET_BUF_SIZE_NUM_BL, iValue ) )
|
||||
if ( GetNumericIniSet ( IniXMLDocument, "client", "jitbuf", MIN_NET_BUF_SIZE_NUM_BL, MAX_NET_BUF_SIZE_NUM_BL, iValue ) )
|
||||
{
|
||||
pClient->SetSockBufSize ( iValue );
|
||||
}
|
||||
|
@ -142,16 +142,16 @@ void CSettings::ReadIniFile ( const QString& sFileName )
|
|||
switch ( iValue )
|
||||
{
|
||||
case 0:
|
||||
pClient->SetAudioCompressionOut ( CAudioCompression::CT_NONE );
|
||||
pClient->SetAudioCompressionOut ( CT_NONE );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pClient->SetAudioCompressionOut ( CAudioCompression::CT_IMAADPCM );
|
||||
pClient->SetAudioCompressionOut ( CT_IMAADPCM );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
break;
|
||||
pClient->SetAudioCompressionOut ( CAudioCompression::CT_MSADPCM );
|
||||
pClient->SetAudioCompressionOut ( CT_MSADPCM );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -206,15 +206,15 @@ void CSettings::WriteIniFile ( const QString& sFileName )
|
|||
// for integer numbers!)
|
||||
switch ( pClient->GetAudioCompressionOut() )
|
||||
{
|
||||
case CAudioCompression::CT_NONE:
|
||||
case CT_NONE:
|
||||
SetNumericIniSet ( IniXMLDocument, "client", "audiocompression", 0 );
|
||||
break;
|
||||
|
||||
case CAudioCompression::CT_IMAADPCM:
|
||||
case CT_IMAADPCM:
|
||||
SetNumericIniSet ( IniXMLDocument, "client", "audiocompression", 1 );
|
||||
break;
|
||||
|
||||
case CAudioCompression::CT_MSADPCM:
|
||||
case CT_MSADPCM:
|
||||
SetNumericIniSet ( IniXMLDocument, "client", "audiocompression", 2 );
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,9 @@
|
|||
|
||||
|
||||
/* Definitions ****************************************************************/
|
||||
// Maximum block size for network input buffer. Consider two bytes per sample.
|
||||
#define MAX_SIZE_BYTES_NETW_BUF ( MAX_NET_BLOCK_SIZE_FACTOR * MIN_BLOCK_SIZE_SAMPLES * 2 )
|
||||
// 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 ********************************************************************/
|
||||
|
@ -57,7 +58,7 @@ public:
|
|||
const CHostAddress& HostAddr );
|
||||
|
||||
protected:
|
||||
void Init ( const quint16 iPortNumber = LLCON_PORT_NUMBER );
|
||||
void Init ( const quint16 iPortNumber = LLCON_DFAULT_PORT_NUMBER );
|
||||
|
||||
QUdpSocket SocketDevice;
|
||||
|
||||
|
|
|
@ -29,16 +29,24 @@
|
|||
void CSoundBase::Init ( const int iNewStereoBufferSize )
|
||||
{
|
||||
// init audio sound card buffer
|
||||
vecsAudioSndCrdStereo.Init ( iNewStereoBufferSize );
|
||||
if ( !bIsCallbackAudioInterface )
|
||||
{
|
||||
vecsAudioSndCrdStereo.Init ( iNewStereoBufferSize );
|
||||
}
|
||||
}
|
||||
|
||||
void CSoundBase::Start()
|
||||
{
|
||||
bRun = true;
|
||||
|
||||
// TODO start audio interface
|
||||
|
||||
// start the audio thread
|
||||
start();
|
||||
// start the audio thread in case we do not have an callback
|
||||
// based audio interface
|
||||
if ( !bIsCallbackAudioInterface )
|
||||
{
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
void CSoundBase::Stop()
|
||||
|
@ -47,7 +55,10 @@ void CSoundBase::Stop()
|
|||
bRun = false;
|
||||
|
||||
// give thread some time to terminate
|
||||
wait ( 5000 );
|
||||
if ( !bIsCallbackAudioInterface )
|
||||
{
|
||||
wait ( 5000 );
|
||||
}
|
||||
|
||||
|
||||
// TODO stop audio interface (previously done in Close function, we
|
||||
|
@ -74,7 +85,6 @@ void CSoundBase::run()
|
|||
#endif
|
||||
|
||||
// main loop of working thread
|
||||
bRun = true;
|
||||
while ( bRun )
|
||||
{
|
||||
// get audio from sound card (blocking function)
|
||||
|
|
|
@ -34,9 +34,11 @@
|
|||
class CSoundBase : public QThread
|
||||
{
|
||||
public:
|
||||
CSoundBase ( void (*fpNewCallback) ( CVector<short>& psData, void* arg ),
|
||||
CSoundBase ( const bool bNewIsCallbackAudioInterface,
|
||||
void (*fpNewCallback) ( CVector<short>& psData, void* arg ),
|
||||
void* arg ) : fpCallback ( fpNewCallback ), pCallbackArg ( arg ),
|
||||
bRun ( false ) {}
|
||||
bRun ( false ),
|
||||
bIsCallbackAudioInterface ( bNewIsCallbackAudioInterface ) {}
|
||||
virtual ~CSoundBase() {}
|
||||
|
||||
virtual void Init ( const int iNewStereoBufferSize );
|
||||
|
@ -50,6 +52,12 @@ protected:
|
|||
void (*fpCallback) ( CVector<short>& psData, void* arg );
|
||||
void* pCallbackArg;
|
||||
|
||||
// callback function call for derived classes
|
||||
void Callback ( CVector<short>& psData )
|
||||
{
|
||||
(*fpCallback) ( psData, pCallbackArg );
|
||||
}
|
||||
|
||||
// these functions should be overwritten by derived class for
|
||||
// non callback based audio interfaces
|
||||
virtual bool Read ( CVector<short>& psData ) { printf ( "no sound!" ); return false; }
|
||||
|
@ -57,6 +65,7 @@ protected:
|
|||
|
||||
void run();
|
||||
bool bRun;
|
||||
bool bIsCallbackAudioInterface;
|
||||
|
||||
CVector<short> vecsAudioSndCrdStereo;
|
||||
};
|
||||
|
|
20
src/util.h
20
src/util.h
|
@ -407,23 +407,23 @@ public:
|
|||
QString strName;
|
||||
};
|
||||
|
||||
enum EAudComprType
|
||||
{
|
||||
CT_NONE = 0,
|
||||
CT_IMAADPCM = 1,
|
||||
CT_MSADPCM = 2
|
||||
};
|
||||
|
||||
class CNetworkTransportProps
|
||||
{
|
||||
public:
|
||||
enum EAudioCodingType
|
||||
{
|
||||
ACT_NONE = 0,
|
||||
ACT_IMA_ADPCM = 1,
|
||||
ACT_MS_ADPCM = 2
|
||||
};
|
||||
|
||||
CNetworkTransportProps() : iNetworkPacketSize ( 0 ), iMonoAudioBlockSize ( 0 ),
|
||||
iNumAudioChannels ( 0 ), iSampleRate ( 0 ),
|
||||
eAudioCodingType ( ACT_NONE ), iAudioCodingArg ( 0 ) {}
|
||||
eAudioCodingType ( CT_NONE ), iAudioCodingArg ( 0 ) {}
|
||||
|
||||
CNetworkTransportProps ( const unsigned int iNNPS, const unsigned int iNMABS,
|
||||
const unsigned int iNNACH, const unsigned int iNSR,
|
||||
const EAudioCodingType eNACT, const int iNACA ) :
|
||||
const EAudComprType eNACT, const int iNACA ) :
|
||||
iNetworkPacketSize ( iNNPS ), iMonoAudioBlockSize ( iNMABS ),
|
||||
iNumAudioChannels ( iNNACH ), iSampleRate ( iNSR ), eAudioCodingType ( eNACT ),
|
||||
iAudioCodingArg ( iNACA ) {}
|
||||
|
@ -432,7 +432,7 @@ public:
|
|||
unsigned int iMonoAudioBlockSize;
|
||||
unsigned int iNumAudioChannels;
|
||||
unsigned int iSampleRate;
|
||||
EAudioCodingType eAudioCodingType;
|
||||
EAudComprType eAudioCodingType;
|
||||
int iAudioCodingArg;
|
||||
};
|
||||
|
||||
|
|
|
@ -29,15 +29,10 @@
|
|||
|
||||
|
||||
/* Implementation *************************************************************/
|
||||
#include <qmutex.h>
|
||||
|
||||
// external references
|
||||
extern AsioDrivers* asioDrivers;
|
||||
bool loadAsioDriver ( char *name );
|
||||
|
||||
// mutex
|
||||
QMutex ASIOMutex;
|
||||
|
||||
// TODO the following variables should be in the class definition but we cannot
|
||||
// do it here since we have static callback functions which cannot access the
|
||||
// class members :-(((
|
||||
|
@ -52,188 +47,12 @@ int iBufferSizeMono;
|
|||
int iBufferSizeStereo;
|
||||
int iASIOBufferSizeMono;
|
||||
|
||||
// event
|
||||
HANDLE m_ASIOEvent;
|
||||
CVector<short> vecsTmpAudioSndCrdStereo;
|
||||
|
||||
// wave in
|
||||
short* psCaptureBuffer;
|
||||
int iBufferPosCapture;
|
||||
bool bCaptureBufferOverrun;
|
||||
QMutex ASIOMutex;
|
||||
|
||||
// wave out
|
||||
short* psPlayBuffer;
|
||||
int iBufferPosPlay;
|
||||
bool bPlayBufferUnderrun;
|
||||
|
||||
int iMinNumSndBuf;
|
||||
int iCurNumSndBufIn;
|
||||
int iCurNumSndBufOut;
|
||||
int iNewNumSndBufIn;
|
||||
int iNewNumSndBufOut;
|
||||
bool bSetNumSndBufToMinimumValue;
|
||||
|
||||
// we must implement these functions here to get access to global variables
|
||||
int CSound::GetOutNumBuf() { return iNewNumSndBufOut; }
|
||||
int CSound::GetInNumBuf() { return iNewNumSndBufIn; }
|
||||
|
||||
|
||||
/******************************************************************************\
|
||||
* Wave in *
|
||||
\******************************************************************************/
|
||||
bool CSound::Read ( CVector<short>& psData )
|
||||
{
|
||||
int i;
|
||||
bool bError;
|
||||
|
||||
// check if device must be opened or reinitialized
|
||||
if ( bChangParamIn )
|
||||
{
|
||||
// reinit sound interface
|
||||
Init ( iBufferSizeStereo );
|
||||
|
||||
// reset flag
|
||||
bChangParamIn = false;
|
||||
}
|
||||
|
||||
// wait until enough data is available
|
||||
int iWaitCount = 0;
|
||||
while ( iBufferPosCapture < iBufferSizeStereo )
|
||||
{
|
||||
if ( !bCaptureBufferOverrun )
|
||||
{
|
||||
// regular case
|
||||
WaitForSingleObject ( m_ASIOEvent, INFINITE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// it seems that the buffers are too small, wait
|
||||
// just one time to avoid CPU to go up to 100% and
|
||||
// then leave this function
|
||||
if ( iWaitCount == 0 )
|
||||
{
|
||||
WaitForSingleObject ( m_ASIOEvent, INFINITE );
|
||||
iWaitCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASIOMutex.lock(); // get mutex lock
|
||||
{
|
||||
// check for buffer overrun in ASIO thread
|
||||
bError = bCaptureBufferOverrun;
|
||||
if ( bCaptureBufferOverrun )
|
||||
{
|
||||
// reset flag
|
||||
bCaptureBufferOverrun = false;
|
||||
}
|
||||
|
||||
// copy data from sound card capture buffer in function output buffer
|
||||
for ( i = 0; i < iBufferSizeStereo; i++ )
|
||||
{
|
||||
psData[i] = psCaptureBuffer[i];
|
||||
}
|
||||
|
||||
// move all other data in buffer
|
||||
const int iLenCopyRegion = iBufferPosCapture - iBufferSizeStereo;
|
||||
for ( i = 0; i < iLenCopyRegion; i++ )
|
||||
{
|
||||
psCaptureBuffer[i] = psCaptureBuffer[iBufferSizeStereo + i];
|
||||
}
|
||||
|
||||
// adjust "current block to write" pointer
|
||||
iBufferPosCapture -= iBufferSizeStereo;
|
||||
|
||||
// in case more than one buffer was ready, reset event
|
||||
ResetEvent ( m_ASIOEvent );
|
||||
}
|
||||
ASIOMutex.unlock();
|
||||
|
||||
return bError;
|
||||
}
|
||||
|
||||
void CSound::SetInNumBuf ( int iNewNum )
|
||||
{
|
||||
// check new parameter
|
||||
if ( ( iNewNum < MAX_SND_BUF_IN ) && ( iNewNum >= iMinNumSndBuf ) )
|
||||
{
|
||||
// change only if parameter is different
|
||||
if ( iNewNum != iNewNumSndBufIn )
|
||||
{
|
||||
iNewNumSndBufIn = iNewNum;
|
||||
bChangParamIn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************\
|
||||
* Wave out *
|
||||
\******************************************************************************/
|
||||
bool CSound::Write ( CVector<short>& psData )
|
||||
{
|
||||
bool bError;
|
||||
|
||||
// check if device must be opened or reinitialized
|
||||
if ( bChangParamOut )
|
||||
{
|
||||
// reinit sound interface
|
||||
Init ( iBufferSizeStereo );
|
||||
|
||||
// reset flag
|
||||
bChangParamOut = false;
|
||||
}
|
||||
|
||||
ASIOMutex.lock(); // get mutex lock
|
||||
{
|
||||
// check for buffer underrun in ASIO thread
|
||||
bError = bPlayBufferUnderrun;
|
||||
if ( bPlayBufferUnderrun )
|
||||
{
|
||||
// reset flag
|
||||
bPlayBufferUnderrun = false;
|
||||
}
|
||||
|
||||
// first check if enough data in buffer is available
|
||||
const int iPlayBufferLen = iCurNumSndBufOut * iBufferSizeStereo;
|
||||
|
||||
if ( iBufferPosPlay + iBufferSizeStereo > iPlayBufferLen )
|
||||
{
|
||||
// buffer overrun, return error
|
||||
bError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy stereo data from function input in soundcard play buffer
|
||||
for ( int i = 0; i < iBufferSizeStereo; i++ )
|
||||
{
|
||||
psPlayBuffer[iBufferPosPlay + i] = psData[i];
|
||||
}
|
||||
|
||||
iBufferPosPlay += iBufferSizeStereo;
|
||||
}
|
||||
}
|
||||
ASIOMutex.unlock();
|
||||
|
||||
return bError;
|
||||
}
|
||||
|
||||
void CSound::SetOutNumBuf ( int iNewNum )
|
||||
{
|
||||
// check new parameter
|
||||
if ( ( iNewNum < MAX_SND_BUF_OUT ) && ( iNewNum >= iMinNumSndBuf ) )
|
||||
{
|
||||
// change only if parameter is different
|
||||
if ( iNewNum != iNewNumSndBufOut )
|
||||
{
|
||||
iNewNumSndBufOut = iNewNum;
|
||||
bChangParamOut = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST
|
||||
CSound* pSound;
|
||||
|
||||
|
||||
/******************************************************************************\
|
||||
|
@ -244,24 +63,11 @@ void CSound::SetDev ( const int iNewDev )
|
|||
// check if an ASIO driver was already initialized
|
||||
if ( lCurDev >= 0 )
|
||||
{
|
||||
// the new driver was not selected before, use default settings for
|
||||
// buffer sizes
|
||||
bSetNumSndBufToMinimumValue = true;
|
||||
|
||||
// a device was already been initialized and is used, kill working
|
||||
// thread and clean up
|
||||
// stop driver
|
||||
ASIOStop();
|
||||
|
||||
// set event to ensure that thread leaves the waiting function
|
||||
if ( m_ASIOEvent != NULL )
|
||||
{
|
||||
SetEvent ( m_ASIOEvent );
|
||||
}
|
||||
|
||||
// wait for the thread to terminate
|
||||
Sleep ( 500 );
|
||||
|
||||
// dispose ASIO buffers
|
||||
ASIODisposeBuffers();
|
||||
|
||||
|
@ -273,14 +79,6 @@ void CSound::SetDev ( const int iNewDev )
|
|||
|
||||
if ( !strErrorMessage.empty() )
|
||||
{
|
||||
// The new driver initializing was not successful, try to preserve
|
||||
// the old buffer settings -> this is possible, if errornous driver
|
||||
// had failed before the buffer setting was done. If it failed after
|
||||
// setting the minimum buffer sizes, the following flag modification
|
||||
// does not have any effect which means the old settings cannot be
|
||||
// recovered anymore (TODO better solution)
|
||||
bSetNumSndBufToMinimumValue = false;
|
||||
|
||||
// loading and initializing the new driver failed, go back to original
|
||||
// driver and display error message
|
||||
LoadAndInitializeDriver ( lCurDev );
|
||||
|
@ -313,10 +111,6 @@ void CSound::SetDev ( const int iNewDev )
|
|||
}
|
||||
else
|
||||
{
|
||||
// the new driver was not selected before, use default settings for
|
||||
// buffer sizes
|
||||
bSetNumSndBufToMinimumValue = true;
|
||||
|
||||
// try to find one usable driver (select the first valid driver)
|
||||
if ( !LoadAndInitializeFirstValidDriver() )
|
||||
{
|
||||
|
@ -510,40 +304,7 @@ const bool bPreferPowerOfTwoAudioBufferSize = false;
|
|||
}
|
||||
}
|
||||
|
||||
// calculate the minimum required number of soundcard buffers
|
||||
iMinNumSndBuf = static_cast<int> (
|
||||
ceil ( static_cast<double> ( iASIOBufferSizeMono ) / iBufferSizeMono ) );
|
||||
|
||||
// TODO better solution
|
||||
// For some ASIO buffer sizes, the above calculation seems not to work although
|
||||
// it should be correct. Maybe there is a misunderstanding or a bug in the
|
||||
// sound interface implementation. As a workaround, we implement a table here, to
|
||||
// get working parameters for the most common ASIO buffer settings
|
||||
// Interesting observation: only 256 samples seems to be wrong, all other tested
|
||||
// buffer sizes like 192, 512, 384, etc. are correct...
|
||||
if ( iASIOBufferSizeMono == 256 )
|
||||
{
|
||||
iMinNumSndBuf = 4;
|
||||
}
|
||||
Q_ASSERT ( iMinNumSndBuf < MAX_SND_BUF_IN );
|
||||
Q_ASSERT ( iMinNumSndBuf < MAX_SND_BUF_OUT );
|
||||
|
||||
// set or just check the sound card buffer sizes
|
||||
if ( bSetNumSndBufToMinimumValue )
|
||||
{
|
||||
// use minimum buffer sizes as default
|
||||
iNewNumSndBufIn = iMinNumSndBuf;
|
||||
iNewNumSndBufOut = iMinNumSndBuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
// correct number of sound card buffers if required
|
||||
iNewNumSndBufIn = max ( iMinNumSndBuf, iNewNumSndBufIn );
|
||||
iNewNumSndBufOut = max ( iMinNumSndBuf, iNewNumSndBufOut );
|
||||
}
|
||||
iCurNumSndBufIn = iNewNumSndBufIn;
|
||||
iCurNumSndBufOut = iNewNumSndBufOut;
|
||||
|
||||
/*
|
||||
// display warning in case the ASIO buffer is too big
|
||||
if ( iMinNumSndBuf > 6 )
|
||||
{
|
||||
|
@ -557,6 +318,7 @@ if ( iASIOBufferSizeMono == 256 )
|
|||
"before you try to change the ASIO driver buffer size all ASIO "
|
||||
"applications including llcon are closed." ), "Ok", 0 );
|
||||
}
|
||||
*/
|
||||
|
||||
// prepare input channels
|
||||
for ( i = 0; i < NUM_IN_OUT_CHANNELS; i++ )
|
||||
|
@ -621,40 +383,11 @@ void CSound::Init ( const int iNewStereoBufferSize )
|
|||
iBufferSizeStereo = iNewStereoBufferSize;
|
||||
iBufferSizeMono = iBufferSizeStereo / 2;
|
||||
|
||||
// store new buffer number values
|
||||
iCurNumSndBufIn = iNewNumSndBufIn;
|
||||
iCurNumSndBufOut = iNewNumSndBufOut;
|
||||
// TEST
|
||||
PrepareDriver();
|
||||
|
||||
// initialize write block pointer in and overrun flag
|
||||
iBufferPosCapture = 0;
|
||||
bCaptureBufferOverrun = false;
|
||||
|
||||
// create memory for capture buffer
|
||||
if ( psCaptureBuffer != NULL )
|
||||
{
|
||||
delete[] psCaptureBuffer;
|
||||
}
|
||||
psCaptureBuffer = new short[iCurNumSndBufIn * iBufferSizeStereo];
|
||||
|
||||
// initialize write block pointer out and underrun flag
|
||||
iBufferPosPlay = 0;
|
||||
bPlayBufferUnderrun = false;
|
||||
|
||||
// create memory for play buffer
|
||||
if ( psPlayBuffer != NULL )
|
||||
{
|
||||
delete[] psPlayBuffer;
|
||||
}
|
||||
psPlayBuffer = new short[iCurNumSndBufOut * iBufferSizeStereo];
|
||||
|
||||
// clear new buffer
|
||||
for ( int i = 0; i < iCurNumSndBufOut * iBufferSizeStereo; i++ )
|
||||
{
|
||||
psPlayBuffer[i] = 0;
|
||||
}
|
||||
|
||||
// reset event
|
||||
ResetEvent ( m_ASIOEvent );
|
||||
// create memory for intermediate audio buffer
|
||||
vecsTmpAudioSndCrdStereo.Init ( iBufferSizeStereo );
|
||||
}
|
||||
ASIOMutex.unlock();
|
||||
|
||||
|
@ -666,33 +399,15 @@ void CSound::Close()
|
|||
{
|
||||
// stop driver
|
||||
ASIOStop();
|
||||
|
||||
// set event to ensure that thread leaves the waiting function
|
||||
if ( m_ASIOEvent != NULL )
|
||||
{
|
||||
SetEvent ( m_ASIOEvent );
|
||||
}
|
||||
|
||||
// wait for the thread to terminate
|
||||
Sleep ( 500 );
|
||||
|
||||
// set flag to open devices the next time it is initialized
|
||||
bChangParamIn = true;
|
||||
bChangParamOut = true;
|
||||
}
|
||||
|
||||
CSound::CSound ( void (*fpNewCallback) ( CVector<short>& psData, void* arg ), void* arg ) :
|
||||
CSoundBase ( fpNewCallback, arg )
|
||||
CSoundBase ( true, fpNewCallback, arg )
|
||||
{
|
||||
// init number of sound buffers
|
||||
iNewNumSndBufIn = NUM_SOUND_BUFFERS_IN;
|
||||
iCurNumSndBufIn = NUM_SOUND_BUFFERS_IN;
|
||||
iNewNumSndBufOut = NUM_SOUND_BUFFERS_OUT;
|
||||
iCurNumSndBufOut = NUM_SOUND_BUFFERS_OUT;
|
||||
iMinNumSndBuf = 1;
|
||||
|
||||
// should be initialized because an error can occur during init
|
||||
m_ASIOEvent = NULL;
|
||||
// TEST
|
||||
pSound = this;
|
||||
|
||||
|
||||
// get available ASIO driver names in system
|
||||
for ( int i = 0; i < MAX_NUMBER_SOUND_CARDS; i++ )
|
||||
|
@ -719,19 +434,6 @@ CSound::CSound ( void (*fpNewCallback) ( CVector<short>& psData, void* arg ), vo
|
|||
asioCallbacks.sampleRateDidChange = &sampleRateChanged;
|
||||
asioCallbacks.asioMessage = &asioMessages;
|
||||
asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
|
||||
|
||||
// init buffer pointer to zero
|
||||
psCaptureBuffer = NULL;
|
||||
psPlayBuffer = NULL;
|
||||
|
||||
// we use an event controlled structure
|
||||
// create event
|
||||
m_ASIOEvent = CreateEvent ( NULL, FALSE, FALSE, NULL );
|
||||
|
||||
// init flags
|
||||
bChangParamIn = false;
|
||||
bChangParamOut = false;
|
||||
bSetNumSndBufToMinimumValue = false;
|
||||
}
|
||||
|
||||
CSound::~CSound()
|
||||
|
@ -741,22 +443,6 @@ CSound::~CSound()
|
|||
ASIODisposeBuffers();
|
||||
ASIOExit();
|
||||
asioDrivers->removeCurrentDriver();
|
||||
|
||||
// delete allocated memory
|
||||
if ( psCaptureBuffer != NULL )
|
||||
{
|
||||
delete[] psCaptureBuffer;
|
||||
}
|
||||
if ( psPlayBuffer != NULL )
|
||||
{
|
||||
delete[] psPlayBuffer;
|
||||
}
|
||||
|
||||
// close the handle for the event
|
||||
if ( m_ASIOEvent != NULL )
|
||||
{
|
||||
CloseHandle ( m_ASIOEvent );
|
||||
}
|
||||
}
|
||||
|
||||
// ASIO callbacks -------------------------------------------------------------
|
||||
|
@ -774,141 +460,106 @@ void CSound::bufferSwitch ( long index, ASIOBool processNow )
|
|||
|
||||
ASIOMutex.lock(); // get mutex lock
|
||||
{
|
||||
// first check buffer state of capture and play buffers
|
||||
const int iCaptureBufferLen = iCurNumSndBufIn * iBufferSizeStereo;
|
||||
|
||||
bCaptureBufferOverrun =
|
||||
( iBufferPosCapture + 2 * iASIOBufferSizeMono > iCaptureBufferLen );
|
||||
|
||||
bPlayBufferUnderrun = ( 2 * iASIOBufferSizeMono > iBufferPosPlay );
|
||||
|
||||
// perform the processing for input and output
|
||||
for ( int i = 0; i < 2 * NUM_IN_OUT_CHANNELS; i++ ) // stereo
|
||||
{
|
||||
if ( bufferInfos[i].isInput == ASIOTrue )
|
||||
{
|
||||
// CAPTURE -----------------------------------------------------
|
||||
// first check if space in buffer is available
|
||||
if ( !bCaptureBufferOverrun )
|
||||
// copy new captured block in thread transfer buffer (copy
|
||||
// mono data interleaved in stereo buffer)
|
||||
switch ( channelInfos[i].type )
|
||||
{
|
||||
// copy new captured block in thread transfer buffer (copy
|
||||
// mono data interleaved in stereo buffer)
|
||||
switch ( channelInfos[i].type )
|
||||
case ASIOSTInt16LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
case ASIOSTInt16LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
psCaptureBuffer[iBufferPosCapture +
|
||||
2 * iCurSample + bufferInfos[i].channelNum] =
|
||||
( (short*) bufferInfos[i].buffers[index] )[iCurSample];
|
||||
}
|
||||
break;
|
||||
vecsTmpAudioSndCrdStereo[2 * iCurSample + bufferInfos[i].channelNum] =
|
||||
( (short*) bufferInfos[i].buffers[index] )[iCurSample];
|
||||
}
|
||||
break;
|
||||
|
||||
case ASIOSTInt24LSB:
|
||||
case ASIOSTInt24LSB:
|
||||
|
||||
// not yet tested, horrible things might happen with the following code ;-)
|
||||
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert current sample in 16 bit format
|
||||
int iCurSam = 0;
|
||||
memcpy ( &iCurSam, ( (char*) bufferInfos[i].buffers[index] ) + iCurSample * 3, 3 );
|
||||
iCurSam >>= 8;
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert current sample in 16 bit format
|
||||
int iCurSam = 0;
|
||||
memcpy ( &iCurSam, ( (char*) bufferInfos[i].buffers[index] ) + iCurSample * 3, 3 );
|
||||
iCurSam >>= 8;
|
||||
|
||||
psCaptureBuffer[iBufferPosCapture +
|
||||
2 * iCurSample + bufferInfos[i].channelNum] = static_cast<short> ( iCurSam );
|
||||
}
|
||||
break;
|
||||
|
||||
case ASIOSTInt32LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert to 16 bit
|
||||
psCaptureBuffer[iBufferPosCapture +
|
||||
2 * iCurSample + bufferInfos[i].channelNum] =
|
||||
(((int*) bufferInfos[i].buffers[index])[iCurSample] >> 16);
|
||||
}
|
||||
break;
|
||||
vecsTmpAudioSndCrdStereo[2 * iCurSample + bufferInfos[i].channelNum] =
|
||||
static_cast<short> ( iCurSam );
|
||||
}
|
||||
break;
|
||||
|
||||
case ASIOSTInt32LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert to 16 bit
|
||||
vecsTmpAudioSndCrdStereo[2 * iCurSample + bufferInfos[i].channelNum] =
|
||||
(((int*) bufferInfos[i].buffers[index])[iCurSample] >> 16);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
// call processing callback function
|
||||
pSound->Callback( vecsTmpAudioSndCrdStereo );
|
||||
|
||||
// perform the processing for input and output
|
||||
for ( int i = 0; i < 2 * NUM_IN_OUT_CHANNELS; i++ ) // stereo
|
||||
{
|
||||
if ( bufferInfos[i].isInput != ASIOTrue )
|
||||
{
|
||||
// PLAYBACK ----------------------------------------------------
|
||||
if ( !bPlayBufferUnderrun )
|
||||
// copy data from sound card in output buffer (copy
|
||||
// interleaved stereo data in mono sound card buffer)
|
||||
switch ( channelInfos[i].type )
|
||||
{
|
||||
// copy data from sound card in output buffer (copy
|
||||
// interleaved stereo data in mono sound card buffer)
|
||||
switch ( channelInfos[i].type )
|
||||
case ASIOSTInt16LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
case ASIOSTInt16LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
( (short*) bufferInfos[i].buffers[index] )[iCurSample] =
|
||||
psPlayBuffer[2 * iCurSample + bufferInfos[i].channelNum];
|
||||
}
|
||||
break;
|
||||
( (short*) bufferInfos[i].buffers[index] )[iCurSample] =
|
||||
vecsTmpAudioSndCrdStereo[2 * iCurSample + bufferInfos[i].channelNum];
|
||||
}
|
||||
break;
|
||||
|
||||
case ASIOSTInt24LSB:
|
||||
case ASIOSTInt24LSB:
|
||||
|
||||
// not yet tested, horrible things might happen with the following code ;-)
|
||||
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert current sample in 24 bit format
|
||||
int iCurSam = static_cast<int> ( psPlayBuffer[2 * iCurSample + bufferInfos[i].channelNum] );
|
||||
iCurSam <<= 8;
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert current sample in 24 bit format
|
||||
int iCurSam = static_cast<int> ( vecsTmpAudioSndCrdStereo[2 * iCurSample + bufferInfos[i].channelNum] );
|
||||
iCurSam <<= 8;
|
||||
|
||||
memcpy ( ( (char*) bufferInfos[i].buffers[index] ) + iCurSample * 3, &iCurSam, 3 );
|
||||
}
|
||||
break;
|
||||
|
||||
case ASIOSTInt32LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert to 32 bit
|
||||
int iCurSam = static_cast<int> ( psPlayBuffer[2 * iCurSample + bufferInfos[i].channelNum] );
|
||||
( (int*) bufferInfos[i].buffers[index] )[iCurSample] = ( iCurSam << 16 );
|
||||
}
|
||||
break;
|
||||
memcpy ( ( (char*) bufferInfos[i].buffers[index] ) + iCurSample * 3, &iCurSam, 3 );
|
||||
}
|
||||
break;
|
||||
|
||||
case ASIOSTInt32LSB:
|
||||
for ( iCurSample = 0; iCurSample < iASIOBufferSizeMono; iCurSample++ )
|
||||
{
|
||||
// convert to 32 bit
|
||||
int iCurSam = static_cast<int> ( vecsTmpAudioSndCrdStereo[2 * iCurSample + bufferInfos[i].channelNum] );
|
||||
( (int*) bufferInfos[i].buffers[index] )[iCurSample] = ( iCurSam << 16 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Manage thread interface buffers for input and output ----------------
|
||||
// capture
|
||||
if ( !bCaptureBufferOverrun )
|
||||
{
|
||||
iBufferPosCapture += 2 * iASIOBufferSizeMono;
|
||||
}
|
||||
|
||||
// play
|
||||
if ( !bPlayBufferUnderrun )
|
||||
{
|
||||
// move all other data in play buffer
|
||||
const int iLenCopyRegion = iBufferPosPlay - 2 * iASIOBufferSizeMono;
|
||||
for ( iCurSample = 0; iCurSample < iLenCopyRegion; iCurSample++ )
|
||||
{
|
||||
psPlayBuffer[iCurSample] =
|
||||
psPlayBuffer[2 * iASIOBufferSizeMono + iCurSample];
|
||||
}
|
||||
|
||||
// adjust "current block to write" pointer
|
||||
iBufferPosPlay -= 2 * iASIOBufferSizeMono;
|
||||
}
|
||||
|
||||
|
||||
// finally if the driver supports the ASIOOutputReady() optimization,
|
||||
// do it here, all data are in place -----------------------------------
|
||||
if ( bASIOPostOutput )
|
||||
{
|
||||
ASIOOutputReady();
|
||||
}
|
||||
|
||||
// set event
|
||||
SetEvent ( m_ASIOEvent );
|
||||
}
|
||||
ASIOMutex.unlock();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <qmutex.h>
|
||||
#include <qmessagebox.h>
|
||||
#include "../src/util.h"
|
||||
#include "../src/global.h"
|
||||
|
@ -59,8 +60,6 @@ public:
|
|||
virtual ~CSound();
|
||||
|
||||
virtual void Init ( const int iNewStereoBufferSize );
|
||||
virtual bool Read ( CVector<short>& psData );
|
||||
virtual bool Write ( CVector<short>& psData );
|
||||
virtual void Close();
|
||||
|
||||
int GetNumDev() { return lNumDevs; }
|
||||
|
@ -69,10 +68,10 @@ public:
|
|||
void SetDev ( const int iNewDev );
|
||||
int GetDev() { return lCurDev; }
|
||||
|
||||
void SetOutNumBuf ( const int iNewNum );
|
||||
int GetOutNumBuf();
|
||||
void SetInNumBuf ( const int iNewNum );
|
||||
int GetInNumBuf();
|
||||
void SetOutNumBuf ( const int iNewNum ) {}
|
||||
int GetOutNumBuf() { return 1; }
|
||||
void SetInNumBuf ( const int iNewNum ) {}
|
||||
int GetInNumBuf() { return 1; }
|
||||
|
||||
protected:
|
||||
bool LoadAndInitializeFirstValidDriver();
|
||||
|
@ -97,9 +96,6 @@ protected:
|
|||
long lNumDevs;
|
||||
long lCurDev;
|
||||
char* cDriverNames[MAX_NUMBER_SOUND_CARDS];
|
||||
|
||||
bool bChangParamIn;
|
||||
bool bChangParamOut;
|
||||
};
|
||||
|
||||
#endif // !defined ( AFX_SOUNDIN_H__9518A621_7F78_11D3_8C0D_EEBF182CF549__INCLUDED_ )
|
||||
|
|
Loading…
Reference in a new issue