📄 conv_cor.c
字号:
* data I/O
* name type type function
* -------------------------------------------------------------------
* ExcVec fxpt_16 i excitation vector (ternary codeword)
* ExcVecLen int i excitation vector length
* LPImpResp fxpt_16 i LPC Impulse Response
* LenTruncH int i length to truncate impulse response
* Conv fxpt_16 o Convolution of codeword with impulse
* response
*
***************************************************************************
* For first code word, calculate and save convolution
* of code word with truncated (to len) impulse response:
*
* NOTES: A standard convolution of two L point sequences
* produces 2L-1 points, however, this convolution
* generates only the first L points.
*
* A "scalar times vector accumulation" method is used
* to exploit (skip) zero samples of the code words:
*
* min(L-i+1, len)
* y = SUM ex * h , where i = 1, ..., L points
* i+j-1, t j=1 i j
*
* ex |1 2 . . . L|
* h |x x len ... 2 1| = y(1)
* h |x x len ... 2 1| = y(2)
* : :
* h |x x len ... 2 1| = y(L)
*
***************************************************************************/
#if 0 /* now implemented in its own file */
void CalcStochConv(
fxpt_16 ExcVec[], /* 15.0 format */
fxpt_16 LPImpResp[], /* 2.13 format */
fxpt_16 Conv[MAX_CW_VEC_LEN]) /* 15.0 format */
{
int i, j;
FXPT_PUSHSTATE("CalcStochConv", -1.0, -1.0);
/* Initialize */
for (i=0; i< SF_LEN; i++) {
Conv[i] = 0;
}
for (i=0; i< SF_LEN; i++) {
if (ExcVec[i] != 0) {
for(j=0; j<min(SF_LEN - i, LEN_TRUNC_H); j++) {
/*Conv[i+j] += ExcVec[i] * LPImpResp[j];*/
Conv[i+j] = fxpt_add16(Conv[i+j],
fxpt_mult16_round(ExcVec[i], LPImpResp[j],
13));
}
}
}
FXPT_POPSTATE();
}
#endif
/**************************************************************************
*
* ROUTINE
* EndCorrectStoch
*
* FUNCTION
* End correct the convolution sum
*
* SYNOPSIS
* EndCorrectStoch(ExcVal, LPImpResp, LenTruncH, Conv)
*
* formal
*
* data I/O
* name type type function
* -------------------------------------------------------------------
* ExcVal fxpt_16 i Excitation value
* LPImpResp fxpt_16 i LPC impulse response
* LenTruncH int i Length to truncate impulse response
* Conv fxpt_16 o Convolution sum
*
***************************************************************************
*
* End correct the convolution sum on subsequent code words:
* (Do two end corrections for a shift by 2 code book)
*
* y = 0
* 0, 0
* y = y + ex * h where i = 1, ..., L points
* i, m i-1, m-1 -m i and m = 1, ..., cbsize-1 code words
*
* NOTE: The data movements in loops "do 59 ..." and "do 69 ..."
* are performed many times and can be quite time consuming.
* Therefore, special precautions should be taken when
* implementing this. Some implementation suggestions:
* 1. Circular buffers with pointers to eliminate data moves.
* 2. Fast "block move" operation as offered on some DSPs.
*
*
***************************************************************************/
#if 0 /* function now in it's own file */
void EndCorrectStoch(
fxpt_16 ExcVal, /* 15.0 format */
fxpt_16 LPImpResp[], /* 2.13 format */
fxpt_16 Conv[]) /* 15.0 format */
{
int i;
FXPT_PUSHSTATE("EndCorrectStoch", -1.0, -1.0);
if (ExcVal != 0) {
/* Ternary stochastic code book (-1, 0, +1) */
if (ExcVal == 1) {
for (i=LEN_TRUNC_H-1; i>0; i--) {
/*Conv[i-1] += LPImpResp[i];*/
Conv[i-1] = fxpt_add16(Conv[i-1],
fxpt_shr16_round(LPImpResp[i], 13));
}
}
else {
for(i=LEN_TRUNC_H-1; i>0; i--) {
/*Conv[i-1] -= LPImpResp[i];*/
Conv[i-1] = fxpt_sub16(Conv[i-1],
fxpt_shr16_round(LPImpResp[i], 13));
}
}
}
for(i=SF_LEN-1; i>0; i--) {
Conv[i] = Conv[i-1];
}
/*Conv[0] = ExcVal*LPImpResp[0];*/
Conv[0] = fxpt_mult16_round(ExcVal, LPImpResp[0], 13);
FXPT_POPSTATE();
}
#endif
/**************************************************************************
*
* ROUTINE
* CalcCorEngStoch
*
* FUNCTION
* Calculate correlation and energy
*
* SYNOPSIS
* CalcCorEngStoch(Residual, Conv, ExcVal1, ExcVal2, First, Cor, Energy)
*
* formal
*
* data I/O
* name type type function
* -------------------------------------------------------------------
* Residual fxpt_16 i Spectrum and adaptive residual
* Conv fxpt_16 i Convolution sum
* ExcVal1 fxpt_16 i First excitation vector value
* ExcVal2 fxpt_16 i Second excitation vector value
* First int i First subframe flag
* Cor fxpt_32 o Correlation
* Energy fxpt_32 o Energy
*
***************************************************************************
*
* Calculate correlation and energy:
* e0 = spectrum & pitch prediction residual
* y = error weighting filtered code words
*
* \/\/\/ CELP's computations are focused in this correlation \/\/\/
* - For a 512 code book this correlation takes 4 MIPS!
* - Decimation?, Down-sample & decimate?, FEC codes?
*
***************************************************************************/
#if 0 /* function now in it's own file */
void CalcCorEngStoch(
fxpt_16 Residual[RES_LEN], /* 15.0 format */
fxpt_16 Conv[], /* 15.0 format */
fxpt_16 ExcVal1, /* 15.0 format */
fxpt_16 ExcVal2, /* 15.0 format */
int First,
fxpt_32 *Cor, /* 30.1 format */
fxpt_32 *Energy) /* 30.1 format */
{
int i;
static fxpt_16 NextLastConv=0;
static fxpt_16 LastConv=0;
FXPT_PUSHSTATE("CalcCorEngStoch", -1.0, -1.0);
/* Initialize */
*Cor = 0;
/* Calculate correlation */
for (i=0; i<SF_LEN; i++) {
/**Cor += Conv[i]*Residual[i];*/
*Cor = fxpt_mac32(*Cor, Conv[i], Residual[i]);
}
/* End correct energy on subsequent code words */
if ((ExcVal1 == 0) && (ExcVal2 == 0) && (!First)) {
/**Energy -= NextLastConv*NextLastConv + LastConv*LastConv;*/
*Energy = fxpt_sub32(*Energy, fxpt_add32(
fxpt_mult32_fast(NextLastConv, NextLastConv),
fxpt_mult32_fast(LastConv, LastConv)));
}
else {
*Energy = 0;
for (i=0; i<SF_LEN; i++) {
/**Energy += Conv[i] * Conv[i];*/
*Energy = fxpt_mac32(*Energy, Conv[i], Conv[i]);
}
}
NextLastConv = Conv[SF_LEN-2];
LastConv = Conv[SF_LEN-1];
FXPT_POPSTATE();
}
#endif
/**************************************************************************
*
* ROUTINE
* CompGainErrStoch
*
* FUNCTION
* Compute gain and error
*
* SYNOPSIS
* CompGainErrStoch(Energy, Cor, Gain, Error)
*
* formal
*
* data I/O
* name type type function
* -------------------------------------------------------------------
* Energy fxpt_32 i Energy
* Cor fxpt_32 i Correlation
* Gain fxpt_16 o Codebook Gain
* Error fxpt_32 o Codebook Error
*
***************************************************************************
*
* Compute gain and error:
* NOTE: Actual MSPE = e0.e0 - gain(2*cor-gain*eng)
* since e0.e0 is independent of the code word,
* minimizing MSPE is equivalent to maximizing:
* match = gain(2*cor-gain*eng)
* If unquantized gain is used, this simplifies:
* match = cor*gain
*
* Independent (open-loop) quantization of gain and match (index):
*
***************************************************************************/
void CompGainErrStoch(
fxpt_32 Energy, /* 30.0 format */
fxpt_32 Cor, /* 30.0 format */
fxpt_32 *Gain, /* 27.4 format */
fxpt_32 *Error) /* 30.1 format */
{
FXPT_PUSHSTATE("CompGainErrStoch", -1.0, -1.0);
if (Energy == 0)
*Gain = Cor;
else
/**Gain = Cor/Energy;*/
*Gain = fxpt_div32(Cor, Energy, 4);
/**Error = Cor * *Gain;*/
// *Error = fxpt_mult64_round(Cor, *Gain, 4);
*Error = fxpt_mult64_round_good(Cor, *Gain, 3);
FXPT_POPSTATE();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -