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; iBlockSize = iNewBlockSize;
iMemSize = iNewBlockSize * iNewNumBlocks; iMemSize = iNewBlockSize * iNewNumBlocks;
// fade in first block added to the buffer
bFadeInNewPutData = true;
// allocate and clear memory for actual data buffer // 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 // use the "get" flag to make sure the buffer is cleared
Clear ( CT_GET ); 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_ #ifdef _DEBUG_
static FILE* pFileBI = fopen("bufferin.dat", "w"); static FILE* pFileBI = fopen("bufferin.dat", "w");
@ -79,7 +53,7 @@ fflush(pFileBI);
bool bPutOK = true; bool bPutOK = true;
// get size of data to be added to the buffer // 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 // Check if there is not enough space available -> correct
if ( GetAvailSpace() < iInSize ) if ( GetAvailSpace() < iInSize )
@ -88,9 +62,6 @@ fflush(pFileBI);
// prepare for new data // prepare for new data
Clear ( CT_PUT ); Clear ( CT_PUT );
// set flag to fade in new block to avoid clicks
bFadeInNewPutData = true;
bPutOK = false; // return error flag bPutOK = false; // return error flag
// check for special case: buffer memory is not sufficient // 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 // copy new data in internal buffer
int iCurPos = 0; int iCurPos = 0;
if ( iPutPos + iInSize > iMemSize ) if ( iPutPos + iInSize > iMemSize )
@ -117,12 +82,12 @@ fflush(pFileBI);
// data must be written in two steps because of wrap around // data must be written in two steps because of wrap around
while ( iPutPos < iMemSize ) while ( iPutPos < iMemSize )
{ {
vecdMemory[iPutPos++] = vecdData[iCurPos++]; vecbyMemory[iPutPos++] = vecbyData[iCurPos++];
} }
for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ ) for ( iPutPos = 0; iPutPos < iRemSpace; iPutPos++ )
{ {
vecdMemory[iPutPos] = vecdData[iCurPos++]; vecbyMemory[iPutPos] = vecbyData[iCurPos++];
} }
} }
else else
@ -131,7 +96,7 @@ fflush(pFileBI);
const int iEnd = iPutPos + iInSize; const int iEnd = iPutPos + iInSize;
while ( iPutPos < iEnd ) while ( iPutPos < iEnd )
{ {
vecdMemory[iPutPos++] = vecdData[iCurPos++]; vecbyMemory[iPutPos++] = vecbyData[iCurPos++];
} }
} }
@ -148,13 +113,12 @@ fflush(pFileBI);
return bPutOK; return bPutOK;
} }
bool CNetBuf::Get ( CVector<double>& vecdData ) bool CNetBuf::Get ( CVector<uint8_t>& vecbyData )
{ {
bool bGetOK = true; // init return value bool bGetOK = true; // init return value
bool bFadeOutExtrap = false;
// get size of data to be get from the buffer // 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 // Check if there is not enough data available -> correct
if ( GetAvailData() < iInSize ) if ( GetAvailData() < iInSize )
@ -163,11 +127,6 @@ bool CNetBuf::Get ( CVector<double>& vecdData )
// prepare for getting data // prepare for getting data
Clear ( CT_GET ); 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 bGetOK = false; // return error flag
// check for special case: buffer memory is not sufficient // 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 // data must be read in two steps because of wrap around
while ( iGetPos < iMemSize ) while ( iGetPos < iMemSize )
{ {
vecdData[iCurPos++] = vecdMemory[iGetPos++]; vecbyData[iCurPos++] = vecbyMemory[iGetPos++];
} }
for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ ) for ( iGetPos = 0; iGetPos < iRemData; iGetPos++ )
{ {
vecdData[iCurPos++] = vecdMemory[iGetPos]; vecbyData[iCurPos++] = vecbyMemory[iGetPos];
} }
} }
else else
@ -202,7 +161,7 @@ bool CNetBuf::Get ( CVector<double>& vecdData )
const int iEnd = iGetPos + iInSize; const int iEnd = iGetPos + iInSize;
while ( iGetPos < iEnd ) 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; 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; return bGetOK;
} }
@ -303,7 +245,7 @@ void CNetBuf::Clear ( const EClearType eClearType )
if ( eClearType == CT_GET ) if ( eClearType == CT_GET )
{ {
// clear buffer // clear buffer
vecdMemory.Reset ( 0.0 ); vecbyMemory.Reset ( 0 );
// correct buffer so that after the current get operation the pointer // correct buffer so that after the current get operation the pointer
// are at maximum distance // are at maximum distance
@ -334,38 +276,6 @@ void CNetBuf::Clear ( const EClearType eClearType )
iPutPos -= iMemSize; 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 // check for special case
if ( iPutPos == iGetPos ) 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 *******************************************/ /* conversion buffer implementation *******************************************/
void CConvBuf::Init ( const int iNewMemSize ) void CConvBuf::Init ( const int iNewMemSize )

View file

@ -29,15 +29,6 @@
#include "global.h" #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 ********************************************************************/ /* Classes ********************************************************************/
class CNetBuf class CNetBuf
{ {
@ -48,8 +39,8 @@ public:
void Init ( const int iNewBlockSize, const int iNewNumBlocks ); void Init ( const int iNewBlockSize, const int iNewNumBlocks );
int GetSize() { return iMemSize / iBlockSize; } int GetSize() { return iMemSize / iBlockSize; }
bool Put ( CVector<double>& vecdData ); bool Put ( const CVector<uint8_t>& vecbyData );
bool Get ( CVector<double>& vecdData ); bool Get ( CVector<uint8_t>& vecbyData );
protected: protected:
enum EBufState { BS_OK, BS_FULL, BS_EMPTY }; enum EBufState { BS_OK, BS_FULL, BS_EMPTY };
@ -57,22 +48,12 @@ protected:
void Clear ( const EClearType eClearType ); void Clear ( const EClearType eClearType );
int GetAvailSpace() const; int GetAvailSpace() const;
int GetAvailData() const; int GetAvailData() const;
void FadeInAudioDataBlock ( CVector<double>& vecdData );
void FadeOutExtrapolateAudioDataBlock ( CVector<double>& vecdData,
const double dExPDiff, const double dExPLastV );
CVector<double> vecdMemory; CVector<uint8_t> vecbyMemory;
int iMemSize; int iMemSize;
int iBlockSize; int iBlockSize;
int iGetPos, iPutPos; int iGetPos, iPutPos;
EBufState eBufState; EBufState eBufState;
bool bFadeInNewPutData;
int iNumSamFading;
int iNumSamFadingExtra;
// extrapolation parameters
double dExPDiff;
double dExPLastV;
}; };

View file

@ -28,9 +28,8 @@
/******************************************************************************\ /******************************************************************************\
* CChannelSet * * CChannelSet *
\******************************************************************************/ \******************************************************************************/
CChannelSet::CChannelSet ( const int iNewUploadRateLimitKbps ) : CChannelSet::CChannelSet() :
bWriteStatusHTMLFile ( false ), bWriteStatusHTMLFile ( false )
iUploadRateLimitKbps ( iNewUploadRateLimitKbps )
{ {
// enable all channels (for the server all channel must be enabled the // enable all channels (for the server all channel must be enabled the
// entire life time of the software // 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 // read out all input buffers to decrease timeout counter on
// disconnected channels // 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 // if channel was just disconnected, set flag that connected
// client list is sent to all other clients // client list is sent to all other clients
@ -668,56 +668,9 @@ CChannel::CChannel ( const bool bNIsServer ) :
bIsEnabled ( false ), bIsEnabled ( false ),
iCurNetwOutBlSiFact ( DEF_NET_BLOCK_SIZE_FACTOR ) iCurNetwOutBlSiFact ( DEF_NET_BLOCK_SIZE_FACTOR )
{ {
// query all possible network in buffer sizes for determining if an // init network input properties
// audio packet was received (the following code only works if all NetwBufferInProps.iAudioBlockSize = 0;
// possible network buffer sizes are different!) NetwBufferInProps.iNetwInBufSize = 0;
// 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 );
}
// initial value for connection time out counter, we calculate the total // initial value for connection time out counter, we calculate the total
// number of samples here and subtract the number of samples of the block // number of samples here and subtract the number of samples of the block
@ -730,11 +683,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
// init the socket buffer // init the socket buffer
SetSockBufSize ( DEF_NET_BUF_SIZE_NUM_BL ); SetSockBufSize ( DEF_NET_BUF_SIZE_NUM_BL );
// set initial input and output block size factors // set initial output block size factors
SetAudioBlockSizeAndComprIn (
MIN_SERVER_BLOCK_SIZE_SAMPLES * DEF_NET_BLOCK_SIZE_FACTOR,
CT_MSADPCM );
if ( bIsServer ) if ( bIsServer )
{ {
SetNetwBufSizeFactOut ( DEF_NET_BLOCK_SIZE_FACTOR ); 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 ) void CChannel::SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut )
{ {
// this function is intended for the server (not the client) // this function is intended for the server (not the client)
QMutexLocker locker ( &Mutex ); QMutexLocker locker ( &Mutex );
// use the network block size factor only for the server // store new value
if ( bIsServer ) iCurNetwOutBlSiFact = iNewNetwBlSiFactOut;
{
// store new value
iCurNetwOutBlSiFact = iNewNetwBlSiFactOut;
// init audio compression and get audio compression block size // init audio compression and get audio compression block size
iAudComprSizeOut = AudioCompressionOut.Init ( iAudComprSizeOut = AudioCompressionOut.Init (
iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES, eAudComprTypeOut ); iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES, eAudComprTypeOut );
// init conversion buffer // init conversion buffer
ConvBuf.Init ( iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES ); ConvBuf.Init ( iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES );
}
} }
void CChannel::SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut ) void CChannel::SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut )
@ -1021,11 +937,22 @@ void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTranspor
QMutexLocker locker ( &Mutex ); QMutexLocker locker ( &Mutex );
// apply received parameters to internal data struct // apply received parameters to internal data struct
vecNetwBufferInProps[0].iAudioBlockSize = NetworkTransportProps.iMonoAudioBlockSize; NetwBufferInProps.iAudioBlockSize = NetworkTransportProps.iMonoAudioBlockSize;
vecNetwBufferInProps[0].eAudComprType = NetworkTransportProps.eAudioCodingType; NetwBufferInProps.eAudComprType = NetworkTransportProps.eAudioCodingType;
vecNetwBufferInProps[0].iNetwInBufSize = AudioCompressionIn.Init ( NetwBufferInProps.iNetwInBufSize = NetworkTransportProps.iNetworkPacketSize;
vecNetwBufferInProps[0].iAudioBlockSize,
vecNetwBufferInProps[0].eAudComprType ); // 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() void CChannel::OnReqNetTranspProps()
@ -1040,7 +967,7 @@ void CChannel::CreateNetTranspPropsMessFromCurrentSettings()
iCurAudioBlockSizeOut, iCurAudioBlockSizeOut,
1, // right now we only use mono 1, // right now we only use mono
SYSTEM_SAMPLE_RATE, // right now only one sample rate is supported SYSTEM_SAMPLE_RATE, // right now only one sample rate is supported
AudioCompressionOut.GetType(), CT_CELT, // always CELT coding
0 ); 0 );
// send current network transport properties // send current network transport properties
@ -1064,11 +991,6 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
bool bIsProtocolPacket = false; bool bIsProtocolPacket = false;
bool bIsAudioPacket = false; bool bIsAudioPacket = false;
bool bNewConnection = false; bool bNewConnection = false;
bool bReinitializeIn = false;
// intermediate storage for new parameters
int iNewAudioBlockSize;
EAudComprType eNewAudComprType;
if ( bIsEnabled ) 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 // only try to parse audio if it was not a protocol packet
if ( !bIsProtocolPacket ) 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(); Mutex.lock();
{ {
// only process audio if packet has correct size // only process audio if packet has correct size
if ( bIsAudioPacket ) if ( iNumBytes == NetwBufferInProps.iNetwInBufSize )
{ {
// decompress audio // set audio packet flag
CVector<short> vecsDecomprAudio ( AudioCompressionIn.Decode ( vecbyData ) ); bIsAudioPacket = true;
// convert received data from short to double // store new packet in jitter buffer
const int iAudioSize = vecsDecomprAudio.Size(); if ( SockBuf.Put ( vecbyData ) )
CVector<double> vecdDecomprAudio ( iAudioSize );
for ( int i = 0; i < iAudioSize; i++ )
{
vecdDecomprAudio[i] = static_cast<double> ( vecsDecomprAudio[i] );
}
if ( SockBuf.Put ( vecdDecomprAudio ) )
{ {
eRet = PS_AUDIO_OK; eRet = PS_AUDIO_OK;
} }
@ -1152,28 +1028,13 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
eRet = PS_AUDIO_ERR; eRet = PS_AUDIO_ERR;
} }
// update cycle time variance measurement, take care of // update cycle time variance measurement
// 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
{
// TODO only update if time difference of received packets is below // TODO only update if time difference of received packets is below
// a limit to avoid having short network troubles incorporated in the // a limit to avoid having short network troubles incorporated in the
// statistic // statistic
CycleTimeVariance.Update(); CycleTimeVariance.Update();
}
} }
else else
{ {
@ -1219,20 +1080,24 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
return eRet; return eRet;
} }
EGetDataStat CChannel::GetData ( CVector<double>& vecdData ) EGetDataStat CChannel::GetData ( CVector<uint8_t>& vecbyData )
{ {
QMutexLocker locker ( &Mutex ); QMutexLocker locker ( &Mutex );
EGetDataStat eGetStatus; EGetDataStat eGetStatus;
const bool bSockBufState = SockBuf.Get ( vecdData ); const bool bSockBufState = SockBuf.Get ( vecbyData );
// decrease time-out counter // decrease time-out counter
if ( iConTimeOut > 0 ) if ( iConTimeOut > 0 )
{ {
// TODO
// subtract the number of samples of the current block since the // subtract the number of samples of the current block since the
// time out counter is based on samples not on blocks // time out counter is based on samples not on blocks
iConTimeOut -= vecdData.Size(); iConTimeOut -= vecbyData.Size();
if ( iConTimeOut <= 0 ) if ( iConTimeOut <= 0 )
{ {

View file

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

View file

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

View file

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

View file

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

View file

@ -38,12 +38,12 @@
/* Definitions ****************************************************************/ /* Definitions ****************************************************************/
// define this macro to get debug output // define this macro to get debug output
#define _DEBUG_ //#define _DEBUG_
#undef _DEBUG_ #undef _DEBUG_
// version and application name (always use this version) // version and application name (always use this version)
#undef VERSION #undef VERSION
#define VERSION "2.3.1cvs" #define VERSION "3.0.0cvs"
#define APP_NAME "llcon" #define APP_NAME "llcon"
// file name for logging file // file name for logging file
@ -53,34 +53,20 @@
#define DEFAULT_SERVER_ADDRESS "llcon.dyndns.org" #define DEFAULT_SERVER_ADDRESS "llcon.dyndns.org"
// defined port number for client and server // defined port number for client and server
#define LLCON_DEFAULT_PORT_NUMBER 22123 #define LLCON_DEFAULT_PORT_NUMBER 22124
// system sample rate // system sample rate (the sound card and audio coder works on this sample rate)
#define SYSTEM_SAMPLE_RATE 33000 #define SYSTEM_SAMPLE_RATE 48000
// sound card sample rate. Should be always 48 kHz to avoid sound card driver // System block size, this is the block size on which the audio coder works.
// internal sample rate conversion which might be buggy // All other block sizes must be a multiple of this size
#define SND_CRD_SAMPLE_RATE 48000 #define SYSTEM_BLOCK_SIZE_SAMPLES 128
// 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 )
// define the maximum mono audio buffer size at a sample rate // define the maximum mono audio buffer size at a sample rate
// of 48 kHz, this is important for defining the maximum number // of 48 kHz, this is important for defining the maximum number
// of bytes to be expected from the network interface (we assume // of bytes to be expected from the network interface
// here that "MAX_NET_BLOCK_SIZE_FACTOR * MIN_SERVER_BLOCK_SIZE_SAMPLES"
// is smaller than this value here)
#define MAX_MONO_AUD_BUFF_SIZE_AT_48KHZ 4096 #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) // minimum/maximum network buffer size (which can be chosen by slider)
#define MIN_NET_BUF_SIZE_NUM_BL 1 // number of blocks #define MIN_NET_BUF_SIZE_NUM_BL 1 // number of blocks
#define MAX_NET_BUF_SIZE_NUM_BL 20 // number of blocks #define MAX_NET_BUF_SIZE_NUM_BL 20 // number of blocks
@ -88,9 +74,6 @@
// default network buffer size // default network buffer size
#define DEF_NET_BUF_SIZE_NUM_BL 10 // number of blocks #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, // maximum number of recognized sound cards installed in the system,
// definition for "no device" // definition for "no device"
#define MAX_NUMBER_SOUND_CARDS 10 #define MAX_NUMBER_SOUND_CARDS 10
@ -130,10 +113,12 @@
#elif HAVE_INTTYPES_H #elif HAVE_INTTYPES_H
# include <inttypes.h> # include <inttypes.h>
#elif defined ( _WIN32 ) #elif defined ( _WIN32 )
typedef __int16 int16_t;
typedef unsigned __int32 uint32_t; typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t; typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t; typedef unsigned __int8 uint8_t;
#else #else
typedef short int16_t;
typedef unsigned int uint32_t; typedef unsigned int uint32_t;
typedef unsigned short uint16_t; typedef unsigned short uint16_t;
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
@ -196,10 +181,10 @@ public:
/* Prototypes for global functions ********************************************/ /* Prototypes for global functions ********************************************/
// command line parsing, TODO do not declare functions globally but in a class // command line parsing, TODO do not declare functions globally but in a class
std::string UsageArguments ( char **argv ); std::string UsageArguments ( char** argv );
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 );
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 );
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);
// posting a window message // posting a window message
void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam = 0, 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 bUseGUI = true;
bool bConnectOnStartup = false; bool bConnectOnStartup = false;
bool bDisalbeLEDs = false; bool bDisalbeLEDs = false;
int iUploadRateLimitKbps = DEF_MAX_UPLOAD_RATE_KBPS;
quint16 iPortNumber = LLCON_DEFAULT_PORT_NUMBER; quint16 iPortNumber = LLCON_DEFAULT_PORT_NUMBER;
std::string strIniFileName = ""; std::string strIniFileName = "";
std::string strHTMLStatusFileName = ""; 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 --------------------------------------------------------- // port number ---------------------------------------------------------
if ( GetNumericArgument ( argc, argv, i, "-p", "--port", if ( GetNumericArgument ( argc, argv, i, "-p", "--port",
0, 65535, rDbleArgument ) ) 0, 65535, rDbleArgument ) )
@ -246,8 +234,7 @@ int main ( int argc, char** argv )
iPortNumber, iPortNumber,
strHTMLStatusFileName.c_str(), strHTMLStatusFileName.c_str(),
strHistoryFileName.c_str(), strHistoryFileName.c_str(),
strServerName.c_str(), strServerName.c_str() );
iUploadRateLimitKbps );
if ( bUseGUI ) if ( bUseGUI )
{ {
@ -307,10 +294,11 @@ std::string UsageArguments ( char **argv )
" client)\n" " client)\n"
" -p, --port local port number (only avaiable for server)\n" " -p, --port local port number (only avaiable for server)\n"
" -m, --htmlstatus enable HTML status file, set file name (only\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" " -y, --history enable connection history and set file\n"
" name (only available for server)\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" " -c, --connect connect to last server on startup (only\n"
" available for client)\n" " available for client)\n"
" -d, --disableleds disable LEDs in main window (only available\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"; "Example: " + std::string ( argv[0] ) + " -l -inifile myinifile.ini\n";
} }
bool GetFlagArgument ( int, char **argv, int &i, bool GetFlagArgument ( int argc,
std::string strShortOpt, std::string strLongOpt ) char** argv,
int& i,
std::string strShortOpt,
std::string strLongOpt )
{ {
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) 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, bool GetStringArgument ( int argc,
std::string strShortOpt, std::string strLongOpt, char** argv,
std::string & strArg ) int& i,
std::string strShortOpt,
std::string strLongOpt,
std::string& strArg )
{ {
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) 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, bool GetNumericArgument ( int argc,
std::string strShortOpt, std::string strLongOpt, char** argv,
double rRangeStart, double rRangeStop, int& i,
double & rValue) std::string strShortOpt,
std::string strLongOpt,
double rRangeStart,
double rRangeStop,
double& rValue)
{ {
if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) ) if ( ( !strShortOpt.compare ( argv[i] ) ) || ( !strLongOpt.compare ( argv[i] ) ) )
{ {
@ -392,7 +390,8 @@ bool GetNumericArgument ( int argc, char **argv, int &i,
/******************************************************************************\ /******************************************************************************\
* Window Message System * * Window Message System *
\******************************************************************************/ \******************************************************************************/
void PostWinMessage ( const _MESSAGE_IDENT MessID, const int iMessageParam, void PostWinMessage ( const _MESSAGE_IDENT MessID,
const int iMessageParam,
const int iChanNum ) const int iChanNum )
{ {
// first check if application is initialized // first check if application is initialized

View file

@ -124,6 +124,7 @@ MESSAGES
- 0: none, no audio coding applied - 0: none, no audio coding applied
- 1: IMA-ADPCM - 1: IMA-ADPCM
- 2: MS-ADPCM - 2: MS-ADPCM
- 3: CELT
- "audiocod arg": argument for the audio coder, if not used this value shall be set to 0 - "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_ACKN 1 // acknowledge
#define PROTMESSID_JITT_BUF_SIZE 10 // jitter buffer size #define PROTMESSID_JITT_BUF_SIZE 10 // jitter buffer size
#define PROTMESSID_REQ_JITT_BUF_SIZE 11 // request 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 12 // network buffer size factor
#define PROTMESSID_NET_BLSI_FACTOR 13 // network buffer size factor #define PROTMESSID_CHANNEL_GAIN 13 // set channel gain for mix
#define PROTMESSID_CHANNEL_GAIN 14 // set channel gain for mix #define PROTMESSID_CONN_CLIENTS_LIST 14 // connected client list
#define PROTMESSID_CONN_CLIENTS_LIST 15 // connected client list #define PROTMESSID_SERVER_FULL 15 // server full message
#define PROTMESSID_SERVER_FULL 16 // server full message #define PROTMESSID_REQ_CONN_CLIENTS_LIST 16 // request connected client list
#define PROTMESSID_REQ_CONN_CLIENTS_LIST 17 // request connected client list #define PROTMESSID_CHANNEL_NAME 17 // set channel name for fader tag
#define PROTMESSID_CHANNEL_NAME 18 // set channel name for fader tag #define PROTMESSID_CHAT_TEXT 18 // contains a chat text
#define PROTMESSID_CHAT_TEXT 19 // contains a chat text #define PROTMESSID_PING_MS 19 // for measuring ping time
#define PROTMESSID_PING_MS 20 // for measuring ping time #define PROTMESSID_NETW_TRANSPORT_PROPS 20 // properties for network transport
#define PROTMESSID_NETW_TRANSPORT_PROPS 21 // properties for network transport #define PROTMESSID_REQ_NETW_TRANSPORT_PROPS 21 // request properties for network transport
#define PROTMESSID_REQ_NETW_TRANSPORT_PROPS 22 // request properties for network transport #define PROTMESSID_DISCONNECTION 22 // disconnection
#define PROTMESSID_DISCONNECTION 23 // disconnection
// lengths of message as defined in protocol.cpp file // lengths of message as defined in protocol.cpp file
#define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2) #define MESS_HEADER_LENGTH_BYTE 7 // TAG (2), ID (2), cnt (1), length (2)

Binary file not shown.

Binary file not shown.

Before

(image error) Size: 103 KiB

After

(image error) Size: 48 KiB

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -48,8 +48,8 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\Qt&quot;;../src;ASIOSDK2/common;ASIOSDK2/host;ASIOSDK2/host/pc" 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" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;QT_DLL;QT_THREAD_SUPPORT;USE_ALLOCA"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="3" RuntimeLibrary="3"
@ -146,8 +146,8 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="2" Optimization="2"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\Qt&quot;;../src;ASIOSDK2/common;ASIOSDK2/host;ASIOSDK2/host/pc" 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" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;QT_DLL;QT_THREAD_SUPPORT;USE_ALLOCA"
StringPooling="true" StringPooling="true"
RuntimeLibrary="2" RuntimeLibrary="2"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"
@ -465,28 +465,6 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </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 <File
RelativePath="..\src\server.cpp" RelativePath="..\src\server.cpp"
> >
@ -945,6 +923,250 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
</Filter> </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>
<Filter <Filter
Name="Header Files" Name="Header Files"
@ -1002,14 +1224,6 @@
RelativePath="..\src\protocol.h" RelativePath="..\src\protocol.h"
> >
</File> </File>
<File
RelativePath="..\src\resample.h"
>
</File>
<File
RelativePath="..\src\resamplefilter.h"
>
</File>
<File <File
RelativePath="..\src\server.h" RelativePath="..\src\server.h"
> >

View file

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

View file

@ -55,7 +55,7 @@
class CSound : public CSoundBase class CSound : public CSoundBase
{ {
public: 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 ~CSound();
virtual int Init ( const int iNewPrefMonoBufferSize ); virtual int Init ( const int iNewPrefMonoBufferSize );
@ -87,7 +87,7 @@ protected:
// callbacks // callbacks
static void bufferSwitch ( long index, ASIOBool processNow ); 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 void sampleRateChanged ( ASIOSampleRate sRate ) {}
static long asioMessages ( long selector, long value, void* message, double* opt ); static long asioMessages ( long selector, long value, void* message, double* opt );