LCOV - code coverage report
Current view: top level - lib_com - guided_plc_util_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 77 134 57.5 %
Date: 2025-05-03 01:55:50 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h"
       7             : #include "prot_fx.h"
       8             : #include "rom_com.h"
       9             : #include "basop_util.h"
      10             : #include "rom_basop_util.h"
      11             : 
      12             : /*-------------------------------------------------------------------*
      13             :  * Local function prototypes
      14             :  *-------------------------------------------------------------------*/
      15             : static void reorder_lsfs( Word16 *lsf, const Word16 min_dist, const Word16 n, const Word32 sr_core );
      16             : 
      17             : 
      18             : /*-------------------------------------------------------------------*
      19             :  * getLookAheadResSig()
      20             :  *
      21             :  *
      22             :  *-------------------------------------------------------------------*/
      23         312 : void getLookAheadResSig(
      24             :     Word16 *speechLookAhead, /* Qx */
      25             :     Word16 *A_3Q12,          /* 3Q12 */
      26             :     Word16 *res,             /* Qx */
      27             :     const Word16 L_frame,    /* Q0 */
      28             :     const Word16 numSubFrame /* Q0 */
      29             : )
      30             : {
      31             :     Word16 *p_A;
      32             :     Word16 i_subfr;
      33         312 :     Word16 subfr_len[2] = { L_SUBFR, L_SUBFR };
      34         312 :     move16();
      35         312 :     move16();
      36             : 
      37         312 :     if ( GT_16( L_FRAME16k, L_frame ) )
      38             :     {
      39           0 :         subfr_len[1] = 48;
      40           0 :         move16(); /* 0.75 * L_SUBFR(64) */
      41             :     }
      42             : 
      43         312 :     p_A = A_3Q12; /* Q12 */
      44         936 :     FOR( i_subfr = 0; i_subfr < numSubFrame * L_SUBFR; i_subfr += L_SUBFR )
      45             :     {
      46             :         /* calculate residual signal */
      47         624 :         Residu3_fx( p_A, &speechLookAhead[i_subfr], &res[i_subfr],
      48         624 :                     subfr_len[i_subfr / 64], 0 );
      49             : 
      50             :         /* pointer initialization */
      51         624 :         p_A += ( M + 1 );
      52             :     }
      53             : 
      54         312 :     return;
      55             : }
      56             : 
      57             : /*-------------------------------------------------------------------*
      58             :  * updatelsfForConcealment()
      59             :  *
      60             :  *
      61             :  *-------------------------------------------------------------------*/
      62             : 
      63        1266 : void updateLSFForConcealment(
      64             :     PLC_ENC_EVS_HANDLE decState,
      65             :     Word16 *lsf_14Q1 /* 14Q1 */
      66             : )
      67             : {
      68             :     Word16 i;
      69        1266 :     Word32 L_tmp = 0;
      70        1266 :     const Word16 divide_by_3_Q15 = 10923; /* 1/3 in Q15 */
      71             : 
      72       21522 :     FOR( i = 0; i < M; i++ )
      73             :     {
      74       20256 :         L_tmp = L_mult( divide_by_3_Q15, decState->lsfoldbfi1_14Q1[i] );                    /* Q17 */
      75       20256 :         L_tmp = L_mac( L_tmp, divide_by_3_Q15, decState->lsfoldbfi0_14Q1[i] );              /* Q17 */
      76       20256 :         decState->lsf_adaptive_mean_14Q1[i] = mac_r( L_tmp, divide_by_3_Q15, lsf_14Q1[i] ); /* 14Q1 */
      77       20256 :         move16();
      78       20256 :         decState->lsfoldbfi1_14Q1[i] = decState->lsfoldbfi0_14Q1[i]; /* 14Q1 */
      79       20256 :         move16();
      80       20256 :         decState->lsfoldbfi0_14Q1[i] = lsf_14Q1[i]; /* 14Q1 */
      81       20256 :         move16();
      82             :     }
      83             : 
      84        1266 :     return;
      85             : }
      86             : /*-------------------------------------------------------------------*
      87             :  * getConcealedLP()
      88             :  *
      89             :  *
      90             :  *-------------------------------------------------------------------*/
      91             : 
      92         312 : void getConcealedLP(
      93             :     PLC_ENC_EVS_HANDLE memDecState,
      94             :     Word16 *AqCon,          /* 14Q1 */
      95             :     const Word16 lsfBase[], /* Q1 * 1.28 */
      96             :     const Word16 last_good, /* Q0 */
      97             :     const Word16 L_frame    /* Q0 */
      98             : )
      99             : {
     100             :     Word16 *lsf;
     101             :     Word16 lsp[( NB_DIV + 1 ) * M];
     102             :     Word32 int_fs;
     103             : 
     104         312 :     lsf = memDecState->lsf_con;
     105         312 :     move16();
     106             : 
     107         312 :     dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold_14Q1, last_good,
     108         312 :               1, memDecState->mem_MA_14Q1, memDecState->mem_AR, &( memDecState->stab_fac_Q15 ), memDecState->lsf_adaptive_mean_14Q1,
     109             :               1, NULL, 0, NULL, NULL, lsfBase, 0 );
     110             : 
     111         312 :     Copy( memDecState->lspold_Q15, lsp, M ); /* Q15 */
     112             : 
     113         312 :     int_fs = INT_FS_FX;
     114         312 :     move32();
     115         312 :     if ( EQ_16( L_frame, L_FRAME_16k ) )
     116             :     {
     117         312 :         int_fs = INT_FS_16k_FX;
     118         312 :         move32();
     119             :     }
     120         312 :     lsf2lsp_fx( lsf, &lsp[M], M, int_fs );
     121             : 
     122         312 :     int_lsp_fx( L_frame, &lsp[0], &lsp[M], AqCon, M, interpol_frac_fx, 0 );
     123             : 
     124         312 :     return;
     125             : }
     126             : /*-------------------------------------------------------------------*
     127             :  * getConcealedLSF()
     128             :  *
     129             :  *
     130             :  *-------------------------------------------------------------------*/
     131         954 : void getConcealedLSF(
     132             :     PLC_ENC_EVS_HANDLE memDecState,
     133             :     const Word16 lsfBase[], /* Q1 * 1.28 */
     134             :     const Word16 last_good, /* Q0 */
     135             :     const Word16 L_frame    /* Q0 */
     136             : )
     137             : {
     138         954 :     Word16 *lsf = memDecState->lsf_con;
     139             : 
     140             : 
     141         954 :     dlpc_bfi( L_frame, &lsf[0], memDecState->lsfold_14Q1, last_good,
     142         954 :               1, memDecState->mem_MA_14Q1, memDecState->mem_AR, &( memDecState->stab_fac_Q15 ), memDecState->lsf_adaptive_mean_14Q1,
     143             :               1, NULL, 0, NULL, NULL, lsfBase, 0 );
     144             : 
     145         954 :     return;
     146             : }
     147             : 
     148             : /*-------------------------------------------------------------------*
     149             :  * RecLpcSpecPowDiffuseLc()
     150             :  *
     151             :  *
     152             :  *-------------------------------------------------------------------*/
     153             : 
     154          19 : void RecLpcSpecPowDiffuseLc(
     155             :     Word16 *lspq,    /* Q15 */
     156             :     Word16 *lsp_old, /* Q15 */
     157             :     Word16 *lsfq,    /* Q2.56 */
     158             :     Decoder_State *st,
     159             :     const Word16 reset_q /* Q0 */
     160             : )
     161             : {
     162             :     const Word16 *means;
     163             :     Word16 lsf_old[M];
     164             :     Word16 i;
     165             : 
     166          19 :     means = PlcGetLsfBase( st->lpcQuantization,
     167          19 :                            st->narrowBand,
     168             :                            st->sr_core );
     169             : 
     170          19 :     Copy( st->lsf_old_fx, lsf_old, M ); /* Q2.56 */
     171             : 
     172          19 :     modify_lsf( lsf_old, M, st->sr_core, reset_q );
     173             : 
     174          19 :     lsf2lsp_fx( lsf_old, lsp_old, M, st->sr_core );
     175             : 
     176          19 :     IF( reset_q )
     177             :     {
     178           0 :         FOR( i = 0; i < M; i++ )
     179             :         {
     180           0 :             lsfq[i] = add( st->mem_MA_fx[i], means[i] ); /* Q2.56 */
     181           0 :             move16();
     182             :         }
     183           0 :         sort_fx( lsfq, 0, sub( M, 1 ) );
     184             : 
     185           0 :         reorder_lsfs( lsfq, LSF_GAP_FX, M, st->sr_core );
     186           0 :         lsf2lsp_fx( lsfq, lspq, M, st->sr_core );
     187             :     }
     188             :     ELSE
     189             :     {
     190          19 :         modify_lsf( lsfq, M, st->sr_core, reset_q );
     191          19 :         lsf2lsp_fx( lsfq, lspq, M, st->sr_core );
     192             :     }
     193             : 
     194          19 :     return;
     195             : }
     196             : /*-------------------------------------------------------------------*
     197             :  * modify_lsf()
     198             :  *
     199             :  *
     200             :  *-------------------------------------------------------------------*/
     201         642 : void modify_lsf(
     202             :     Word16 *lsf,          /* Q14 */
     203             :     const Word16 n,       /* Q0 */
     204             :     const Word32 sr_core, /* Q0 */
     205             :     const Word16 reset_q  /* Q0 */
     206             : )
     207             : {
     208             :     Word16 i, k, th_x1p28_Q14;
     209             :     Word16 gap, gap_sum;
     210             : 
     211             : 
     212         642 :     th_x1p28_Q14 = 4864 /*1900.0f*1.28f Q1*/;
     213         642 :     move16();
     214         642 :     if ( EQ_32( sr_core, INT_FS_16k ) )
     215             :     {
     216         642 :         th_x1p28_Q14 = 6080 /*2375.0f*1.28f Q1*/;
     217         642 :         move16();
     218             :     }
     219             : 
     220         642 :     IF( reset_q == 0 )
     221             :     {
     222          38 :         th_x1p28_Q14 = 2048; /* 800.0f*1.28f Q1*/
     223          38 :         move16();
     224          38 :         if ( EQ_32( sr_core, INT_FS_16k ) )
     225             :         {
     226          38 :             th_x1p28_Q14 = 2560; /*1000.0f*1.28f Q1*/
     227          38 :             move16();
     228             :         }
     229             :     }
     230             : 
     231        3115 :     FOR( i = 1; i < n; i++ )
     232             :     {
     233        3115 :         IF( GE_16( lsf[i], th_x1p28_Q14 ) )
     234             :         {
     235         642 :             BREAK;
     236             :         }
     237             :     }
     238             : 
     239         642 :     gap = mult_r( lsf[i - 1], InvIntTable[i] ); /* Q14 */
     240             : 
     241         642 :     move16();
     242         642 :     gap_sum = gap;
     243         642 :     i--;
     244        3115 :     FOR( k = 0; k < i; k++ )
     245             :     {
     246        2473 :         move16();
     247        2473 :         lsf[k] = gap_sum; /* Q14 */
     248        2473 :         gap_sum = add( gap_sum, gap );
     249             :     }
     250         642 : }
     251             : 
     252             : 
     253           0 : static void reorder_lsfs(
     254             :     Word16 *lsf,            /* i/o: vector of lsfs in the frequency domain (0..0.5)             1.28 Q1*/
     255             :     const Word16 min_dist0, /* i  : minimum required distance                                                   1.28 Q1*/
     256             :     const Word16 n,         /* i  : LPC order                                                                                           Q0*/
     257             :     const Word32 sr_core    /* i  : input sampling frequency                                                            Q0*/
     258             : )
     259             : {
     260             :     Word16 i;
     261             :     Word16 curr_min_dist;
     262             :     Word16 min_dist_fac2;
     263             :     Word16 min_dist_fac3;
     264             :     Word16 lsf_min;
     265             :     Word16 lsf_max;
     266             :     Word16 fs2;
     267             :     Word16 th1, th2;
     268             :     Word16 min_dist;
     269             : 
     270             : 
     271           0 :     fs2 = 16384 /*6400.0 * 1.28 Q1*/;
     272           0 :     move16();
     273             : 
     274           0 :     if ( EQ_32( sr_core, INT_FS_16k ) )
     275             :     {
     276           0 :         fs2 = 20480 /*8000.0 * 1.28 Q1*/;
     277           0 :         move16();
     278             :     }
     279             : 
     280             :     /*-----------------------------------------------------------------*
     281             :      * Verify the LSF ordering and minimum GAP
     282             :      *-----------------------------------------------------------------*/
     283           0 :     IF( EQ_32( sr_core, INT_FS_16k ) )
     284             :     {
     285           0 :         th1 = 3200; /*1000.0 * 1.25 * 1.28 Q1*/
     286           0 :         move16();
     287           0 :         th2 = 6080; /*1900.0 * 1.25 * 1.28 Q1*/
     288           0 :         move16();
     289           0 :         min_dist = add( min_dist0, shr( min_dist0, 2 ) );
     290             :     }
     291             :     ELSE
     292             :     {
     293           0 :         th1 = 2560; /* 1000.0 * 1.28 Q1 */
     294           0 :         move16();
     295           0 :         th2 = 4864; /* 1900.0 * 1.28 Q1 */
     296           0 :         move16();
     297           0 :         min_dist = min_dist0;
     298           0 :         move16();
     299             :     }
     300           0 :     min_dist_fac2 = shl( min_dist, 1 );
     301           0 :     min_dist_fac3 = add( min_dist, min_dist_fac2 );
     302           0 :     curr_min_dist = min_dist_fac3;
     303           0 :     move16();
     304             : 
     305           0 :     lsf_min = curr_min_dist;
     306           0 :     move16();
     307             : 
     308           0 :     FOR( i = 0; i < n; i++ )
     309             :     {
     310           0 :         IF( GT_16( lsf[i], th1 ) )
     311             :         {
     312           0 :             curr_min_dist = min_dist_fac2;
     313           0 :             move16();
     314             :         }
     315             :         ELSE
     316             :         {
     317           0 :             if ( GT_16( lsf[i], th2 ) )
     318             :             {
     319           0 :                 curr_min_dist = min_dist;
     320           0 :                 move16();
     321             :             }
     322             :         }
     323             : 
     324           0 :         if ( LT_16( lsf[i], lsf_min ) )
     325             :         {
     326           0 :             lsf[i] = lsf_min;
     327           0 :             move16();
     328             :         }
     329             : 
     330           0 :         lsf_min = add( lsf[i], curr_min_dist ); /* 1.28 Q1 */
     331             :     }
     332             : 
     333             :     /*------------------------------------------------------------------------------------------*
     334             :      * Reverify the LSF ordering and minimum GAP in the reverse order (security)
     335             :      *------------------------------------------------------------------------------------------*/
     336             : 
     337           0 :     lsf_max = sub( fs2, curr_min_dist );
     338             : 
     339           0 :     IF( GT_16( lsf[n - 1], lsf_max ) ) /* If danger of unstable filter in case of resonance in HF */
     340             :     {
     341           0 :         FOR( i = n - 1; i >= 0; i-- ) /* Reverify the minimum ISF gap in the reverse direction */
     342             :         {
     343           0 :             IF( LE_16( lsf[i], th2 ) )
     344             :             {
     345           0 :                 curr_min_dist = min_dist_fac2;
     346           0 :                 move16();
     347             :             }
     348             :             ELSE
     349             :             {
     350           0 :                 if ( LE_16( lsf[i], th1 ) )
     351             :                 {
     352           0 :                     curr_min_dist = min_dist_fac3;
     353           0 :                     move16();
     354             :                 }
     355             :             }
     356             : 
     357           0 :             if ( GT_16( lsf[i], lsf_max ) )
     358             :             {
     359           0 :                 lsf[i] = lsf_max;
     360           0 :                 move16();
     361             :             }
     362           0 :             lsf_max = sub( lsf[i], curr_min_dist ); /* 1.28 Q1 */
     363             :         }
     364             :     }
     365             : 
     366           0 :     return;
     367             : }

Generated by: LCOV version 1.14