LCOV - code coverage report
Current view: top level - lib_enc - find_tar_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ b9bfbe380d1c207f5198ba67a82398b3d313550e Lines: 93 112 83.0 %
Date: 2025-11-15 04:01:59 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       15201 : 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       15201 :     Flag Overflow = 0;
      35       15201 :     move32();
      36             :     /*------------------------------------------------------------------------*
      37             :      * Find the target vector for excitation search:
      38             :      *
      39             :      *             |------|  res[n]
      40             :      * speech[n]---| A(z) |--------
      41             :      *             |------|       |   |--------| error[n]  |------|
      42             :      *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target
      43             :      *                   exc          |--------|           |------|
      44             :      *
      45             :      * Instead of subtracting the zero-input response of filters from
      46             :      * the weighted input speech, the above configuration is used to
      47             :      * compute the target vector.
      48             :      *-----------------------------------------------------------------------*/
      49      258417 :     FOR( i = 0; i < M; i++ )
      50             :     {
      51      243216 :         temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */
      52      243216 :         move16();
      53             :     }
      54       15201 :     Syn_filt_s( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 ); /* error in Q_new -1 */
      55             : 
      56       15201 :     Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new -1*/
      57             : 
      58       15201 :     deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new -1 */
      59             : 
      60             : 
      61             :     /*-----------------------------------------------------------------*
      62             :      * Find target in residual domain (cn[]) for innovation search
      63             :      *--------------------------------------------------------------*/
      64       15201 :     IF( cn != NULL )
      65             :     {
      66             :         /* first half: xn[] --> cn[] */
      67       15185 :         temp[0] = 0;
      68       15185 :         move16();
      69       15185 :         preemph_copy_fx( xn, cn, tilt_fac, L_SUBFR / 2, temp );
      70       15185 :         syn_filt_s_lc_fx( 1, Ap, cn, temp, L_SUBFR / 2 );   /* Q-1 -> Q-2 */
      71       15185 :         Residu3_lc_fx( p_Aq, M, temp, cn, L_SUBFR / 2, 1 ); /* Q-2 -> Q-1 */
      72       15185 :         Scale_sig( cn, L_SUBFR / 2, 1 );
      73             : 
      74             :         /* second half: res[] --> cn[] (approximated and faster) */
      75       15185 :         Copy( &res[i_subfr + ( L_SUBFR / 2 )], cn + ( L_SUBFR / 2 ), L_SUBFR / 2 ); /* Q_new */
      76             :     }
      77             : 
      78             :     /*---------------------------------------------------------------*
      79             :      * Compute impulse response, h1[], of weighted synthesis filter  *
      80             :      *---------------------------------------------------------------*/
      81             : 
      82       15201 :     scale = norm_s( Ap[0] );
      83       15201 :     scaleq = norm_s( p_Aq[0] );
      84       15201 :     d = sub( scaleq, scale );
      85       15201 :     IF( d >= 0 )
      86             :     {
      87       15195 :         Copy( p_Aq, Aqs, M + 1 ); /* Q12 */
      88       15195 :         s = add( scaleq, 1 );
      89       15195 :         s2 = shr( 16384, d );
      90             :     }
      91             :     ELSE
      92             :     {
      93           6 :         Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */
      94           6 :         s = add( scale, 1 );
      95           6 :         s2 = 16384;
      96             :     }
      97       15201 :     Overflow = 0;
      98       15201 :     move16();
      99      258417 :     FOR( i = 0; i < M; i++ )
     100             :     {
     101      243216 :         Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     102     2067336 :         FOR( j = 1; j <= i; j++ )
     103             :         {
     104     1824120 :             Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     105             :         }
     106      243216 :         h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     107             :     }
     108       15201 :     Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     109      258417 :     FOR( j = 1; j <= M; j++ )
     110             :     {
     111      243216 :         Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     112             :     }
     113       15201 :     h1[M] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     114             : 
     115      730672 :     FOR( i = M + 1; i < L_subfr; i++ )
     116             :     {
     117      715471 :         Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */
     118    11447536 :         FOR( j = 2; j <= M; j++ )
     119             :         {
     120    10732065 :             Ltmp = L_msu_o( Ltmp, Aqs[j], h1[i - j], &Overflow ); /* Q27 */
     121             :         }
     122      715471 :         h1[i] = round_fx_o( L_shl_o( Ltmp, s, &Overflow ), &Overflow ); /* Q11 + s */
     123             :     }
     124       15201 :     IF( Overflow )
     125             :     {
     126           0 :         s2 = shr( s2, 1 );
     127           0 :         FOR( i = 0; i < M; i++ )
     128             :         {
     129           0 :             Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     130           0 :             FOR( j = 1; j <= i; j++ )
     131             :             {
     132           0 :                 Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     133             :             }
     134           0 :             h1[i] = round_fx( L_shl_sat( Ltmp, s ) ); /* Q11 + s */
     135             :         }
     136           0 :         Ltmp = L_mult( Ap[i], s2 ); /* Q27 */
     137           0 :         FOR( j = 1; j <= M; j++ )
     138             :         {
     139           0 :             Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     140             :         }
     141           0 :         h1[M] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */
     142           0 :         FOR( i = M + 1; i < L_subfr; i++ )
     143             :         {
     144           0 :             Ltmp = L_msu( 0, Aqs[1], h1[i - 1] ); /* Q27 */
     145           0 :             FOR( j = 2; j <= M; j++ )
     146             :             {
     147           0 :                 Ltmp = L_msu( Ltmp, Aqs[j], h1[i - j] ); /* Q27 */
     148             :             }
     149           0 :             h1[i] = round_fx( L_shl( Ltmp, s ) ); /* Q11 + s */
     150             :         }
     151             :     }
     152             : 
     153       15201 :     tmp = 0;
     154       15201 :     Deemph2( h1, tilt_fac, L_subfr, &tmp );
     155             : 
     156       15201 :     return;
     157             : }
     158             : 
     159      783679 : void find_targets_ivas_fx(
     160             :     const Word16 *speech,  /* i  : pointer to the speech frame                      Q_new-1*/
     161             :     const Word16 *mem_syn, /* i  : memory of the synthesis filter                   Q_new-1*/
     162             :     const Word16 i_subfr,  /* i  : subframe index                                   Q0*/
     163             :     Word16 *mem_w0,        /* i/o: weighting filter denominator memory              Q_new-1*/
     164             :     const Word16 *p_Aq,    /* i  : interpolated quantized A(z) filter               Q12*/
     165             :     const Word16 *res,     /* i  : residual signal                                  Q_new*/
     166             :     const Word16 L_subfr,  /* i  : length of vectors for gain quantization          Q0*/
     167             :     const Word16 *Ap,      /* i  : unquantized A(z) filter with bandwidth expansion Q12*/
     168             :     Word16 tilt_fac,       /* i  : tilt factor                                      Q15*/
     169             :     Word16 *xn,            /* o  : Close-loop Pitch search target vector            Q_new-1*/
     170             :     Word16 *cn,            /* o  : target vector in residual domain                 Q_new*/
     171             :     Word16 *h1             /* o  : impulse response of weighted synthesis filter    Q(14 - norm_s(h1[0]))*/
     172             : )
     173             : {
     174             :     Word16 i;
     175             :     Word16 temp[M + 6 * L_SUBFR]; /* error of quantization */
     176             :     Word16 scale, scaleq, j, d, s, s2, tmp;
     177             :     Word16 Aqs[M + 1];
     178             :     Word32 h1_32[6 * L_SUBFR];
     179             :     Word16 sf;
     180             :     Word64 Ltmp64;
     181             : 
     182             :     /*------------------------------------------------------------------------*
     183             :      * Find the target vector for excitation search:
     184             :      *
     185             :      *             |------|  res[n]
     186             :      * speech[n]---| A(z) |--------
     187             :      *             |------|       |   |--------| error[n]  |------|
     188             :      *                   zero -- (-)--| 1/A(z) |-----------| W(z) |-- target
     189             :      *                   exc          |--------|           |------|
     190             :      *
     191             :      * Instead of subtracting the zero-input response of filters from
     192             :      * the weighted input speech, the above configuration is used to
     193             :      * compute the target vector.
     194             :      *-----------------------------------------------------------------------*/
     195    13322543 :     FOR( i = 0; i < M; i++ )
     196             :     {
     197    12538864 :         temp[i] = sub_sat( speech[i + i_subfr - M], mem_syn[i] ); /* Q_new - 1 */
     198    12538864 :         move16();
     199             :     }
     200             : 
     201      783679 :     syn_filt_fx( 1, p_Aq, M, &res[i_subfr], temp + M, L_subfr, temp, 0 );
     202             : 
     203      783679 :     Residu3_fx( Ap, temp + M, xn, L_subfr, 0 ); /* xn in Q_new - 1 */
     204             : 
     205      783679 :     deemph_fx( xn, tilt_fac, L_subfr, mem_w0 ); /* xn in Q_new - 1 */
     206             : 
     207             : 
     208             :     /*-----------------------------------------------------------------*
     209             :      * Find target in residual domain (cn[]) for innovation search
     210             :      *--------------------------------------------------------------*/
     211      783679 :     IF( cn != NULL )
     212             :     {
     213             :         /* first half: xn[] --> cn[] */
     214      783679 :         temp[0] = 0;
     215      783679 :         move16();
     216      783679 :         preemph_copy_fx( xn, cn, tilt_fac, L_subfr / 2, temp );
     217      783679 :         syn_filt_s_lc_fx( 1, Ap, cn, temp, L_subfr / 2 );   /* Q-1 -> Q-2 */
     218      783679 :         Residu3_lc_fx( p_Aq, M, temp, cn, L_subfr / 2, 1 ); /* Q-2 -> Q-1 */
     219      783679 :         Scale_sig( cn, L_subfr / 2, 1 );
     220             : 
     221             :         /* second half: res[] --> cn[] (approximated and faster) */
     222      783679 :         Copy( &res[i_subfr + ( L_subfr / 2 )], cn + ( L_subfr / 2 ), L_subfr / 2 );
     223             :     }
     224             : 
     225             :     /*---------------------------------------------------------------*
     226             :      * Compute impulse response, h1[], of weighted synthesis filter  *
     227             :      *---------------------------------------------------------------*/
     228             : 
     229      783679 :     scale = norm_s( Ap[0] );
     230      783679 :     scaleq = norm_s( p_Aq[0] );
     231      783679 :     d = sub( scaleq, scale );
     232      783679 :     IF( d >= 0 )
     233             :     {
     234      783679 :         Copy( p_Aq, Aqs, M + 1 ); /* Q12 */
     235      783679 :         s = add( scaleq, 1 );
     236      783679 :         s2 = shr( 16384, d );
     237             :     }
     238             :     ELSE
     239             :     {
     240           0 :         Copy_Scale_sig( p_Aq, Aqs, M + 1, d ); /* Q12 */
     241           0 :         s = add( scale, 1 );
     242           0 :         s2 = 16384;
     243           0 :         move16();
     244             :     }
     245             : 
     246      783679 :     set32_fx( h1_32, 0, L_subfr );
     247    13322543 :     FOR( i = 0; i < M; i++ )
     248             :     {
     249    12538864 :         Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     250   106580344 :         FOR( j = 1; j <= i; j++ )
     251             :         {
     252    94041480 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     253             :         }
     254    12538864 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     255    12538864 :         move32();
     256             :     }
     257             : 
     258      783679 :     Ltmp64 = W_mult_16_16( Ap[i], s2 ); /* Q27 */
     259    13322543 :     FOR( j = 1; j <= M; j++ )
     260             :     {
     261    12538864 :         Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     262             :     }
     263      783679 :     h1_32[M] = W_extract_l( Ltmp64 ); /* Q27 */
     264      783679 :     move32();
     265             : 
     266    39907984 :     FOR( i = M + 1; i < L_subfr; i++ )
     267             :     {
     268    39124305 :         Ltmp64 = W_msu_16_16( 0, Aqs[1], extract_h( L_shl_sat( h1_32[i - 1], s ) ) ); /* Q27 */
     269   625988880 :         FOR( j = 2; j <= M; j++ )
     270             :         {
     271   586864575 :             Ltmp64 = W_msu_16_16( Ltmp64, Aqs[j], extract_h( L_shl_sat( h1_32[i - j], s ) ) ); /* Q27 */
     272             :         }
     273    39124305 :         h1_32[i] = W_extract_l( Ltmp64 ); /* Q27 */
     274    39124305 :         move32();
     275             :     }
     276             : 
     277      783679 :     sf = sub( L_norm_arr( h1_32, L_subfr ), 1 );
     278      783679 :     Copy_Scale_sig32_16( h1_32, h1, L_subfr, sf ); // Q11 + sf
     279             : 
     280      783679 :     tmp = 0;
     281      783679 :     move16();
     282      783679 :     Deemph2( h1, tilt_fac, L_subfr, &tmp ); // Q11 + sf - 1
     283             : 
     284      783679 :     return;
     285             : }

Generated by: LCOV version 1.14