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 @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 163 163 100.0 %
Date: 2025-08-23 01:22:27 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      901887 : 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      901887 :     L_frame_glob = st->L_frame;
      36      901887 :     move16();
      37      901887 :     preemph = st->preemph_fac; // Q15
      38      901887 :     move16();
      39             : 
      40             :     /* Output synth */
      41      901887 :     Copy( xn_buf, synthout, L_frame_glob );
      42             : 
      43             :     /* Update synth */
      44             : 
      45      901887 :     synth = buf + M + 1;
      46      901887 :     Copy( st->syn, buf, M + 1 );
      47      901887 :     Copy( xn_buf, synth, L_frame_glob );
      48      901887 :     Copy( synth + sub( L_frame_glob, M + 1 ), st->syn, M + 1 );
      49             : 
      50             :     {
      51      901887 :         IF( !fb ) /* TV2FhG -> Condition differs from floating point */
      52             :         {
      53             : 
      54             :             /* Emphasis of synth -> synth_pe */
      55      901887 :             tmp = synth[-M - 1];
      56      901887 :             move16();
      57      901887 :             IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
      58             :             {
      59      219098 :                 st->Q_syn = E_UTIL_f_preemph3( synth - M, preemph, add( M, L_frame_glob ), &tmp, 1 );
      60      219098 :                 move16();
      61      219098 :                 st->prev_Q_syn = st->Q_syn = sub( st->Q_syn, 1 );
      62      219098 :                 move16();
      63      219098 :                 move16();
      64             :             }
      65             :             ELSE
      66             :             {
      67      682789 :                 E_UTIL_f_preemph2( 2, synth - M, preemph, add( M, L_frame_glob ), &tmp );
      68      682789 :                 st->prev_Q_syn = st->Q_syn = 0; /* in case of MDCT, Q0 seems to be used*/
      69      682789 :                 move16();
      70      682789 :                 move16();
      71             :             }
      72      901887 :             Copy( synth + sub( L_frame_glob, M ), st->mem_syn2_fx, M );
      73      901887 :             Copy( synth + sub( L_frame_glob, L_SYN_MEM ), st->mem_syn_r, L_SYN_MEM );
      74      901887 :             IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
      75             :             {
      76      219098 :                 test();
      77      219098 :                 IF( ( st->tcxonly == 0 ) || LE_16( L_frame_glob, L_FRAME16k ) )
      78             :                 {
      79             :                     /* Update excitation */
      80      117488 :                     IF( NE_16( add( st->Q_syn, 1 ), st->Q_exc ) )
      81             :                     {
      82       41886 :                         Scale_sig( st->old_exc_fx, L_EXC_MEM_DEC, sub( add( st->Q_syn, 1 ), st->Q_exc ) );
      83             :                     }
      84      117488 :                     st->Q_exc = add( st->Q_syn, 1 );
      85      117488 :                     move16();
      86      117488 :                     st->Q_subfr[0] = st->Q_subfr[1] = st->Q_subfr[2] = st->Q_subfr[3] = st->Q_subfr[4] = st->Q_exc;
      87      117488 :                     move16();
      88      117488 :                     move16();
      89      117488 :                     move16();
      90      117488 :                     move16();
      91      117488 :                     move16();
      92             : 
      93      117488 :                     assert( L_frame_glob < L_EXC_MEM_DEC );
      94      117488 :                     Copy( st->old_exc_fx + L_frame_glob, st->old_exc_fx, sub( L_EXC_MEM_DEC, L_frame_glob ) );
      95      117488 :                     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      219098 :                 Copy( A, st->old_Aq_12_8_fx /*Q12*/, M + 1 );
      99             :             }
     100             :         }
     101             :     }
     102      901887 :     return;
     103             : }
     104             : 
     105             : /* Returns: number of bits used (including "bits") */
     106       14024 : 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       14024 :     target_bits = s_min( target_bits, NPRM_RESQ );
     122             : 
     123             :     /* Requantize the spectrum line-by-line */
     124             :     /* fac_m = deadzone * 0.5f; */
     125       14024 :     num_zeros = 0;
     126       14024 :     move16();
     127             : 
     128      626095 :     FOR( i = 0; i < L_frame; i++ )
     129             :     {
     130      625128 :         IF( GE_16( bits, target_bits ) ) /* no bits left */
     131             :         {
     132       13057 :             BREAK;
     133             :         }
     134             : 
     135      612071 :         IF( x_Q[i] != 0 )
     136             :         {
     137       12293 :             sign = x_fac[i];
     138       12293 :             move16();
     139       12293 :             if ( x_Q[i] < 0 )
     140        6106 :                 sign = negate( sign );
     141             : 
     142             :             /* x_Q[i] += sign*(prm[bits++] * 0.5f - fac_m); */
     143       12293 :             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       12293 :             move32();
     145       12293 :             bits = add( bits, 1 );
     146             :         }
     147             :         ELSE
     148             :         {
     149      599778 :             zeros[num_zeros] = i;
     150      599778 :             move16();
     151      599778 :             num_zeros = add( num_zeros, 1 );
     152             :         }
     153             :     }
     154             : 
     155             :     /* Requantize zeroed-lines of the spectrum */
     156       14024 :     fac_p = msu_r( 1417339264l /*0.33f*2.0f Q31*/, deadzone, 21627 /*0.33f*2.0f Q15*/ ); /* Q15 */
     157       14024 :     target_bits = sub( target_bits, 1 );                                                 /* reserve 1 bit for the check below */
     158             : 
     159       14024 :     s = sub( x_Q_e, 1 );
     160       46319 :     FOR( j = 0; j < num_zeros; j++ )
     161             :     {
     162       33629 :         IF( GE_16( bits, target_bits ) ) /* 1 or 0 bits left */
     163             :         {
     164        1334 :             BREAK;
     165             :         }
     166             : 
     167       32295 :         i = zeros[j];
     168       32295 :         move16();
     169             : 
     170       32295 :         IF( prm[bits] != 0 )
     171             :         {
     172        9178 :             bits = add( bits, 1 );
     173        9178 :             L_tmp = L_mult( fac_p, x_fac[i] ); /* Q30 */
     174        9178 :             if ( prm[bits] == 0 )
     175        4749 :                 L_tmp = L_negate( L_tmp );
     176        9178 :             x_Q[i] = L_shr( L_tmp, s );
     177        9178 :             move32();
     178             :         }
     179       32295 :         bits = add( bits, 1 );
     180             :     }
     181             : 
     182       14024 :     return bits;
     183             : }
     184             : /*---------------------------------------------------------------
     185             :  * tcx_res_invQ_gain()
     186             :  *
     187             :  *
     188             :  *--------------------------------------------------------------*/
     189      357564 : 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      357564 :     gain = *gain_tcx;
     199      357564 :     move16();
     200             : 
     201             :     /* make sure we have a bit of headroom */
     202      357564 :     IF( GT_16( gain, 0x7000 ) )
     203             :     {
     204       20301 :         gain = shr( gain, 1 );
     205       20301 :         *gain_tcx_e = add( *gain_tcx_e, 1 );
     206       20301 :         move16();
     207             :     }
     208             : 
     209             :     /*Refine the gain quantization*/
     210      357564 :     tmp1 = s_min( resQBits, TCX_RES_Q_BITS_GAIN );
     211     1269058 :     FOR( bits = 0; bits < tmp1; bits++ )
     212             :     {
     213      911494 :         tmp2 = gain_corr_fac[bits];
     214      911494 :         move16();
     215      911494 :         if ( prm[bits] == 0 )
     216             :         {
     217      460411 :             tmp2 = gain_corr_inv_fac[bits];
     218      460411 :             move16();
     219             :         }
     220             : 
     221      911494 :         gain = mult_r( gain, tmp2 );
     222      911494 :         if ( prm[bits] != 0 )
     223      451083 :             gain = shl( gain, 1 );
     224             :     }
     225             : 
     226      357564 :     *gain_tcx = gain;
     227      357564 :     move16();
     228             : 
     229             : 
     230      357564 :     return bits;
     231             : }
     232             : 
     233             : /*---------------------------------------------------------------
     234             :  * tcx_res_invQ_spec()
     235             :  *
     236             :  *
     237             :  *--------------------------------------------------------------*/
     238      357564 : 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      357564 :     resQBits = s_min( resQBits, NPRM_RESQ );
     256             : 
     257             :     /* Requantize the spectrum line-by-line */
     258      357564 :     fac_m = shr( sq_round, 1 );
     259      357564 :     fac_p = sub( 0x4000 /*0.5f Q15*/, fac_m ); // Q15
     260             : 
     261      357564 :     lf_deemph_factor = 0x4000; /*0.5f Q15*/
     262      357564 :     move16();
     263      357564 :     s = sub( x_e, 1 );
     264             : 
     265    12494614 :     FOR( i = 0; i < L_frame; i++ )
     266             :     {
     267    12483133 :         IF( GE_16( bits, resQBits ) )
     268             :         {
     269      346083 :             BREAK;
     270             :         }
     271             : 
     272    12137050 :         test();
     273    12137050 :         test();
     274    12137050 :         IF( ( x[i] != 0 ) && ( ( lf_deemph_factors == NULL ) || ( GT_16( lf_deemph_factors[i], 0x2000 /*0.5f in Q14*/ ) ) ) )
     275             :         {
     276     2172442 :             if ( lf_deemph_factors != NULL )
     277             :             {
     278      447034 :                 lf_deemph_factor = lf_deemph_factors[i]; // Q14
     279      447034 :                 move16();
     280             :             }
     281             : 
     282     2172442 :             IF( prm[bits] == 0 )
     283             :             {
     284             : 
     285             :                 /* Debug initialization to catch illegal cases of x[i] */
     286     1086696 :                 tmp = 0;
     287     1086696 :                 move32();
     288             : 
     289     1086696 :                 if ( x[i] > 0 )
     290      546204 :                     tmp = L_mult( fac_m, lf_deemph_factor ); // Q14+Q15-1 = Q28
     291     1086696 :                 if ( x[i] < 0 )
     292      540492 :                     tmp = L_mult( fac_p, lf_deemph_factor ); // Q14+Q15-1 = Q28
     293             : 
     294     1086696 :                 assert( tmp != 0 );
     295             : 
     296     1086696 :                 x[i] = L_sub( x[i], L_shr( tmp, s ) ); // Q(31 - x_e)
     297     1086696 :                 move32();
     298             :             }
     299             :             ELSE
     300             :             {
     301             : 
     302             :                 /* Debug initialization to catch illegal cases of x[i] */
     303     1085746 :                 tmp = 0;
     304     1085746 :                 move32();
     305             : 
     306     1085746 :                 if ( x[i] > 0 )
     307      544174 :                     tmp = L_mult( fac_p, lf_deemph_factor ); // Q14+Q15-1 = Q28
     308     1085746 :                 if ( x[i] < 0 )
     309      541572 :                     tmp = L_mult( fac_m, lf_deemph_factor ); // Q14+Q15-1 = Q28
     310             : 
     311     1085746 :                 assert( tmp != 0 );
     312             : 
     313     1085746 :                 x[i] = L_add( x[i], L_shr( tmp, s ) ); // Q(31 - x_e)
     314     1085746 :                 move32();
     315             :             }
     316     2172442 :             bits = add( bits, 1 );
     317             :         }
     318             :     }
     319             : 
     320             :     /*Quantize zeroed-line of the spectrum*/
     321      357564 :     resQBits = sub( resQBits, 1 );
     322             : 
     323      357564 :     IF( lf_deemph_factors == NULL )
     324             :     {
     325      390726 :         FOR( i = 0; i < L_frame; i++ )
     326             :         {
     327      390726 :             IF( GE_16( bits, resQBits ) )
     328             :             {
     329      255859 :                 BREAK;
     330             :             }
     331             : 
     332      134867 :             IF( x[i] == 0 )
     333             :             {
     334       89589 :                 IF( prm[bits] != 0 )
     335             :                 {
     336       39603 :                     bits = add( bits, 1 );
     337             : 
     338       39603 :                     tmp = L_mult( 21627 /*1.32f Q14*/, fac_p /*Q15*/ ); // Q28
     339       39603 :                     if ( prm[bits] == 0 )
     340       20142 :                         tmp = L_negate( tmp );
     341             : 
     342       39603 :                     x[i] = L_shr( tmp, s ); // Q(31 - x_e)
     343       39603 :                     move32();
     344             :                 }
     345       89589 :                 bits = add( bits, 1 );
     346             :             }
     347             :         }
     348             :     }
     349             :     ELSE
     350             :     {
     351      101705 :         c = sub( 21627 /*0.66f Q15*/, mult_r( sq_round, 21627 /*0.66f Q15*/ ) ); // Q15
     352             : 
     353      499220 :         FOR( i = 0; i < L_frame; i++ )
     354             :         {
     355      499220 :             IF( GE_16( bits, resQBits ) )
     356             :             {
     357      101705 :                 BREAK;
     358             :             }
     359             : 
     360      397515 :             test();
     361      397515 :             IF( ( x[i] == 0 ) && ( GT_16( lf_deemph_factors[i], 0x2000 ) ) )
     362             :             {
     363      321475 :                 IF( prm[bits] != 0 )
     364             :                 {
     365      100077 :                     bits = add( bits, 1 );
     366             : 
     367      100077 :                     tmp = L_mult( c, lf_deemph_factors[i] ); // Q28
     368      100077 :                     if ( prm[bits] == 0 )
     369       50342 :                         tmp = L_negate( tmp );
     370             : 
     371      100077 :                     x[i] = L_shr( tmp, s ); // Q(31 - x_e)
     372      100077 :                     move32();
     373             :                 }
     374      321475 :                 bits = add( bits, 1 );
     375             :             }
     376             :         }
     377             :     }
     378             : 
     379      357564 :     return bits;
     380             : }

Generated by: LCOV version 1.14