LCOV - code coverage report
Current view: top level - lib_enc - find_tar_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 22b74eaeaa63d28e0fcc8ed21c8f7c451f461847 Lines: 93 112 83.0 %
Date: 2025-10-19 02:52:40 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           0 :             h1[i] = round_fx( L_shl_sat( Ltmp, s ) ); /* Q11 + s */
     138             :         }
     139           0 :         Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     140           0 :         FOR( j = 1; j <= M; j++ )
     141             :         {
     142           0 :             Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     143             :         }
     144           0 :         h1[M] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */
     145           0 :         FOR( i = M + 1; i < L_subfr; i++ )
     146             :         {
     147           0 :             Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */
     148           0 :             FOR( j = 2; j <= M; j++ )
     149             :             {
     150           0 :                 Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     151             :             }
     152           0 :             h1[i] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */
     153             :         }
     154             :     }
     155             : 
     156        9435 :     tmp = 0;
     157        9435 :     Deemph2( h1, tilt_fac, L_subfr, &tmp );
     158             : 
     159        9435 :     return;
     160             : }
     161             : 
     162      635786 : void find_targets_ivas_fx(
     163             :     const Word16 *speech,  /* i  : pointer to the speech frame                      Q_new-1*/
     164             :     const Word16 *mem_syn, /* i  : memory of the synthesis filter                   Q_new-1*/
     165             :     const Word16 i_subfr,  /* i  : subframe index                                   Q0*/
     166             :     Word16 *mem_w0,        /* i/o: weighting filter denominator memory              Q_new-1*/
     167             :     const Word16 *p_Aq,    /* i  : interpolated quantized A(z) filter               Q12*/
     168             :     const Word16 *res,     /* i  : residual signal                                  Q_new*/
     169             :     const Word16 L_subfr,  /* i  : length of vectors for gain quantization          Q0*/
     170             :     const Word16 *Ap,      /* i  : unquantized A(z) filter with bandwidth expansion Q12*/
     171             :     Word16 tilt_fac,       /* i  : tilt factor                                                                          Q15*/
     172             :     Word16 *xn,            /* o  : Close-loop Pitch search target vector            Q_new-1*/
     173             :     Word16 *cn,            /* o  : target vector in residual domain                 Q_new*/
     174             :     Word16 *h1             /* o  : impulse response of weighted synthesis filter    Q(14 - norm_s(h1[0]))*/
     175             : )
     176             : {
     177             :     Word16 i;
     178             :     Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */
     179             :     Word16 scale, scaleq, j, d, s, s2, tmp;
     180             :     Word16 Aqs[M + 1];
     181             :     Word32 h1_32[6 * L_SUBFR];
     182             :     Word16 sf;
     183             :     Word64 Ltmp64;
     184             : 
     185             :     /*------------------------------------------------------------------------*
     186             :      * Find the target vector for excitation search:
     187             :      *
     188             :      *             |------|  res[n]
     189             :      * speech[n]---| A(z) |--------
     190             :      *             |------|       |   |--------| error[n]  |------|
     191             :      *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target
     192             :      *                   exc          |--------|           |------|
     193             :      *
     194             :      * Instead of subtracting the zero-input response of filters from
     195             :      * the weighted input speech, the above configuration is used to
     196             :      * compute the target vector.
     197             :      *-----------------------------------------------------------------------*/
     198    10808362 :     FOR( i = 0; i < M; i++ )
     199             :     {
     200    10172576 :         temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */
     201    10172576 :         move16();
     202             :     }
     203             : 
     204      635786 :     syn_filt_fx( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 );
     205             : 
     206      635786 :     Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new - 1 */
     207             : 
     208      635786 :     deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new - 1 */
     209             : 
     210             : 
     211             :     /*-----------------------------------------------------------------*
     212             :      * Find target in residual domain (cn[]) for innovation search
     213             :      *--------------------------------------------------------------*/
     214      635786 :     IF( cn != NULL )
     215             :     {
     216             :         /* first half: xn[] --> cn[] */
     217      635786 :         temp[0] = 0;
     218      635786 :         move16();
     219      635786 :         preemph_copy_fx( xn, cn, tilt_fac, L_subfr / 2, temp );
     220      635786 :         syn_filt_s_lc_fx( 1, Ap, cn, temp, L_subfr / 2 );   /* Q-1 -> Q-2 */
     221      635786 :         Residu3_lc_fx( p_Aq, M, temp, cn, L_subfr / 2, 1 ); /* Q-2 -> Q-1 */
     222      635786 :         Scale_sig( cn, L_subfr / 2, 1 );
     223             : 
     224             :         /* second half: res[] --> cn[] (approximated and faster) */
     225      635786 :         Copy( &res[i_subfr + ( L_subfr / 2 )], cn + ( L_subfr / 2 ), L_subfr / 2 );
     226             :     }
     227             : 
     228             :     /*---------------------------------------------------------------*
     229             :      * Compute impulse response, h1[], of weighted synthesis filter  *
     230             :      *---------------------------------------------------------------*/
     231             : 
     232      635786 :     scale = norm_s( Ap[0] );
     233      635786 :     scaleq = norm_s( p_Aq[0] );
     234      635786 :     d = sub( scaleq, scale );
     235      635786 :     IF( d >= 0 )
     236             :     {
     237      635786 :         Copy( p_Aq, Aqs, M + 1 ); /* Q12 */
     238      635786 :         s = add( scaleq, 1 );
     239      635786 :         s2 = shr( 16384, d );
     240             :     }
     241             :     ELSE
     242             :     {
     243           0 :         Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */
     244           0 :         s = add( scale, 1 );
     245           0 :         s2 = 16384;
     246           0 :         move16();
     247             :     }
     248             : 
     249      635786 :     set32_fx( h1_32, 0, L_subfr );
     250    10808362 :     FOR( i = 0; i < M; i++ )
     251             :     {
     252    10172576 :         Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     253    86466896 :         FOR( j = 1; j <= i; j++ )
     254             :         {
     255    76294320 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     256             :         }
     257    10172576 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     258    10172576 :         move32();
     259             :     }
     260             : 
     261      635786 :     Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     262    10808362 :     FOR( j = 1; j <= M; j++ )
     263             :     {
     264    10172576 :         Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     265             :     }
     266      635786 :     h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */
     267      635786 :     move32();
     268             : 
     269    32699168 :     FOR( i = M + 1; i < L_subfr; i++ )
     270             :     {
     271    32063382 :         Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_sat( h1_32[i - 1], s ) ) ); /* Q27 */
     272   513014112 :         FOR( j = 2; j <= M; j++ )
     273             :         {
     274   480950730 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     275             :         }
     276    32063382 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     277    32063382 :         move32();
     278             :     }
     279             : 
     280      635786 :     sf = sub( L_norm_arr( h1_32, L_subfr ), 1 );
     281      635786 :     Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf
     282             : 
     283      635786 :     tmp = 0;
     284      635786 :     move16();
     285      635786 :     Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1
     286             : 
     287      635786 :     return;
     288             : }

Generated by: LCOV version 1.14