make the source compilable under Windows, no working functionality yet

This commit is contained in:
Volker Fischer 2009-07-24 20:17:01 +00:00
parent 548c8df2c7
commit f53d28fc11
16 changed files with 35 additions and 1440 deletions

View File

@ -1,554 +0,0 @@
/******************************************************************************\
* Copyright (c) 2004-2009
*
* Author(s):
* Volker Fischer, Erik de Castro Lopo
*
* This code is based on the Open-Source implementation of IMA-ADPCM / MS-ADPCM
* written by Erik de Castro Lopo <erikd[at-#]mega-nerd[dot*]com> in 1999-2004
*
* Changes:
* - only support for one channel
* - put 2 audio samples in header to get even number of audio samples encoded
*
******************************************************************************
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
\******************************************************************************/
#include "audiocompr.h"
/* Implementation *************************************************************/
int CAudioCompression::Init ( const int iNewAudioLen,
const EAudComprType eNewAuCoTy )
{
eAudComprType = eNewAuCoTy;
switch ( eNewAuCoTy )
{
case CT_NONE:
return iCodeSize = 2 * iNewAudioLen; // short = 2 * byte
case CT_IMAADPCM:
return ImaAdpcm.Init ( iNewAudioLen );
case CT_MSADPCM:
return MsAdpcm.Init ( iNewAudioLen );
default:
return 0;
}
}
CVector<uint8_t> CAudioCompression::Encode ( const CVector<short>& vecsAudio )
{
if ( eAudComprType == CT_NONE )
{
// no compression, simply ship pure samples
CVector<uint8_t> vecbyOut ( iCodeSize );
const int iAudSize = iCodeSize / 2;
for ( int i = 0; i < iAudSize; i++ )
{
vecbyOut[2 * i] = vecsAudio[i] & 0xFF;
vecbyOut[2 * i + 1] = ( vecsAudio[i] >> 8 ) & 0xFF;
}
return vecbyOut;
}
else
{
switch ( eAudComprType )
{
case CT_IMAADPCM:
return ImaAdpcm.Encode ( vecsAudio ); // IMA-ADPCM
case CT_MSADPCM:
return MsAdpcm.Encode ( vecsAudio ); // MS-ADPCM
default:
return CVector<uint8_t> ( 0 );
}
}
}
CVector<short> CAudioCompression::Decode ( const CVector<uint8_t>& vecbyAdpcm )
{
if ( eAudComprType == CT_NONE )
{
// no compression, reassemble pure samples
const int iAudSize = iCodeSize / 2;
CVector<short> vecsOut ( iAudSize );
for ( int i = 0; i < iAudSize; i++ )
{
int current = vecbyAdpcm[2 * i] | ( vecbyAdpcm[2 * i + 1] << 8 );
if ( current & 0x8000 )
{
current -= 0x10000;
}
vecsOut[i] = (short) current;
}
return vecsOut;
}
else
{
switch ( eAudComprType )
{
case CT_IMAADPCM:
return ImaAdpcm.Decode ( vecbyAdpcm ); // IMA-ADPCM
case CT_MSADPCM:
return MsAdpcm.Decode ( vecbyAdpcm ); // MS-ADPCM
default:
return CVector<short> ( 0 );
}
}
}
/******************************************************************************\
* IMA-ADPCM implementation *
\******************************************************************************/
int CImaAdpcm::Init ( const int iNewAudioLen )
{
// set lengths for audio and compressed data
iAudSize = iNewAudioLen;
iAdpcmSize = 4 /* bytes header */ + (int) ceil (
(double) ( iAudSize - 2 /* first two samples are in header */ ) / 2 );
iStepindEnc = 0;
return iAdpcmSize;
}
CVector<uint8_t> CImaAdpcm::Encode ( const CVector<short>& vecsAudio )
{
int i;
CVector<uint8_t> vecbyAdpcm;
CVector<uint8_t> vecbyAdpcmTemp;
// init size
vecbyAdpcm.Init ( iAdpcmSize );
vecbyAdpcmTemp.Init ( iAudSize );
/* Encode the block header ---------------------------------------------- */
vecbyAdpcm[0] = vecsAudio[0] & 0xFF;
vecbyAdpcm[1] = ( vecsAudio[0] >> 8 ) & 0xFF;
vecbyAdpcm[2] = iStepindEnc;
int iPrevAudio = vecsAudio[0];
/* Encode the samples as 4 bit ------------------------------------------ */
for ( i = 1; i < iAudSize; i++ )
{
// init diff and step
int diff = vecsAudio[i] - iPrevAudio;
Q_ASSERT ( iStepindEnc < IMA_STEP_SIZE_TAB_LEN );
int step = ima_step_size[iStepindEnc];
short bytecode = 0;
int vpdiff = step >> 3;
if ( diff < 0 )
{
bytecode = 8;
diff = -diff;
}
short mask = 4;
while ( mask )
{
if ( diff >= step )
{
bytecode |= mask;
diff -= step;
vpdiff += step;
}
step >>= 1;
mask >>= 1;
}
if ( bytecode & 8 )
{
iPrevAudio -= vpdiff;
}
else
{
iPrevAudio += vpdiff;
}
// adjust step size
Q_ASSERT ( bytecode < IMA_INDX_ADJUST_TAB_LEN );
iStepindEnc += ima_indx_adjust[bytecode];
// check that values do not exceed the bounds
iPrevAudio = CheckBounds ( iPrevAudio, _MINSHORT, _MAXSHORT );
iStepindEnc = CheckBounds ( iStepindEnc, 0, IMA_STEP_SIZE_TAB_LEN - 1 );
// use a temporary buffer as an intermediate result buffer
vecbyAdpcmTemp[i] = bytecode;
}
/* Pack the 4 bit encoded samples --------------------------------------- */
// The first encoded audio sample is in header
vecbyAdpcm[3] = vecbyAdpcmTemp[1] & 0x0F;
for ( i = 4; i < iAdpcmSize; i++ )
{
vecbyAdpcm[i] = vecbyAdpcmTemp[2 * i - 6] & 0x0F;
vecbyAdpcm[i] |= ( vecbyAdpcmTemp[2 * i - 5] << 4 ) & 0xF0;
}
return vecbyAdpcm;
}
CVector<short> CImaAdpcm::Decode ( const CVector<uint8_t>& vecbyAdpcm )
{
int i;
CVector<short> vecsAudio;
vecsAudio.Init ( iAudSize );
/* Read the block header ------------------------------------------------ */
int current = vecbyAdpcm[0] | ( vecbyAdpcm[1] << 8 );
if ( current & 0x8000 )
{
current -= 0x10000;
}
// get and bound step index
int iStepindDec = CheckBounds ( vecbyAdpcm[2], 0, IMA_STEP_SIZE_TAB_LEN - 1 );
// set first sample which was delivered in the header
vecsAudio[0] = current;
/* -------------------------------------------------------------------------
pull apart the packed 4 bit samples and store them in their correct
sample positions */
// the first encoded audio sample is in header
vecsAudio[1] = vecbyAdpcm[3] & 0x0F;
for ( i = 4; i < iAdpcmSize; i++ )
{
const short bytecode = vecbyAdpcm[i];
vecsAudio[2 * i - 6] = bytecode & 0x0F;
vecsAudio[2 * i - 5] = ( bytecode >> 4 ) & 0x0F;
}
/* Decode the encoded 4 bit samples ------------------------------------- */
for ( i = 1; i < iAudSize; i++ )
{
const short bytecode = vecsAudio[i] & 0xF;
Q_ASSERT ( iStepindDec < IMA_STEP_SIZE_TAB_LEN );
short step = ima_step_size[iStepindDec];
int current = vecsAudio[i - 1];
int diff = step >> 3;
if ( bytecode & 1 )
{
diff += step >> 2;
}
if ( bytecode & 2 )
{
diff += step >> 1;
}
if ( bytecode & 4 )
{
diff += step;
}
if ( bytecode & 8 )
{
diff = -diff;
}
current += diff;
Q_ASSERT ( bytecode < IMA_INDX_ADJUST_TAB_LEN );
iStepindDec += ima_indx_adjust[bytecode];
// check that values do not exceed the bounds
current = CheckBounds ( current, _MINSHORT, _MAXSHORT );
iStepindDec = CheckBounds ( iStepindDec, 0, IMA_STEP_SIZE_TAB_LEN - 1 );
vecsAudio[i] = current;
}
return vecsAudio;
}
/******************************************************************************\
* MS-ADPCM implementation *
\******************************************************************************/
/*
MS ADPCM block layout:
byte purpose
0 block predictor [0..6]
1,2 initial idelta (positive)
3,4 sample 1
5,6 sample 0
7..n packed bytecodes
*/
int CMsAdpcm::Init ( const int iNewAudioLen )
{
// set lengths for audio and compressed data
iAudSize = iNewAudioLen;
iAdpcmSize = 7 /* bytes header */ + (int) ceil (
(double) ( iAudSize - 2 /* first two samples are in header */ ) / 2 );
return iAdpcmSize;
}
CVector<uint8_t> CMsAdpcm::Encode ( const CVector<short>& vecsAudio )
{
CVector<short> vecsAudioTemp;
CVector<uint8_t> vecbyAdpcm;
// init size
vecsAudioTemp.Init ( iAudSize );
vecbyAdpcm.Init ( iAdpcmSize );
// copy input vector (because we want to overwrite it)
vecsAudioTemp = vecsAudio;
// choose predictor
int bpred;
int idelta;
ChoosePredictor ( vecsAudio, bpred, idelta );
/* Encode the block header ---------------------------------------------- */
vecbyAdpcm[0] = bpred;
vecbyAdpcm[1] = idelta & 0xFF;
vecbyAdpcm[2] = ( idelta >> 8 ) & 0xFF;
vecbyAdpcm[3] = vecsAudio[1] & 0xFF;
vecbyAdpcm[4] = ( vecsAudio[1] >> 8 ) & 0xFF;
vecbyAdpcm[5] = vecsAudio[0] & 0xFF;
vecbyAdpcm[6] = ( vecsAudio[0] >> 8 ) & 0xFF;
/* Encode the samples as 4 bit ------------------------------------------ */
unsigned int blockindx = 7;
uint8_t byte = 0;
for ( int k = 2; k < iAudSize; k++ )
{
const int predict = ( vecsAudioTemp[k - 1] * ms_AdaptCoeff1[bpred] +
vecsAudioTemp[k - 2] * ms_AdaptCoeff2[bpred] ) >> 8;
int errordelta = ( vecsAudio[k] - predict ) / idelta;
if ( errordelta < -8 )
{
errordelta = -8 ;
}
else
{
if (errordelta > 7)
{
errordelta = 7;
}
}
int newsamp = predict + ( idelta * errordelta );
if ( newsamp > 32767 )
{
newsamp = 32767;
}
else
{
if ( newsamp < -32768 )
{
newsamp = -32768;
}
}
if ( errordelta < 0 )
{
errordelta += 0x10;
}
byte = ( byte << 4 ) | ( errordelta & 0xF );
if ( k % 2 )
{
vecbyAdpcm[blockindx++] = byte;
byte = 0;
}
idelta = ( idelta * ms_AdaptationTable[errordelta] ) >> 8;
if ( idelta < 16 )
{
idelta = 16;
}
vecsAudioTemp[k] = newsamp;
}
return vecbyAdpcm;
}
CVector<short> CMsAdpcm::Decode ( const CVector<uint8_t>& vecbyAdpcm )
{
CVector<short> vecsAudio;
short bytecode;
vecsAudio.Init ( iAudSize );
/* Read the block header ------------------------------------------------ */
short bpred = vecbyAdpcm[0];
if ( bpred >= 7 )
{
// no valid MS ADPCM stream, do not decode
return vecsAudio;
}
short chan_idelta = vecbyAdpcm[1] | ( vecbyAdpcm[2] << 8 );
vecsAudio[1] = vecbyAdpcm[3] | ( vecbyAdpcm[4] << 8 );
vecsAudio[0] = vecbyAdpcm[5] | ( vecbyAdpcm[6] << 8 );
/* -------------------------------------------------------------------------
pull apart the packed 4 bit samples and store them in their correct
sample positions */
for ( int i = 7; i < iAdpcmSize; i++ )
{
bytecode = vecbyAdpcm[i];
vecsAudio[2 * i - 12] = ( bytecode >> 4 ) & 0x0F;
vecsAudio[2 * i - 11] = bytecode & 0x0F;
}
/* Decode the encoded 4 bit samples ------------------------------------- */
for ( int k = 2; k < iAudSize; k ++ )
{
bytecode = vecsAudio[k] & 0xF;
// compute next Adaptive Scale Factor (ASF)
int idelta = chan_idelta;
// => / 256 => FIXED_POINT_ADAPTATION_BASE == 256
chan_idelta = ( ms_AdaptationTable[bytecode] * idelta ) >> 8;
if ( chan_idelta < 16 )
{
chan_idelta = 16;
}
if ( bytecode & 0x8 )
{
bytecode -= 0x10;
}
// => / 256 => FIXED_POINT_COEFF_BASE == 256
const int predict = ( ( vecsAudio[k - 1] * ms_AdaptCoeff1[bpred] ) +
( vecsAudio[k - 2] * ms_AdaptCoeff2[bpred] ) ) >> 8;
int current = ( bytecode * idelta ) + predict;
if ( current > 32767 )
{
current = 32767;
}
else
{
if ( current < -32768 )
{
current = -32768;
}
}
vecsAudio[k] = current;
}
return vecsAudio;
}
void CMsAdpcm::ChoosePredictor ( const CVector<short>& vecsAudio,
int& block_pred,
int& idelta )
{
/*
Choosing the block predictor:
Each block requires a predictor and an idelta for each channel. The
predictor is in the range [0..6] which is an index into the two AdaptCoeff
tables. The predictor is chosen by trying all of the possible predictors on
a small set of samples at the beginning of the block. The predictor with the
smallest average abs (idelta) is chosen as the best predictor for this
block. The value of idelta is chosen to to give a 4 bit code value of +/- 4
(approx. half the max. code value). If the average abs (idelta) is zero, the
sixth predictor is chosen. If the value of idelta is less then 16 it is set
to 16.
*/
unsigned int best_bpred = 0;
unsigned int best_idelta = 0;
/* Microsoft uses an IDELTA_COUNT (number of sample pairs used to choose
best predictor) value of 3. The best possible results would be obtained
by using all the samples to choose the predictor. */
unsigned int idelta_count = min ( MSADPCM_IDELTA_COUNT, vecsAudio.Size() - 1 );
for ( unsigned int bpred = 0; bpred < MSADPCM_ADAPT_COEFF_COUNT; bpred++ )
{
unsigned int idelta_sum = 0;
for ( unsigned int k = 2; k < 2 + idelta_count; k++ )
{
idelta_sum += abs ( vecsAudio[k] -
( ( vecsAudio[k - 1] * ms_AdaptCoeff1[bpred] +
vecsAudio[k - 2] * ms_AdaptCoeff2[bpred] ) >> 8 ) );
}
idelta_sum /= ( 4 * idelta_count );
if ( bpred == 0 || idelta_sum < best_idelta )
{
best_bpred = bpred;
best_idelta = idelta_sum;
}
if ( !idelta_sum )
{
best_bpred = bpred;
best_idelta = 16;
break;
}
}
if ( best_idelta < 16 )
{
best_idelta = 16;
}
block_pred = best_bpred;
idelta = best_idelta;
return;
}

View File

@ -1,154 +0,0 @@
/******************************************************************************\
* Copyright (c) 2004-2009
*
* Author(s):
* Volker Fischer, Erik de Castro Lopo
*
******************************************************************************
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
\******************************************************************************/
#if !defined ( AUDIOCOMPR_H_OIHGE76GEKJH3249_GEG98EG3_43441912__INCLUDED_ )
#define AUDIOCOMPR_H_OIHGE76GEKJH3249_GEG98EG3_43441912__INCLUDED_
#include "util.h"
#include "global.h"
#include "buffer.h"
/* Definitions ****************************************************************/
// tables IMA-ADPCM
#define IMA_INDX_ADJUST_TAB_LEN 16
static int ima_indx_adjust[IMA_INDX_ADJUST_TAB_LEN] =
{
-1, -1, -1, -1, /* +0 - +3, decrease the step size */
2, 4, 6, 8, /* +4 - +7, increase the step size */
-1, -1, -1, -1, /* -0 - -3, decrease the step size */
2, 4, 6, 8, /* -4 - -7, increase the step size */
};
#define IMA_STEP_SIZE_TAB_LEN 89
static int ima_step_size[IMA_STEP_SIZE_TAB_LEN] =
{
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230,
253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963,
1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442,
11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
32767
};
// tables MS-ADPCM
#define MSADPCM_IDELTA_COUNT 20
#define MSADPCM_ADAPT_COEFF_COUNT 7
static int ms_AdaptCoeff1[MSADPCM_ADAPT_COEFF_COUNT] =
{
256, 512, 0, 192, 240, 460, 392
};
static int ms_AdaptCoeff2[MSADPCM_ADAPT_COEFF_COUNT] =
{
0, -256, 0, 64, 0, -208, -232
};
static int ms_AdaptationTable[] =
{
230, 230, 230, 230, 307, 409, 512, 614,
768, 614, 512, 409, 307, 230, 230, 230
};
/* Classes ********************************************************************/
/* IMA-ADPCM ---------------------------------------------------------------- */
class CImaAdpcm
{
public:
CImaAdpcm() : iStepindEnc ( 0 ) {}
virtual ~CImaAdpcm() {}
int Init ( const int iNewAudioLen );
CVector<uint8_t> Encode ( const CVector<short>& vecsAudio );
CVector<short> Decode ( const CVector<uint8_t>& vecbyAdpcm );
protected:
int iAudSize;
int iAdpcmSize;
int iStepindEnc;
// inline functions must be declared in the header
inline int CheckBounds ( const int iData, const int iMin, const int iMax )
{
if ( iData > iMax )
{
return iMax;
}
if ( iData < iMin )
{
return iMin;
}
return iData;
}
};
/* MS-ADPCM ----------------------------------------------------------------- */
class CMsAdpcm
{
public:
CMsAdpcm() {}
virtual ~CMsAdpcm() {}
int Init ( const int iNewAudioLen );
CVector<uint8_t> Encode ( const CVector<short>& vecsAudio );
CVector<short> Decode ( const CVector<uint8_t>& vecbyAdpcm );
protected:
int iAudSize;
int iAdpcmSize;
void ChoosePredictor ( const CVector<short>& vecsAudio,
int& block_pred,
int& idelta );
};
/* Audio compression class -------------------------------------------------- */
class CAudioCompression
{
public:
CAudioCompression() {}
virtual ~CAudioCompression() {}
int Init ( const int iNewAudioLen,
const EAudComprType eNewAuCoTy );
CVector<uint8_t> Encode ( const CVector<short>& vecsAudio );
CVector<short> Decode ( const CVector<uint8_t>& vecbyAdpcm );
EAudComprType GetType() { return eAudComprType; }
protected:
EAudComprType eAudComprType;
CImaAdpcm ImaAdpcm;
CMsAdpcm MsAdpcm;
int iCodeSize;
};
#endif /* !defined ( AUDIOCOMPR_H_OIHGE76GEKJH3249_GEG98EG3_43441912__INCLUDED_ ) */

View File

@ -244,86 +244,6 @@ int CChannelSet::GetFreeChan()
return INVALID_CHANNEL_ID;
}
void CChannelSet::SetOutputParameters()
{
// The strategy is as follows: Change the parameters for each channel
// until the total upload rate is lower than the limit. We first set the
// audio compression from None to MS-ADPCM for each channel and if this
// is not enough, we start to increase the buffer size factor out.
bool bUploadRateIsBelowLimit = false;
// first initialize all channels with the first parameter set (highest
// upload data rate)
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// set new parameters
vecChannels[i].SetNetwBufSizeFactOut ( 1 );
vecChannels[i].SetAudioCompressionOut ( CT_NONE );
}
}
// calculate and check total upload rate (maybe the initialization already
// gives desired upload rate)
bUploadRateIsBelowLimit =
( CalculateTotalUploadRateKbps() <= iUploadRateLimitKbps );
// try other parameter sets if required
const int iNumTrials = 3;
EAudComprType eCurAudComprType;
int iCurBlockSizeFact;
int iCurTrialIdx = 0;
while ( ( iCurTrialIdx < iNumTrials ) && ( !bUploadRateIsBelowLimit ) )
{
switch ( iCurTrialIdx )
{
case 0:
// using other audio compression gives most reduction
eCurAudComprType = CT_MSADPCM;
iCurBlockSizeFact = 1;
break;
case 1:
// trying to use larger block size factor to further reduce rate
eCurAudComprType = CT_MSADPCM;
iCurBlockSizeFact = 2;
break;
case 2:
// trying to use larger block size factor to further reduce rate
eCurAudComprType = CT_MSADPCM;
iCurBlockSizeFact = 3;
break;
}
// we try to set the worst parameters to the clients which connected
// the latest to the server, therefore we apply the new parameters to
// the last channels first
int iCurCh = USED_NUM_CHANNELS - 1;
while ( ( iCurCh >= 0 ) && ( !bUploadRateIsBelowLimit ) )
{
if ( vecChannels[iCurCh].IsConnected() )
{
// set new parameters
vecChannels[iCurCh].SetNetwBufSizeFactOut ( iCurBlockSizeFact );
vecChannels[iCurCh].SetAudioCompressionOut ( eCurAudComprType );
// calculate and check total upload rate
bUploadRateIsBelowLimit =
( CalculateTotalUploadRateKbps() <= iUploadRateLimitKbps );
}
// next channel (backwards counting)
iCurCh--;
}
// next trial index
iCurTrialIdx++;
}
}
int CChannelSet::CheckAddr ( const CHostAddress& Addr )
{
CHostAddress InetAddr;
@ -431,9 +351,6 @@ bAudioOK = true;
// requested
if ( bNewChannelReserved && bAudioOK )
{
// update output network parameters for all connected clients
SetOutputParameters();
// send message about new channel
emit ChannelConnected ( HostAdr );
@ -529,9 +446,6 @@ const EGetDataStat eGetStat=GS_BUFFER_OK;//TEST
// a channel is now disconnected, take action on it
if ( bChannelIsNowDisconnected )
{
// update output network parameters for all connected clients
SetOutputParameters();
// update channel list for all currently connected clients
CreateAndSendChanListForAllConChannels();
}
@ -542,8 +456,7 @@ const EGetDataStat eGetStat=GS_BUFFER_OK;//TEST
void CChannelSet::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CVector<QString>& vecsName,
CVector<int>& veciJitBufSize,
CVector<int>& veciNetwOutBlSiFact,
CVector<EAudComprType>& veceAudComprType )
CVector<int>& veciNetwOutBlSiFact )
{
CHostAddress InetAddr;
@ -552,7 +465,6 @@ void CChannelSet::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
vecsName.Init ( USED_NUM_CHANNELS );
veciJitBufSize.Init ( USED_NUM_CHANNELS );
veciNetwOutBlSiFact.Init ( USED_NUM_CHANNELS );
veceAudComprType.Init ( USED_NUM_CHANNELS );
// check all possible channels
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
@ -564,7 +476,6 @@ void CChannelSet::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
vecsName[i] = vecChannels[i].GetName();
veciJitBufSize[i] = vecChannels[i].GetSockBufSize();
veciNetwOutBlSiFact[i] = vecChannels[i].GetNetwBufSizeFactOut();
veceAudComprType[i] = vecChannels[i].GetAudioCompressionOut();
}
}
}
@ -651,7 +562,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
sName ( "" ),
vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ),
bIsEnabled ( false ),
iCurNetwOutBlSiFact ( DEF_NET_BLOCK_SIZE_FACTOR )
iCurNetwOutBlSiFact ( 0 )
{
// init network input properties
NetwBufferInProps.iAudioBlockSize = 0;
@ -669,6 +580,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
SetSockBufSize ( DEF_NET_BUF_SIZE_NUM_BL );
// set initial output block size factors
/*
if ( bIsServer )
{
SetNetwBufSizeFactOut ( DEF_NET_BLOCK_SIZE_FACTOR );
@ -677,9 +589,7 @@ CChannel::CChannel ( const bool bNIsServer ) :
{
SetNetwBufSizeOut ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
}
// set initial audio compression format for output
SetAudioCompressionOut ( CT_MSADPCM );
*/
// connections -------------------------------------------------------------
@ -772,26 +682,7 @@ void CChannel::SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut )
iAudComprSizeOut = iNewNetwBlSiFactOut * SYSTEM_BLOCK_SIZE_SAMPLES;
// init conversion buffer
ConvBuf.Init ( iNewNetwBlSiFactOut * MIN_SERVER_BLOCK_SIZE_SAMPLES );
}
void CChannel::SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut )
{
// store new value
eAudComprTypeOut = eNewAudComprTypeOut;
if ( bIsServer )
{
// call "set network buffer size factor" function because its
// initialization depends on the audio compression format and
// implicitely, the audio compression is initialized
SetNetwBufSizeFactOut ( iCurNetwOutBlSiFact );
}
else
{
// for client set arbitrary block size
SetNetwBufSizeOut ( iCurAudioBlockSizeOut );
}
ConvBuf.Init ( iNewNetwBlSiFactOut * SYSTEM_BLOCK_SIZE_SAMPLES );
}
bool CChannel::SetSockBufSize ( const int iNumBlocks )
@ -806,7 +697,7 @@ bool CChannel::SetSockBufSize ( const int iNumBlocks )
// the network block size is a multiple of the internal minimal
// block size
SockBuf.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES, iNumBlocks );
SockBuf.Init ( SYSTEM_BLOCK_SIZE_SAMPLES, iNumBlocks );
return false; // -> no error
}
@ -924,7 +815,6 @@ void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTranspor
// apply received parameters to internal data struct
NetwBufferInProps.iAudioBlockSize = NetworkTransportProps.iMonoAudioBlockSize;
NetwBufferInProps.eAudComprType = NetworkTransportProps.eAudioCodingType;
NetwBufferInProps.iNetwInBufSize = NetworkTransportProps.iNetworkPacketSize;
// re-initialize cycle time variance measurement if necessary
@ -950,7 +840,7 @@ void CChannel::CreateNetTranspPropsMessFromCurrentSettings()
{
CNetworkTransportProps NetworkTransportProps (
iAudComprSizeOut,
iCurAudioBlockSizeOut,
0, // TODO
1, // right now we only use mono
SYSTEM_SAMPLE_RATE, // right now only one sample rate is supported
CT_CELT, // always CELT coding
@ -1130,14 +1020,14 @@ CVector<uint8_t> CChannel::PrepSendPacket ( const CVector<short>& vecsNPacket )
{
// a packet is ready, compress audio
vecbySendBuf.Init ( iAudComprSizeOut );
vecbySendBuf = AudioCompressionOut.Encode ( ConvBuf.Get() );
// vecbySendBuf = AudioCompressionOut.Encode ( ConvBuf.Get() );
}
}
else
{
// a packet is ready, compress audio
vecbySendBuf.Init ( iAudComprSizeOut );
vecbySendBuf = AudioCompressionOut.Encode ( vecsNPacket );
// vecbySendBuf = AudioCompressionOut.Encode ( vecsNPacket );
}
return vecbySendBuf;
@ -1145,16 +1035,7 @@ CVector<uint8_t> CChannel::PrepSendPacket ( const CVector<short>& vecsNPacket )
int CChannel::GetUploadRateKbps()
{
int iAudioSizeOut;
if ( bIsServer )
{
iAudioSizeOut = iCurNetwOutBlSiFact * MIN_SERVER_BLOCK_SIZE_SAMPLES;
}
else
{
iAudioSizeOut = iCurAudioBlockSizeOut;
}
const int iAudioSizeOut = iCurNetwOutBlSiFact * SYSTEM_BLOCK_SIZE_SAMPLES;
// we assume that the UDP packet which is transported via IP has an
// additional header size of

View File

@ -103,9 +103,6 @@ public:
bool SetSockBufSize ( const int iNumBlocks );
int GetSockBufSize() { return iCurSockBufSize; }
void SetNetwBufSizeOut ( const int iNewAudioBlockSizeOut );
int GetNetwBufSizeOut() { return iCurAudioBlockSizeOut; }
int GetAudioBlockSizeIn() { return NetwBufferInProps.iAudioBlockSize; }
int GetUploadRateKbps();
@ -114,9 +111,6 @@ public:
void SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut );
int GetNetwBufSizeFactOut() { return iCurNetwOutBlSiFact; }
void SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut );
EAudComprType GetAudioCompressionOut() { return eAudComprTypeOut; }
// network protocol interface
void CreateJitBufMes ( const int iJitBufSize )
{
@ -180,7 +174,6 @@ protected:
bool bIsServer;
int iCurNetwOutBlSiFact;
int iCurAudioBlockSizeOut;
QMutex Mutex;
@ -191,8 +184,6 @@ protected:
};
sNetwProperties NetwBufferInProps;
EAudComprType eAudComprTypeOut;
public slots:
void OnSendProtMessage ( CVector<uint8_t> vecMessage );
void OnJittBufSizeChange ( int iNewJitBufSize );
@ -238,8 +229,7 @@ public:
void GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CVector<QString>& vecsName,
CVector<int>& veciJitBufSize,
CVector<int>& veciNetwOutBlSiFact,
CVector<EAudComprType>& veceAudComprType );
CVector<int>& veciNetwOutBlSiFact );
// access functions for actual channels
bool IsConnected ( const int iChanNum )
@ -262,7 +252,6 @@ protected:
void CreateAndSendChanListForThisChan ( const int iCurChanID );
void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText );
void WriteHTMLChannelList();
void SetOutputParameters();
/* do not use the vector class since CChannel does not have appropriate
copy constructor/operator */

View File

@ -302,7 +302,7 @@ void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate )
vecbyNetwData.Init ( iCeltNumCodedBytes );
// the channel works on the audio coded block size
Channel.SetNetwBufSizeOut ( iCeltNumCodedBytes );
// Channel.SetNetwBufSizeOut ( iCeltNumCodedBytes );
}
void CClient::ProcessAudioData ( CVector<int16_t>& vecsStereoSndCrd )
@ -497,7 +497,7 @@ void CClient::UpdateSocketBufferSize()
// one block in the jitter buffer
const double dEstCurBufSet = ( dAudioBufferDurationMs +
3.3 * ( Channel.GetTimingStdDev() + CycleTimeVariance.GetStdDev() ) ) /
MIN_SERVER_BLOCK_DURATION_MS + 0.5;
SYSTEM_BLOCK_DURATION_MS_FLOAT + 0.5;
// upper/lower hysteresis decision
const int iUpperHystDec = LlconMath().round ( dEstCurBufSet - dHysteresis );

View File

@ -109,7 +109,6 @@ public:
}
int GetSockBufSize() { return Channel.GetSockBufSize(); }
int GetNetwBufSizeOut() { return Channel.GetNetwBufSizeOut(); }
int GetAudioBlockSizeIn() { return Channel.GetAudioBlockSizeIn(); }
int GetUploadRateKbps() { return Channel.GetUploadRateKbps(); }
@ -126,17 +125,6 @@ public:
{ return iSndCrdPreferredMonoBlSizeIndex; }
int GetSndCrdActualMonoBlSize() { return iMonoBlockSizeSam; }
void SetAudioCompressionOut ( const EAudComprType eNewAudComprTypeOut )
{
Channel.SetAudioCompressionOut ( eNewAudComprTypeOut );
// tell the server that audio coding has changed (it
// is important to call this function AFTER we have applied
// the new setting to the channel!)
Channel.CreateNetTranspPropsMessFromCurrentSettings();
}
EAudComprType GetAudioCompressionOut() { return Channel.GetAudioCompressionOut(); }
void SetRemoteChanGain ( const int iId, const double dGain )
{ Channel.SetRemoteChanGain ( iId, dGain ); }

View File

@ -89,6 +89,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
}
// audio compression type
/*
switch ( pClient->GetAudioCompressionOut() )
{
case CT_NONE:
@ -103,6 +104,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
radioButtonMS_ADPCM->setChecked ( true );
break;
}
*/
AudioCompressionButtonGroup.addButton ( radioButtonNoAudioCompr );
AudioCompressionButtonGroup.addButton ( radioButtonIMA_ADPCM );
AudioCompressionButtonGroup.addButton ( radioButtonMS_ADPCM );
@ -259,6 +261,7 @@ void CClientSettingsDlg::OnOpenChatOnNewMessageStateChanged ( int value )
void CClientSettingsDlg::OnAudioCompressionButtonGroupClicked ( QAbstractButton* button )
{
/*
if ( button == radioButtonNoAudioCompr )
{
pClient->SetAudioCompressionOut ( CT_NONE );
@ -273,6 +276,7 @@ void CClientSettingsDlg::OnAudioCompressionButtonGroupClicked ( QAbstractButton*
{
pClient->SetAudioCompressionOut ( CT_MSADPCM );
}
*/
UpdateDisplay();
}
@ -291,7 +295,7 @@ void CClientSettingsDlg::OnPingTimeResult ( int iPingTime )
- consider the jitter buffer on the server side, too
*/
const int iTotalJitterBufferDelayMS = MIN_SERVER_BLOCK_DURATION_MS *
const int iTotalJitterBufferDelayMS = SYSTEM_BLOCK_DURATION_MS_FLOAT *
( 2 /* buffer at client and server */ * pClient->GetSockBufSize() ) / 2;
// we assume that we have two period sizes for the input and one for the
@ -301,9 +305,11 @@ void CClientSettingsDlg::OnPingTimeResult ( int iPingTime )
3 * pClient->GetSndCrdActualMonoBlSize() *
1000 / SYSTEM_SAMPLE_RATE;
const int iDelayToFillNetworkPackets =
( pClient->GetNetwBufSizeOut() + pClient->GetAudioBlockSizeIn() ) *
1000 / SYSTEM_SAMPLE_RATE;
// TODO
const int iDelayToFillNetworkPackets =0;// TEST
// ( pClient->GetNetwBufSizeOut() + pClient->GetAudioBlockSizeIn() ) *
// 1000 / SYSTEM_SAMPLE_RATE;
const int iTotalBufferDelay = iDelayToFillNetworkPackets +
iTotalJitterBufferDelayMS + iTotalSoundCardDelayMS;

View File

@ -62,6 +62,10 @@
// All other block sizes must be a multiple of this size
#define SYSTEM_BLOCK_SIZE_SAMPLES 128
#define SYSTEM_BLOCK_DURATION_MS_FLOAT \
( static_cast<double> ( SYSTEM_BLOCK_SIZE_SAMPLES ) / \
SYSTEM_SAMPLE_RATE * 1000 )
// define the maximum mono audio buffer size at a sample rate
// of 48 kHz, this is important for defining the maximum number
// of bytes to be expected from the network interface

View File

@ -107,7 +107,7 @@ void CLlconServerDlg::OnTimer()
// out network block size
vecpListViewItems[i]->setText ( 5,
QString().setNum (
double ( veciNetwOutBlSiFact[i] * MIN_SERVER_BLOCK_DURATION_MS ), 'f', 2 ) );
static_cast<double> ( veciNetwOutBlSiFact[i] * SYSTEM_BLOCK_DURATION_MS_FLOAT ), 'f', 2 ) );
// output audio compression
switch ( veceAudComprType[i] )

View File

@ -1,207 +0,0 @@
/******************************************************************************\
* Copyright (c) 2004-2009
*
* Author(s):
* Volker Fischer
*
* The polyphase filter is calculated with Matlab, the associated file
* is ResampleFilter.m.
*
******************************************************************************
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
\******************************************************************************/
#include "resample.h"
/******************************************************************************\
* Stereo Audio Resampler *
\******************************************************************************/
void CStereoAudioResample::ResampleStereo ( CVector<double>& vecdInput,
CVector<double>& vecdOutput )
{
int j;
if ( dRation == 1.0 )
{
// if ratio is 1, no resampling is needed, just copy vector
vecdOutput = vecdInput;
}
else
{
const int iTwoTimesNumTaps = 2 * iNumTaps;
/* move old data from the end to the history part of the buffer and
add new data (shift register) */
// shift old values
int iMovLen = iStereoInputBlockSize;
for ( j = 0; j < iTwoTimesNumTaps; j++ )
{
vecdIntBuffStereo[j] = vecdIntBuffStereo[iMovLen++];
}
// add new block of data
int iBlockEnd = iTwoTimesNumTaps;
for ( j = 0; j < iStereoInputBlockSize; j++ )
{
vecdIntBuffStereo[iBlockEnd++] = vecdInput[j];
}
// main loop
for ( j = 0; j < iMonoOutputBlockSize; j++ )
{
// calculate filter phase
const int ip = (int) ( j * iI / dRation ) % iI;
// sample position in stereo input vector
const int in = 2 * ( (int) ( j / dRation ) + iNumTaps - 1 );
// convolution
double dyL = 0.0;
double dyR = 0.0;
for ( int i = 0; i < iNumTaps; i++ )
{
const double dCurFiltTap = pFiltTaps[ip + i * iI];
const int iCurSamplePos = in - 2 * i;
dyL += dCurFiltTap * vecdIntBuffStereo[iCurSamplePos];
dyR += dCurFiltTap * vecdIntBuffStereo[iCurSamplePos + 1];
}
vecdOutput[2 * j] = dyL;
vecdOutput[2 * j + 1] = dyR;
}
}
}
void CStereoAudioResample::ResampleMono ( CVector<double>& vecdInput,
CVector<double>& vecdOutput )
{
int j;
if ( dRation == 1.0 )
{
// if ratio is 1, no resampling is needed, just copy vector
vecdOutput = vecdInput;
}
else
{
/* move old data from the end to the history part of the buffer and
add new data (shift register) */
// shift old values
int iMovLen = iMonoInputBlockSize;
for ( j = 0; j < iNumTaps; j++ )
{
vecdIntBuffMono[j] = vecdIntBuffMono[iMovLen++];
}
// add new block of data
int iBlockEnd = iNumTaps;
for ( j = 0; j < iMonoInputBlockSize; j++ )
{
vecdIntBuffMono[iBlockEnd++] = vecdInput[j];
}
// main loop
for ( j = 0; j < iMonoOutputBlockSize; j++ )
{
// calculate filter phase
const int ip = (int) ( j * iI / dRation ) % iI;
// sample position in input vector
const int in = (int) ( j / dRation ) + iNumTaps - 1;
// convolution
double dy = 0.0;
for ( int i = 0; i < iNumTaps; i++ )
{
dy += pFiltTaps[ip + i * iI] * vecdIntBuffMono[in - i];
}
vecdOutput[j] = dy;
}
}
}
void CStereoAudioResample::Init ( const int iNewMonoInputBlockSize,
const int iFrom,
const int iTo )
{
dRation = ( (double) iTo ) / iFrom;
iMonoInputBlockSize = iNewMonoInputBlockSize;
iStereoInputBlockSize = 2 * iNewMonoInputBlockSize;
iMonoOutputBlockSize = (int) ( iNewMonoInputBlockSize * dRation );
// set correct parameters
if ( iFrom >= iTo ) // downsampling case
{
switch ( iTo )
{
case ( SND_CRD_SAMPLE_RATE / 2 ): // 48 kHz to 24 kHz
pFiltTaps = fResTaps2;
iNumTaps = INTERP_I_2 * NUM_TAPS_PER_PHASE2;
iI = DECIM_D_2;
break;
case ( SND_CRD_SAMPLE_RATE * 11 / 16 ): // 48 kHz to 33 kHz
pFiltTaps = fResTaps16_11;
iNumTaps = INTERP_I_16_11 * NUM_TAPS_PER_PHASE16_11;
iI = DECIM_D_16_11;
break;
case SND_CRD_SAMPLE_RATE: // 48 kHz to 48 kHz
// no resampling needed
pFiltTaps = NULL;
iNumTaps = 0;
iI = 1;
break;
default:
// resample ratio not defined, throw error
throw 0;
break;
}
}
else // upsampling case (assumption: iTo == SND_CRD_SAMPLE_RATE)
{
switch ( iFrom )
{
case ( SND_CRD_SAMPLE_RATE / 2 ): // 24 kHz to 48 kHz
pFiltTaps = fResTaps2;
iNumTaps = DECIM_D_2 * NUM_TAPS_PER_PHASE2;
iI = INTERP_I_2;
break;
case ( SND_CRD_SAMPLE_RATE * 11 / 16 ): // 33 kHz to 48 kHz
pFiltTaps = fResTaps16_11;
iNumTaps = DECIM_D_16_11 * NUM_TAPS_PER_PHASE16_11;
iI = INTERP_I_16_11;
break;
default:
// resample ratio not defined, throw error
throw 0;
break;
}
}
// allocate memory for internal buffer, clear sample history (for
// the stereo case we have to consider that two times the number of taps of
// additional memory is required)
vecdIntBuffMono.Init ( iMonoInputBlockSize + iNumTaps, 0.0 );
vecdIntBuffStereo.Init ( iStereoInputBlockSize + 2 * iNumTaps, 0.0 );
}

View File

@ -1,59 +0,0 @@
/******************************************************************************\
* Copyright (c) 2004-2009
*
* Author(s):
* Volker Fischer
*
******************************************************************************
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
\******************************************************************************/
#if !defined ( RESAMPLE_H__3B0FEUFE7876F_FE8FE_CA63_4344_1912__INCLUDED_ )
#define RESAMPLE_H__3B0FEUFE7876F_FE8FE_CA63_4344_1912__INCLUDED_
#include "util.h"
#include "resamplefilter.h"
#include "global.h"
/* Classes ********************************************************************/
class CStereoAudioResample
{
public:
CStereoAudioResample() {}
virtual ~CStereoAudioResample() {}
void Init ( const int iNewMonoInputBlockSize, const int iFrom, const int iTo );
void ResampleMono ( CVector<double>& vecdInput, CVector<double>& vecdOutput );
void ResampleStereo ( CVector<double>& vecdInput, CVector<double>& vecdOutput );
protected:
double dRation;
CVector<double> vecdIntBuffMono;
CVector<double> vecdIntBuffStereo;
int iMonoInputBlockSize;
int iStereoInputBlockSize;
int iMonoOutputBlockSize;
float* pFiltTaps;
int iNumTaps;
int iI;
};
#endif // !defined ( RESAMPLE_H__3B0FEUFE7876F_FE8FE_CA63_4344_1912__INCLUDED_ )

View File

@ -1,145 +0,0 @@
/* Automatically generated file with MATLAB */
/* File name: "ResampleFilter.m" */
/* Filter taps in time-domain */
#ifndef _RESAMPLEFILTER_H_
#define _RESAMPLEFILTER_H_
#define NUM_TAPS_PER_PHASE2 4
#define NUM_TAPS_PER_PHASE16_11 4
#define NUM_TAPS_PER_PHASE1 4
#define INTERP_I_2 2
#define DECIM_D_2 1
#define INTERP_I_16_11 16
#define DECIM_D_16_11 11
#define INTERP_DECIM_I_D1 10
// Filter for ratio 2
static float fResTaps2[INTERP_I_2 * DECIM_D_2 * NUM_TAPS_PER_PHASE2] = {
-0.00543278438387929850f,
-0.04267524016158903000f,
0.20891570602538878000f,
0.83952404734744124000f,
0.83952404734744124000f,
0.20891570602538878000f,
-0.04267524016158903000f,
-0.00543278438387929850f
};
// Filter for ratio 16 / 11
static float fResTaps16_11[INTERP_I_16_11 * DECIM_D_16_11 * NUM_TAPS_PER_PHASE16_11] = {
-0.00389889725874395950f,
-0.00683214543790156090f,
-0.01072680249202097000f,
-0.01553896779709462000f,
-0.02111182416262372800f,
-0.02715802026999649900f,
-0.03324873986594503000f,
-0.03881136024854929500f,
-0.04313717468451081600f,
-0.04540006283235589100f,
-0.04468627284754060600f,
-0.04003467459491787100f,
-0.03048601148793385700f,
-0.01513888135261078900f,
0.00679052165107026960f,
0.03590841121927474500f,
0.07258699462937284700f,
0.11691555417711026000f,
0.16866274617280169000f,
0.22725337385053512000f,
0.29176217038299262000f,
0.36092619189350539000f,
0.43317632432273434000f,
0.50668722287057033000f,
0.57944380845094834000f,
0.64932132566729828000f,
0.71417500205550644000f,
0.77193461070469982000f,
0.82069878531213381000f,
0.85882380658614410000f,
0.88500178763806503000f,
0.89832372561302798000f,
0.89832372561302798000f,
0.88500178763806503000f,
0.85882380658614410000f,
0.82069878531213381000f,
0.77193461070469982000f,
0.71417500205550644000f,
0.64932132566729828000f,
0.57944380845094834000f,
0.50668722287057033000f,
0.43317632432273434000f,
0.36092619189350539000f,
0.29176217038299262000f,
0.22725337385053512000f,
0.16866274617280169000f,
0.11691555417711026000f,
0.07258699462937284700f,
0.03590841121927474500f,
0.00679052165107026960f,
-0.01513888135261078900f,
-0.03048601148793385700f,
-0.04003467459491787100f,
-0.04468627284754060600f,
-0.04540006283235589100f,
-0.04313717468451081600f,
-0.03881136024854929500f,
-0.03324873986594503000f,
-0.02715802026999649900f,
-0.02111182416262372800f,
-0.01553896779709462000f,
-0.01072680249202097000f,
-0.00683214543790156090f,
-0.00389889725874395950f
};
// Filter for ratios close to 1
static float fResTaps1[INTERP_DECIM_I_D1 * NUM_TAPS_PER_PHASE1] = {
-0.00200330615661920140f,
-0.00657158284969252320f,
-0.01434325067267541500f,
-0.02515649349164660000f,
-0.03781954301370460400f,
-0.04991380271447259900f,
-0.05780029046175797600f,
-0.05688089663877354800f,
-0.04212153837626786400f,
-0.00879070792017156400f,
0.04668529656863164300f,
0.12588850452342773000f,
0.22775132810044491000f,
0.34821676223650200000f,
0.48031735951868820000f,
0.61470848494637820000f,
0.74061377477860824000f,
0.84706508415438742000f,
0.92426036786924715000f,
0.96483311873999922000f,
0.96483311873999922000f,
0.92426036786924715000f,
0.84706508415438742000f,
0.74061377477860824000f,
0.61470848494637820000f,
0.48031735951868820000f,
0.34821676223650200000f,
0.22775132810044491000f,
0.12588850452342773000f,
0.04668529656863164300f,
-0.00879070792017156400f,
-0.04212153837626786400f,
-0.05688089663877354800f,
-0.05780029046175797600f,
-0.04991380271447259900f,
-0.03781954301370460400f,
-0.02515649349164660000f,
-0.01434325067267541500f,
-0.00657158284969252320f,
-0.00200330615661920140f
};
#endif /* _RESAMPLEFILTER_H_ */

View File

@ -1,121 +0,0 @@
% /****************************************************************************\
% * Copyright (c) 2004-2009
% *
% * Author(s):
% * Volker Fischer
% *
% \****************************************************************************/
function resamplefilter()
% Number of taps per poly phase for different resampling types
GlobalNoTaps = 4; % use global value for all types
NoTapsP2 = GlobalNoTaps; % 24 kHz
NoTapsP16_11 = GlobalNoTaps; % 33 kHz
NoTapsP1 = GlobalNoTaps; % 48 kHz
% Filter for ratio 2 -----------------------------------------------------------
% I and D
I2 = 2;
D2 = 1;
% filter design
h2 = DesignFilter(NoTapsP2, I2, 0.97);
% Filter for ratio 16 / 11 -----------------------------------------------------
% I and D
I16_11 = 16;
D16_11 = 11;
% filter design
h16_11 = DesignFilter(NoTapsP16_11, I16_11, 0.90);
% Filter for ratios close to 1 -------------------------------------------------
% Fixed for sample-rate conversiones of R ~ 1
I1 = 10; % D = I in this mode
% MMSE filter-design and windowing
h1 = DesignFilter(NoTapsP1, I1, 0.97);
% Export coefficiants to file ****************************************
fid = fopen('resamplefilter.h', 'w');
fprintf(fid, '/* Automatically generated file with MATLAB */\n');
fprintf(fid, '/* File name: "ResampleFilter.m" */\n');
fprintf(fid, '/* Filter taps in time-domain */\n\n');
fprintf(fid, '#ifndef _RESAMPLEFILTER_H_\n');
fprintf(fid, '#define _RESAMPLEFILTER_H_\n\n');
fprintf(fid, '#define NUM_TAPS_PER_PHASE2 ');
fprintf(fid, int2str(NoTapsP2));
fprintf(fid, '\n');
fprintf(fid, '#define NUM_TAPS_PER_PHASE16_11 ');
fprintf(fid, int2str(NoTapsP16_11));
fprintf(fid, '\n');
fprintf(fid, '#define NUM_TAPS_PER_PHASE1 ');
fprintf(fid, int2str(NoTapsP1));
fprintf(fid, '\n');
fprintf(fid, '#define INTERP_I_2 ');
fprintf(fid, int2str(I2));
fprintf(fid, '\n');
fprintf(fid, '#define DECIM_D_2 ');
fprintf(fid, int2str(D2));
fprintf(fid, '\n');
fprintf(fid, '#define INTERP_I_16_11 ');
fprintf(fid, int2str(I16_11));
fprintf(fid, '\n');
fprintf(fid, '#define DECIM_D_16_11 ');
fprintf(fid, int2str(D16_11));
fprintf(fid, '\n');
fprintf(fid, '#define INTERP_DECIM_I_D1 ');
fprintf(fid, int2str(I1));
fprintf(fid, '\n');
fprintf(fid, '\n\n');
% Write filter taps
fprintf(fid, '\n// Filter for ratio 2\n');
ExportFilterTaps(fid, 'fResTaps2[INTERP_I_2 * DECIM_D_2 * NUM_TAPS_PER_PHASE2]', h2);
fprintf(fid, '\n// Filter for ratio 16 / 11\n');
ExportFilterTaps(fid, 'fResTaps16_11[INTERP_I_16_11 * DECIM_D_16_11 * NUM_TAPS_PER_PHASE16_11]', h16_11);
fprintf(fid, '// Filter for ratios close to 1\n');
ExportFilterTaps(fid, 'fResTaps1[INTERP_DECIM_I_D1 * NUM_TAPS_PER_PHASE1]', h1);
fprintf(fid, '\n#endif /* _RESAMPLEFILTER_H_ */\n');
fclose(fid);
return;
function h = DesignFilter(NoTapsPIn, I, cutofffactor)
% number of taps, consider interpolation factor
NoTapsP = NoTapsPIn * I;
% Cut-off frequency (normlized)
fc = cutofffactor / I;
% MMSE filter design with Kaiser window, consider interpolation factor
h = I * firls(NoTapsP - 1, [0 fc fc 1], [1 1 0 0]) .* kaiser(NoTapsP, 5)';
return;
function ExportFilterTaps(f, name, h)
% Write filter taps
fprintf(f, ['static float ' name ' = {\n']);
fprintf(f, ' %.20ff,\n', h(1:end - 1));
fprintf(f, ' %.20ff\n', h(end));
fprintf(f, '};\n\n');
return;

View File

@ -96,7 +96,9 @@ void CServer::Start()
if ( !IsRunning() )
{
// start main timer
Timer.start ( MIN_SERVER_BLOCK_DURATION_MS );
// TEST
Timer.start ( static_cast<int> ( ceil ( SYSTEM_BLOCK_DURATION_MS_FLOAT ) ) );
// init time for response time evaluation
CycleTimeVariance.Reset();

View File

@ -59,8 +59,10 @@ public:
CVector<int>& veciNetwOutBlSiFact,
CVector<EAudComprType>& veceAudComprType )
{
ChannelSet.GetConCliParam ( vecHostAddresses, vecsName,
veciJitBufSize, veciNetwOutBlSiFact, veceAudComprType );
ChannelSet.GetConCliParam ( vecHostAddresses,
vecsName,
veciJitBufSize,
veciNetwOutBlSiFact );
}
bool GetTimingStdDev ( double& dCurTiStdDev );

View File

@ -133,26 +133,6 @@ void CSettings::ReadIniFile ( const QString& sFileName )
{
pClient->SetOpenChatOnNewMessage ( bValue );
}
// audio compression type (check CAudioCompression::EAudComprType definition
// for integer numbers!)
if ( GetNumericIniSet ( IniXMLDocument, "client", "audiocompression", 0, 2, iValue ) )
{
switch ( iValue )
{
case 0:
pClient->SetAudioCompressionOut ( CT_NONE );
break;
case 1:
pClient->SetAudioCompressionOut ( CT_IMAADPCM );
break;
case 2:
break;
pClient->SetAudioCompressionOut ( CT_MSADPCM );
}
}
}
void CSettings::WriteIniFile ( const QString& sFileName )
@ -206,23 +186,6 @@ void CSettings::WriteIniFile ( const QString& sFileName )
SetFlagIniSet ( IniXMLDocument, "client", "openchatonnewmessage",
pClient->GetOpenChatOnNewMessage() );
// audio compression type (check CAudioCompression::EAudComprType definition
// for integer numbers!)
switch ( pClient->GetAudioCompressionOut() )
{
case CT_NONE:
SetNumericIniSet ( IniXMLDocument, "client", "audiocompression", 0 );
break;
case CT_IMAADPCM:
SetNumericIniSet ( IniXMLDocument, "client", "audiocompression", 1 );
break;
case CT_MSADPCM:
SetNumericIniSet ( IniXMLDocument, "client", "audiocompression", 2 );
break;
}
// prepare file name for storing initialization data in XML file
QString sCurFileName = sFileName;
if ( sCurFileName.isEmpty() )