Loading lib_com/lsf_tools_fx.c +147 −0 Original line number Diff line number Diff line Loading @@ -631,6 +631,153 @@ Word16 lpc2lsp_fx( return ( 1 ); } #ifdef FIX_ISSUE_1165 /*===================================================================*/ /* FUNCTION : lpc2lsp_ivas_fx () */ /*-------------------------------------------------------------------*/ /* PURPOSE : Convert LPC coefficients to LSP coefficients */ /*-------------------------------------------------------------------*/ /* INPUT ARGUMENTS : */ /* */ /* _ (Word32 []) a : LPC coefficients, Q27 */ /* _ (Word16 []) old_freq: Previous frame LSP coefficients, Q15 */ /* _ (Word16 []) order: LPC order */ /*-------------------------------------------------------------------*/ /* OUTPUT ARGUMENTS : */ /* _ (Word16 []) freq: LSP coefficients, Q15 */ /*-------------------------------------------------------------------*/ /* INPUT/OUTPUT ARGUMENTS : */ /* _ None */ /*-------------------------------------------------------------------*/ /* RETURN ARGUMENTS : */ /* _ (Word16) flag: 1 means all 10 LSPs are found, 0 otherwise */ /*===================================================================*/ /*NOTE: This function was created to avoid a crash that happens in the*/ /* first for loop of this function while performing L_shl on a in*/ /* lpc2lsp_fx, this computation assigns value to Lacc, which is */ /* kept in Q26 here to avoid L_shl when a has saturated value. */ Word16 lpc2lsp_ivas_fx( Word32 *a, Word16 *freq, Word16 *old_freq, Word16 order ) { Word16 i; Word16 rt, low, high, prev_rt, rc; Word32 p[11], q[11]; /* Q26 */ Word32 Ltemp, v_low; Word32 Lacc; Word16 tfreq[21]; /* First construct the P,Q polynomial */ /* p[0] = q[0] = 1 */ /* p[i] = -lpcCoeff[i] - lpcCoeff[11-i] - p[i-1] ( 1<=i<=5)*/ /* q[i] = -lpcCoeff[i] + lpcCoeff[11-i] + q[i-1] ( 1<=i<=5)*/ Ltemp = L_deposit_h( 0x400 ); /* Ltemp is 1.0 in Q26 */ p[0] = Ltemp; move32(); q[0] = Ltemp; move32(); FOR( i = 1; i < ( order / 2 ) + 1; i++ ) { Lacc = L_shr( a[order - i], 1 ); move32(); /* Q26 */ Lacc = L_sub( Lacc, L_shr( a[i - 1], 1 ) ); /* Lacc=-lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */ q[i] = L_add( ( Lacc ), q[i - 1] ); move32(); /* Q26 */ Lacc = L_add( Lacc, a[i - 1] ); /* Lacc=lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */ p[i] = L_sub( L_negate( Lacc ), p[i - 1] ); move32(); /* Q26 */ } /* Search roots of the P and Q polynomials */ v_low = polynomial_eval_fx( 0, p, order ); /* Q25 */ move16(); move16(); move16(); move16(); low = 0; high = 8; prev_rt = 0; rc = 0; /* root counter */ FOR( i = 0; i < 32; i++ ) { rt = root_search_fx( low, high, &v_low, p, order ); low = high; move16(); high = add( high, 8 ); IF( GE_16( rt, prev_rt ) ) { tfreq[rc] = rt; move16(); rc = add( rc, 2 ); } prev_rt = add( rt, 6 ); } /* End for P roots */ tfreq[rc] = 0x3f80; move16(); /* Set a high enough value as fake root for Q search */ IF( LT_16( rc, order ) ) { /* lost P root */ /* copy from previous LSP and return */ FOR( i = 0; i < order; i++ ) { move16(); freq[i] = old_freq[i]; } return ( 0 ); } ELSE { /* Search for Q roots between P roots */ v_low = L_deposit_h( 0x800 ); /* Init a positive value for v_low */ rc = 1; move16(); FOR( i = 0; i < order / 2; i++ ) { low = shr( tfreq[rc - 1], 6 ); high = add( shr( tfreq[rc + 1], 6 ), 1 ); rt = root_search_fx( low, high, &v_low, q, order ); IF( rt < 0 ) { /* No Q root in this interval */ /* copy from previous LSP and return */ FOR( i = 0; i < order; i++ ) { move16(); freq[i] = old_freq[i]; } return ( 0 ); } ELSE { move16(); tfreq[rc] = rt; rc = add( rc, 2 ); } /* end else, find Q root */ } /* end for */ } /* end else */ FOR( i = 0; i < order; i++ ) { freq[i] = tfreq[i]; move16(); } return ( 1 ); } #endif /*===================================================================*/ /* FUNCTION : lsp2lpc_fx () */ /*-------------------------------------------------------------------*/ Loading lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -122,4 +122,5 @@ #define FIX_1113_OPT_DIRAC_BIN_REND /* FhG: Various optimizations to ivas_dirac_dec_binaual_functions.c */ #define FIX_ISSUE_1187 /* Ittiam: Fix for issue 1187: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from bass_pf_enc_fx function*/ #define FIX_ISSUE_1186 /* Ittiam: Fix for Issue 1186: Energy/scaling issue for ISM-1 at all bitrates */ #define FIX_ISSUE_1165 /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */ #endif lib_com/prot_fx.h +8 −0 Original line number Diff line number Diff line Loading @@ -808,6 +808,14 @@ Word16 lpc2lsp_fx( Word16 *old_freq, Word16 order ); #ifdef FIX_ISSUE_1165 Word16 lpc2lsp_ivas_fx( Word32 *a, Word16 *freq, Word16 *old_freq, Word16 order ); #endif void lsp2lpc_fx( Word16 *a, Word16 *freq, Loading lib_enc/enc_acelp_fx.c +347 −0 Original line number Diff line number Diff line Loading @@ -1495,6 +1495,349 @@ void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const return; } #ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ) { Word16 sign[L_SUBFR], vec[L_SUBFR]; Word16 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR]; Word16 rrixix[4][16]; Word16 rrixiy[4][256]; Word16 dn2[L_SUBFR]; Word16 psk, ps, alpk, alp = 0; Word16 codvec[NB_PULSE_MAX]; Word16 pos_max[4]; Word16 dn2_pos[8 * 4]; UWord8 ipos[NB_PULSE_MAX]; Word16 *p0, *p1, *p2, *p3; Word16 *h, *h_inv; Word16 i, j, k, l, st, pos; Word16 val, tmp, scale; Word32 s, L_tmp; Word16 nb_pulse, nb_pulse_m2; Word16 check = 0; /* debug code not instrumented */ #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); #endif alp = config->alp; /* Q13 */ /* initial value for energy of all fixed pulses */ move16(); nb_pulse = config->nb_pulse; move16(); nb_pulse_m2 = sub( nb_pulse, 2 ); set16_fx( codvec, 0, nb_pulse ); /* * Find sign for each pulse position. */ E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, 0x7fff, L_SUBFR ); /* * Select the most important 8 position per track according to dn2[]. */ E_ACELP_findcandidates( dn2, dn2_pos, pos_max ); /* * Compute h_inv[i]. */ set16_fx( h_buf, 0, L_SUBFR ); set16_fx( h_buf + ( 2 * L_SUBFR ), 0, L_SUBFR ); h = h_buf + L_SUBFR; h_inv = h_buf + ( 3 * L_SUBFR ); /*Check the energy if it is too high then scale to prevent an overflow*/ scale = 0; move16(); L_tmp = L_deposit_l( 0 ); BASOP_SATURATE_WARNING_OFF_EVS FOR( i = 0; i < L_SUBFR; i++ ) { #ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); /*Q25*/ #else L_tmp = L_mac( L_tmp, H[i], H[i] ); #endif } val = extract_h( L_tmp ); /*Q9*/ BASOP_SATURATE_WARNING_ON_EVS if ( GT_16( val, 0x2000 ) ) { scale = -1; move16(); } if ( GT_16( val, 0x7000 ) ) { scale = -2; move16(); } if ( EQ_16( val, 32767 ) ) { scale = -3; move16(); } Copy_Scale_sig( H, h, L_SUBFR, scale ); /*Q12+scale*/ E_ACELP_vec_neg_fx( h, h_inv, L_SUBFR ); /* * Compute correlation matrices needed for the codebook search. */ E_ACELP_corrmatrix_fx( h, sign, vec, rrixix, rrixiy ); /* * Deep first search: * ------------------ * 20 bits (4p): 4 iter x ((4x16)+(8x16)) = 768 tests * 36 bits (8p): 4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16) * +(8x16)+(8x16)) = 1248 tests * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16) * +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests */ psk = -1; move16(); alpk = 1; move16(); /*Number of iterations*/ FOR( k = 0; k < config->nbiter; k++ ) { E_ACELP_setup_pulse_search_pos( config, k, ipos ); /* format of alp changes to Q(15-ALP2_E) */ pos = config->fixedpulses; move16(); IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */ { ps = 0; move16(); alp = 0; move16(); set16_fx( vec, 0, L_SUBFR ); } ELSE IF( EQ_16( config->fixedpulses, 2 ) ) /* 2222 and 3322 */ { /* first stage: fix 2 pulses */ ind[0] = pos_max[ipos[0]]; move16(); ind[1] = pos_max[ipos[1]]; move16(); ps = add( dn[ind[0]], dn[ind[1]] ); /*alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] + rrixiy[ipos[0]][((ind[0] >> 2) << 4) + (ind[1] >> 2)];*/ i = shr( ind[0], 2 ); j = shr( ind[1], 2 ); l = add( shl( i, 4 ), j ); s = L_mult( rrixix[ipos[0]][i], _1_ ); /* Q9+Q12+1 */ s = L_mac( s, rrixix[ipos[1]][j], _1_ ); /* Q9+Q12+1 */ alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); /* Q9+Q12+1-16 */ p0 = h - ind[0]; /*Q12+scale*/ IF( sign[ind[0]] < 0 ) { p0 = h_inv - ind[0]; /*Q12+scale*/ } p1 = h - ind[1]; /*Q12+scale*/ IF( sign[ind[1]] < 0 ) { p1 = h_inv - ind[1]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { vec[i] = add( *p0++, *p1++ ); /*Q12+scale*/ move16(); } } ELSE /* 3333 and above */ { /* first stage: fix 4 pulses */ ind[0] = pos_max[ipos[0]]; /*Q0*/ move16(); ind[1] = pos_max[ipos[1]]; /*Q0*/ move16(); ind[2] = pos_max[ipos[2]]; /*Q0*/ move16(); ind[3] = pos_max[ipos[3]]; /*Q0*/ move16(); /*ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];*/ ps = add( add( add( dn[ind[0]], dn[ind[1]] ), dn[ind[2]] ), dn[ind[3]] ); p0 = h - ind[0]; /*Q12+scale*/ IF( sign[ind[0]] < 0 ) { p0 = h_inv - ind[0]; /*Q12+scale*/ } p1 = h - ind[1]; /*Q12+scale*/ IF( sign[ind[1]] < 0 ) { p1 = h_inv - ind[1]; /*Q12+scale*/ } p2 = h - ind[2]; /*Q12+scale*/ IF( sign[ind[2]] < 0 ) { p2 = h_inv - ind[2]; /*Q12+scale*/ } p3 = h - ind[3]; /*Q12+scale*/ IF( sign[ind[3]] < 0 ) { p3 = h_inv - ind[3]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); /*Q12+scale*/ move16(); } L_tmp = L_mult( vec[0], vec[0] ); /*Q25+2*scale*/ FOR( i = 1; i < L_SUBFR; i++ ) #ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q25+2*scale*/ #else L_tmp = L_mac( L_tmp, vec[i], vec[i] ); #endif alp = round_fx( L_shr( L_tmp, 3 ) ); /*Q6+2*scale*/ /*alp *= 0.5F; */ } /* other stages of 2 pulses */ st = 0; move16(); FOR( j = pos; j < nb_pulse; j += 2 ) { IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */ { /* * Calculate correlation of all possible positions * of the next 2 pulses with previous fixed pulses. * Each pulse can have 16 possible positions. */ E_ACELP_h_vec_corr1_fx( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] ); E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); /* * Find best positions of 2 pulses. */ E_ACELP_2pulse_search( config->nbpos[st], ipos[j], ipos[j + 1], &ps, &alp, &ind[j], &ind[j + 1], dn, dn2_pos, cor_x, cor_y, rrixiy ); } ELSE /* single pulse search */ { E_ACELP_h_vec_corr2_fx( h, vec, ipos[j], sign, rrixix, cor_x ); E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); E_ACELP_1pulse_search( &ipos[j], &ps, &alp, &ind[j], dn, cor_x, cor_y ); } IF( GT_16( nb_pulse_m2, j ) ) { p0 = h - ind[j]; /*Q12+scale*/ IF( sign[ind[j]] < 0 ) { p0 = h_inv - ind[j]; /*Q12+scale*/ } p1 = h - ind[j + 1]; /*Q12+scale*/ IF( sign[ind[j + 1]] < 0 ) { p1 = h_inv - ind[j + 1]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { tmp = add( *p0++, *p1++ ); #ifdef BASOP_NOGLOB vec[i] = add_o( vec[i], tmp, &Overflow ); /* can saturate here. */ move16(); #else vec[i] = add( vec[i], tmp ); /* can saturate here. */ move16(); #endif } } st = add( st, 1 ); } /* memorise the best codevector */ /*ps = ps * ps; MULT(1);*/ ps = mult( ps, ps ); /*s = (alpk * ps) - (psk * alp); MULT(2);ADD(1);*/ s = L_msu( L_mult( alpk, ps ), psk, alp ); /*Q9+Q6+1=Q16*/ if ( psk < 0 ) { s = 1; move32(); } IF( s > 0 ) { psk = ps; move16(); alpk = alp; move16(); Copy( ind, codvec, nb_pulse ); /*Q0*/ check = 1; /* debug code not instrumented */ } } assert( check ); /* debug code not instrumented */ /* * Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations. */ E_ACELP_build_code( nb_pulse, codvec, sign, code, ind ); set16_fx( y, 0, L_SUBFR ); FOR( k = 0; k < nb_pulse; ++k ) { i = codvec[k]; /*Q0*/ move16(); p0 = h_inv - i; /*Q12+scale*/ IF( sign[i] > 0 ) { p0 -= 2 * L_SUBFR; } FOR( i = 0; i < L_SUBFR; i++ ) { #ifdef BASOP_NOGLOB y[i] = add_o( y[i], *p0++, &Overflow ); /*Q12+scale*/ #else y[i] = add( y[i], *p0++ ); #endif move16(); } } return; } #endif /* * E_ACELP_4t_fx Loading Loading @@ -1651,7 +1994,11 @@ void E_ACELP_4t_ivas_fx( } ELSE { #ifdef FIX_ISSUE_1165 E_ACELP_4tsearch_ivas_fx( dn, cn, H, code, &config, ind, y ); #else E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y ); #endif } E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index ); return; Loading lib_enc/prot_fx_enc.h +4 −0 Original line number Diff line number Diff line Loading @@ -1559,6 +1559,10 @@ void Mode2_pit_encode_fx( Word16 pit_res_max ); void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); #ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); #endif void E_ACELP_4t_fx( Word16 dn[], /* Qdn */ Word16 cn[] /* Q_xn */, Loading Loading
lib_com/lsf_tools_fx.c +147 −0 Original line number Diff line number Diff line Loading @@ -631,6 +631,153 @@ Word16 lpc2lsp_fx( return ( 1 ); } #ifdef FIX_ISSUE_1165 /*===================================================================*/ /* FUNCTION : lpc2lsp_ivas_fx () */ /*-------------------------------------------------------------------*/ /* PURPOSE : Convert LPC coefficients to LSP coefficients */ /*-------------------------------------------------------------------*/ /* INPUT ARGUMENTS : */ /* */ /* _ (Word32 []) a : LPC coefficients, Q27 */ /* _ (Word16 []) old_freq: Previous frame LSP coefficients, Q15 */ /* _ (Word16 []) order: LPC order */ /*-------------------------------------------------------------------*/ /* OUTPUT ARGUMENTS : */ /* _ (Word16 []) freq: LSP coefficients, Q15 */ /*-------------------------------------------------------------------*/ /* INPUT/OUTPUT ARGUMENTS : */ /* _ None */ /*-------------------------------------------------------------------*/ /* RETURN ARGUMENTS : */ /* _ (Word16) flag: 1 means all 10 LSPs are found, 0 otherwise */ /*===================================================================*/ /*NOTE: This function was created to avoid a crash that happens in the*/ /* first for loop of this function while performing L_shl on a in*/ /* lpc2lsp_fx, this computation assigns value to Lacc, which is */ /* kept in Q26 here to avoid L_shl when a has saturated value. */ Word16 lpc2lsp_ivas_fx( Word32 *a, Word16 *freq, Word16 *old_freq, Word16 order ) { Word16 i; Word16 rt, low, high, prev_rt, rc; Word32 p[11], q[11]; /* Q26 */ Word32 Ltemp, v_low; Word32 Lacc; Word16 tfreq[21]; /* First construct the P,Q polynomial */ /* p[0] = q[0] = 1 */ /* p[i] = -lpcCoeff[i] - lpcCoeff[11-i] - p[i-1] ( 1<=i<=5)*/ /* q[i] = -lpcCoeff[i] + lpcCoeff[11-i] + q[i-1] ( 1<=i<=5)*/ Ltemp = L_deposit_h( 0x400 ); /* Ltemp is 1.0 in Q26 */ p[0] = Ltemp; move32(); q[0] = Ltemp; move32(); FOR( i = 1; i < ( order / 2 ) + 1; i++ ) { Lacc = L_shr( a[order - i], 1 ); move32(); /* Q26 */ Lacc = L_sub( Lacc, L_shr( a[i - 1], 1 ) ); /* Lacc=-lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */ q[i] = L_add( ( Lacc ), q[i - 1] ); move32(); /* Q26 */ Lacc = L_add( Lacc, a[i - 1] ); /* Lacc=lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */ p[i] = L_sub( L_negate( Lacc ), p[i - 1] ); move32(); /* Q26 */ } /* Search roots of the P and Q polynomials */ v_low = polynomial_eval_fx( 0, p, order ); /* Q25 */ move16(); move16(); move16(); move16(); low = 0; high = 8; prev_rt = 0; rc = 0; /* root counter */ FOR( i = 0; i < 32; i++ ) { rt = root_search_fx( low, high, &v_low, p, order ); low = high; move16(); high = add( high, 8 ); IF( GE_16( rt, prev_rt ) ) { tfreq[rc] = rt; move16(); rc = add( rc, 2 ); } prev_rt = add( rt, 6 ); } /* End for P roots */ tfreq[rc] = 0x3f80; move16(); /* Set a high enough value as fake root for Q search */ IF( LT_16( rc, order ) ) { /* lost P root */ /* copy from previous LSP and return */ FOR( i = 0; i < order; i++ ) { move16(); freq[i] = old_freq[i]; } return ( 0 ); } ELSE { /* Search for Q roots between P roots */ v_low = L_deposit_h( 0x800 ); /* Init a positive value for v_low */ rc = 1; move16(); FOR( i = 0; i < order / 2; i++ ) { low = shr( tfreq[rc - 1], 6 ); high = add( shr( tfreq[rc + 1], 6 ), 1 ); rt = root_search_fx( low, high, &v_low, q, order ); IF( rt < 0 ) { /* No Q root in this interval */ /* copy from previous LSP and return */ FOR( i = 0; i < order; i++ ) { move16(); freq[i] = old_freq[i]; } return ( 0 ); } ELSE { move16(); tfreq[rc] = rt; rc = add( rc, 2 ); } /* end else, find Q root */ } /* end for */ } /* end else */ FOR( i = 0; i < order; i++ ) { freq[i] = tfreq[i]; move16(); } return ( 1 ); } #endif /*===================================================================*/ /* FUNCTION : lsp2lpc_fx () */ /*-------------------------------------------------------------------*/ Loading
lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -122,4 +122,5 @@ #define FIX_1113_OPT_DIRAC_BIN_REND /* FhG: Various optimizations to ivas_dirac_dec_binaual_functions.c */ #define FIX_ISSUE_1187 /* Ittiam: Fix for issue 1187: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from bass_pf_enc_fx function*/ #define FIX_ISSUE_1186 /* Ittiam: Fix for Issue 1186: Energy/scaling issue for ISM-1 at all bitrates */ #define FIX_ISSUE_1165 /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */ #endif
lib_com/prot_fx.h +8 −0 Original line number Diff line number Diff line Loading @@ -808,6 +808,14 @@ Word16 lpc2lsp_fx( Word16 *old_freq, Word16 order ); #ifdef FIX_ISSUE_1165 Word16 lpc2lsp_ivas_fx( Word32 *a, Word16 *freq, Word16 *old_freq, Word16 order ); #endif void lsp2lpc_fx( Word16 *a, Word16 *freq, Loading
lib_enc/enc_acelp_fx.c +347 −0 Original line number Diff line number Diff line Loading @@ -1495,6 +1495,349 @@ void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const return; } #ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ) { Word16 sign[L_SUBFR], vec[L_SUBFR]; Word16 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR]; Word16 rrixix[4][16]; Word16 rrixiy[4][256]; Word16 dn2[L_SUBFR]; Word16 psk, ps, alpk, alp = 0; Word16 codvec[NB_PULSE_MAX]; Word16 pos_max[4]; Word16 dn2_pos[8 * 4]; UWord8 ipos[NB_PULSE_MAX]; Word16 *p0, *p1, *p2, *p3; Word16 *h, *h_inv; Word16 i, j, k, l, st, pos; Word16 val, tmp, scale; Word32 s, L_tmp; Word16 nb_pulse, nb_pulse_m2; Word16 check = 0; /* debug code not instrumented */ #ifdef BASOP_NOGLOB_DECLARE_LOCAL Flag Overflow = 0; move32(); #endif alp = config->alp; /* Q13 */ /* initial value for energy of all fixed pulses */ move16(); nb_pulse = config->nb_pulse; move16(); nb_pulse_m2 = sub( nb_pulse, 2 ); set16_fx( codvec, 0, nb_pulse ); /* * Find sign for each pulse position. */ E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, 0x7fff, L_SUBFR ); /* * Select the most important 8 position per track according to dn2[]. */ E_ACELP_findcandidates( dn2, dn2_pos, pos_max ); /* * Compute h_inv[i]. */ set16_fx( h_buf, 0, L_SUBFR ); set16_fx( h_buf + ( 2 * L_SUBFR ), 0, L_SUBFR ); h = h_buf + L_SUBFR; h_inv = h_buf + ( 3 * L_SUBFR ); /*Check the energy if it is too high then scale to prevent an overflow*/ scale = 0; move16(); L_tmp = L_deposit_l( 0 ); BASOP_SATURATE_WARNING_OFF_EVS FOR( i = 0; i < L_SUBFR; i++ ) { #ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); /*Q25*/ #else L_tmp = L_mac( L_tmp, H[i], H[i] ); #endif } val = extract_h( L_tmp ); /*Q9*/ BASOP_SATURATE_WARNING_ON_EVS if ( GT_16( val, 0x2000 ) ) { scale = -1; move16(); } if ( GT_16( val, 0x7000 ) ) { scale = -2; move16(); } if ( EQ_16( val, 32767 ) ) { scale = -3; move16(); } Copy_Scale_sig( H, h, L_SUBFR, scale ); /*Q12+scale*/ E_ACELP_vec_neg_fx( h, h_inv, L_SUBFR ); /* * Compute correlation matrices needed for the codebook search. */ E_ACELP_corrmatrix_fx( h, sign, vec, rrixix, rrixiy ); /* * Deep first search: * ------------------ * 20 bits (4p): 4 iter x ((4x16)+(8x16)) = 768 tests * 36 bits (8p): 4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16) * +(8x16)+(8x16)) = 1248 tests * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16) * +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests */ psk = -1; move16(); alpk = 1; move16(); /*Number of iterations*/ FOR( k = 0; k < config->nbiter; k++ ) { E_ACELP_setup_pulse_search_pos( config, k, ipos ); /* format of alp changes to Q(15-ALP2_E) */ pos = config->fixedpulses; move16(); IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */ { ps = 0; move16(); alp = 0; move16(); set16_fx( vec, 0, L_SUBFR ); } ELSE IF( EQ_16( config->fixedpulses, 2 ) ) /* 2222 and 3322 */ { /* first stage: fix 2 pulses */ ind[0] = pos_max[ipos[0]]; move16(); ind[1] = pos_max[ipos[1]]; move16(); ps = add( dn[ind[0]], dn[ind[1]] ); /*alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] + rrixiy[ipos[0]][((ind[0] >> 2) << 4) + (ind[1] >> 2)];*/ i = shr( ind[0], 2 ); j = shr( ind[1], 2 ); l = add( shl( i, 4 ), j ); s = L_mult( rrixix[ipos[0]][i], _1_ ); /* Q9+Q12+1 */ s = L_mac( s, rrixix[ipos[1]][j], _1_ ); /* Q9+Q12+1 */ alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); /* Q9+Q12+1-16 */ p0 = h - ind[0]; /*Q12+scale*/ IF( sign[ind[0]] < 0 ) { p0 = h_inv - ind[0]; /*Q12+scale*/ } p1 = h - ind[1]; /*Q12+scale*/ IF( sign[ind[1]] < 0 ) { p1 = h_inv - ind[1]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { vec[i] = add( *p0++, *p1++ ); /*Q12+scale*/ move16(); } } ELSE /* 3333 and above */ { /* first stage: fix 4 pulses */ ind[0] = pos_max[ipos[0]]; /*Q0*/ move16(); ind[1] = pos_max[ipos[1]]; /*Q0*/ move16(); ind[2] = pos_max[ipos[2]]; /*Q0*/ move16(); ind[3] = pos_max[ipos[3]]; /*Q0*/ move16(); /*ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];*/ ps = add( add( add( dn[ind[0]], dn[ind[1]] ), dn[ind[2]] ), dn[ind[3]] ); p0 = h - ind[0]; /*Q12+scale*/ IF( sign[ind[0]] < 0 ) { p0 = h_inv - ind[0]; /*Q12+scale*/ } p1 = h - ind[1]; /*Q12+scale*/ IF( sign[ind[1]] < 0 ) { p1 = h_inv - ind[1]; /*Q12+scale*/ } p2 = h - ind[2]; /*Q12+scale*/ IF( sign[ind[2]] < 0 ) { p2 = h_inv - ind[2]; /*Q12+scale*/ } p3 = h - ind[3]; /*Q12+scale*/ IF( sign[ind[3]] < 0 ) { p3 = h_inv - ind[3]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); /*Q12+scale*/ move16(); } L_tmp = L_mult( vec[0], vec[0] ); /*Q25+2*scale*/ FOR( i = 1; i < L_SUBFR; i++ ) #ifdef BASOP_NOGLOB L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q25+2*scale*/ #else L_tmp = L_mac( L_tmp, vec[i], vec[i] ); #endif alp = round_fx( L_shr( L_tmp, 3 ) ); /*Q6+2*scale*/ /*alp *= 0.5F; */ } /* other stages of 2 pulses */ st = 0; move16(); FOR( j = pos; j < nb_pulse; j += 2 ) { IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */ { /* * Calculate correlation of all possible positions * of the next 2 pulses with previous fixed pulses. * Each pulse can have 16 possible positions. */ E_ACELP_h_vec_corr1_fx( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] ); E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); /* * Find best positions of 2 pulses. */ E_ACELP_2pulse_search( config->nbpos[st], ipos[j], ipos[j + 1], &ps, &alp, &ind[j], &ind[j + 1], dn, dn2_pos, cor_x, cor_y, rrixiy ); } ELSE /* single pulse search */ { E_ACELP_h_vec_corr2_fx( h, vec, ipos[j], sign, rrixix, cor_x ); E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y ); E_ACELP_1pulse_search( &ipos[j], &ps, &alp, &ind[j], dn, cor_x, cor_y ); } IF( GT_16( nb_pulse_m2, j ) ) { p0 = h - ind[j]; /*Q12+scale*/ IF( sign[ind[j]] < 0 ) { p0 = h_inv - ind[j]; /*Q12+scale*/ } p1 = h - ind[j + 1]; /*Q12+scale*/ IF( sign[ind[j + 1]] < 0 ) { p1 = h_inv - ind[j + 1]; /*Q12+scale*/ } FOR( i = 0; i < L_SUBFR; i++ ) { tmp = add( *p0++, *p1++ ); #ifdef BASOP_NOGLOB vec[i] = add_o( vec[i], tmp, &Overflow ); /* can saturate here. */ move16(); #else vec[i] = add( vec[i], tmp ); /* can saturate here. */ move16(); #endif } } st = add( st, 1 ); } /* memorise the best codevector */ /*ps = ps * ps; MULT(1);*/ ps = mult( ps, ps ); /*s = (alpk * ps) - (psk * alp); MULT(2);ADD(1);*/ s = L_msu( L_mult( alpk, ps ), psk, alp ); /*Q9+Q6+1=Q16*/ if ( psk < 0 ) { s = 1; move32(); } IF( s > 0 ) { psk = ps; move16(); alpk = alp; move16(); Copy( ind, codvec, nb_pulse ); /*Q0*/ check = 1; /* debug code not instrumented */ } } assert( check ); /* debug code not instrumented */ /* * Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations. */ E_ACELP_build_code( nb_pulse, codvec, sign, code, ind ); set16_fx( y, 0, L_SUBFR ); FOR( k = 0; k < nb_pulse; ++k ) { i = codvec[k]; /*Q0*/ move16(); p0 = h_inv - i; /*Q12+scale*/ IF( sign[i] > 0 ) { p0 -= 2 * L_SUBFR; } FOR( i = 0; i < L_SUBFR; i++ ) { #ifdef BASOP_NOGLOB y[i] = add_o( y[i], *p0++, &Overflow ); /*Q12+scale*/ #else y[i] = add( y[i], *p0++ ); #endif move16(); } } return; } #endif /* * E_ACELP_4t_fx Loading Loading @@ -1651,7 +1994,11 @@ void E_ACELP_4t_ivas_fx( } ELSE { #ifdef FIX_ISSUE_1165 E_ACELP_4tsearch_ivas_fx( dn, cn, H, code, &config, ind, y ); #else E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y ); #endif } E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index ); return; Loading
lib_enc/prot_fx_enc.h +4 −0 Original line number Diff line number Diff line Loading @@ -1559,6 +1559,10 @@ void Mode2_pit_encode_fx( Word16 pit_res_max ); void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); #ifdef FIX_ISSUE_1165 void E_ACELP_4tsearch_ivas_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/ ); #endif void E_ACELP_4t_fx( Word16 dn[], /* Qdn */ Word16 cn[] /* Q_xn */, Loading