start work for supporting CELT codec, code does not compile at the moment (backup checkin)

This commit is contained in:
Volker Fischer 2009-07-24 14:31:25 +00:00
parent 4642431103
commit 034530474c
21 changed files with 499 additions and 583 deletions

View file

@ -35,40 +35,14 @@ void CNetBuf::Init ( const int iNewBlockSize, const int iNewNumBlocks )
iBlockSize = iNewBlockSize;
iMemSize = iNewBlockSize * iNewNumBlocks;
// fade in first block added to the buffer
bFadeInNewPutData = true;
// allocate and clear memory for actual data buffer
vecdMemory.Init ( iMemSize );
vecbyMemory.Init ( iMemSize );
// use the "get" flag to make sure the buffer is cleared
Clear ( CT_GET );
// initialize number of samples for fading effect
if ( FADE_IN_OUT_NUM_SAM < iBlockSize )
{
iNumSamFading = iBlockSize;
}
else
{
iNumSamFading = FADE_IN_OUT_NUM_SAM;
}
if ( FADE_IN_OUT_NUM_SAM_EXTRA > iBlockSize )
{
iNumSamFadingExtra = iBlockSize;
}
else
{
iNumSamFadingExtra = FADE_IN_OUT_NUM_SAM_EXTRA;
}
// init variables for extrapolation (in case a fade out is needed)
dExPDiff = 0.0;
dExPLastV = 0.0;
}
bool CNetBuf::Put ( CVector<double>& vecdData )
bool CNetBuf::Put ( const CVector<uint8_t>& vecbyData )
{
#ifdef _DEBUG_
static FILE* pFileBI = fopen("bufferin.dat", "w");
@ -79,7 +53,7 @@ fflush(pFileBI);
bool bPutOK = true;
// get size of data to be added to the buffer
const int iInSize = vecdData.Size();
const int iInSize = vecbyData.Size();
// Check if there is not enough space available -> correct
if ( GetAvailSpace() < iInSize )
@ -88,9 +62,6 @@ fflush(pFileBI);
// prepare for new data
Clear ( CT_PUT );
// set flag to fade in new block to avoid clicks
bFadeInNewPutData = true;
bPutOK = false; // return error flag
// check for special case: buffer memory is not sufficient
@ -101,12 +72,6 @@ fflush(pFileBI);
}
}
// fade in new block if required
if ( bFadeInNewPutData )
{
FadeInAudioDataBlock ( vecdData );
}
// copy new data in internal buffer
int iCurPos = 0;
if ( iPutPos + iInSize > iMemSize )
@ -117,12 +82,12 @@ fflush(pFileBI);
// data must be written in two steps because of wrap around
while ( iPutPos < iMemSize )
{
vecdMemory[iPutPos++] = vecdData[iCurPos++];
vecbyMemory[iPutPos++] = vecbyData[iCurPos++];
}
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
{
vecdMemory[iPutPos] = vecdData[iCurPos++];
vecbyMemory[iPutPos] = vecbyData[iCurPos++];
}
}
else
@ -131,7 +96,7 @@ fflush(pFileBI);
const int iEnd = iPutPos + iInSize;
while ( iPutPos < iEnd )
{
vecdMemory[iPutPos++] = vecdData[iCurPos++];
vecbyMemory[iPutPos++] = vecbyData[iCurPos++];
}
}
@ -148,13 +113,12 @@ fflush(pFileBI);
return bPutOK;
}
bool CNetBuf::Get ( CVector<double>& vecdData )
bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
{
bool bGetOK = true; // init return value
bool bFadeOutExtrap = false;
bool bGetOK = true; // init return value
// get size of data to be get from the buffer
const int iInSize = vecdData.Size();
const int iInSize = vecbyData.Size();
// Check if there is not enough data available -> correct
if ( GetAvailData() < iInSize )
@ -163,11 +127,6 @@ bool CNetBuf::Get ( CVector<double>& vecdData )
// prepare for getting data
Clear ( CT_GET );
// set flag to fade in next new block in buffer and fade out last
// block by extrapolation to avoid clicks
bFadeInNewPutData = true;
bFadeOutExtrap = true;
bGetOK = false; // return error flag
// check for special case: buffer memory is not sufficient
@ -188,12 +147,12 @@ bool CNetBuf::Get ( CVector<double>& vecdData )
// data must be read in two steps because of wrap around
while ( iGetPos < iMemSize )
{
vecdData[iCurPos++] = vecdMemory[iGetPos++];
vecbyData[iCurPos++] = vecbyMemory[iGetPos++];
}
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
{
vecdData[iCurPos++] = vecdMemory[iGetPos];
vecbyData[iCurPos++] = vecbyMemory[iGetPos];
}
}
else
@ -202,7 +161,7 @@ bool CNetBuf::Get ( CVector<double>& vecdData )
const int iEnd = iGetPos + iInSize;
while ( iGetPos < iEnd )
{
vecdData[iCurPos++] = vecdMemory[iGetPos++];
vecbyData[iCurPos++] = vecbyMemory[iGetPos++];
}
}
@ -216,23 +175,6 @@ bool CNetBuf::Get ( CVector<double>& vecdData )
eBufState = CNetBuf::BS_OK;
}
/* extrapolate data from old block to avoid "clicks"
we have to do this method since we cannot fade out the old block
anymore since it is already gone (processed or send through the
network) */
if ( bFadeOutExtrap )
{
FadeOutExtrapolateAudioDataBlock ( vecdData, dExPDiff, dExPLastV );
}
/* save some paramters from last block which is needed in case we do not
have enough data for next "get" operation and need to extrapolate the
signal to avoid "clicks"
we assume here that "iBlockSize" is larger than 1! */
dExPDiff = vecdData[iInSize - 1] - vecdData[iInSize - 2];
dExPLastV = vecdData[iInSize - 1];
return bGetOK;
}
@ -303,7 +245,7 @@ void CNetBuf::Clear ( const EClearType eClearType )
if ( eClearType == CT_GET )
{
// clear buffer
vecdMemory.Reset ( 0.0 );
vecbyMemory.Reset ( 0 );
// correct buffer so that after the current get operation the pointer
// are at maximum distance
@ -334,38 +276,6 @@ void CNetBuf::Clear ( const EClearType eClearType )
iPutPos -= iMemSize;
}
// fade out old data right before new put pointer
int iCurPos = iPutPos - iNumSamFading;
int i = iNumSamFading;
if ( iCurPos < 0 )
{
// wrap around
iCurPos += iMemSize;
// data must be processed in two steps because of wrap around
while ( iCurPos < iMemSize )
{
vecdMemory[iCurPos++] *= ( (double) i / iNumSamFading );
i--;
}
for ( iCurPos = 0; iCurPos < iPutPos; iCurPos++ )
{
vecdMemory[iCurPos] *= ( (double) i / iNumSamFading );
i--;
}
}
else
{
// data can be processed in one step
while ( iCurPos < iPutPos )
{
vecdMemory[iCurPos++] *= ( (double) i / iNumSamFading );
i--;
}
}
// check for special case
if ( iPutPos == iGetPos )
{
@ -378,40 +288,6 @@ void CNetBuf::Clear ( const EClearType eClearType )
}
}
void CNetBuf::FadeInAudioDataBlock ( CVector<double>& vecdData )
{
// correct fading length if necessary
const int iCurFadingLen = min ( vecdData.Size(), iNumSamFading );
// apply linear fading
for ( int i = 0; i < iCurFadingLen; i++ )
{
vecdData[i] *= ( (double) i / iCurFadingLen );
}
// reset flag
bFadeInNewPutData = false;
}
void CNetBuf::FadeOutExtrapolateAudioDataBlock ( CVector<double>& vecdData,
const double dExPDiff,
const double dExPLastV )
{
// correct fading length if necessary
const int iCurFadingLenExtra = min ( vecdData.Size(), iNumSamFadingExtra );
// apply linear extrapolation and linear fading
for ( int i = 0; i < iCurFadingLenExtra; i++ )
{
// calculate extrapolated value
vecdData[i] = ( ( i + 1 ) * dExPDiff + dExPLastV );
// linear fading
vecdData[i] *= ( (double) ( iCurFadingLenExtra - i ) / iCurFadingLenExtra );
}
}
/* conversion buffer implementation *******************************************/
void CConvBuf::Init ( const int iNewMemSize )

View file

@ -29,15 +29,6 @@
#include "global.h"
/* Definitions ****************************************************************/
// time for fading effect for masking drop outs
#define FADE_IN_OUT_TIME ( (double) 2 ) // ms
#define FADE_IN_OUT_NUM_SAM ( (int) ( SYSTEM_SAMPLE_RATE * FADE_IN_OUT_TIME ) / 1000 )
// for extrapolation a shorter time for fading
#define FADE_IN_OUT_NUM_SAM_EXTRA 10 // samples
/* Classes ********************************************************************/
class CNetBuf
{
@ -48,8 +39,8 @@ public:
void Init ( const int iNewBlockSize, const int iNewNumBlocks );
int GetSize() { return iMemSize / iBlockSize; }
bool Put ( CVector<double>& vecdData );
bool Get ( CVector<double>& vecdData );
bool Put ( const CVector<uint8_t>& vecbyData );
bool Get ( CVector<uint8_t>& vecbyData );
protected:
enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
@ -57,22 +48,12 @@ protected:
void Clear ( const EClearType eClearType );
int GetAvailSpace() const;
int GetAvailData() const;
void FadeInAudioDataBlock ( CVector<double>& vecdData );
void FadeOutExtrapolateAudioDataBlock ( CVector<double>& vecdData,
const double dExPDiff, const double dExPLastV );
CVector<double> vecdMemory;
int iMemSize;
int iBlockSize;
int iGetPos, iPutPos;
EBufState eBufState;
bool bFadeInNewPutData;
int iNumSamFading;
int iNumSamFadingExtra;
// extrapolation parameters
double dExPDiff;
double dExPLastV;
CVector<uint8_t> vecbyMemory;
int iMemSize;
int iBlockSize;
int iGetPos, iPutPos;
EBufState eBufState;
};

View file

@ -28,9 +28,8 @@
/******************************************************************************\
* CChannelSet *
\******************************************************************************/
CChannelSet::CChannelSet ( const int iNewUploadRateLimitKbps ) :
bWriteStatusHTMLFile ( false ),
iUploadRateLimitKbps ( iNewUploadRateLimitKbps )
CChannelSet::CChannelSet() :
bWriteStatusHTMLFile ( false )
{
// enable all channels (for the server all channel must be enabled the
// entire life time of the software
@ -492,7 +491,8 @@ void CChannelSet::GetBlockAllConC ( CVector<int>& vecChanID,
{
// read out all input buffers to decrease timeout counter on
// disconnected channels
const EGetDataStat eGetStat = vecChannels[i].GetData ( vecdData );
// const EGetDataStat eGetStat = vecChannels[i].GetData ( vecdData );
const EGetDataStat eGetStat=GS_BUFFER_OK;//TEST
// if channel was just disconnected, set flag that connected
// client list is sent to all other clients
@ -668,56 +668,9 @@ CChannel::CChannel ( const bool bNIsServer ) :
bIsEnabled ( 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
// possible network buffer sizes are different!)
// we add a special entry for network modes which are managed via the
// protocol -> "+ 1"
const int iNumSupportedAudComprTypes = 3;
vecNetwBufferInProps.Init ( iNumSupportedAudComprTypes *
MAX_NET_BLOCK_SIZE_FACTOR + 1 );
// init special mode (with invalid data)
vecNetwBufferInProps[0].iAudioBlockSize = 0;
vecNetwBufferInProps[0].eAudComprType = CT_NONE;
vecNetwBufferInProps[0].iNetwInBufSize = 0;
for ( int i = 0; i < MAX_NET_BLOCK_SIZE_FACTOR; i++ )
{
// (consider the special mode -> "1 +")
const int iNoneIdx = 1 + iNumSupportedAudComprTypes * i;
const int iIMAIdx = 1 + iNumSupportedAudComprTypes * i + 1;
const int iMSIdx = 1 + iNumSupportedAudComprTypes * i + 2;
// network block size factor must start from 1 -> i + 1
const int iCurNetBlockSizeFact = i + 1;
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 = CT_NONE;
vecNetwBufferInProps[iNoneIdx].iNetwInBufSize = AudioCompressionIn.Init (
vecNetwBufferInProps[iNoneIdx].iAudioBlockSize,
vecNetwBufferInProps[iNoneIdx].eAudComprType );
// IMA ADPCM
vecNetwBufferInProps[iIMAIdx].eAudComprType = CT_IMAADPCM;
vecNetwBufferInProps[iIMAIdx].iNetwInBufSize = AudioCompressionIn.Init (
vecNetwBufferInProps[iIMAIdx].iAudioBlockSize,
vecNetwBufferInProps[iIMAIdx].eAudComprType );
// MS ADPCM
vecNetwBufferInProps[iMSIdx].eAudComprType = CT_MSADPCM;
vecNetwBufferInProps[iMSIdx].iNetwInBufSize = AudioCompressionIn.Init (
vecNetwBufferInProps[iMSIdx].iAudioBlockSize,
vecNetwBufferInProps[iMSIdx].eAudComprType );
}
// init network input properties
NetwBufferInProps.iAudioBlockSize = 0;
NetwBufferInProps.iNetwInBufSize = 0;
// initial value for connection time out counter, we calculate the total
// number of samples here and subtract the number of samples of the block
@ -730,11 +683,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
// init the socket buffer
SetSockBufSize ( DEF_NET_BUF_SIZE_NUM_BL );
// set initial input and output block size factors
SetAudioBlockSizeAndComprIn (
MIN_SERVER_BLOCK_SIZE_SAMPLES * DEF_NET_BLOCK_SIZE_FACTOR,
CT_MSADPCM );
// set initial output block size factors
if ( bIsServer )
{
SetNetwBufSizeFactOut ( DEF_NET_BLOCK_SIZE_FACTOR );
@ -824,53 +773,20 @@ void CChannel::SetEnable ( const bool bNEnStat )
}
}
void CChannel::SetAudioBlockSizeAndComprIn ( const int iNewBlockSize,
const EAudComprType eNewAudComprType )
{
QMutexLocker locker ( &Mutex );
// store block size value
iCurAudioBlockSizeIn = iNewBlockSize;
// init audio compression unit
AudioCompressionIn.Init ( iNewBlockSize, eNewAudComprType );
}
void CChannel::SetNetwBufSizeOut ( const int iNewAudioBlockSizeOut )
{
// this function is intended for the client (not the server)
QMutexLocker locker ( &Mutex );
// direct setting of audio buffer (without buffer size factor) is
// right now only intendet for the client, not the server
if ( !bIsServer )
{
// 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 );
// use the network block size factor only for the server
if ( bIsServer )
{
// store new value
iCurNetwOutBlSiFact = iNewNetwBlSiFactOut;
// store new value
iCurNetwOutBlSiFact = iNewNetwBlSiFactOut;
// init audio compression and get audio compression block size
iAudComprSizeOut = AudioCompressionOut.Init (
iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES, eAudComprTypeOut );
// init audio compression and get audio compression block size
iAudComprSizeOut = AudioCompressionOut.Init (
iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES, eAudComprTypeOut );
// init conversion buffer
ConvBuf.Init ( iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES );
}
// init conversion buffer
ConvBuf.Init ( iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES );
}
void CChannel::SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut )
@ -1021,11 +937,22 @@ void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTranspor
QMutexLocker locker ( &Mutex );
// apply received parameters to internal data struct
vecNetwBufferInProps[0].iAudioBlockSize = NetworkTransportProps.iMonoAudioBlockSize;
vecNetwBufferInProps[0].eAudComprType = NetworkTransportProps.eAudioCodingType;
vecNetwBufferInProps[0].iNetwInBufSize = AudioCompressionIn.Init (
vecNetwBufferInProps[0].iAudioBlockSize,
vecNetwBufferInProps[0].eAudComprType );
NetwBufferInProps.iAudioBlockSize = NetworkTransportProps.iMonoAudioBlockSize;
NetwBufferInProps.eAudComprType = NetworkTransportProps.eAudioCodingType;
NetwBufferInProps.iNetwInBufSize = NetworkTransportProps.iNetworkPacketSize;
// re-initialize cycle time variance measurement if necessary
if ( NetwBufferInProps.iAudioBlockSize != CycleTimeVariance.GetBlockLength() )
{
// re-init (we have to use the buffer size which works
// on the system sample rate, therefore we use the
// decompressed audio buffer size instead of the network
// buffer size)
CycleTimeVariance.Init ( NetwBufferInProps.iAudioBlockSize,
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
CycleTimeVariance.Reset();
}
}
void CChannel::OnReqNetTranspProps()
@ -1040,7 +967,7 @@ void CChannel::CreateNetTranspPropsMessFromCurrentSettings()
iCurAudioBlockSizeOut,
1, // right now we only use mono
SYSTEM_SAMPLE_RATE, // right now only one sample rate is supported
AudioCompressionOut.GetType(),
CT_CELT, // always CELT coding
0 );
// send current network transport properties
@ -1064,11 +991,6 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
bool bIsProtocolPacket = false;
bool bIsAudioPacket = false;
bool bNewConnection = false;
bool bReinitializeIn = false;
// intermediate storage for new parameters
int iNewAudioBlockSize;
EAudComprType eNewAudComprType;
if ( bIsEnabled )
{
@ -1088,62 +1010,16 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
// only try to parse audio if it was not a protocol packet
if ( !bIsProtocolPacket )
{
Mutex.lock();
{
// check if this is an audio packet by checking all possible lengths
const int iPossNetwSizes = vecNetwBufferInProps.Size();
for ( int i = 0; i < iPossNetwSizes; i++ )
{
// check for low/high quality audio packets and set flags
if ( iNumBytes == vecNetwBufferInProps[i].iNetwInBufSize )
{
bIsAudioPacket = true;
// check if we are correctly initialized
iNewAudioBlockSize =
vecNetwBufferInProps[i].iAudioBlockSize;
eNewAudComprType =
vecNetwBufferInProps[i].eAudComprType;
if ( ( iNewAudioBlockSize != iCurAudioBlockSizeIn ) ||
( eNewAudComprType != AudioCompressionIn.GetType() ) )
{
bReinitializeIn = true;
}
}
}
}
Mutex.unlock();
// actual initialization call has to be made
// outside the mutex region since it internally
// usees the same mutex, too
if ( bReinitializeIn )
{
// re-initialize to new value
SetAudioBlockSizeAndComprIn (
iNewAudioBlockSize, eNewAudComprType );
}
Mutex.lock();
{
// only process audio if packet has correct size
if ( bIsAudioPacket )
if ( iNumBytes == NetwBufferInProps.iNetwInBufSize )
{
// decompress audio
CVector<short> vecsDecomprAudio ( AudioCompressionIn.Decode ( vecbyData ) );
// set audio packet flag
bIsAudioPacket = true;
// convert received data from short to double
const int iAudioSize = vecsDecomprAudio.Size();
CVector<double> vecdDecomprAudio ( iAudioSize );
for ( int i = 0; i < iAudioSize; i++ )
{
vecdDecomprAudio[i] = static_cast<double> ( vecsDecomprAudio[i] );
}
if ( SockBuf.Put ( vecdDecomprAudio ) )
// store new packet in jitter buffer
if ( SockBuf.Put ( vecbyData ) )
{
eRet = PS_AUDIO_OK;
}
@ -1152,28 +1028,13 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
eRet = PS_AUDIO_ERR;
}
// update cycle time variance measurement, take care of
// re-initialization, too, if necessary
if ( iAudioSize != CycleTimeVariance.GetBlockLength() )
{
// re-init (we have to use the buffer size which works
// on the system sample rate, therefore we use the
// decompressed audio buffer size instead of the network
// buffer size)
CycleTimeVariance.Init ( iAudioSize,
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
CycleTimeVariance.Reset();
}
else
{
// update cycle time variance measurement
// TODO only update if time difference of received packets is below
// a limit to avoid having short network troubles incorporated in the
// statistic
CycleTimeVariance.Update();
}
CycleTimeVariance.Update();
}
else
{
@ -1219,20 +1080,24 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
return eRet;
}
EGetDataStat CChannel::GetData ( CVector<double>& vecdData )
EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData )
{
QMutexLocker locker ( &Mutex );
EGetDataStat eGetStatus;
const bool bSockBufState = SockBuf.Get ( vecdData );
const bool bSockBufState = SockBuf.Get ( vecbyData );
// decrease time-out counter
if ( iConTimeOut > 0 )
{
// TODO
// subtract the number of samples of the current block since the
// time out counter is based on samples not on blocks
iConTimeOut -= vecdData.Size();
iConTimeOut -= vecbyData.Size();
if ( iConTimeOut <= 0 )
{

View file

@ -62,10 +62,6 @@ enum EGetDataStat
GS_CHAN_NOT_CONNECTED
};
// low upload data rate settings
#define LOW_UPL_SET_AUDIO_COMPRESSION CT_MSADPCM
#define LOW_UPL_SET_BLOCK_SIZE_FACTOR_OUT MAX_NET_BLOCK_SIZE_FACTOR
/* Classes ********************************************************************/
// CChannel --------------------------------------------------------------------
@ -81,7 +77,7 @@ public:
EPutDataStat PutData ( const CVector<uint8_t>& vecbyData,
int iNumBytes );
EGetDataStat GetData ( CVector<double>& vecdData );
EGetDataStat GetData ( CVector<uint8_t>& vecbyData );
CVector<uint8_t> PrepSendPacket ( const CVector<short>& vecsNPacket );
@ -111,7 +107,7 @@ public:
void SetNetwBufSizeOut ( const int iNewAudioBlockSizeOut );
int GetNetwBufSizeOut() { return iCurAudioBlockSizeOut; }
int GetAudioBlockSizeIn() { return iCurAudioBlockSizeIn; }
int GetAudioBlockSizeIn() { return NetwBufferInProps.iAudioBlockSize; }
int GetUploadRateKbps();
double GetTimingStdDev() { return CycleTimeVariance.GetStdDev(); }
@ -152,9 +148,6 @@ public:
void CreateDisconnectionMes() { Protocol.CreateDisconnectionMes(); }
protected:
void SetAudioBlockSizeAndComprIn ( const int iNewBlockSize,
const EAudComprType eNewAudComprType );
bool ProtocolIsEnabled();
// audio compression
@ -189,19 +182,17 @@ protected:
bool bIsEnabled;
bool bIsServer;
int iCurAudioBlockSizeIn;
int iCurNetwOutBlSiFact;
int iCurAudioBlockSizeOut;
QMutex Mutex;
struct sNetwBufferInProps
struct sNetwProperties
{
int iNetwInBufSize;
int iAudioBlockSize;
EAudComprType eAudComprType;
int iNetwInBufSize;
int iAudioBlockSize;
};
CVector<sNetwBufferInProps> vecNetwBufferInProps;
sNetwProperties NetwBufferInProps;
EAudComprType eAudComprTypeOut;
@ -233,7 +224,7 @@ class CChannelSet : public QObject
Q_OBJECT
public:
CChannelSet ( const int iNewUploadRateLimitKbps = DEF_MAX_UPLOAD_RATE_KBPS );
CChannelSet();
virtual ~CChannelSet() {}
bool PutData ( const CVector<uint8_t>& vecbyRecBuf,
@ -267,9 +258,6 @@ public:
void StartStatusHTMLFileWriting ( const QString& strNewFileName,
const QString& strNewServerNameWithPort );
void SetUploadRateLimitKbps ( const int iNewUploadRateLimitKbps )
{ iUploadRateLimitKbps = iNewUploadRateLimitKbps; }
protected:
CVector<CChannelShortInfo> CreateChannelList();
void CreateAndSendChanListForAllConChannels();
@ -278,7 +266,7 @@ protected:
void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText );
void WriteHTMLChannelList();
void SetOutputParameters();
int CalculateTotalUploadRateKbps();
int CalculateTotalUploadRateKbps();
/* do not use the vector class since CChannel does not have appropriate
copy constructor/operator */
@ -287,8 +275,6 @@ protected:
CVector<QString> vstrChatColors;
int iUploadRateLimitKbps;
// HTML file server status
bool bWriteStatusHTMLFile;
QString strServerHTMLFileListName;

View file

@ -36,9 +36,7 @@ CClient::CClient ( const quint16 iPortNumber ) :
vstrIPAddress ( MAX_NUM_SERVER_ADDR_ITEMS, "" ), strName ( "" ),
bOpenChatOnNewMessage ( true ),
bDoAutoSockBufSize ( true ),
iSndCrdPreferredMonoBlSizeIndex ( CSndCrdBufferSizes::GetDefaultIndex() ),
iClientSampleRate ( SYSTEM_SAMPLE_RATE ),
iSndCrdMonoBlockSizeSam ( 0 )
iSndCrdPreferredMonoBlSizeIndex ( CSndCrdBufferSizes::GetDefaultIndex() )
{
// connection for protocol
QObject::connect ( &Channel,
@ -164,7 +162,7 @@ void CClient::SetSndCrdPreferredMonoBlSizeIndex ( const int iNewIdx )
}
// init with new block size index parameter
Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex );
Init ( iSndCrdPreferredMonoBlSizeIndex );
if ( bWasRunning )
{
@ -191,7 +189,7 @@ QString CClient::SetSndCrdDev ( const int iNewDev )
// init again because the sound card actual buffer size might
// be changed on new device
Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex );
Init ( iSndCrdPreferredMonoBlSizeIndex );
if ( bWasRunning )
{
@ -214,7 +212,7 @@ void CClient::OnSndCrdReinitRequest()
// reinit the driver (we use the currently selected driver) and
// init client object, too
Sound.SetDev ( Sound.GetDev() );
Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex );
Init ( iSndCrdPreferredMonoBlSizeIndex );
if ( bWasRunning )
{
@ -225,7 +223,7 @@ void CClient::OnSndCrdReinitRequest()
void CClient::Start()
{
// init object
Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex );
Init ( iSndCrdPreferredMonoBlSizeIndex );
// enable channel
Channel.SetEnable ( true );
@ -254,7 +252,7 @@ void CClient::Stop()
PostWinMessage ( MS_RESET_ALL, 0 );
}
void CClient::AudioCallback ( CVector<short>& psData, void* arg )
void CClient::AudioCallback ( CVector<int16_t>& psData, void* arg )
{
// get the pointer to the object
CClient* pMyClientObj = reinterpret_cast<CClient*> ( arg );
@ -263,70 +261,62 @@ void CClient::AudioCallback ( CVector<short>& psData, void* arg )
pMyClientObj->ProcessAudioData ( psData );
}
void CClient::Init ( const int iSampleRate,
const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate )
void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate )
{
// store new sample rate
iClientSampleRate = iSampleRate;
// translate block size index in actual block size
const int iPrefMonoBlockSizeSamAtSndCrdSamRate = CSndCrdBufferSizes::
GetBufferSizeFromIndex ( iPrefMonoBlockSizeSamIndexAtSndCrdSamRate );
// get actual sound card buffer size using preferred size
iSndCrdMonoBlockSizeSam = Sound.Init ( iPrefMonoBlockSizeSamAtSndCrdSamRate );
iSndCrdStereoBlockSizeSam = 2 * iSndCrdMonoBlockSizeSam;
iMonoBlockSizeSam = iSndCrdMonoBlockSizeSam * iClientSampleRate / SND_CRD_SAMPLE_RATE;
iMonoBlockSizeSam = Sound.Init ( iPrefMonoBlockSizeSamAtSndCrdSamRate );
iStereoBlockSizeSam = 2 * iMonoBlockSizeSam;
// the channel works on the same block size as the sound interface
Channel.SetNetwBufSizeOut ( iMonoBlockSizeSam );
vecsAudioSndCrdStereo.Init ( iSndCrdStereoBlockSizeSam );
vecdAudioSndCrdMono.Init ( iSndCrdMonoBlockSizeSam );
vecdAudioSndCrdStereo.Init ( iSndCrdStereoBlockSizeSam );
vecsAudioSndCrdStereo.Init ( iStereoBlockSizeSam );
vecdAudioStereo.Init ( iStereoBlockSizeSam );
// resample objects are always initialized with the input block size
// record
ResampleObjDown.Init ( iSndCrdMonoBlockSizeSam,
SND_CRD_SAMPLE_RATE, iClientSampleRate );
// playback
ResampleObjUp.Init ( iMonoBlockSizeSam,
iClientSampleRate, SND_CRD_SAMPLE_RATE );
// init network buffers
vecsNetwork.Init ( iMonoBlockSizeSam );
vecdNetwData.Init ( iMonoBlockSizeSam );
// init response time evaluation
CycleTimeVariance.Init ( iMonoBlockSizeSam,
iClientSampleRate, TIME_MOV_AV_RESPONSE );
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
CycleTimeVariance.Reset();
// init reverberation
AudioReverb.Init ( iClientSampleRate );
AudioReverb.Init ( SYSTEM_SAMPLE_RATE );
// init audio endocder/decoder (mono)
CeltMode = celt_mode_create (
SYSTEM_SAMPLE_RATE, 1, iMonoBlockSizeSam, NULL );
CeltEncoder = celt_encoder_create ( CeltMode );
CeltDecoder = celt_decoder_create ( CeltMode );
// 16: low/normal quality 132 kbsp (128) / 90 kbps (256)
// 40: high good 204 kbps (128) / 162 kbps (256)
iCeltNumCodedBytes = 16;
vecCeltData.Init ( iCeltNumCodedBytes );
// init network buffers
vecsNetwork.Init ( iMonoBlockSizeSam );
vecbyNetwData.Init ( iCeltNumCodedBytes );
// the channel works on the audio coded block size
Channel.SetNetwBufSizeOut ( iCeltNumCodedBytes );
}
void CClient::ProcessAudioData ( CVector<short>& vecsStereoSndCrd )
void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
{
int i, j;
// convert data from short to double
for ( i = 0; i < iSndCrdStereoBlockSizeSam; i++ )
{
vecdAudioSndCrdStereo[i] = (double) vecsStereoSndCrd[i];
}
// resample data for each channel seaparately
ResampleObjDown.ResampleStereo ( vecdAudioSndCrdStereo, vecdAudioStereo );
// update stereo signal level meter
SignalLevelMeter.Update ( vecdAudioStereo );
SignalLevelMeter.Update ( vecsStereoSndCrd );
// convert data from short to double
for ( i = 0; i < iStereoBlockSizeSam; i++ )
{
vecdAudioStereo[i] = (double) vecsStereoSndCrd[i];
}
// add reverberation effect if activated
if ( iReverbLevel != 0 )
@ -395,11 +385,17 @@ void CClient::ProcessAudioData ( CVector<short>& vecsStereoSndCrd )
}
// send it through the network
Socket.SendPacket ( Channel.PrepSendPacket ( vecsNetwork ),
Channel.GetAddress() );
// Socket.SendPacket ( Channel.PrepSendPacket ( vecsNetwork ),
// Channel.GetAddress() );
celt_encode(CeltEncoder, &vecsNetwork[0], NULL, &vecCeltData[0], iCeltNumCodedBytes);
Socket.SendPacket ( vecCeltData, Channel.GetAddress() );
// receive a new block
if ( Channel.GetData ( vecdNetwData ) == GS_BUFFER_OK )
if ( Channel.GetData ( vecbyNetwData ) == GS_BUFFER_OK )
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN );
}
@ -424,16 +420,36 @@ fflush(pFileDelay);
// check if channel is connected
if ( Channel.IsConnected() )
{
// resample data
ResampleObjUp.ResampleMono ( vecdNetwData, vecdAudioSndCrdMono );
/*
// convert data from double to short type and copy mono
// received data in both sound card channels
for ( i = 0, j = 0; i < iSndCrdMonoBlockSizeSam; i++, j += 2 )
{
vecsStereoSndCrd[j] = vecsStereoSndCrd[j + 1] =
Double2Short ( vecdAudioSndCrdMono[i] );
Double2Short ( vecdNetwData[i] );
}
*/
CVector<short> vecsAudioSndCrdMono ( iMonoBlockSizeSam );
/*
for ( i = 0; i < iMonoBlockSizeSam; i++ )
{
vecsAudioSndCrdMono[i] = Double2Short ( vecdNetwData[i] );
}
*/
// TEST CELT
//celt_encode(CeltEncoder, &vecsAudioSndCrdMono[0], NULL, &vecCeltData[0], iCeltNumCodedBytes);
celt_decode(CeltDecoder, &vecbyNetwData[0], iCeltNumCodedBytes, &vecsAudioSndCrdMono[0]);
for ( i = 0, j = 0; i < iMonoBlockSizeSam; i++, j += 2 )
{
vecsStereoSndCrd[j] = vecsStereoSndCrd[j + 1] =
vecsAudioSndCrdMono[i];
}
}
else
{
@ -472,7 +488,7 @@ void CClient::UpdateSocketBufferSize()
// a minimum buffer size of the sum of both sizes
const double dAudioBufferDurationMs =
( iMonoBlockSizeSam + Channel.GetAudioBlockSizeIn() ) * 1000 /
iClientSampleRate;
SYSTEM_SAMPLE_RATE;
// accumulate the standard deviations of input network stream and
// internal timer,

View file

@ -31,9 +31,9 @@
#include <qstring.h>
#include <qdatetime.h>
#include <qmessagebox.h>
#include "celt.h"
#include "global.h"
#include "socket.h"
#include "resample.h"
#include "channel.h"
#include "audiocompr.h"
#include "util.h"
@ -125,7 +125,7 @@ public:
void SetSndCrdPreferredMonoBlSizeIndex ( const int iNewIdx );
int GetSndCrdPreferredMonoBlSizeIndex()
{ return iSndCrdPreferredMonoBlSizeIndex; }
int GetSndCrdActualMonoBlSize() { return iSndCrdMonoBlockSizeSam; }
int GetSndCrdActualMonoBlSize() { return iMonoBlockSizeSam; }
void SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut )
{
@ -160,8 +160,7 @@ protected:
// callback function must be static, otherwise it does not work
static void AudioCallback ( CVector<short>& psData, void* arg );
void Init ( const int iSampleRate,
const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate );
void Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate );
void ProcessAudioData ( CVector<short>& vecsStereoSndCrd );
void UpdateSocketBufferSize();
@ -169,11 +168,18 @@ protected:
CChannel Channel;
bool bDoAutoSockBufSize;
// audio encoder/decoder
CELTMode* CeltMode;
CELTEncoder* CeltEncoder;
CELTDecoder* CeltDecoder;
int iCeltNumCodedBytes;
CVector<unsigned char> vecCeltData;
CSocket Socket;
CSound Sound;
CStereoSignalLevelMeter SignalLevelMeter;
CVector<double> vecdNetwData;
CVector<uint8_t> vecbyNetwData;
int iAudioInFader;
bool bReverbOnLeftChan;
@ -181,24 +187,15 @@ protected:
CAudioReverb AudioReverb;
int iSndCrdPreferredMonoBlSizeIndex;
int iClientSampleRate;
int iSndCrdMonoBlockSizeSam;
int iSndCrdStereoBlockSizeSam;
int iMonoBlockSizeSam;
int iStereoBlockSizeSam;
bool bOpenChatOnNewMessage;
CVector<short> vecsAudioSndCrdStereo;
CVector<double> vecdAudioSndCrdMono;
CVector<double> vecdAudioSndCrdStereo;
CVector<int16_t> vecsAudioSndCrdStereo;
CVector<double> vecdAudioStereo;
CVector<short> vecsNetwork;
// resample objects
CStereoAudioResample ResampleObjDown;
CStereoAudioResample ResampleObjUp;
CVector<int16_t> vecsNetwork;
// for ping measurement
CPreciseTime PreciseTime;

View file

@ -177,13 +177,13 @@ void CClientSettingsDlg::UpdateSoundCardFrame()
// we have input and output
TextLabelPreferredSndCrdBufDelay->setText (
QString().setNum ( (double) iPrefBufSize * 2 *
1000 / SND_CRD_SAMPLE_RATE, 'f', 2 ) + " ms (" +
1000 / SYSTEM_SAMPLE_RATE, 'f', 2 ) + " ms (" +
QString().setNum ( iPrefBufSize ) + ")" );
// actual size (use yellow color if different from preferred size)
const QString strActSizeValues =
QString().setNum ( (double) iCurActualBufSize * 2 *
1000 / SND_CRD_SAMPLE_RATE, 'f', 2 ) + " ms (" +
1000 / SYSTEM_SAMPLE_RATE, 'f', 2 ) + " ms (" +
QString().setNum ( iCurActualBufSize ) + ")";
if ( iPrefBufSize != iCurActualBufSize )
@ -299,7 +299,7 @@ void CClientSettingsDlg::OnPingTimeResult ( int iPingTime )
// the actual sound card buffer size
const int iTotalSoundCardDelayMS =
3 * pClient->GetSndCrdActualMonoBlSize() *
1000 / SND_CRD_SAMPLE_RATE;
1000 / SYSTEM_SAMPLE_RATE;
const int iDelayToFillNetworkPackets =
( pClient->GetNetwBufSizeOut() + pClient->GetAudioBlockSizeIn() ) *

View file

@ -38,12 +38,12 @@
/* Definitions ****************************************************************/
// define this macro to get debug output
#define _DEBUG_
//#define _DEBUG_
#undef _DEBUG_
// version and application name (always use this version)
#undef VERSION
#define VERSION "2.3.1cvs"
#define VERSION "3.0.0cvs"
#define APP_NAME "llcon"
// file name for logging file
@ -53,34 +53,20 @@
#define DEFAULT_SERVER_ADDRESS "llcon.dyndns.org"
// defined port number for client and server
#define LLCON_DEFAULT_PORT_NUMBER 22123
#define LLCON_DEFAULT_PORT_NUMBER 22124
// system sample rate
#define SYSTEM_SAMPLE_RATE 33000
// system sample rate (the sound card and audio coder works on this sample rate)
#define SYSTEM_SAMPLE_RATE 48000
// sound card sample rate. Should be always 48 kHz to avoid sound card driver
// internal sample rate conversion which might be buggy
#define SND_CRD_SAMPLE_RATE 48000
// minimum server block duration - all other buffer durations must be a multiple
// of this duration
#define MIN_SERVER_BLOCK_DURATION_MS 2 // ms
#define MIN_SERVER_BLOCK_SIZE_SAMPLES ( MIN_SERVER_BLOCK_DURATION_MS * SYSTEM_SAMPLE_RATE / 1000 )
// System block size, this is the block size on which the audio coder works.
// All other block sizes must be a multiple of this size
#define SYSTEM_BLOCK_SIZE_SAMPLES 128
// 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)
// of bytes to be expected from the network interface
#define MAX_MONO_AUD_BUFF_SIZE_AT_48KHZ 4096
// maximum value of factor for network block size
#define MAX_NET_BLOCK_SIZE_FACTOR 3
// default network block size factor (only used for server)
#define DEF_NET_BLOCK_SIZE_FACTOR 2
// 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
@ -88,9 +74,6 @@
// default network buffer size
#define DEF_NET_BUF_SIZE_NUM_BL 10 // number of blocks
// default maximum upload rate at server (typical DSL upload for good DSL)
#define DEF_MAX_UPLOAD_RATE_KBPS 800 // kbps
// maximum number of recognized sound cards installed in the system,
// definition for "no device"
#define MAX_NUMBER_SOUND_CARDS 10
@ -130,10 +113,12 @@
#elif HAVE_INTTYPES_H
# include <inttypes.h>
#elif defined ( _WIN32 )
typedef __int16 int16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
#else
typedef short int16_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
@ -196,10 +181,10 @@ public:
/* Prototypes for global functions ********************************************/
// command line parsing, TODO do not declare functions globally but in a class
std::string UsageArguments ( char **argv );
bool GetFlagArgument ( int, char **argv, int &i, std::string strShortOpt, std::string strLongOpt );
bool GetStringArgument ( int argc, char **argv, int &i, std::string strShortOpt, std::string strLongOpt, std::string & strArg );
bool GetNumericArgument ( int argc, char **argv, int &i, std::string strShortOpt, std::string strLongOpt, double rRangeStart, double rRangeStop, double & rValue);
std::string UsageArguments ( char** argv );
bool GetFlagArgument ( int argc, char** argv, int& i, std::string strShortOpt, std::string strLongOpt );
bool GetStringArgument ( int argc, char** argv, int& i, std::string strShortOpt, std::string strLongOpt, std::string& strArg );
bool GetNumericArgument ( int argc, char** argv, int& i, std::string strShortOpt, std::string strLongOpt, double rRangeStart, double rRangeStop, double& rValue);
// posting a window message
void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam = 0,

View file

@ -48,7 +48,6 @@ int main ( int argc, char** argv )
bool bUseGUI = true;
bool bConnectOnStartup = false;
bool bDisalbeLEDs = false;
int iUploadRateLimitKbps = DEF_MAX_UPLOAD_RATE_KBPS;
quint16 iPortNumber = LLCON_DEFAULT_PORT_NUMBER;
std::string strIniFileName = "";
std::string strHTMLStatusFileName = "";
@ -97,17 +96,6 @@ int main ( int argc, char** argv )
}
// force low upload data rate flag -------------------------------------
if ( GetNumericArgument ( argc, argv, i, "-u", "--maxuploadrate",
100, 1000000, rDbleArgument ) )
{
iUploadRateLimitKbps = static_cast<int> ( rDbleArgument );
cout << "maximum upload rate: " << iUploadRateLimitKbps <<
" kbps" << std::endl;
continue;
}
// port number ---------------------------------------------------------
if ( GetNumericArgument ( argc, argv, i, "-p", "--port",
0, 65535, rDbleArgument ) )
@ -246,8 +234,7 @@ int main ( int argc, char** argv )
iPortNumber,
strHTMLStatusFileName.c_str(),
strHistoryFileName.c_str(),
strServerName.c_str(),
iUploadRateLimitKbps );
strServerName.c_str() );
if ( bUseGUI )
{
@ -307,10 +294,11 @@ std::string UsageArguments ( char **argv )
" client)\n"
" -p, --port local port number (only avaiable for server)\n"
" -m, --htmlstatus enable HTML status file, set file name (only\n"
" avaiable for server)\n"
" available for server)\n"
" -a, --servername server name required for HTML status (only\n"
" available for server)\n"
" -y, --history enable connection history and set file\n"
" name (only available for server)\n"
" -u, --maxuploadrate maximum upload rate (only avaiable for server)\n"
" -c, --connect connect to last server on startup (only\n"
" available for client)\n"
" -d, --disableleds disable LEDs in main window (only available\n"
@ -319,8 +307,11 @@ std::string UsageArguments ( char **argv )
"Example: " + std::string ( argv[0] ) + " -l -inifile myinifile.ini\n";
}
bool GetFlagArgument ( int, char **argv, int &i,
std::string strShortOpt, std::string strLongOpt )
bool GetFlagArgument ( int argc,
char** argv,
int& i,
std::string strShortOpt,
std::string strLongOpt )
{
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) )
{
@ -332,9 +323,12 @@ bool GetFlagArgument ( int, char **argv, int &i,
}
}
bool GetStringArgument ( int argc, char **argv, int &i,
std::string strShortOpt, std::string strLongOpt,
std::string & strArg )
bool GetStringArgument ( int argc,
char** argv,
int& i,
std::string strShortOpt,
std::string strLongOpt,
std::string& strArg )
{
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) )
{
@ -355,10 +349,14 @@ bool GetStringArgument ( int argc, char **argv, int &i,
}
}
bool GetNumericArgument ( int argc, char **argv, int &i,
std::string strShortOpt, std::string strLongOpt,
double rRangeStart, double rRangeStop,
double & rValue)
bool GetNumericArgument ( int argc,
char** argv,
int& i,
std::string strShortOpt,
std::string strLongOpt,
double rRangeStart,
double rRangeStop,
double& rValue)
{
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) )
{
@ -392,7 +390,8 @@ bool GetNumericArgument ( int argc, char **argv, int &i,
/******************************************************************************\
* Window Message System *
\******************************************************************************/
void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam,
void PostWinMessage ( const _MESSAGE_IDENT MessID,
const int iMessageParam,
const int iChanNum )
{
// first check if application is initialized

View file

@ -124,6 +124,7 @@ MESSAGES
- 0: none, no audio coding applied
- 1: IMA-ADPCM
- 2: MS-ADPCM
- 3: CELT
- "audiocod arg": argument for the audio coder, if not used this value shall be set to 0

View file

@ -40,18 +40,17 @@
#define PROTMESSID_ACKN 1 // acknowledge
#define PROTMESSID_JITT_BUF_SIZE 10 // jitter buffer size
#define PROTMESSID_REQ_JITT_BUF_SIZE 11 // request jitter buffer size
#define PROTMESSID_PING 12 // OLD, not used anymore
#define PROTMESSID_NET_BLSI_FACTOR 13 // network buffer size factor
#define PROTMESSID_CHANNEL_GAIN 14 // set channel gain for mix
#define PROTMESSID_CONN_CLIENTS_LIST 15 // connected client list
#define PROTMESSID_SERVER_FULL 16 // server full message
#define PROTMESSID_REQ_CONN_CLIENTS_LIST 17 // request connected client list
#define PROTMESSID_CHANNEL_NAME 18 // set channel name for fader tag
#define PROTMESSID_CHAT_TEXT 19 // contains a chat text
#define PROTMESSID_PING_MS 20 // for measuring ping time
#define PROTMESSID_NETW_TRANSPORT_PROPS 21 // properties for network transport
#define PROTMESSID_REQ_NETW_TRANSPORT_PROPS 22 // request properties for network transport
#define PROTMESSID_DISCONNECTION 23 // disconnection
#define PROTMESSID_NET_BLSI_FACTOR 12 // network buffer size factor
#define PROTMESSID_CHANNEL_GAIN 13 // set channel gain for mix
#define PROTMESSID_CONN_CLIENTS_LIST 14 // connected client list
#define PROTMESSID_SERVER_FULL 15 // server full message
#define PROTMESSID_REQ_CONN_CLIENTS_LIST 16 // request connected client list
#define PROTMESSID_CHANNEL_NAME 17 // set channel name for fader tag
#define PROTMESSID_CHAT_TEXT 18 // contains a chat text
#define PROTMESSID_PING_MS 19 // for measuring ping time
#define PROTMESSID_NETW_TRANSPORT_PROPS 20 // properties for network transport
#define PROTMESSID_REQ_NETW_TRANSPORT_PROPS 21 // request properties for network transport
#define PROTMESSID_DISCONNECTION 22 // disconnection
// lengths of message as defined in protocol.cpp file
#define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2)

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -30,10 +30,8 @@ CServer::CServer ( const QString& strLoggingFileName,
const quint16 iPortNumber,
const QString& strHTMLStatusFileName,
const QString& strHistoryFileName,
const QString& strServerNameForHTMLStatusFile,
const int iNewUploadRateLimitKbps ) :
Socket ( &ChannelSet, this, iPortNumber ),
ChannelSet ( iNewUploadRateLimitKbps )
const QString& strServerNameForHTMLStatusFile ) :
Socket ( &ChannelSet, this, iPortNumber )
{
vecsSendData.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES );

View file

@ -46,8 +46,7 @@ public:
const quint16 iPortNumber,
const QString& strHTMLStatusFileName,
const QString& strHistoryFileName,
const QString& strServerNameForHTMLStatusFile,
const int iNewUploadRateLimitKbps );
const QString& strServerNameForHTMLStatusFile );
virtual ~CServer() {}
void Start();

View file

@ -37,7 +37,7 @@ class CSoundBase : public QThread
public:
CSoundBase ( const bool bNewIsCallbackAudioInterface,
void (*fpNewProcessCallback) ( CVector<short>& psData, void* pParg ),
void (*fpNewProcessCallback) ( CVector<int16_t>& psData, void* pParg ),
void* pParg ) : fpProcessCallback ( fpNewProcessCallback ),
pProcessCallbackArg ( pParg ), bRun ( false ),
bIsCallbackAudioInterface ( bNewIsCallbackAudioInterface ) {}
@ -56,25 +56,25 @@ public:
protected:
// function pointer to callback function
void (*fpProcessCallback) ( CVector<short>& psData, void* arg );
void (*fpProcessCallback) ( CVector<int16_t>& psData, void* arg );
void* pProcessCallbackArg;
// callback function call for derived classes
void ProcessCallback ( CVector<short>& psData )
void ProcessCallback ( CVector<int16_t>& psData )
{
(*fpProcessCallback) ( psData, pProcessCallbackArg );
}
// 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; }
virtual bool Write ( CVector<short>& psData ) { printf ( "no sound!" ); return false; }
virtual bool Read ( CVector<int16_t>& psData ) { printf ( "no sound!" ); return false; }
virtual bool Write ( CVector<int16_t>& psData ) { printf ( "no sound!" ); return false; }
void run();
bool bRun;
bool bIsCallbackAudioInterface;
CVector<short> vecsAudioSndCrdStereo;
CVector<int16_t> vecsAudioSndCrdStereo;
signals:
void ReinitRequest();

View file

@ -27,10 +27,10 @@
/* Implementation *************************************************************/
// Input level meter implementation --------------------------------------------
void CStereoSignalLevelMeter::Update ( CVector<double>& vecdAudio )
void CStereoSignalLevelMeter::Update ( CVector<short>& vecsAudio )
{
// get the stereo vector size
const int iStereoVecSize = vecdAudio.Size();
const int iStereoVecSize = vecsAudio.Size();
// Get maximum of current block
//
@ -43,28 +43,28 @@ void CStereoSignalLevelMeter::Update ( CVector<double>& vecdAudio )
// special cases but for the average music signals the following code
// should give good results.
//
double dMaxL = 0.0;
double dMaxR = 0.0;
short sMaxL = 0;
short sMaxR = 0;
for ( int i = 0; i < iStereoVecSize; i += 6 ) // 2 * 3 = 6 -> stereo
{
// left channel
if ( dMaxL < vecdAudio[i] )
if ( sMaxL < vecsAudio[i] )
{
dMaxL = vecdAudio[i];
sMaxL = vecsAudio[i];
}
// right channel
if ( dMaxR < vecdAudio[i + 1] )
if ( sMaxR < vecsAudio[i + 1] )
{
dMaxR = vecdAudio[i + 1];
sMaxR = vecsAudio[i + 1];
}
}
dCurLevelL = UpdateCurLevel ( dCurLevelL, dMaxL );
dCurLevelR = UpdateCurLevel ( dCurLevelR, dMaxR );
dCurLevelL = UpdateCurLevel ( dCurLevelL, sMaxL );
dCurLevelR = UpdateCurLevel ( dCurLevelR, sMaxR );
}
double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel, const double& dMax )
double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel, const short& sMax )
{
// decrease max with time
if ( dCurLevel >= METER_FLY_BACK )
@ -78,9 +78,9 @@ double CStereoSignalLevelMeter::UpdateCurLevel ( double dCurLevel, const double&
}
// update current level -> only use maximum
if ( dMax > dCurLevel )
if ( static_cast<double> ( sMax ) > dCurLevel )
{
return dMax;
return static_cast<double> ( sMax );
}
else
{
@ -331,6 +331,7 @@ CAboutDlg::CAboutDlg ( QWidget* parent ) : QDialog ( parent )
"</b></p>"
"<ul>"
"<li>Qt cross-platform application framework: <i>http://trolltech.com</li>"
"<li>The CELT ultra-low delay audio codec: <i>http://www.celt-codec.org</li>"
"<li>Audio reverberation code: by Perry R. Cook and Gary P. Scavone, "
"1995 - 2004 (taken from <i>The Synthesis ToolKit in C++ (STK)</i>)</li>"
"<li>ADPCM coders by Erik de Castro Lopo</li>"

View file

@ -363,14 +363,14 @@ public:
CStereoSignalLevelMeter() { Reset(); }
virtual ~CStereoSignalLevelMeter() {}
void Update ( CVector<double>& vecdAudio );
void Update ( CVector<short>& vecsAudio );
double MicLevelLeft() { return CalcLogResult ( dCurLevelL ); }
double MicLevelRight() { return CalcLogResult ( dCurLevelR ); }
void Reset() { dCurLevelL = 0.0; dCurLevelR = 0.0; }
protected:
double CalcLogResult ( const double& dLinearLevel );
double UpdateCurLevel ( double dCurLevel, const double& dMax );
double UpdateCurLevel ( double dCurLevel, const short& sMax );
double dCurLevelL;
double dCurLevelR;
@ -417,7 +417,8 @@ enum EAudComprType
{
CT_NONE = 0,
CT_IMAADPCM = 1,
CT_MSADPCM = 2
CT_MSADPCM = 2,
CT_CELT = 3
};
class CNetworkTransportProps
@ -448,17 +449,15 @@ public:
// we use a conservative value as default, this value does not
// give perfekt latency results but should work ok on most
// sound cards and drivers
static int GetDefaultIndex() { return 5; }
static int GetDefaultIndex() { return 1; }
static int GetNumOfBufferSizes() { return 16; }
static int GetNumOfBufferSizes() { return 4; }
static int GetBufferSizeFromIndex ( const int iIdx )
{
if ( ( iIdx >= 0 ) && ( iIdx < 16 ) )
if ( ( iIdx >= 0 ) && ( iIdx < 4 ) )
{
const int pSizes[16] = {
96, 128, 160, 192, 224, 256, 288, 320, 352,
384, 416, 448, 480, 512, 768, 1024 };
const int pSizes[4] = { 128, 256, 512, 1024 };
return pSizes[iIdx];
}
else

View file

@ -48,8 +48,8 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\Qt&quot;;../src;ASIOSDK2/common;ASIOSDK2/host;ASIOSDK2/host/pc"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;QT_DLL;QT_THREAD_SUPPORT"
AdditionalIncludeDirectories="&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\Qt&quot;;../src;ASIOSDK2/common;ASIOSDK2/host;ASIOSDK2/host/pc;../libs/celt/libcelt"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;QT_DLL;QT_THREAD_SUPPORT;USE_ALLOCA"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@ -146,8 +146,8 @@
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\Qt&quot;;../src;ASIOSDK2/common;ASIOSDK2/host;ASIOSDK2/host/pc"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;QT_DLL;QT_THREAD_SUPPORT"
AdditionalIncludeDirectories="&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\Qt&quot;;../src;ASIOSDK2/common;ASIOSDK2/host;ASIOSDK2/host/pc;../libs/celt/libcelt"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;QT_DLL;QT_THREAD_SUPPORT;USE_ALLOCA"
StringPooling="true"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
@ -465,28 +465,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\resample.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\server.cpp"
>
@ -945,6 +923,250 @@
</FileConfiguration>
</File>
</Filter>
<Filter
Name="CELT"
>
<File
RelativePath="..\libs\celt\libcelt\bands.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\celt.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\cwrs.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\entcode.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\entdec.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\entenc.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\header.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\kfft_single.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\kiss_fft.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\kiss_fftr.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\laplace.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\mdct.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\modes.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\pitch.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\psy.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\quant_bands.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\rangedec.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\rangeenc.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\rate.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libs\celt\libcelt\vq.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
@ -1002,14 +1224,6 @@
RelativePath="..\src\protocol.h"
>
</File>
<File
RelativePath="..\src\resample.h"
>
</File>
<File
RelativePath="..\src\resamplefilter.h"
>
</File>
<File
RelativePath="..\src\server.h"
>

View file

@ -188,7 +188,7 @@ std::string CSound::CheckDeviceCapabilities()
// message is returned.
// check the sample rate
const ASIOError CanSaRateReturn = ASIOCanSampleRate ( SND_CRD_SAMPLE_RATE );
const ASIOError CanSaRateReturn = ASIOCanSampleRate ( SYSTEM_SAMPLE_RATE );
if ( ( CanSaRateReturn == ASE_NoClock ) ||
( CanSaRateReturn == ASE_NotPresent ) )
{
@ -327,7 +327,7 @@ int CSound::Init ( const int iNewPrefMonoBufferSize )
iASIOBufferSizeStereo = 2 * iASIOBufferSizeMono;
// set the sample rate
ASIOSetSampleRate ( SND_CRD_SAMPLE_RATE );
ASIOSetSampleRate ( SYSTEM_SAMPLE_RATE );
// create memory for intermediate audio buffer
vecsTmpAudioSndCrdStereo.Init ( iASIOBufferSizeStereo );

View file

@ -55,7 +55,7 @@
class CSound : public CSoundBase
{
public:
CSound ( void (*fpNewCallback) ( CVector<short>& psData, void* arg ), void* arg );
CSound ( void (*fpNewCallback) ( CVector<int16_t>& psData, void* arg ), void* arg );
virtual ~CSound();
virtual int Init ( const int iNewPrefMonoBufferSize );
@ -87,7 +87,7 @@ protected:
// callbacks
static void bufferSwitch ( long index, ASIOBool processNow );
static ASIOTime* bufferSwitchTimeInfo ( ASIOTime *timeInfo, long index, ASIOBool processNow );
static ASIOTime* bufferSwitchTimeInfo ( ASIOTime* timeInfo, long index, ASIOBool processNow );
static void sampleRateChanged ( ASIOSampleRate sRate ) {}
static long asioMessages ( long selector, long value, void* message, double* opt );