?? sp_enc.c
字號:
err += rct[i - 1] *sum;
if ( err <= 0.0 )
err = 0.01F;
}
memcpy( rc, rct, 4 * sizeof( Float32 ) );
memcpy( old_A, A, MP1 * sizeof( Float32 ) );
}
/*
* lpc
*
*
* Parameters:
* old_A O: Vector of old LP coefficients [M+1]
* x I: Input signal
* x_12k2 I: Input signal 12.2k
* a O: predictor coefficients
* mode I: AMR mode
* Function:
* LP analysis
*
* In 12.2 kbit/s mode linear prediction (LP) analysis is performed
* twice per speech frame using the auto-correlation approach with
* 30 ms asymmetric windows. No lookahead is used in
* the auto-correlation computation.
*
* In other modes analysis is performed once per speech frame
* using the auto-correlation approach with 30 ms asymmetric windows.
* A lookahead of 40 samples (5 ms) is used in the auto-correlation computation.
*
* The auto-correlations of windowed speech are converted to the LP
* coefficients using the Levinson-Durbin algorithm.
* Then the LP coefficients are transformed to the Line Spectral Pair
* (LSP) domain for quantization and interpolation purposes.
* The interpolated quantified and unquantized filter coefficients
* are converted back to the LP filter coefficients
* (to construct the synthesis and weighting filters at each subframe).
*
* Returns:
* void
*
*/
static void lpc( Float32 *old_A, Float32 x[], Float32 x_12k2[], Float32 a[], int mode )
{
Word32 i;
Float32 r[MP1];
Float32 rc[4];
if ( mode == MR122 ) {
Autocorr( x_12k2, r, window_160_80 );
/*
* Lag windowing
*/
for ( i = 1; i <= M; i++ ) {
r[i] = r[i] * lag_wind[i - 1];
}
r[0] *= 1.0001F;
if ( r[0] < 1.0F )
r[0] = 1.0F;
/*
* Levinson Durbin
*/
Levinson( old_A, r, &a[MP1], rc );
/*
* Autocorrelations
*/
Autocorr( x_12k2, r, window_232_8 );
/*
* Lag windowing
*/
for ( i = 1; i <= M; i++ ) {
r[i] = r[i] * lag_wind[i - 1];
}
r[0] *= 1.0001F;
if ( r[0] < 1.0F )
r[0] = 1.0F;
/*
* Levinson Durbin
*/
Levinson( old_A, r, &a[MP1 * 3], rc );
}
else {
/*
* Autocorrelations
*/
Autocorr( x, r, window_200_40 );
/*
* a 60 Hz bandwidth expansion is used by lag windowing
* the auto-correlations. Further, auto-correlation[0] is
* multiplied by the white noise correction factor 1.0001
* which is equivalent to adding a noise floor at -40 dB.
*/
for ( i = 1; i <= M; i++ ) {
r[i] = r[i] * lag_wind[i - 1];
}
r[0] *= 1.0001F;
if ( r[0] < 1.0F )
r[0] = 1.0F;
/*
* Levinson Durbin
*/
Levinson( old_A, r, &a[MP1 * 3], rc );
}
}
/*
* Chebps
*
*
* Parameters:
* x I: Cosine value for the freqency given
* f I: angular freqency
* Function:
* Evaluates the Chebyshev polynomial series
*
* Returns:
* result of polynomial evaluation
*/
static Float32 Chebps( Float32 x, Float32 f[] )
{
Float32 b0, b1, b2, x2;
Word32 i;
x2 = 2.0F * x;
b2 = 1.0F;
b1 = x2 + f[1];
for ( i = 2; i < 5; i++ ) {
b0 = x2 * b1 - b2 + f[i];
b2 = b1;
b1 = b0;
}
return( x * b1 - b2 + f[i] );
}
/*
* Az_lsp
*
*
* Parameters:
* a I: Predictor coefficients [MP1]
* lsp O: Line spectral pairs [M]
* old_lsp I: Old lsp, in case not found 10 roots [M]
*
* Function:
* LP to LSP conversion
*
* The LP filter coefficients A[], are converted to the line spectral pair
* (LSP) representation for quantization and interpolation purposes.
*
* Returns:
* void
*/
static void Az_lsp( Float32 a[], Float32 lsp[], Float32 old_lsp[] )
{
Word32 i, j, nf, ip;
Float32 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
Float32 y;
Float32 *coef;
Float32 f1[6], f2[6];
/*
* find the sum and diff. pol. F1(z) and F2(z)
*/
f1[0] = 1.0F;
f2[0] = 1.0F;
for ( i = 0; i < ( NC ); i++ ) {
f1[i + 1] = a[i + 1] +a[M - i] - f1[i];
f2[i + 1] = a[i + 1] -a[M - i] + f2[i];
}
f1[NC] *= 0.5F;
f2[NC] *= 0.5F;
/*
* find the LSPs using the Chebychev pol. evaluation
*/
nf = 0; /* number of found frequencies */
ip = 0; /* indicator for f1 or f2 */
coef = f1;
xlow = grid[0];
ylow = Chebps( xlow, coef );
j = 0;
while ( ( nf < M ) && ( j < 60 ) ) {
j++;
xhigh = xlow;
yhigh = ylow;
xlow = grid[j];
ylow = Chebps( xlow, coef );
if ( ylow * yhigh <= 0 ) {
/* divide 4 times the interval */
for ( i = 0; i < 4; i++ ) {
xmid = ( xlow + xhigh ) * 0.5F;
ymid = Chebps( xmid, coef );
if ( ylow * ymid <= 0.0F ) {
yhigh = ymid;
xhigh = xmid;
}
else {
ylow = ymid;
xlow = xmid;
}
}
/*
* Linear interpolation
* xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow)
*/
y = yhigh - ylow;
if ( y == 0 ) {
xint = xlow;
}
else {
y = ( xhigh - xlow ) / ( yhigh - ylow );
xint = xlow - ylow * y;
}
lsp[nf] = xint;
xlow = xint;
nf++;
if ( ip == 0 ) {
ip = 1;
coef = f2;
}
else {
ip = 0;
coef = f1;
}
ylow = Chebps( xlow, coef );
}
}
/* Check if M roots found */
if ( nf < M ) {
memcpy( lsp, old_lsp, M <<2 );
}
return;
}
/*
* Get_lsp_pol
*
*
* Parameters:
* lsp I: line spectral frequencies
* f O: polynomial F1(z) or F2(z)
*
* Function:
* Find the polynomial F1(z) or F2(z) from the LSPs.
*
* F1(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 )
* i=0,2,4,6,8
* F2(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 )
* i=1,3,5,7,9
*
* where lsp[] is the LSP vector in the cosine domain.
*
* The expansion is performed using the following recursion:
*
* f[0] = 1
* b = -2.0 * lsp[0]
* f[1] = b
* for i=2 to 5 do
* b = -2.0 * lsp[2*i-2];
* f[i] = b*f[i-1] + 2.0*f[i-2];
* for j=i-1 down to 2 do
* f[j] = f[j] + b*f[j-1] + f[j-2];
* f[1] = f[1] + b;
*
* Returns:
* void
*/
static void Get_lsp_pol( Float32 *lsp, Float32 *f )
{
Word32 i, j;
Float32 T0;
f[0] = 1.0F;
f[1] = -2.0F * lsp[0];
for ( i = 2; i <= 5; i++ ) {
T0 = -2.0F * lsp[2 * i - 2];
f[i] = ( Float32 )( T0 * f[i - 1] +2.0F * f[i - 2] );
for ( j = i - 1; j >= 2; j-- ) {
f[j] = f[j] + T0 * f[j - 1] +f[j - 2];
}
f[1] = f[1] + T0;
}
return;
}
/*
* Lsp_Az
*
*
* Parameters:
* lsp I: Line spectral frequencies
* a O: Predictor coefficients
*
* Function:
* Converts from the line spectral pairs (LSP) to LP coefficients,
* for a 10th order filter.
*
* Returns:
* void
*/
static void Lsp_Az( Float32 lsp[], Float32 a[] )
{
Float32 f1[6], f2[6];
Word32 i, j;
Get_lsp_pol( &lsp[0], f1 );
Get_lsp_pol( &lsp[1], f2 );
for ( i = 5; i > 0; i-- ) {
f1[i] += f1[i - 1];
f2[i] -= f2[i - 1];
}
a[0] = 1;
for ( i = 1, j = 10; i <= 5; i++, j-- ) {
a[i] = ( Float32 )( ( f1[i] + f2[i] ) * 0.5F );
a[j] = ( Float32 )( ( f1[i] - f2[i] ) * 0.5F );
}
return;
}
/*
* Int_lpc_1and3_2
*
*
* Parameters:
* lsp_old I: LSP vector at the 4th subfr. of past frame [M]
* lsp_mid I: LSP vector at the 2nd subframe of present frame [M]
* lsp_new I: LSP vector at the 4th subframe of present frame [M]
* az O: interpolated LP parameters in subframes 1 and 3
* [AZ_SIZE]
*
* Function:
* Interpolation of the LPC parameters. Same as the Int_lpc
* function but we do not recompute Az() for subframe 2 and
* 4 because it is already available.
*
* Returns:
* void
*/
static void Int_lpc_1and3_2( Float32 lsp_old[], Float32 lsp_mid[], Float32
lsp_new[], Float32 az[] )
{
Float32 lsp[M];
Word32 i;
for ( i = 0; i < M; i += 2 ) {
lsp[i] = ( lsp_mid[i] + lsp_old[i] ) * 0.5F;
lsp[i + 1] = ( lsp_mid[i + 1] +lsp_old[i+1] )*0.5F;
}
/* Subframe 1 */
Lsp_Az( lsp, az );
az += MP1 * 2;
for ( i = 0; i < M; i += 2 ) {
lsp[i] = ( lsp_mid[i] + lsp_new[i] ) * 0.5F;
lsp[i + 1] = ( lsp_mid[i + 1] +lsp_new[i+1] )*0.5F;
}
/* Subframe 3 */
Lsp_Az( lsp, az );
return;
}
/*
* Lsp_lsf
*
*
* Parameters:
* lsp I: LSP vector
* lsf O: LSF vector
*
* Function:
* Transformation lsp to lsf, LPC order M
*
* Returns:
* void
*/
static void Lsp_lsf( Float32 lsp[], Float32 lsf[] )
{
Word32 i;
for ( i = 0; i < M; i++ ) {
lsf[i] = ( Float32 )( acos( lsp[i] )*SCALE_LSP_FREQ );
}
return;
}
/*
* Lsf_wt
*
*
* Parameters:
* lsf I: LSF vector
* wf O: square of weighting factors
*
* Function:
* Compute LSF weighting factors
*
* Returns:
* void
*/
static void Lsf_wt( Float32 *lsf, Float32 *wf )
{
Float32 temp;
Word32 i;
wf[0] = lsf[1];
for ( i = 1; i < 9; i++ ) {
wf[i] = lsf[i + 1] -lsf[i - 1];
}
wf[9] = 4000.0F - lsf[8];
for ( i = 0; i < 10; i++ ) {
if ( wf[i] < 450.0F ) {
temp = 3.347F - SLOPE1_WGHT_LSF * wf[i];
}
else {
temp = 1.8F - SLOPE2_WGHT_LSF * ( wf[i] - 450.0F );
}
wf[i] = temp * temp;
}
return;
}
/*
* Vq_subvec
*
*
* Parameters:
* lsf_r1 I: 1st LSF residual vector
* lsf_r2 I: 2nd LSF residual vector
* dico I: quantization codebook
* wf1 I: 1st LSF weighting factors
* wf2 I: 2nd LSF weighting factors
* dico_size I: size of quantization codebook
* Function:
* Quantization of a 4 dimensional subvector
*
* Returns:
* index quantization index
*/
static Word16 Vq_subvec( Float32 *lsf_r1, Float32 *lsf_r2, const Float32 *dico,
Float32 *wf1, Float32 *wf2, Word16 dico_size )
{
Float64 temp, dist, dist_min;
const Float32 *p_dico;
Word32 i, index = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -