added MS-ADPCM
This commit is contained in:
parent
441e320e79
commit
83faac5a6d
3 changed files with 335 additions and 26 deletions
|
@ -4,8 +4,8 @@
|
||||||
* Author(s):
|
* Author(s):
|
||||||
* Volker Fischer, Erik de Castro Lopo
|
* Volker Fischer, Erik de Castro Lopo
|
||||||
*
|
*
|
||||||
* This code is based on the Open-Source implementation of IMA-ADPCM written
|
* This code is based on the Open-Source implementation of IMA-ADPCM / MS-ADPCM
|
||||||
* by Erik de Castro Lopo <erikd[at-#]mega-nerd[dot*]com> in 1999-2004
|
* written by Erik de Castro Lopo <erikd[at-#]mega-nerd[dot*]com> in 1999-2004
|
||||||
*
|
*
|
||||||
* Changes:
|
* Changes:
|
||||||
* - only support for one channel
|
* - only support for one channel
|
||||||
|
@ -46,7 +46,11 @@ int CAudioCompression::Init ( const int iNewAudioLen,
|
||||||
case CT_IMAADPCM:
|
case CT_IMAADPCM:
|
||||||
return ImaAdpcm.Init ( iNewAudioLen );
|
return ImaAdpcm.Init ( iNewAudioLen );
|
||||||
|
|
||||||
default: return 0;
|
case CT_MSADPCM:
|
||||||
|
return MsAdpcm.Init ( iNewAudioLen );
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +76,9 @@ CVector<unsigned char> CAudioCompression::Encode ( const CVector<short>& vecsAud
|
||||||
case CT_IMAADPCM:
|
case CT_IMAADPCM:
|
||||||
return ImaAdpcm.Encode ( vecsAudio ); // IMA-ADPCM
|
return ImaAdpcm.Encode ( vecsAudio ); // IMA-ADPCM
|
||||||
|
|
||||||
|
case CT_MSADPCM:
|
||||||
|
return MsAdpcm.Encode ( vecsAudio ); // MS-ADPCM
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CVector<unsigned char> ( 0 );
|
return CVector<unsigned char> ( 0 );
|
||||||
}
|
}
|
||||||
|
@ -105,6 +112,9 @@ CVector<short> CAudioCompression::Decode ( const CVector<unsigned char>& vecbyAd
|
||||||
case CT_IMAADPCM:
|
case CT_IMAADPCM:
|
||||||
return ImaAdpcm.Decode ( vecbyAdpcm ); // IMA-ADPCM
|
return ImaAdpcm.Decode ( vecbyAdpcm ); // IMA-ADPCM
|
||||||
|
|
||||||
|
case CT_MSADPCM:
|
||||||
|
return MsAdpcm.Decode ( vecbyAdpcm ); // MS-ADPCM
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CVector<short> ( 0 );
|
return CVector<short> ( 0 );
|
||||||
}
|
}
|
||||||
|
@ -112,7 +122,10 @@ CVector<short> CAudioCompression::Decode ( const CVector<unsigned char>& vecbyAd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* IMA-ADPCM implementation ------------------------------------------------- */
|
|
||||||
|
/******************************************************************************\
|
||||||
|
* IMA-ADPCM implementation *
|
||||||
|
\******************************************************************************/
|
||||||
int CImaAdpcm::Init ( const int iNewAudioLen )
|
int CImaAdpcm::Init ( const int iNewAudioLen )
|
||||||
{
|
{
|
||||||
// set lengths for audio and compressed data
|
// set lengths for audio and compressed data
|
||||||
|
@ -135,7 +148,8 @@ CVector<unsigned char> CImaAdpcm::Encode ( const CVector<short>& vecsAudio )
|
||||||
vecbyAdpcm.Init ( iAdpcmSize );
|
vecbyAdpcm.Init ( iAdpcmSize );
|
||||||
vecbyAdpcmTemp.Init ( iAudSize );
|
vecbyAdpcmTemp.Init ( iAudSize );
|
||||||
|
|
||||||
/* encode the block header ----------------------------------------------- */
|
|
||||||
|
/* Encode the block header ---------------------------------------------- */
|
||||||
vecbyAdpcm[0] = vecsAudio[0] & 0xFF;
|
vecbyAdpcm[0] = vecsAudio[0] & 0xFF;
|
||||||
vecbyAdpcm[1] = ( vecsAudio[0] >> 8 ) & 0xFF;
|
vecbyAdpcm[1] = ( vecsAudio[0] >> 8 ) & 0xFF;
|
||||||
vecbyAdpcm[2] = iStepindEnc;
|
vecbyAdpcm[2] = iStepindEnc;
|
||||||
|
@ -143,7 +157,7 @@ CVector<unsigned char> CImaAdpcm::Encode ( const CVector<short>& vecsAudio )
|
||||||
int iPrevAudio = vecsAudio[0];
|
int iPrevAudio = vecsAudio[0];
|
||||||
|
|
||||||
|
|
||||||
/* encode the samples as 4 bit ------------------------------------------- */
|
/* Encode the samples as 4 bit ------------------------------------------ */
|
||||||
for ( i = 1; i < iAudSize; i++ )
|
for ( i = 1; i < iAudSize; i++ )
|
||||||
{
|
{
|
||||||
// init diff and step
|
// init diff and step
|
||||||
|
@ -190,12 +204,12 @@ CVector<unsigned char> CImaAdpcm::Encode ( const CVector<short>& vecsAudio )
|
||||||
iPrevAudio = CheckBounds ( iPrevAudio, _MINSHORT, _MAXSHORT );
|
iPrevAudio = CheckBounds ( iPrevAudio, _MINSHORT, _MAXSHORT );
|
||||||
iStepindEnc = CheckBounds ( iStepindEnc, 0, IMA_STEP_SIZE_TAB_LEN - 1 );
|
iStepindEnc = CheckBounds ( iStepindEnc, 0, IMA_STEP_SIZE_TAB_LEN - 1 );
|
||||||
|
|
||||||
// use the input buffer as an intermediate result buffer
|
// use a temporary buffer as an intermediate result buffer
|
||||||
vecbyAdpcmTemp[i] = bytecode;
|
vecbyAdpcmTemp[i] = bytecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* pack the 4 bit encoded samples ---------------------------------------- */
|
/* Pack the 4 bit encoded samples --------------------------------------- */
|
||||||
// The first encoded audio sample is in header
|
// The first encoded audio sample is in header
|
||||||
vecbyAdpcm[3] = vecbyAdpcmTemp[1] & 0x0F;
|
vecbyAdpcm[3] = vecbyAdpcmTemp[1] & 0x0F;
|
||||||
|
|
||||||
|
@ -216,7 +230,7 @@ CVector<short> CImaAdpcm::Decode ( const CVector<unsigned char>& vecbyAdpcm )
|
||||||
vecsAudio.Init ( iAudSize );
|
vecsAudio.Init ( iAudSize );
|
||||||
|
|
||||||
|
|
||||||
/* read and check the block header --------------------------------------- */
|
/* Read the block header ------------------------------------------------ */
|
||||||
int current = vecbyAdpcm[0] | ( vecbyAdpcm[1] << 8 );
|
int current = vecbyAdpcm[0] | ( vecbyAdpcm[1] << 8 );
|
||||||
if ( current & 0x8000 )
|
if ( current & 0x8000 )
|
||||||
{
|
{
|
||||||
|
@ -230,10 +244,10 @@ CVector<short> CImaAdpcm::Decode ( const CVector<unsigned char>& vecbyAdpcm )
|
||||||
vecsAudio[0] = current;
|
vecsAudio[0] = current;
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
pull apart the packed 4 bit samples and store them in their correct sample
|
pull apart the packed 4 bit samples and store them in their correct
|
||||||
positions */
|
sample positions */
|
||||||
// The first encoded audio sample is in header
|
// the first encoded audio sample is in header
|
||||||
vecsAudio[1] = vecbyAdpcm[3] & 0x0F;
|
vecsAudio[1] = vecbyAdpcm[3] & 0x0F;
|
||||||
|
|
||||||
for ( i = 4; i < iAdpcmSize; i++ )
|
for ( i = 4; i < iAdpcmSize; i++ )
|
||||||
|
@ -244,7 +258,7 @@ CVector<short> CImaAdpcm::Decode ( const CVector<unsigned char>& vecbyAdpcm )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* decode the encoded 4 bit samples -------------------------------------- */
|
/* Decode the encoded 4 bit samples ------------------------------------- */
|
||||||
for ( i = 1; i < iAudSize; i++ )
|
for ( i = 1; i < iAudSize; i++ )
|
||||||
{
|
{
|
||||||
const short bytecode = vecsAudio[i] & 0xF ;
|
const short bytecode = vecsAudio[i] & 0xF ;
|
||||||
|
@ -286,3 +300,255 @@ CVector<short> CImaAdpcm::Decode ( const CVector<unsigned char>& vecbyAdpcm )
|
||||||
|
|
||||||
return vecsAudio;
|
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<unsigned char> CMsAdpcm::Encode ( const CVector<short>& vecsAudio )
|
||||||
|
{
|
||||||
|
CVector<short> vecsAudioTemp;
|
||||||
|
CVector<unsigned char> 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;
|
||||||
|
unsigned char 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<unsigned char>& 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;
|
||||||
|
}
|
||||||
|
|
|
@ -31,10 +31,11 @@
|
||||||
|
|
||||||
|
|
||||||
/* Definitions ****************************************************************/
|
/* Definitions ****************************************************************/
|
||||||
// tables
|
// tables IMA-ADPCM
|
||||||
#define IMA_INDX_ADJUST_TAB_LEN 16
|
#define IMA_INDX_ADJUST_TAB_LEN 16
|
||||||
static int ima_indx_adjust[IMA_INDX_ADJUST_TAB_LEN] =
|
static int ima_indx_adjust[IMA_INDX_ADJUST_TAB_LEN] =
|
||||||
{ -1, -1, -1, -1, /* +0 - +3, decrease the step size */
|
{
|
||||||
|
-1, -1, -1, -1, /* +0 - +3, decrease the step size */
|
||||||
2, 4, 6, 8, /* +4 - +7, increase the step size */
|
2, 4, 6, 8, /* +4 - +7, increase the step size */
|
||||||
-1, -1, -1, -1, /* -0 - -3, decrease the step size */
|
-1, -1, -1, -1, /* -0 - -3, decrease the step size */
|
||||||
2, 4, 6, 8, /* -4 - -7, increase the step size */
|
2, 4, 6, 8, /* -4 - -7, increase the step size */
|
||||||
|
@ -42,7 +43,8 @@ static int ima_indx_adjust[IMA_INDX_ADJUST_TAB_LEN] =
|
||||||
|
|
||||||
#define IMA_STEP_SIZE_TAB_LEN 89
|
#define IMA_STEP_SIZE_TAB_LEN 89
|
||||||
static int ima_step_size[IMA_STEP_SIZE_TAB_LEN] =
|
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,
|
{
|
||||||
|
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,
|
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,
|
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,
|
1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
|
||||||
|
@ -51,6 +53,26 @@ static int ima_step_size[IMA_STEP_SIZE_TAB_LEN] =
|
||||||
32767
|
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 ********************************************************************/
|
/* Classes ********************************************************************/
|
||||||
/* IMA-ADPCM ---------------------------------------------------------------- */
|
/* IMA-ADPCM ---------------------------------------------------------------- */
|
||||||
|
@ -87,11 +109,32 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* MS-ADPCM ----------------------------------------------------------------- */
|
||||||
|
class CMsAdpcm
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMsAdpcm() {}
|
||||||
|
virtual ~CMsAdpcm() {}
|
||||||
|
|
||||||
|
int Init ( const int iNewAudioLen );
|
||||||
|
CVector<unsigned char> Encode ( const CVector<short>& vecsAudio );
|
||||||
|
CVector<short> Decode ( const CVector<unsigned char>& vecbyAdpcm );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int iAudSize;
|
||||||
|
int iAdpcmSize;
|
||||||
|
|
||||||
|
void ChoosePredictor ( const CVector<short>& vecsAudio,
|
||||||
|
int& block_pred,
|
||||||
|
int& idelta );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Audio compression class -------------------------------------------------- */
|
/* Audio compression class -------------------------------------------------- */
|
||||||
class CAudioCompression
|
class CAudioCompression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum EAudComprType { CT_NONE, CT_IMAADPCM };
|
enum EAudComprType { CT_NONE, CT_IMAADPCM, CT_MSADPCM };
|
||||||
|
|
||||||
CAudioCompression() {}
|
CAudioCompression() {}
|
||||||
virtual ~CAudioCompression() {}
|
virtual ~CAudioCompression() {}
|
||||||
|
@ -104,8 +147,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
EAudComprType eAudComprType;
|
EAudComprType eAudComprType;
|
||||||
CImaAdpcm ImaAdpcm;
|
CImaAdpcm ImaAdpcm;
|
||||||
|
CMsAdpcm MsAdpcm;
|
||||||
int iCodeSize;
|
int iCodeSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* !defined ( AUDIOCOMPR_H_OIHGE76GEKJH3249_GEG98EG3_43441912__INCLUDED_ ) */
|
#endif /* !defined ( AUDIOCOMPR_H_OIHGE76GEKJH3249_GEG98EG3_43441912__INCLUDED_ ) */
|
||||||
|
|
|
@ -300,7 +300,7 @@ CAboutDlg::CAboutDlg ( QWidget* parent ) : QDialog ( parent )
|
||||||
"<li>Qt cross-platform application framework: <i>http://trolltech.com</li>"
|
"<li>Qt cross-platform application framework: <i>http://trolltech.com</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 \"The Synthesis ToolKit in C++ (STK)\")</li>"
|
"1995 - 2004 (taken from \"The Synthesis ToolKit in C++ (STK)\")</li>"
|
||||||
"<li>IMA-ADPCM: by Erik de Castro Lopo</li>"
|
"<li>ADPCM coders by Erik de Castro Lopo</li>"
|
||||||
"<li>Parts from Dream DRM Receiver by Volker Fischer and Alexander "
|
"<li>Parts from Dream DRM Receiver by Volker Fischer and Alexander "
|
||||||
"Kurpiers: <i>http://drm.sf.net</li>"
|
"Kurpiers: <i>http://drm.sf.net</li>"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
|
|
Loading…
Reference in a new issue