LCOV - code coverage report
Current view: top level - lib_dec - FEC_adapt_codebook_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 59 243 24.3 %
Date: 2025-05-03 01:55:50 Functions: 1 3 33.3 %

          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 <stdlib.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "cnst.h"    /* Common constants                       */
       8             : #include "rom_dec.h" /* Decoder static table prototypes        */
       9             : #include "prot_fx.h" /* Function prototypes                    */
      10             : 
      11             : 
      12             : /*---------------------------------------------------------------------*
      13             :  * FEC_SinOnset()
      14             :  *
      15             :  * Create an artificial onset when it is lost
      16             :  *---------------------------------------------------------------------*/
      17           3 : Word16 FEC_SinOnset_fx(
      18             :     Word16 *exc,
      19             :     /* i/o : exc vector to modify                                           */ // Qin = Qold, Qout = Q_exc
      20             :     Word16 puls_pos,                                                           /* i   : last pulse position desired                                    */
      21             :     const Word16 T0,                                                           /* i   : Pitch information of the 1 subfr                               */
      22             :     Word32 enr_q,                                                              /* i   : energy provide by the encoder                                  */
      23             :     Word16 *Aq,                                                                /* i   : A(z) filter   Q12                                              */
      24             :     const Word16 L_frame                                                       /* i   : frame length                                                   */
      25             :     ,
      26             :     const Word16 Qold )
      27             : {
      28             :     Word16 P0, onset_len, sign, i, len, L_subfr, L_subfr2;
      29             :     Word16 h1[L_SUBFR16k], mem[M], exc_tmp[L_FRAME16k + MODE1_L_FIR_FER];
      30             :     Word16 *pt_end, *pt_exc, enr_LP, gain, H_low_s[5], exp_gain, exp2, tmp;
      31             :     Word32 L_tmp;
      32             :     Word16 Q_exc;
      33             : 
      34           3 :     sign = 0;
      35           3 :     move16();
      36           3 :     Q_exc = Qold;
      37           3 :     move16();
      38           3 :     L_subfr = L_SUBFR;
      39           3 :     move16();
      40           3 :     if ( EQ_16( L_frame, L_FRAME16k ) )
      41             :     {
      42           3 :         L_subfr = L_SUBFR16k;
      43           3 :         move16();
      44             :     }
      45             : 
      46           3 :     L_subfr2 = shl( L_subfr, 1 );
      47           3 :     onset_len = s_max( T0, L_subfr2 );
      48             : 
      49           3 :     P0 = puls_pos;
      50           3 :     move16();
      51             : 
      52           3 :     IF( P0 < 0 )
      53             :     {
      54           0 :         sign = 1;
      55           0 :         move16();
      56           0 :         P0 = negate( P0 );
      57             :     }
      58             : 
      59           3 :     test();
      60           3 :     test();
      61           3 :     IF( GT_16( P0, PIT_MAX ) && EQ_16( L_frame, L_FRAME ) )
      62             :     {
      63           0 :         P0 = PIT_MAX;
      64           0 :         move16(); /* Should never be the case, however... */
      65             :     }
      66           3 :     ELSE IF( GT_16( P0, PIT16k_MAX ) && EQ_16( L_frame, L_FRAME16k ) )
      67             :     {
      68           0 :         P0 = PIT16k_MAX;
      69           0 :         move16(); /* Should never be the case, however... */
      70             :     }
      71           3 :     set16_fx( exc_tmp, 0, add( L_frame, MODE1_L_FIR_FER ) ); /* Reset excitation vector */
      72             : 
      73             :     /*-------------------------------------------------------------------------------*
      74             :      * Find LP filter impulse response energy and Generate the scaled pulse prototype
      75             :      *-------------------------------------------------------------------------------*/
      76             : 
      77           3 :     set16_fx( h1, 0, L_subfr ); /* Find the impulse response */
      78           3 :     set16_fx( mem, 0, M );
      79           3 :     h1[0] = 1024; // 1.0f Q10
      80           3 :     move16();
      81           3 :     Syn_filt_s( 1, Aq, M, h1, h1, L_subfr, mem, 0 );
      82             : 
      83             : 
      84           3 :     enr_LP = extract_h( Dot_product12( h1, h1, L_subfr, &exp_gain ) );
      85           3 :     exp_gain = sub( exp_gain, 10 + 10 ); /* h1 in Q10 */
      86             : 
      87             :     /* divide by LP filter E, scaled by transmitted E */
      88             :     /* gain = (float)sqrt( enr_q / enr_LP ); */
      89             : 
      90           3 :     enr_q = L_max( enr_q, 1 );
      91             : 
      92           3 :     exp2 = norm_l( enr_q );
      93           3 :     tmp = extract_h( L_shl( enr_q, exp2 ) );
      94           3 :     tmp = mult( tmp, 24576 ); /* multpiply by 1.5 */
      95             : 
      96           3 :     IF( LT_16( tmp, 16384 ) )
      97             :     {
      98           0 :         exp2 = add( exp2, 1 );
      99           0 :         tmp = shl( tmp, 1 );
     100             :     }
     101           3 :     exp2 = sub( 30, exp2 ); /* in Q15 */
     102             : 
     103             : 
     104           3 :     IF( GT_16( enr_LP, tmp ) )
     105             :     {
     106           0 :         enr_LP = shr( enr_LP, 1 );
     107           0 :         exp_gain = add( exp_gain, 1 );
     108             :     }
     109             : 
     110           3 :     tmp = div_s( enr_LP, tmp );
     111           3 :     exp2 = sub( exp_gain, exp2 );
     112             : 
     113           3 :     L_tmp = L_deposit_h( tmp );
     114           3 :     L_tmp = Isqrt_lc( L_tmp, &exp2 );
     115           3 :     gain = round_fx( L_tmp );
     116             : 
     117           3 :     gain = mult_r( gain, 31457 );         /* multiply by .96 like floating point 0.96f in Q15*/
     118           3 :     exp2 = add( sub( exp2, 15 ), Q_exc ); /* from Q15 to Q_exc */
     119             : 
     120             :     /* Find if rescaling needed */
     121           3 :     tmp = extract_h( L_mult( h_low_fx[2], gain ) );
     122           3 :     exp_gain = norm_s( tmp );
     123           3 :     tmp = sub( exp_gain, exp2 ); /* difference */
     124             : 
     125           3 :     IF( tmp < 0 ) /* Need to correct scaling */
     126             :     {
     127           0 :         Q_exc = add( Q_exc, tmp );
     128           0 :         exp2 = add( exp2, tmp );
     129             :     }
     130             :     /* Scale pulse "prototype" energy */
     131             :     /* Generate the scaled pulse */
     132          18 :     FOR( i = 0; i < MODE1_L_FIR_FER; i++ )
     133             :     {
     134          15 :         L_tmp = L_mult( gain, h_low_fx[i] ); /* Q_exc*Q15 -> Q_exc */
     135          15 :         H_low_s[i] = round_fx( L_shl( L_tmp, exp2 ) );
     136          15 :         move16();
     137             :     }
     138             :     /*------------------------------------------------------------------------------------------*
     139             :      * Construct the harmonic part as a train of low-pass filtered pulses
     140             :      *------------------------------------------------------------------------------------------*/
     141           3 :     pt_exc = exc_tmp + sub( L_frame, add( add( 1, MODE1_L_FIR_FER / 2 ), P0 ) ); /* beginning of the 1st pulse */
     142           3 :     pt_end = exc_tmp + onset_len;
     143           3 :     len = (Word16) ( pt_exc - pt_end );
     144             : 
     145           3 :     len = s_min( len, MODE1_L_FIR_FER );
     146           3 :     IF( !sign )
     147             :     {
     148             : 
     149          18 :         FOR( i = 0; i < len; i++ )
     150             :         {
     151             :             /* The filter response would have E=1 in full band. */
     152          15 :             pt_exc[i] = add( pt_exc[i], H_low_s[i] );
     153          15 :             move16();
     154             :         }
     155             :     }
     156             :     ELSE
     157             :     {
     158           0 :         FOR( i = 0; i < len; i++ )
     159             :         {
     160             :             /* The filter response would have E=1 in full band. */
     161           0 :             pt_exc[i] = sub( pt_exc[i], H_low_s[i] );
     162           0 :             move16();
     163             :         }
     164             :     }
     165           3 :     Copy( &exc_tmp[L_frame - L_EXC_MEM], exc, L_EXC_MEM );
     166           3 :     return Q_exc;
     167             : }
     168             : 
     169           0 : Word16 FEC_enhACB_fx(
     170             :     const Word16 L_frame,      /* i   : frame length                                                              */
     171             :     const Word16 last_L_frame, /* i   : frame length of previous frame                                            */
     172             :     Word16 *exc_io,
     173             :     /* i/o : adaptive codebook memory                                                  */ // st->Q_exc
     174             :     const Word16 new_pit,                                                                 /* i   : decoded first frame pitch                                                 */
     175             :     const Word16 puls_pos,                                                                /* i   : decoder position of the last glottal pulses decoded in the previous frame */
     176             :     const Word16 bfi_pitch                                                                /* i   : Q6 pitch used for concealment                                                */
     177             : )
     178             : {
     179             :     Word16 Tc, P0, sign, pit_search;
     180             :     Word16 Tlist[10], Terr, diff_pit, dist_Plast;
     181             :     Word16 tmp2;
     182             :     Word16 exc[L_FRAME16k + L_SUBFR]; // Q0
     183           0 :     Word16 Do_WI = 1;
     184           0 :     move16();
     185             : 
     186             : 
     187           0 :     set16_fx( exc, 0, L_FRAME16k - L_EXC_MEM );
     188           0 :     set16_fx( exc + L_FRAME16k, 0, L_SUBFR );
     189           0 :     Copy( exc_io, exc + L_FRAME16k - L_EXC_MEM, L_EXC_MEM );
     190             : 
     191           0 :     Tc = shr( bfi_pitch, 6 ); // Q0
     192           0 :     Copy( exc + sub( L_FRAME16k, Tc ), exc + L_FRAME16k, L_SUBFR );
     193             : 
     194             :     /*------------------------------------------------------------
     195             :      * Decode phase information transmitted in the bitstream
     196             :      * (The position of the absolute maximum glottal pulse from
     197             :      * the end of the frame and its sign)
     198             :      *------------------------------------------------------------*/
     199             : 
     200           0 :     P0 = puls_pos;
     201           0 :     move16();
     202           0 :     sign = 0;
     203           0 :     move16();
     204           0 :     IF( P0 < 0 )
     205             :     {
     206           0 :         sign = 1;
     207           0 :         move16();
     208           0 :         P0 = negate( P0 );
     209             :     }
     210             : 
     211           0 :     IF( EQ_16( L_frame, L_FRAME ) )
     212             :     {
     213           0 :         P0 = s_min( PIT_MAX, P0 );
     214             :     }
     215             :     ELSE /* L_frame == L_FRAME16k */
     216             :     {
     217           0 :         P0 = s_min( PIT16k_MAX, P0 );
     218             :     }
     219             : 
     220             :     /*----------------------------------------------------------------------------------
     221             :      * Find the position of the first the maximum(minimum) lp_filtered pulse
     222             :      * <----- Mem --->|<--------------------- L_frame ------------>|<----- L_SUBFR --->|
     223             :      *                |<-------pit_search---->                     |                   |
     224             :      *----------------------------------------------------------------------------------*/
     225             : 
     226           0 :     pit_search = Tc;
     227           0 :     move16();
     228             : 
     229           0 :     Tlist[0] = findpulse_fx( L_frame, exc + sub( L_frame, pit_search ), pit_search, DEC, &sign );
     230           0 :     move16();
     231             : 
     232             :     /*Terr = (short) abs(pit_search-Tlist[0]-P0);*/
     233           0 :     Terr = abs_s( sub( pit_search, add( Tlist[0], P0 ) ) );
     234             : 
     235           0 :     dist_Plast = sub( Tc, Tlist[0] );
     236             : 
     237           0 :     Tlist[1] = findpulse_fx( L_frame, exc + sub( L_frame, pit_search ), add( pit_search, L_SUBFR ), DEC, &sign ); // Q0
     238           0 :     move16();
     239             : 
     240             : 
     241             :     /*if(Terr > abs(Tlist[1]-Tc + P0))*/
     242           0 :     IF( GT_16( Terr, abs_s( add( sub( Tlist[1], Tc ), P0 ) ) ) )
     243             :     {
     244           0 :         dist_Plast = sub( Tc, Tlist[1] );
     245           0 :         Terr = abs_s( add( sub( Tlist[1], Tc ), P0 ) );
     246             :     }
     247             : 
     248           0 :     diff_pit = abs_s( sub( new_pit, Tc ) );
     249             :     /*ftmp = (float) (int)((float)L_frame/(float)Tc+0.5);*/
     250           0 :     tmp2 = mult_r( div_s( 16, Tc ), shr( L_frame, 4 ) );
     251           0 :     test();
     252           0 :     test();
     253           0 :     IF( LE_16( Terr, i_mult( tmp2, diff_pit ) ) &&
     254             :         Terr != 0 &&               /* If Terr = 0, no resynchronization required */
     255             :         sub( Terr, L_SUBFR ) < 0 ) /* prevent catastrophy search */
     256             :     {
     257             :         /* performe excitation resynchronization here */
     258           0 :         Do_WI = FEC_synchro_exc_fx( L_frame, exc, P0, dist_Plast, Tc );
     259           0 :         Copy( exc + L_FRAME16k - L_EXC_MEM, exc_io, L_EXC_MEM );
     260             :     }
     261             :     ELSE
     262             :     {
     263           0 :         Do_WI = 0;
     264           0 :         move16();
     265             :     }
     266             : 
     267           0 :     if ( NE_16( last_L_frame, L_FRAME16k ) )
     268             :     {
     269           0 :         Do_WI = 0;
     270           0 :         move16();
     271             :     }
     272             : 
     273           0 :     return Do_WI;
     274             : }
     275             : 
     276           0 : Word16 FEC_synchro_exc_fx(                       /* o  : do_WI flag                                       */
     277             :                            const Word16 L_frame, /* i  : length of the frame                               */
     278             :                            Word16 *exc,
     279             :                            /* i/o: exc vector to modify                              */ // st->Q_exc
     280             :                            const Word16 desire_puls_pos,                                /* i  : Pulse position send by the encoder                */
     281             :                            const Word16 true_puls_pos,                                  /* i  : Present pulse location                            */
     282             :                            const Word16 Old_pitch                                       /* i  : Pitch use to create temporary adaptive codebook   */
     283             : )
     284             : {
     285             :     Word16 exc_tmp[L_FRAME16k + L_SUBFR];
     286             :     Word16 fact;
     287             :     Word32 L_min_energy, L_tmp; // Q0
     288             :     Word16 *pt_exc, *pt_exc1;
     289             :     Word16 i, j, point_to_remove, point_to_add, nb_min;
     290             :     Word16 min_pos[L_FRAME16k / PIT_MIN_DOUBLEEXTEND], points_by_pos[L_FRAME16k / PIT_MIN_DOUBLEEXTEND];
     291             :     Word16 total_point, tmp_len;
     292             :     Word16 *pt_pos, pos, start_search, tmp16;
     293             :     Word16 remaining_len;
     294             : 
     295           0 :     point_to_add = -1;
     296           0 :     move16();
     297             : 
     298             :     /* Init */
     299           0 :     FOR( i = 0; i < L_FRAME16k / PIT_MIN_DOUBLEEXTEND; i++ )
     300             :     {
     301           0 :         min_pos[i] = 10000;
     302           0 :         move16();
     303           0 :         points_by_pos[i] = 0;
     304           0 :         move16();
     305             :     }
     306             : 
     307             :     /* Find number of point to remove and number of minimum */
     308           0 :     point_to_remove = sub( true_puls_pos, desire_puls_pos ); /* if it is negative it means remove point else it means add point */
     309             : 
     310           0 :     pos = sub( L_frame, true_puls_pos );
     311             : 
     312             :     /* Find number of minimum energy region */
     313             :     /* nb_min = (L_FRAME - true_puls_pos)/Old_pitch */
     314           0 :     tmp16 = shl( Old_pitch, 5 );
     315           0 :     tmp16 = div_s( pos, tmp16 );
     316           0 :     nb_min = shr( tmp16, 10 );
     317             :     /* if Old pitch < 128, must have at least 2 min */
     318           0 :     if ( LE_16( Old_pitch, 128 ) )
     319             :     {
     320           0 :         nb_min = s_max( nb_min, 2 );
     321             :     }
     322             :     /* Must have at least 1 min */
     323           0 :     nb_min = s_max( nb_min, 1 );
     324             : 
     325           0 :     pt_exc = exc + pos;
     326           0 :     move16();
     327             : 
     328             :     /* Find starting point for minimum energy search */
     329           0 :     start_search = mult_r( Old_pitch, -24576 ); // Q0
     330           0 :     if ( EQ_16( s_and( Old_pitch, 3 ), 1 ) )
     331             :     {
     332             :         /* Only be align with integer operation -3*Old_pitch/4 */
     333           0 :         start_search = add( start_search, 1 );
     334             :     }
     335           0 :     IF( add( start_search, pos ) < 0 )
     336             :     {
     337           0 :         start_search = negate( pos );
     338           0 :         if ( LT_16( abs_s( start_search ), shr( Old_pitch, 3 ) ) )
     339             :         {
     340             :             /* it's not safe to remove/add point inside 1/8 of the pulse position */
     341           0 :             return 0;
     342             :         }
     343             :     }
     344             : 
     345             :     /* Find min energy in the first pitch section */
     346             :     /* --------------------------------------------------------------------
     347             :      * The minimum energy regions are determined by the computing the energy
     348             :      * using a sliding 5-sample window. The minimum energy position is set
     349             :      * at the middle of the window at which the energy is at minimum
     350             :      * --------------------------------------------------------------------*/
     351           0 :     L_min_energy = L_add( MAX_32, 0 );
     352           0 :     L_tmp = L_mult( pt_exc[start_search], pt_exc[start_search] );
     353           0 :     L_tmp = L_mac( L_tmp, pt_exc[start_search + 1], pt_exc[start_search + 1] );
     354           0 :     L_tmp = L_mac( L_tmp, pt_exc[start_search + 2], pt_exc[start_search + 2] );
     355           0 :     L_tmp = L_mac( L_tmp, pt_exc[start_search + 3], pt_exc[start_search + 3] );
     356           0 :     L_tmp = L_mac( L_tmp, pt_exc[start_search + 4], pt_exc[start_search + 4] );
     357             : 
     358           0 :     IF( LT_32( L_tmp, L_min_energy ) )
     359             :     {
     360           0 :         L_min_energy = L_add( L_tmp, 0 );
     361           0 :         min_pos[0] = add( add( pos, start_search ), 2 );
     362           0 :         move16();
     363             :     }
     364             : 
     365           0 :     FOR( i = start_search; i < -5; i++ )
     366             :     {
     367           0 :         L_tmp = L_msu( L_tmp, pt_exc[i], pt_exc[i] );
     368           0 :         L_tmp = L_mac( L_tmp, pt_exc[i + 5], pt_exc[i + 5] );
     369             : 
     370           0 :         IF( LT_32( L_tmp, L_min_energy ) )
     371             :         {
     372           0 :             L_min_energy = L_tmp; /* sets to 'L_tmp' in 1 clock */
     373           0 :             move32();
     374           0 :             min_pos[0] = add( add( pos, i ), 2 );
     375           0 :             move16();
     376             :         }
     377             :     }
     378             : 
     379           0 :     FOR( j = 1; j < nb_min; j++ )
     380             :     {
     381           0 :         min_pos[j] = sub( min_pos[j - 1], Old_pitch );
     382             :         /* If the first minimum is in the past, forget this minimum */
     383           0 :         IF( min_pos[j] < 0 )
     384             :         {
     385           0 :             min_pos[j] = -10000;
     386           0 :             move16();
     387           0 :             nb_min = sub( nb_min, 1 );
     388             :         }
     389             :     }
     390             : 
     391             :     /* safety-measure against not properly initialized min_pos[] */
     392           0 :     IF( GE_32( L_min_energy, MAX_32 ) )
     393             :     {
     394           0 :         return 0;
     395             :     }
     396             : 
     397           0 :     IF( GT_16( nb_min, 16 ) ) /* inv_sqi & sqi are built for a maximum of nb_min-2 = 14 values*/
     398             :     {
     399           0 :         return 0;
     400             :     }
     401             :     /*--------------------------------------------------------------------
     402             :      * Determine the number of samples to be added or removed at each pitch
     403             :      * cycle whereby less samples are added/removed at the beginning and
     404             :      * more towards the end of the frame
     405             :      * --------------------------------------------------------------------*/
     406           0 :     test();
     407           0 :     IF( EQ_16( nb_min, 1 ) || EQ_16( abs_s( point_to_remove ), 1 ) )
     408             :     {
     409           0 :         nb_min = 1;
     410           0 :         move16();
     411           0 :         points_by_pos[0] = abs_s( point_to_remove );
     412           0 :         move16();
     413             :     }
     414             :     ELSE
     415             :     {
     416             :         /* First position */
     417             :         /* fact = (float)fabs(point_to_remove) / sqi[nb_min-2]; (nb_min*nb_min) */
     418           0 :         fact = mult_r( shl( abs_s( point_to_remove ), 7 ), inv_sqi[nb_min - 2] ); /*Q7 */
     419           0 :         points_by_pos[0] = mult_r( fact, 256 );                                   /*Q7 */
     420           0 :         move16();
     421           0 :         total_point = points_by_pos[0];
     422           0 :         move16();
     423             : 
     424           0 :         FOR( i = 2; i <= nb_min; i++ )
     425             :         {
     426             :             /* points_by_pos[i-1] = (Word16)(fact*(sqi[i-2]) - total_point+0.5) */
     427           0 :             points_by_pos[i - 1] = sub( shr( extract_l( L_mac0( 64L, fact, sqi[i - 2] ) ), 7 ), total_point );
     428           0 :             move16();
     429           0 :             total_point = add( total_point, points_by_pos[i - 1] );
     430             : 
     431             :             /* ensure a constant increase */
     432           0 :             IF( LT_16( points_by_pos[i - 1], points_by_pos[i - 2] ) )
     433             :             {
     434           0 :                 tmp16 = points_by_pos[i - 2];
     435           0 :                 move16();
     436           0 :                 points_by_pos[i - 2] = points_by_pos[i - 1];
     437           0 :                 move16();
     438           0 :                 points_by_pos[i - 1] = tmp16;
     439           0 :                 move16();
     440             :             }
     441             :         }
     442             :     }
     443             :     /* --------------------------------------------------------------------
     444             :      * Sample deletion or insertion is performed in minimum energy regions.
     445             :      * At the end of this section the last maximum pulse in the concealed
     446             :      * excitation is forced to align to the actual maximum pulse position
     447             :      * at the end of the frame which is transmitted in the future frame.
     448             :      * --------------------------------------------------------------------*/
     449           0 :     if ( point_to_remove > 0 )
     450             :     {
     451           0 :         point_to_add = point_to_remove;
     452           0 :         move16();
     453             :     }
     454             : 
     455           0 :     pt_exc = exc_tmp;
     456           0 :     move16();
     457           0 :     pt_exc1 = exc;
     458           0 :     move16();
     459             : 
     460           0 :     i = 0;
     461           0 :     move16();
     462           0 :     pt_pos = min_pos + sub( nb_min, 1 );
     463             : 
     464           0 :     IF( point_to_add > 0 ) /* Samples insertion */
     465             :     {
     466           0 :         remaining_len = L_frame;
     467           0 :         move16();
     468           0 :         FOR( i = 0; i < nb_min; i++ )
     469             :         {
     470             :             /* Copy section */
     471             :             /* Compute len to copy */
     472           0 :             tmp_len = *pt_pos;
     473           0 :             move16();
     474           0 :             IF( i != 0 )
     475             :             {
     476             :                 /* Compute len to copy */
     477           0 :                 tmp_len = sub( sub( *pt_pos, *( pt_pos + 1 ) ), points_by_pos[i - 1] );
     478             :             }
     479             :             /*Copy section */
     480           0 :             Copy( pt_exc1, pt_exc, tmp_len );
     481           0 :             remaining_len = sub( remaining_len, tmp_len );
     482           0 :             pt_exc1 += tmp_len;
     483           0 :             pt_exc += tmp_len;
     484             : 
     485             :             /* Find point to add and Add points */
     486           0 :             tmp16 = mult_r( *pt_exc1, -1638 );
     487           0 :             FOR( j = 0; j < points_by_pos[i]; j++ )
     488             :             {
     489           0 :                 *pt_exc++ = tmp16;
     490           0 :                 move16(); /* repeat last point */
     491           0 :                 tmp16 = negate( tmp16 );
     492             :             }
     493             : 
     494           0 :             remaining_len = sub( remaining_len, points_by_pos[i] );
     495           0 :             pt_pos--;
     496             :         }
     497             :         /* Copy remaining data */
     498           0 :         remaining_len = s_max( 0, remaining_len );
     499           0 :         Copy( pt_exc1, pt_exc, remaining_len );
     500             :         /* Update true excitation vector */
     501           0 :         Copy( exc_tmp, exc, L_frame );
     502             :     }
     503             :     ELSE /* Samples deletion */
     504             :     {
     505           0 :         remaining_len = L_frame;
     506           0 :         move16();
     507             : 
     508           0 :         FOR( i = 0; i < nb_min; i++ )
     509             :         {
     510             :             /* Compute len to copy */
     511           0 :             tmp_len = *pt_pos;
     512           0 :             move16();
     513           0 :             IF( i != 0 )
     514             :             {
     515             :                 /* Compute len to copy */
     516           0 :                 tmp_len = sub( sub( *pt_pos, *( pt_pos + 1 ) ), points_by_pos[i - 1] );
     517             :             }
     518           0 :             Copy( pt_exc1, pt_exc, tmp_len );
     519           0 :             remaining_len = sub( remaining_len, tmp_len );
     520           0 :             pt_exc1 += tmp_len;
     521           0 :             pt_exc += tmp_len;
     522             :             /* Remove points */
     523           0 :             FOR( j = 0; j < points_by_pos[i]; j++ )
     524             :             {
     525           0 :                 pt_exc1++;
     526             :             }
     527           0 :             pt_pos--;
     528             :         }
     529             :         /* Copy remaining data */
     530           0 :         remaining_len = s_max( 0, remaining_len );
     531           0 :         Copy( pt_exc1, pt_exc, remaining_len );
     532             :         /* Update true excitation vector */
     533           0 :         Copy( exc_tmp, exc, L_frame );
     534             :     }
     535             : 
     536           0 :     return 1;
     537             : }

Generated by: LCOV version 1.14