diff --git a/src/buffer.cpp b/src/buffer.cpp index 5c3a23dc..18769283 100755 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -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& vecdData ) +bool CNetBuf::Put ( const CVector& 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& vecdData ) +bool CNetBuf::Get ( CVector& 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& 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& 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& 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& 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& 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& 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 ) diff --git a/src/buffer.h b/src/buffer.h index 291ea4f5..3e7f1716 100755 --- a/src/buffer.h +++ b/src/buffer.h @@ -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& vecdData ); - bool Get ( CVector& vecdData ); + bool Put ( const CVector& vecbyData ); + bool Get ( CVector& 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& vecdData ); - void FadeOutExtrapolateAudioDataBlock ( CVector& vecdData, - const double dExPDiff, const double dExPLastV ); - CVector vecdMemory; - int iMemSize; - int iBlockSize; - int iGetPos, iPutPos; - EBufState eBufState; - bool bFadeInNewPutData; - int iNumSamFading; - int iNumSamFadingExtra; - - // extrapolation parameters - double dExPDiff; - double dExPLastV; + CVector vecbyMemory; + int iMemSize; + int iBlockSize; + int iGetPos, iPutPos; + EBufState eBufState; }; diff --git a/src/channel.cpp b/src/channel.cpp index 328729a0..3c7b2200 100755 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -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& 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& 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& 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 vecsDecomprAudio ( AudioCompressionIn.Decode ( vecbyData ) ); + // set audio packet flag + bIsAudioPacket = true; - // convert received data from short to double - const int iAudioSize = vecsDecomprAudio.Size(); - CVector vecdDecomprAudio ( iAudioSize ); - for ( int i = 0; i < iAudioSize; i++ ) - { - vecdDecomprAudio[i] = static_cast ( 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& 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& vecbyData, return eRet; } -EGetDataStat CChannel::GetData ( CVector& vecdData ) +EGetDataStat CChannel::GetData ( CVector& 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 ) { diff --git a/src/channel.h b/src/channel.h index 99bc6647..aa037a44 100755 --- a/src/channel.h +++ b/src/channel.h @@ -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& vecbyData, int iNumBytes ); - EGetDataStat GetData ( CVector& vecdData ); + EGetDataStat GetData ( CVector& vecbyData ); CVector PrepSendPacket ( const CVector& 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 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& vecbyRecBuf, @@ -267,9 +258,6 @@ public: void StartStatusHTMLFileWriting ( const QString& strNewFileName, const QString& strNewServerNameWithPort ); - void SetUploadRateLimitKbps ( const int iNewUploadRateLimitKbps ) - { iUploadRateLimitKbps = iNewUploadRateLimitKbps; } - protected: CVector 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 vstrChatColors; - int iUploadRateLimitKbps; - // HTML file server status bool bWriteStatusHTMLFile; QString strServerHTMLFileListName; diff --git a/src/client.cpp b/src/client.cpp index 774f17fb..515bdebc 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -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& psData, void* arg ) +void CClient::AudioCallback ( CVector& psData, void* arg ) { // get the pointer to the object CClient* pMyClientObj = reinterpret_cast ( arg ); @@ -263,70 +261,62 @@ void CClient::AudioCallback ( CVector& 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& vecsStereoSndCrd ) +void CClient::ProcessAudioData ( CVector& 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& 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 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, diff --git a/src/client.h b/src/client.h index d80495d2..28f3b574 100755 --- a/src/client.h +++ b/src/client.h @@ -31,9 +31,9 @@ #include #include #include +#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& psData, void* arg ); - void Init ( const int iSampleRate, - const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ); + void Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ); void ProcessAudioData ( CVector& vecsStereoSndCrd ); void UpdateSocketBufferSize(); @@ -169,11 +168,18 @@ protected: CChannel Channel; bool bDoAutoSockBufSize; + // audio encoder/decoder + CELTMode* CeltMode; + CELTEncoder* CeltEncoder; + CELTDecoder* CeltDecoder; + int iCeltNumCodedBytes; + CVector vecCeltData; + CSocket Socket; CSound Sound; CStereoSignalLevelMeter SignalLevelMeter; - CVector vecdNetwData; + CVector 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 vecsAudioSndCrdStereo; - CVector vecdAudioSndCrdMono; - CVector vecdAudioSndCrdStereo; + CVector vecsAudioSndCrdStereo; CVector vecdAudioStereo; - CVector vecsNetwork; - - // resample objects - CStereoAudioResample ResampleObjDown; - CStereoAudioResample ResampleObjUp; + CVector vecsNetwork; // for ping measurement CPreciseTime PreciseTime; diff --git a/src/clientsettingsdlg.cpp b/src/clientsettingsdlg.cpp index b28e7748..bf5d6e3e 100755 --- a/src/clientsettingsdlg.cpp +++ b/src/clientsettingsdlg.cpp @@ -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() ) * diff --git a/src/global.h b/src/global.h index cd31d91e..54f643b7 100755 --- a/src/global.h +++ b/src/global.h @@ -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 #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, diff --git a/src/main.cpp b/src/main.cpp index 357d0e64..0b39b8eb 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -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 ( 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 diff --git a/src/protocol.cpp b/src/protocol.cpp index 0dd30304..f7ed3781 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -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 diff --git a/src/protocol.h b/src/protocol.h index 0ec164bf..8f830628 100755 --- a/src/protocol.h +++ b/src/protocol.h @@ -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) diff --git a/src/res/frontpicture.xcf b/src/res/frontpicture.xcf index a37c58ed..d5de666e 100755 Binary files a/src/res/frontpicture.xcf and b/src/res/frontpicture.xcf differ diff --git a/src/res/gig.png b/src/res/gig.png index 970d0f48..19df1db1 100755 Binary files a/src/res/gig.png and b/src/res/gig.png differ diff --git a/src/server.cpp b/src/server.cpp index a498489f..7805b84a 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -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 ); diff --git a/src/server.h b/src/server.h index 38f7ab46..109592cc 100755 --- a/src/server.h +++ b/src/server.h @@ -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(); diff --git a/src/soundbase.h b/src/soundbase.h index 6f4414f5..e8e58954 100755 --- a/src/soundbase.h +++ b/src/soundbase.h @@ -37,7 +37,7 @@ class CSoundBase : public QThread public: CSoundBase ( const bool bNewIsCallbackAudioInterface, - void (*fpNewProcessCallback) ( CVector& psData, void* pParg ), + void (*fpNewProcessCallback) ( CVector& 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& psData, void* arg ); + void (*fpProcessCallback) ( CVector& psData, void* arg ); void* pProcessCallbackArg; // callback function call for derived classes - void ProcessCallback ( CVector& psData ) + void ProcessCallback ( CVector& psData ) { (*fpProcessCallback) ( psData, pProcessCallbackArg ); } // these functions should be overwritten by derived class for // non callback based audio interfaces - virtual bool Read ( CVector& psData ) { printf ( "no sound!" ); return false; } - virtual bool Write ( CVector& psData ) { printf ( "no sound!" ); return false; } + virtual bool Read ( CVector& psData ) { printf ( "no sound!" ); return false; } + virtual bool Write ( CVector& psData ) { printf ( "no sound!" ); return false; } void run(); bool bRun; bool bIsCallbackAudioInterface; - CVector vecsAudioSndCrdStereo; + CVector vecsAudioSndCrdStereo; signals: void ReinitRequest(); diff --git a/src/util.cpp b/src/util.cpp index d3ef776b..ef628e5c 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -27,10 +27,10 @@ /* Implementation *************************************************************/ // Input level meter implementation -------------------------------------------- -void CStereoSignalLevelMeter::Update ( CVector& vecdAudio ) +void CStereoSignalLevelMeter::Update ( CVector& 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& 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 ( sMax ) > dCurLevel ) { - return dMax; + return static_cast ( sMax ); } else { @@ -331,6 +331,7 @@ CAboutDlg::CAboutDlg ( QWidget* parent ) : QDialog ( parent ) "

" "
    " "
  • Qt cross-platform application framework: http://trolltech.com
  • " + "
  • The CELT ultra-low delay audio codec: http://www.celt-codec.org
  • " "
  • Audio reverberation code: by Perry R. Cook and Gary P. Scavone, " "1995 - 2004 (taken from The Synthesis ToolKit in C++ (STK))
  • " "
  • ADPCM coders by Erik de Castro Lopo
  • " diff --git a/src/util.h b/src/util.h index 66f212d9..23f31d14 100755 --- a/src/util.h +++ b/src/util.h @@ -363,14 +363,14 @@ public: CStereoSignalLevelMeter() { Reset(); } virtual ~CStereoSignalLevelMeter() {} - void Update ( CVector& vecdAudio ); + void Update ( CVector& 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 diff --git a/windows/llcon.vcproj b/windows/llcon.vcproj index 0b38c831..49b943eb 100755 --- a/windows/llcon.vcproj +++ b/windows/llcon.vcproj @@ -48,8 +48,8 @@ - - - - - - - - @@ -945,6 +923,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - diff --git a/windows/sound.cpp b/windows/sound.cpp index a20b5c27..74a60a3f 100755 --- a/windows/sound.cpp +++ b/windows/sound.cpp @@ -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 ); diff --git a/windows/sound.h b/windows/sound.h index 866d6e1a..cc2feaa0 100755 --- a/windows/sound.h +++ b/windows/sound.h @@ -55,7 +55,7 @@ class CSound : public CSoundBase { public: - CSound ( void (*fpNewCallback) ( CVector& psData, void* arg ), void* arg ); + CSound ( void (*fpNewCallback) ( CVector& 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 );