LCOV - code coverage report
Current view: top level - lib_enc - find_tar_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 97 116 83.6 %
Date: 2025-06-27 02:59:36 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        9458 : 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        9458 :     Flag Overflow = 0;
      36        9458 :     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      160786 :     FOR( i = 0; i < M; i++ )
      52             :     {
      53      151328 :         temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */
      54      151328 :         move16();
      55             :     }
      56        9458 :     Syn_filt_s( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); /* error in Q_new -1 */
      57             : 
      58        9458 :     Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new -1*/
      59             : 
      60        9458 :     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        9458 :     IF( cn != NULL )
      67             :     {
      68             :         /* first half: xn[] --> cn[] */
      69        9448 :         temp[0] = 0;
      70        9448 :         move16();
      71        9448 :         preemph_copy_fx( xn, cn, tilt_fac, L_SUBFR / 2, temp );
      72        9448 :         syn_filt_s_lc_fx( 1, Ap, cn, temp, L_SUBFR / 2 );   /* Q-1 -> Q-2 */
      73        9448 :         Residu3_lc_fx( p_Aq, M, temp, cn, L_SUBFR / 2, 1 ); /* Q-2 -> Q-1 */
      74        9448 :         Scale_sig( cn, L_SUBFR / 2, 1 );
      75             : 
      76             :         /* second half: res[] --> cn[] (approximated and faster) */
      77        9448 :         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        9458 :     scale = norm_s( Ap[0] );
      85        9458 :     scaleq = norm_s( p_Aq[0] );
      86        9458 :     d = sub( scaleq, scale );
      87        9458 :     IF( d >= 0 )
      88             :     {
      89        9452 :         Copy( p_Aq, Aqs, M + 1 ); /* Q12 */
      90        9452 :         s = add( scaleq, 1 );
      91        9452 :         s2 = shr( 16384, d );
      92             :     }
      93             :     ELSE
      94             :     {
      95           6 :         Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */
      96           6 :         s = add( scale, 1 );
      97           6 :         s2 = 16384;
      98             :     }
      99        9458 :     Overflow = 0;
     100        9458 :     move16();
     101      160786 :     FOR( i = 0; i < M; i++ )
     102             :     {
     103      151328 :         Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     104     1286288 :         FOR( j = 1; j <= i; j++ )
     105             :         {
     106     1134960 :             Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     107             :         }
     108      151328 :         h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     109             :     }
     110        9458 :     Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     111      160786 :     FOR( j = 1; j <= M; j++ )
     112             :     {
     113      151328 :         Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     114             :     }
     115        9458 :     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      454624 :     FOR( i = M + 1; i < L_subfr; i++ )
     119             :     {
     120      445166 :         Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */
     121     7122656 :         FOR( j = 2; j <= M; j++ )
     122             :         {
     123     6677490 :             Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     124             :         }
     125      445166 :         h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     126             :     }
     127        9458 :     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_o( Ltmp, s, &Overflow ) ); /* 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        9458 :     tmp = 0;
     157        9458 :     Deemph2( h1, tilt_fac, L_subfr, &tmp );
     158             : 
     159        9458 :     return;
     160             : }
     161             : 
     162      634227 : 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             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     185      634227 :     Flag Overflow = 0;
     186      634227 :     move16();
     187             : #endif
     188             :     /*------------------------------------------------------------------------*
     189             :      * Find the target vector for excitation search:
     190             :      *
     191             :      *             |------|  res[n]
     192             :      * speech[n]---| A(z) |--------
     193             :      *             |------|       |   |--------| error[n]  |------|
     194             :      *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target
     195             :      *                   exc          |--------|           |------|
     196             :      *
     197             :      * Instead of subtracting the zero-input response of filters from
     198             :      * the weighted input speech, the above configuration is used to
     199             :      * compute the target vector.
     200             :      *-----------------------------------------------------------------------*/
     201    10781859 :     FOR( i = 0; i < M; i++ )
     202             :     {
     203    10147632 :         temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */
     204    10147632 :         move16();
     205             :     }
     206             : 
     207      634227 :     syn_filt_fx( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 );
     208             : 
     209      634227 :     Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new - 1 */
     210             : 
     211      634227 :     deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new - 1 */
     212             : 
     213             : 
     214             :     /*-----------------------------------------------------------------*
     215             :      * Find target in residual domain (cn[]) for innovation search
     216             :      *--------------------------------------------------------------*/
     217      634227 :     IF( cn != NULL )
     218             :     {
     219             :         /* first half: xn[] --> cn[] */
     220      634227 :         temp[0] = 0;
     221      634227 :         move16();
     222      634227 :         preemph_copy_fx( xn, cn, tilt_fac, L_subfr / 2, temp );
     223      634227 :         syn_filt_s_lc_fx( 1, Ap, cn, temp, L_subfr / 2 );   /* Q-1 -> Q-2 */
     224      634227 :         Residu3_lc_fx( p_Aq, M, temp, cn, L_subfr / 2, 1 ); /* Q-2 -> Q-1 */
     225      634227 :         Scale_sig( cn, L_subfr / 2, 1 );
     226             : 
     227             :         /* second half: res[] --> cn[] (approximated and faster) */
     228      634227 :         Copy( &res[i_subfr + ( L_subfr / 2 )], cn + ( L_subfr / 2 ), L_subfr / 2 );
     229             :     }
     230             : 
     231             :     /*---------------------------------------------------------------*
     232             :      * Compute impulse response, h1[], of weighted synthesis filter  *
     233             :      *---------------------------------------------------------------*/
     234             : 
     235      634227 :     scale = norm_s( Ap[0] );
     236      634227 :     scaleq = norm_s( p_Aq[0] );
     237      634227 :     d = sub( scaleq, scale );
     238      634227 :     IF( d >= 0 )
     239             :     {
     240      634227 :         Copy( p_Aq, Aqs, M + 1 ); /* Q12 */
     241      634227 :         s = add( scaleq, 1 );
     242      634227 :         s2 = shr( 16384, d );
     243             :     }
     244             :     ELSE
     245             :     {
     246           0 :         Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */
     247           0 :         s = add( scale, 1 );
     248           0 :         s2 = 16384;
     249           0 :         move16();
     250             :     }
     251             : 
     252      634227 :     set32_fx( h1_32, 0, L_subfr );
     253      634227 :     Overflow = 0;
     254      634227 :     move16();
     255    10781859 :     FOR( i = 0; i < M; i++ )
     256             :     {
     257    10147632 :         Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     258    86254872 :         FOR( j = 1; j <= i; j++ )
     259             :         {
     260    76107240 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */
     261             :         }
     262    10147632 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     263    10147632 :         move32();
     264             :     }
     265             : 
     266      634227 :     Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     267    10781859 :     FOR( j = 1; j <= M; j++ )
     268             :     {
     269    10147632 :         Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */
     270             :     }
     271      634227 :     h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */
     272      634227 :     move32();
     273             : 
     274    32622096 :     FOR( i = M + 1; i < L_subfr; i++ )
     275             :     {
     276    31987869 :         Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_o( h1_32[i - 1], s, &Overflow ) ) ); /* Q27 */
     277   511805904 :         FOR( j = 2; j <= M; j++ )
     278             :         {
     279   479818035 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_o( h1_32[i - j], s, &Overflow ) ) ); /* Q27 */
     280             :         }
     281    31987869 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     282    31987869 :         move32();
     283             :     }
     284             : 
     285      634227 :     sf = sub( L_norm_arr( h1_32, L_subfr ), 1 );
     286      634227 :     Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf
     287             : 
     288      634227 :     tmp = 0;
     289      634227 :     move16();
     290      634227 :     Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1
     291             : 
     292      634227 :     return;
     293             : }

Generated by: LCOV version 1.14