LCOV - code coverage report
Current view: top level - lib_dec - tcx_utils_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 163 163 100.0 %
Date: 2025-05-17 01:59:02 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : 
       6             : #include <stdint.h>
       7             : #include <stdlib.h>
       8             : #include <stdio.h>
       9             : #include <assert.h>
      10             : #include "options.h"
      11             : #include "prot_fx.h"
      12             : #include "rom_basop_util.h"
      13             : #include "basop_util.h"
      14             : #include "rom_com.h"
      15             : 
      16             : /*---------------------------------------------------------------
      17             :  * tcx_decoder_memory_update()
      18             :  *
      19             :  *
      20             :  *--------------------------------------------------------------*/
      21      850507 : void tcx_decoder_memory_update(
      22             :     Word16 *xn_buf,    /* i/o: mdct output buffer used also as temporary buffer  : Q0 */
      23             :     Word16 *synthout,  /* o: synth                                               : Q0 */
      24             :     Word16 *A,         /* i: Quantized LPC coefficients                          : Q12*/
      25             :     Decoder_State *st, /* i/o: decoder memory state                                   */
      26             :     Word8 fb           /* i: fullband flag                                            */
      27             : )
      28             : {
      29             :     Word16 tmp;
      30             :     Word16 *synth;
      31             :     Word16 buf[1 + M + LFAC + L_FRAME_PLUS];
      32             :     Word16 L_frame_glob;
      33             :     Word16 preemph;
      34             : 
      35      850507 :     L_frame_glob = st->L_frame;
      36      850507 :     move16();
      37      850507 :     preemph = st->preemph_fac; // Q15
      38      850507 :     move16();
      39             : 
      40             :     /* Output synth */
      41      850507 :     Copy( xn_buf, synthout, L_frame_glob );
      42             : 
      43             :     /* Update synth */
      44             : 
      45      850507 :     synth = buf + M + 1;
      46      850507 :     Copy( st->syn, buf, M + 1 );
      47      850507 :     Copy( xn_buf, synth, L_frame_glob );
      48      850507 :     Copy( synth + sub( L_frame_glob, M + 1 ), st->syn, M + 1 );
      49             : 
      50             :     {
      51      850507 :         IF( !fb ) /* TV2FhG -> Condition differs from floating point */
      52             :         {
      53             : 
      54             :             /* Emphasis of synth -> synth_pe */
      55      850507 :             tmp = synth[-M - 1];
      56      850507 :             move16();
      57      850507 :             IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
      58             :             {
      59      214801 :                 st->Q_syn = E_UTIL_f_preemph3( synth - M, preemph, add( M, L_frame_glob ), &tmp, 1 );
      60      214801 :                 move16();
      61      214801 :                 st->prev_Q_syn = st->Q_syn = sub( st->Q_syn, 1 );
      62      214801 :                 move16();
      63      214801 :                 move16();
      64             :             }
      65             :             ELSE
      66             :             {
      67      635706 :                 E_UTIL_f_preemph2( 2, synth - M, preemph, add( M, L_frame_glob ), &tmp );
      68      635706 :                 st->prev_Q_syn = st->Q_syn = 0; /* in case of MDCT, Q0 seems to be used*/
      69      635706 :                 move16();
      70      635706 :                 move16();
      71             :             }
      72      850507 :             Copy( synth + sub( L_frame_glob, M ), st->mem_syn2_fx, M );
      73      850507 :             Copy( synth + sub( L_frame_glob, L_SYN_MEM ), st->mem_syn_r, L_SYN_MEM );
      74      850507 :             IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
      75             :             {
      76      214801 :                 test();
      77      214801 :                 IF( ( st->tcxonly == 0 ) || LE_16( L_frame_glob, L_FRAME16k ) )
      78             :                 {
      79             :                     /* Update excitation */
      80      113574 :                     IF( NE_16( add( st->Q_syn, 1 ), st->Q_exc ) )
      81             :                     {
      82       40722 :                         Scale_sig( st->old_exc_fx, L_EXC_MEM_DEC, sub( add( st->Q_syn, 1 ), st->Q_exc ) );
      83             :                     }
      84      113574 :                     st->Q_exc = add( st->Q_syn, 1 );
      85      113574 :                     move16();
      86      113574 :                     st->Q_subfr[0] = st->Q_subfr[1] = st->Q_subfr[2] = st->Q_subfr[3] = st->Q_subfr[4] = st->Q_exc;
      87      113574 :                     move16();
      88      113574 :                     move16();
      89      113574 :                     move16();
      90      113574 :                     move16();
      91      113574 :                     move16();
      92             : 
      93      113574 :                     assert( L_frame_glob < L_EXC_MEM_DEC );
      94      113574 :                     Copy( st->old_exc_fx + L_frame_glob, st->old_exc_fx, sub( L_EXC_MEM_DEC, L_frame_glob ) );
      95      113574 :                     Residu3_fx( A, synth, st->old_exc_fx + sub( L_EXC_MEM_DEC, L_frame_glob ), L_frame_glob, 1 );
      96             :                 }
      97             :                 /* Update old_Aq */
      98      214801 :                 Copy( A, st->old_Aq_12_8_fx /*Q12*/, M + 1 );
      99             :             }
     100             :         }
     101             :     }
     102      850507 :     return;
     103             : }
     104             : 
     105             : /* Returns: number of bits used (including "bits") */
     106       13989 : Word16 tcx_ari_res_invQ_spec(
     107             :     Word32 x_Q[],        /* i/o: quantized spectrum                Q(31-x_Q_e) */
     108             :     Word16 x_Q_e,        /* i: quantized spectrum exponent         Q0          */
     109             :     Word16 L_frame,      /* i: number of lines                     Q0          */
     110             :     const Word16 prm[],  /* i: bitstream                           Q0          */
     111             :     Word16 target_bits,  /* i: number of bits available            Q0          */
     112             :     Word16 bits,         /* i: number of bits used so far          Q0          */
     113             :     Word16 deadzone,     /* i: quantizer deadzone                  Q15         */
     114             :     const Word16 x_fac[] /* i: spectrum post-quantization factors  Q14         */
     115             : )
     116             : {
     117             :     Word16 i, j, num_zeros, zeros[L_FRAME_PLUS], fac_p, sign, s;
     118             :     Word32 L_tmp;
     119             : 
     120             :     /* Limit the number of residual bits */
     121       13989 :     target_bits = s_min( target_bits, NPRM_RESQ );
     122             : 
     123             :     /* Requantize the spectrum line-by-line */
     124             :     /* fac_m = deadzone * 0.5f; */
     125       13989 :     num_zeros = 0;
     126       13989 :     move16();
     127             : 
     128      624317 :     FOR( i = 0; i < L_frame; i++ )
     129             :     {
     130      623352 :         IF( GE_16( bits, target_bits ) ) /* no bits left */
     131             :         {
     132       13024 :             BREAK;
     133             :         }
     134             : 
     135      610328 :         IF( x_Q[i] != 0 )
     136             :         {
     137       12196 :             sign = x_fac[i];
     138       12196 :             move16();
     139       12196 :             if ( x_Q[i] < 0 )
     140        6051 :                 sign = negate( sign );
     141             : 
     142             :             /* x_Q[i] += sign*(prm[bits++] * 0.5f - fac_m); */
     143       12196 :             x_Q[i] = L_sub( x_Q[i], L_shr( L_mult( sign, add( deadzone, lshl( prm[bits], 15 ) ) ), x_Q_e ) ); // x_Q_e
     144       12196 :             move32();
     145       12196 :             bits = add( bits, 1 );
     146             :         }
     147             :         ELSE
     148             :         {
     149      598132 :             zeros[num_zeros] = i;
     150      598132 :             move16();
     151      598132 :             num_zeros = add( num_zeros, 1 );
     152             :         }
     153             :     }
     154             : 
     155             :     /* Requantize zeroed-lines of the spectrum */
     156       13989 :     fac_p = msu_r( 1417339264l /*0.33f*2.0f Q31*/, deadzone, 21627 /*0.33f*2.0f Q15*/ ); /* Q15 */
     157       13989 :     target_bits = sub( target_bits, 1 );                                                 /* reserve 1 bit for the check below */
     158             : 
     159       13989 :     s = sub( x_Q_e, 1 );
     160       45950 :     FOR( j = 0; j < num_zeros; j++ )
     161             :     {
     162       33290 :         IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
     163             :         {
     164        1329 :             BREAK;
     165             :         }
     166             : 
     167       31961 :         i = zeros[j];
     168       31961 :         move16();
     169             : 
     170       31961 :         IF( prm[bits] != 0 )
     171             :         {
     172        9212 :             bits = add( bits, 1 );
     173        9212 :             L_tmp = L_mult( fac_p, x_fac[i] ); /* Q30 */
     174        9212 :             if ( prm[bits] == 0 )
     175        4761 :                 L_tmp = L_negate( L_tmp );
     176        9212 :             x_Q[i] = L_shr( L_tmp, s );
     177        9212 :             move32();
     178             :         }
     179       31961 :         bits = add( bits, 1 );
     180             :     }
     181             : 
     182       13989 :     return bits;
     183             : }
     184             : /*---------------------------------------------------------------
     185             :  * tcx_res_invQ_gain()
     186             :  *
     187             :  *
     188             :  *--------------------------------------------------------------*/
     189      345056 : Word16 tcx_res_invQ_gain(
     190             :     Word16 *gain_tcx, /* i/o : gain_tcx_e*/
     191             :     Word16 *gain_tcx_e,
     192             :     Word16 *prm,    /*i : Q0           */
     193             :     Word16 resQBits /*i : Q0           */
     194             : )
     195             : {
     196             :     Word16 bits, gain, tmp1, tmp2;
     197             : 
     198      345056 :     gain = *gain_tcx;
     199      345056 :     move16();
     200             : 
     201             :     /* make sure we have a bit of headroom */
     202      345056 :     IF( GT_16( gain, 0x7000 ) )
     203             :     {
     204       19776 :         gain = shr( gain, 1 );
     205       19776 :         *gain_tcx_e = add( *gain_tcx_e, 1 );
     206       19776 :         move16();
     207             :     }
     208             : 
     209             :     /*Refine the gain quantization*/
     210      345056 :     tmp1 = s_min( resQBits, TCX_RES_Q_BITS_GAIN );
     211     1223978 :     FOR( bits = 0; bits < tmp1; bits++ )
     212             :     {
     213      878922 :         tmp2 = gain_corr_fac[bits];
     214      878922 :         move16();
     215      878922 :         if ( prm[bits] == 0 )
     216             :         {
     217      444096 :             tmp2 = gain_corr_inv_fac[bits];
     218      444096 :             move16();
     219             :         }
     220             : 
     221      878922 :         gain = mult_r( gain, tmp2 );
     222      878922 :         if ( prm[bits] != 0 )
     223      434826 :             gain = shl( gain, 1 );
     224             :     }
     225             : 
     226      345056 :     *gain_tcx = gain;
     227      345056 :     move16();
     228             : 
     229             : 
     230      345056 :     return bits;
     231             : }
     232             : 
     233             : /*---------------------------------------------------------------
     234             :  * tcx_res_invQ_spec()
     235             :  *
     236             :  *
     237             :  *--------------------------------------------------------------*/
     238      345056 : Word16 tcx_res_invQ_spec(
     239             :     Word32 *x, /*Q(31 - x_e)*/
     240             :     Word16 x_e,
     241             :     Word16 L_frame,
     242             :     Word16 *prm,
     243             :     Word16 resQBits,
     244             :     Word16 bits,
     245             :     Word16 sq_round, /*i : sq deadzone Q15*/
     246             :     const Word16 lf_deemph_factors[] /*i : LF deemphasis factors Q14*/ )
     247             : {
     248             :     Word16 i;
     249             :     Word16 fac_m, fac_p;
     250             :     Word16 lf_deemph_factor, c, s;
     251             :     Word32 tmp;
     252             : 
     253             : 
     254             :     /* Limit the number of residual bits */
     255      345056 :     resQBits = s_min( resQBits, NPRM_RESQ );
     256             : 
     257             :     /* Requantize the spectrum line-by-line */
     258      345056 :     fac_m = shr( sq_round, 1 );
     259      345056 :     fac_p = sub( 0x4000 /*0.5f Q15*/, fac_m ); // Q15
     260             : 
     261      345056 :     lf_deemph_factor = 0x4000; /*0.5f Q15*/
     262      345056 :     move16();
     263      345056 :     s = sub( x_e, 1 );
     264             : 
     265    12008782 :     FOR( i = 0; i < L_frame; i++ )
     266             :     {
     267    11997810 :         IF( GE_16( bits, resQBits ) )
     268             :         {
     269      334084 :             BREAK;
     270             :         }
     271             : 
     272    11663726 :         test();
     273    11663726 :         test();
     274    11663726 :         IF( ( x[i] != 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 /*0.5f in Q14*/ ) ) ) )
     275             :         {
     276     2108442 :             if ( lf_deemph_factors != NULL )
     277             :             {
     278      435045 :                 lf_deemph_factor = lf_deemph_factors[i]; // Q14
     279      435045 :                 move16();
     280             :             }
     281             : 
     282     2108442 :             IF( prm[bits] == 0 )
     283             :             {
     284             : 
     285             :                 /* Debug initialization to catch illegal cases of x[i] */
     286     1054367 :                 tmp = 0;
     287     1054367 :                 move32();
     288             : 
     289     1054367 :                 if ( x[i] > 0 )
     290      530483 :                     tmp = L_mult( fac_m, lf_deemph_factor ); // Q14+Q15-1 = Q28
     291     1054367 :                 if ( x[i] < 0 )
     292      523884 :                     tmp = L_mult( fac_p, lf_deemph_factor ); // Q14+Q15-1 = Q28
     293             : 
     294     1054367 :                 assert( tmp != 0 );
     295             : 
     296     1054367 :                 x[i] = L_sub( x[i], L_shr( tmp, s ) ); // Q(31 - x_e)
     297     1054367 :                 move32();
     298             :             }
     299             :             ELSE
     300             :             {
     301             : 
     302             :                 /* Debug initialization to catch illegal cases of x[i] */
     303     1054075 :                 tmp = 0;
     304     1054075 :                 move32();
     305             : 
     306     1054075 :                 if ( x[i] > 0 )
     307      527925 :                     tmp = L_mult( fac_p, lf_deemph_factor ); // Q14+Q15-1 = Q28
     308     1054075 :                 if ( x[i] < 0 )
     309      526150 :                     tmp = L_mult( fac_m, lf_deemph_factor ); // Q14+Q15-1 = Q28
     310             : 
     311     1054075 :                 assert( tmp != 0 );
     312             : 
     313     1054075 :                 x[i] = L_add( x[i], L_shr( tmp, s ) ); // Q(31 - x_e)
     314     1054075 :                 move32();
     315             :             }
     316     2108442 :             bits = add( bits, 1 );
     317             :         }
     318             :     }
     319             : 
     320             :     /*Quantize zeroed-line of the spectrum*/
     321      345056 :     resQBits = sub( resQBits, 1 );
     322             : 
     323      345056 :     IF( lf_deemph_factors == NULL )
     324             :     {
     325      380362 :         FOR( i = 0; i < L_frame; i++ )
     326             :         {
     327      380362 :             IF( GE_16( bits, resQBits ) )
     328             :             {
     329      247209 :                 BREAK;
     330             :             }
     331             : 
     332      133153 :             IF( x[i] == 0 )
     333             :             {
     334       88348 :                 IF( prm[bits] != 0 )
     335             :                 {
     336       39219 :                     bits = add( bits, 1 );
     337             : 
     338       39219 :                     tmp = L_mult( 21627 /*1.32f Q14*/, fac_p /*Q15*/ ); // Q28
     339       39219 :                     if ( prm[bits] == 0 )
     340       19943 :                         tmp = L_negate( tmp );
     341             : 
     342       39219 :                     x[i] = L_shr( tmp, s ); // Q(31 - x_e)
     343       39219 :                     move32();
     344             :                 }
     345       88348 :                 bits = add( bits, 1 );
     346             :             }
     347             :         }
     348             :     }
     349             :     ELSE
     350             :     {
     351       97847 :         c = sub( 21627 /*0.66f Q15*/, mult_r( sq_round, 21627 /*0.66f Q15*/ ) ); // Q15
     352             : 
     353      464945 :         FOR( i = 0; i < L_frame; i++ )
     354             :         {
     355      464945 :             IF( GE_16( bits, resQBits ) )
     356             :             {
     357       97847 :                 BREAK;
     358             :             }
     359             : 
     360      367098 :             test();
     361      367098 :             IF( ( x[i] == 0 ) && ( GT_16( lf_deemph_factors[i], 0x2000 ) ) )
     362             :             {
     363      292065 :                 IF( prm[bits] != 0 )
     364             :                 {
     365       97821 :                     bits = add( bits, 1 );
     366             : 
     367       97821 :                     tmp = L_mult( c, lf_deemph_factors[i] ); // Q28
     368       97821 :                     if ( prm[bits] == 0 )
     369       49178 :                         tmp = L_negate( tmp );
     370             : 
     371       97821 :                     x[i] = L_shr( tmp, s ); // Q(31 - x_e)
     372       97821 :                     move32();
     373             :                 }
     374      292065 :                 bits = add( bits, 1 );
     375             :             }
     376             :         }
     377             :     }
     378             : 
     379      345056 :     return bits;
     380             : }

Generated by: LCOV version 1.14