LCOV - code coverage report
Current view: top level - lib_enc - find_tar_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 93 112 83.0 %
Date: 2025-09-14 03:13:15 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : // #include "prot_fx.h"       /* Function prototypes                    */
       7             : #include "prot_fx.h"     /* Function prototypes                    */
       8             : #include "prot_fx_enc.h" /* Function prototypes                    */
       9             : #include "cnst.h"        /* Common constants                       */
      10             : #include "basop_util.h"
      11             : #include "stl.h"
      12             : 
      13             : 
      14        9435 : void find_targets_fx(
      15             :     const Word16 *speech,  /* i  : pointer to the speech frame                      Q_new-1*/
      16             :     const Word16 *mem_syn, /* i  : memory of the synthesis filter                   Q_new-1*/
      17             :     const Word16 i_subfr,  /* i  : subframe index                                   Q0*/
      18             :     Word16 *mem_w0,        /* i/o: weighting filter denominator memory              Q_new-1*/
      19             :     const Word16 *p_Aq,    /* i  : interpolated quantized A(z) filter               Q12*/
      20             :     const Word16 *res,     /* i  : residual signal                                  Q_new*/
      21             :     const Word16 L_subfr,  /* i  : length of vectors for gain quantization          Q0*/
      22             :     const Word16 *Ap,      /* i  : unquantized A(z) filter with bandwidth expansion Q12*/
      23             :     Word16 tilt_fac,       /* i  : tilt factor                                                                          Q15*/
      24             :     Word16 *xn,            /* o  : Close-loop Pitch search target vector            Q_new-1*/
      25             :     Word16 *cn,            /* o  : target vector in residual domain                 Q_new*/
      26             :     Word16 *h1             /* o  : impulse response of weighted synthesis filter    Q14*/
      27             : )
      28             : {
      29             :     Word16 i;
      30             :     Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */
      31             :     Word16 scale, scaleq, j, d, s, s2, tmp;
      32             :     Word16 Aqs[M + 1];
      33             :     Word32 Ltmp;
      34             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      35        9435 :     Flag Overflow = 0;
      36        9435 :     move32();
      37             : #endif
      38             :     /*------------------------------------------------------------------------*
      39             :      * Find the target vector for excitation search:
      40             :      *
      41             :      *             |------|  res[n]
      42             :      * speech[n]---| A(z) |--------
      43             :      *             |------|       |   |--------| error[n]  |------|
      44             :      *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target
      45             :      *                   exc          |--------|           |------|
      46             :      *
      47             :      * Instead of subtracting the zero-input response of filters from
      48             :      * the weighted input speech, the above configuration is used to
      49             :      * compute the target vector.
      50             :      *-----------------------------------------------------------------------*/
      51      160395 :     FOR( i = 0; i < M; i++ )
      52             :     {
      53      150960 :         temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */
      54      150960 :         move16();
      55             :     }
      56        9435 :     Syn_filt_s( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); /* error in Q_new -1 */
      57             : 
      58        9435 :     Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new -1*/
      59             : 
      60        9435 :     deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new -1 */
      61             : 
      62             : 
      63             :     /*-----------------------------------------------------------------*
      64             :      * Find target in residual domain (cn[]) for innovation search
      65             :      *--------------------------------------------------------------*/
      66        9435 :     IF( cn != NULL )
      67             :     {
      68             :         /* first half: xn[] --> cn[] */
      69        9419 :         temp[0] = 0;
      70        9419 :         move16();
      71        9419 :         preemph_copy_fx( xn, cn, tilt_fac, L_SUBFR / 2, temp );
      72        9419 :         syn_filt_s_lc_fx( 1, Ap, cn, temp, L_SUBFR / 2 );   /* Q-1 -> Q-2 */
      73        9419 :         Residu3_lc_fx( p_Aq, M, temp, cn, L_SUBFR / 2, 1 ); /* Q-2 -> Q-1 */
      74        9419 :         Scale_sig( cn, L_SUBFR / 2, 1 );
      75             : 
      76             :         /* second half: res[] --> cn[] (approximated and faster) */
      77        9419 :         Copy( &res[i_subfr + ( L_SUBFR / 2 )], cn + ( L_SUBFR / 2 ), L_SUBFR / 2 ); /* Q_new */
      78             :     }
      79             : 
      80             :     /*---------------------------------------------------------------*
      81             :      * Compute impulse response, h1[], of weighted synthesis filter  *
      82             :      *---------------------------------------------------------------*/
      83             : 
      84        9435 :     scale = norm_s( Ap[0] );
      85        9435 :     scaleq = norm_s( p_Aq[0] );
      86        9435 :     d = sub( scaleq, scale );
      87        9435 :     IF( d >= 0 )
      88             :     {
      89        9432 :         Copy( p_Aq, Aqs, M + 1 ); /* Q12 */
      90        9432 :         s = add( scaleq, 1 );
      91        9432 :         s2 = shr( 16384, d );
      92             :     }
      93             :     ELSE
      94             :     {
      95           3 :         Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */
      96           3 :         s = add( scale, 1 );
      97           3 :         s2 = 16384;
      98             :     }
      99        9435 :     Overflow = 0;
     100        9435 :     move16();
     101      160395 :     FOR( i = 0; i < M; i++ )
     102             :     {
     103      150960 :         Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     104     1283160 :         FOR( j = 1; j <= i; j++ )
     105             :         {
     106     1132200 :             Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     107             :         }
     108      150960 :         h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     109             :     }
     110        9435 :     Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     111      160395 :     FOR( j = 1; j <= M; j++ )
     112             :     {
     113      150960 :         Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     114             :     }
     115        9435 :     h1[M] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     116             : 
     117             :     // PMT("should we used extended basop here for when the L_subfr > L_SUBFR, to prevent saturation/overflow and the subsequent loop\n")
     118      453904 :     FOR( i = M + 1; i < L_subfr; i++ )
     119             :     {
     120      444469 :         Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */
     121     7111504 :         FOR( j = 2; j <= M; j++ )
     122             :         {
     123     6667035 :             Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     124             :         }
     125      444469 :         h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     126             :     }
     127        9435 :     IF( Overflow )
     128             :     {
     129           0 :         s2 = shr( s2, 1 );
     130           0 :         FOR( i = 0; i < M; i++ )
     131             :         {
     132           0 :             Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     133           0 :             FOR( j = 1; j <= i; j++ )
     134             :             {
     135           0 :                 Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     136             :             }
     137             : #ifdef ISSUE_1867_replace_overflow_libenc
     138           0 :             h1[i] = round_fx( L_shl_sat( Ltmp, s ) ); /* Q11 + s */
     139             : #else
     140             :             h1[i] = round_fx( L_shl_o( Ltmp, s, &Overflow ) );                                          /* Q11 + s */
     141             : #endif
     142             :         }
     143           0 :         Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     144           0 :         FOR( j = 1; j <= M; j++ )
     145             :         {
     146           0 :             Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     147             :         }
     148           0 :         h1[M] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */
     149           0 :         FOR( i = M + 1; i < L_subfr; i++ )
     150             :         {
     151           0 :             Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */
     152           0 :             FOR( j = 2; j <= M; j++ )
     153             :             {
     154           0 :                 Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     155             :             }
     156           0 :             h1[i] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */
     157             :         }
     158             :     }
     159             : 
     160        9435 :     tmp = 0;
     161        9435 :     Deemph2( h1, tilt_fac, L_subfr, &tmp );
     162             : 
     163        9435 :     return;
     164             : }
     165             : 
     166      635982 : void find_targets_ivas_fx(
     167             :     const Word16 *speech,  /* i  : pointer to the speech frame                      Q_new-1*/
     168             :     const Word16 *mem_syn, /* i  : memory of the synthesis filter                   Q_new-1*/
     169             :     const Word16 i_subfr,  /* i  : subframe index                                   Q0*/
     170             :     Word16 *mem_w0,        /* i/o: weighting filter denominator memory              Q_new-1*/
     171             :     const Word16 *p_Aq,    /* i  : interpolated quantized A(z) filter               Q12*/
     172             :     const Word16 *res,     /* i  : residual signal                                  Q_new*/
     173             :     const Word16 L_subfr,  /* i  : length of vectors for gain quantization          Q0*/
     174             :     const Word16 *Ap,      /* i  : unquantized A(z) filter with bandwidth expansion Q12*/
     175             :     Word16 tilt_fac,       /* i  : tilt factor                                                                          Q15*/
     176             :     Word16 *xn,            /* o  : Close-loop Pitch search target vector            Q_new-1*/
     177             :     Word16 *cn,            /* o  : target vector in residual domain                 Q_new*/
     178             :     Word16 *h1             /* o  : impulse response of weighted synthesis filter    Q(14 - norm_s(h1[0]))*/
     179             : )
     180             : {
     181             :     Word16 i;
     182             :     Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */
     183             :     Word16 scale, scaleq, j, d, s, s2, tmp;
     184             :     Word16 Aqs[M + 1];
     185             :     Word32 h1_32[6 * L_SUBFR];
     186             :     Word16 sf;
     187             :     Word64 Ltmp64;
     188             : #ifndef ISSUE_1867_replace_overflow_libenc
     189             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     190             :     Flag Overflow = 0;
     191             :     move16();
     192             : #endif
     193             : #endif
     194             :     /*------------------------------------------------------------------------*
     195             :      * Find the target vector for excitation search:
     196             :      *
     197             :      *             |------|  res[n]
     198             :      * speech[n]---| A(z) |--------
     199             :      *             |------|       |   |--------| error[n]  |------|
     200             :      *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target
     201             :      *                   exc          |--------|           |------|
     202             :      *
     203             :      * Instead of subtracting the zero-input response of filters from
     204             :      * the weighted input speech, the above configuration is used to
     205             :      * compute the target vector.
     206             :      *-----------------------------------------------------------------------*/
     207    10811694 :     FOR( i = 0; i < M; i++ )
     208             :     {
     209    10175712 :         temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */
     210    10175712 :         move16();
     211             :     }
     212             : 
     213      635982 :     syn_filt_fx( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 );
     214             : 
     215      635982 :     Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new - 1 */
     216             : 
     217      635982 :     deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new - 1 */
     218             : 
     219             : 
     220             :     /*-----------------------------------------------------------------*
     221             :      * Find target in residual domain (cn[]) for innovation search
     222             :      *--------------------------------------------------------------*/
     223      635982 :     IF( cn != NULL )
     224             :     {
     225             :         /* first half: xn[] --> cn[] */
     226      635982 :         temp[0] = 0;
     227      635982 :         move16();
     228      635982 :         preemph_copy_fx( xn, cn, tilt_fac, L_subfr / 2, temp );
     229      635982 :         syn_filt_s_lc_fx( 1, Ap, cn, temp, L_subfr / 2 );   /* Q-1 -> Q-2 */
     230      635982 :         Residu3_lc_fx( p_Aq, M, temp, cn, L_subfr / 2, 1 ); /* Q-2 -> Q-1 */
     231      635982 :         Scale_sig( cn, L_subfr / 2, 1 );
     232             : 
     233             :         /* second half: res[] --> cn[] (approximated and faster) */
     234      635982 :         Copy( &res[i_subfr + ( L_subfr / 2 )], cn + ( L_subfr / 2 ), L_subfr / 2 );
     235             :     }
     236             : 
     237             :     /*---------------------------------------------------------------*
     238             :      * Compute impulse response, h1[], of weighted synthesis filter  *
     239             :      *---------------------------------------------------------------*/
     240             : 
     241      635982 :     scale = norm_s( Ap[0] );
     242      635982 :     scaleq = norm_s( p_Aq[0] );
     243      635982 :     d = sub( scaleq, scale );
     244      635982 :     IF( d >= 0 )
     245             :     {
     246      635982 :         Copy( p_Aq, Aqs, M + 1 ); /* Q12 */
     247      635982 :         s = add( scaleq, 1 );
     248      635982 :         s2 = shr( 16384, d );
     249             :     }
     250             :     ELSE
     251             :     {
     252           0 :         Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */
     253           0 :         s = add( scale, 1 );
     254           0 :         s2 = 16384;
     255           0 :         move16();
     256             :     }
     257             : 
     258      635982 :     set32_fx( h1_32, 0, L_subfr );
     259             : #ifndef ISSUE_1867_replace_overflow_libenc
     260             :     Overflow = 0;
     261             :     move16();
     262             : #endif
     263    10811694 :     FOR( i = 0; i < M; i++ )
     264             :     {
     265    10175712 :         Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     266    86493552 :         FOR( j = 1; j <= i; j++ )
     267             :         {
     268             : #ifdef ISSUE_1867_replace_overflow_libenc
     269    76317840 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     270             : #else
     271             :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */
     272             : #endif
     273             :         }
     274    10175712 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     275    10175712 :         move32();
     276             :     }
     277             : 
     278      635982 :     Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     279    10811694 :     FOR( j = 1; j <= M; j++ )
     280             :     {
     281             : #ifdef ISSUE_1867_replace_overflow_libenc
     282    10175712 :         Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     283             : #else
     284             :         Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) );     /* Q27 */
     285             : #endif
     286             :     }
     287      635982 :     h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */
     288      635982 :     move32();
     289             : 
     290    32704736 :     FOR( i = M + 1; i < L_subfr; i++ )
     291             :     {
     292             : #ifdef ISSUE_1867_replace_overflow_libenc
     293    32068754 :         Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_sat( h1_32[i - 1], s ) ) ); /* Q27 */
     294             : #else
     295             :         Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_o( h1_32[i - 1], s, &Overflow ) ) );          /* Q27 */
     296             : #endif
     297   513100064 :         FOR( j = 2; j <= M; j++ )
     298             :         {
     299             : #ifdef ISSUE_1867_replace_overflow_libenc
     300   481031310 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     301             : #else
     302             :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */
     303             : #endif
     304             :         }
     305    32068754 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     306    32068754 :         move32();
     307             :     }
     308             : 
     309      635982 :     sf = sub( L_norm_arr( h1_32, L_subfr ), 1 );
     310      635982 :     Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf
     311             : 
     312      635982 :     tmp = 0;
     313      635982 :     move16();
     314      635982 :     Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1
     315             : 
     316      635982 :     return;
     317             : }

Generated by: LCOV version 1.14