LCOV - code coverage report
Current view: top level - lib_enc - pitch_ol_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1161 1216 95.5 %
Date: 2025-05-03 01:55:50 Functions: 9 10 90.0 %

          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 "cnst.h"
       8             : // #include "prot_fx.h"
       9             : #include "basop_util.h"
      10             : #include "rom_com_fx.h"
      11             : #include "rom_com.h"
      12             : #include "rom_enc.h"
      13             : #include "prot_fx.h"     /* Function prototypes                    */
      14             : #include "prot_fx_enc.h" /* Function prototypes                    */
      15             : 
      16             : /*-----------------------------------------------------------------*
      17             :  * Local Constants
      18             :  *-----------------------------------------------------------------*/
      19             : #define PIT_MIN2   20 /* pit_min for pitch tracking                                                  */
      20             : #define PIT_MIN_1  44 /* for second pitch track */
      21             : #define PIT_MIN2_1 24
      22             : 
      23             : #define THR_relE -2816 /* -11 (Q8) */
      24             : 
      25             : #define THRES0 4792 /* Threshold to favor smaller pitch lags; 1.17 (Q12) */
      26             : #define DELTA0 2    /* multiples' search range initial    */
      27             : #define STEP   1    /* multiples' search range increment  */
      28             : 
      29             : #define THRES1    13107 /* Threshold to favor pitch lags coherence for neighbours; 0.4 (Q15) */
      30             : #define DELTA_COH 14    /* Maximum pitch lags difference for neighbours to be considered as coherent */
      31             : #define THRES3    22938 /* Threshold to favor pitch lags coherence with previous frames; 0.7 (Q15) */
      32             : 
      33             : #define CORR_TH0 13107 /* Noise threshold for past frame correlations; 0.4 (Q15) */
      34             : #define CORR_TH1 16384 /* Noise threshold for past frame correlations; 0.5 (Q15) */
      35             : 
      36             : #define LEN_X   ( ( PIT_MAX / OPL_DECIM ) - ( PIT_MIN2 / OPL_DECIM ) + 1 ) /* Correlation buffer length */
      37             : #define COH_FAC 5734                                                       /* Factor for measuring the pitch coherence; 1.4 (Q12) */
      38             : 
      39             : #define NSUBSECT 7
      40             : #define NSECT    4
      41             : #define NHFR     3
      42             : #define L_FIR_PO 5
      43             : #define L_MEM    ( L_FIR_PO - 2 )
      44             : 
      45             : 
      46             : /*-----------------------------------------------------------------*
      47             :  * Local function prototypes
      48             :  *-----------------------------------------------------------------*/
      49             : 
      50             : static void LP_Decim2_Copy( const Word16 x[], Word16 y[], Word16 l, Word16 mem[] );
      51             : 
      52             : static void pitch_neighbour_fx( Word16 sect0, Word16 pitch_tmp[], Word16 pitch[3][2 * NSECT], Word16 corr_tmp[], Word16 corr[3][2 * NSECT], Word16 thres1[2 * NHFR], Word16 ind_tmp[2 * NHFR] );
      53             : 
      54             : static void find_mult_fx( Word16 *fac, Word16 pitch0, Word16 pitch1, Word16 pit_max0, Word16 *corr, Word16 *old_pitch, Word16 *old_corr, Word16 delta, Word16 step );
      55             : 
      56             : static Word16 pitch_coherence_fx( Word16 pitch0, Word16 pitch1, Word16 fac_max, Word16 diff_max );
      57             : 
      58             : static Word32 Dot_product12_OL( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 );
      59             : 
      60             : static Word32 Dot_product12_OL_back( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 );
      61             : 
      62             : /*-----------------------------------------------------------------*
      63             :  * pitch_ol_init()
      64             :  *
      65             :  * Open loop pitch variable initialization
      66             :  *-----------------------------------------------------------------*/
      67      167386 : void pitch_ol_init_fx(
      68             :     Word16 *old_thres, /* o  : threshold for reinforcement of past pitch influence */
      69             :     Word16 *old_pitch, /* o  : pitch  of the 2nd half-frame of previous frame      */
      70             :     Word16 *delta_pit, /* o  : pitch evolution extrapolation                       */
      71             :     Word16 *old_corr   /* o  : correlation                                         */
      72             : )
      73             : {
      74      167386 :     *old_thres = 0;
      75      167386 :     move16();
      76      167386 :     *old_pitch = 0;
      77      167386 :     move16();
      78      167386 :     *delta_pit = 0;
      79      167386 :     move16();
      80      167386 :     *old_corr = 0;
      81      167386 :     move16();
      82      167386 : }
      83             : 
      84             : 
      85             : /*==================================================================================*/
      86             : /* FUNCTION : pitch_ol_fx()                                       */
      87             : /*----------------------------------------------------------------------------------*/
      88             : /* PURPOSE :
      89             :  * Compute the open loop pitch lag.
      90             :  *
      91             :  * The pitch lag search is divided into two sets.
      92             :  * Each set is divided into three sections.
      93             :  * Each section cannot have a pitch multiple.
      94             :  * We find a maximum for each section.
      95             :  * We compare the maxima of each section.
      96             :  *
      97             :  *                               1st set              2nd set
      98             :  * 1st section: lag delay =  115 down to 62  and  115 down to 78
      99             :  * 2nd section: lag delay =   61 down to 32  and   77 down to 41
     100             :  * 3rd section: lag delay =   31 down to 17  and   40 down to 22
     101             :  * 4th section: lag delay =   16 down to 10  and   21 down to 12
     102             :  *
     103             :  * As there is a margin between section overlaps, especially for
     104             :  * longer delays, this section selection is more robust for not
     105             :  * to find multiples in the same section when pitch evolves rapidly.
     106             :  *
     107             :  * For each section, the length of the vectors to correlate is
     108             :  * greater/equal to the longest pitch delay.                                        */
     109             : /*----------------------------------------------------------------------------------*/
     110             : /*  INPUT ARGUMENTS :                                    */
     111             : /* _ (Word16[]) old_pitch    : OL pitch of the 2nd half-frame of the last frame Q0 */
     112             : /* _ (Word16[]) old_corr_fx    : correlation                                  Q15 */
     113             : /* _ (Word16[]) corr_shift_fx : normalized correlation correction               Q15 */
     114             : /* _ (Word16[]) old_thres_fx  : maximum correlation weighting with respect          */
     115             : /*                              to past frame pitch                             Q15 */
     116             : /* _ (Word16[]) delta_pit    : old pitch extrapolation correction               Q0 */
     117             : /* _ (Word16[]) st_old_wsp2_fx: weighted speech memory                         qwsp */
     118             : /* _ (Word16[]) wsp_fx      : weighted speech for current frame & look-ahead qwsp */
     119             : /* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory                   qwsp */
     120             : /* _ (Word16[]) relE_fx      : relative frame energy                            Q8 */
     121             : /* _ (Word16[]) L_look      : look-ahead                                       Q0 */
     122             : /* _ (Word16[]) Opt_SC_VBR    : SC-VBR flag                                      Q0 */
     123             : /* _ (Word16*) qwsp        : wsp & filter memory Qformat                */
     124             : /*----------------------------------------------------------------------------------*/
     125             : /* OUTPUT ARGUMENTS :                                  */
     126             : /* _ (Word16[]) pitch        : open loop pitch lag for each half-frame          Q0 */
     127             : /* _ (Word16[]) T_op          : open loop pitch lag for each half-frm for quant  Q0 */
     128             : /* _ (Word16[]) voicing_fx    : max normalized correlation for each half-frame  QIn */
     129             : /* _ (Word16[]) old_pitch    : OL pitch of the 2nd half-frame of the last frame Q0 */
     130             : /* _ (Word16[]) old_corr_fx    : correlation                                  Q15 */
     131             : /* _ (Word16[]) old_thres_fx  : maximum correlation weighting with respect          */
     132             : /*                              to past frame pitch                             Q15 */
     133             : /* _ (Word16[]) delta_pit    : old pitch extrapolation correction               Q0 */
     134             : /* _ (Word16[]) st_old_wsp2_fx: weighted speech memory                         qwsp */
     135             : /* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory                   qwsp */
     136             : /*----------------------------------------------------------------------------------*/
     137             : 
     138             : /*----------------------------------------------------------------------------------*/
     139             : /* RETURN ARGUMENTS :                                  */
     140             : /* _ None                                        */
     141             : /*==================================================================================*/
     142             : 
     143        3100 : void pitch_ol_fx(
     144             :     Word16 pitch[3],         /* o  : open loop pitch lag for each half-frame in range [29,231]      Q0  */
     145             :     Word16 voicing[3],       /* o  : maximum normalized correlation for each half-frame in [0,1.0[  Q15 */
     146             :     Word16 *old_pitch,       /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1])  Q0  */
     147             :     Word16 *old_corr,        /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean)        Q15 */
     148             :     Word16 corr_shift,       /* i  : normalized correlation correction                              Q15 */
     149             :     Word16 *old_thres,       /* i/o: maximum correlation weighting with respect to past frame pitch Q15 */
     150             :     Word16 *delta_pit,       /* i/o: old pitch extrapolation correction in range [-14,+14]          Q0  */
     151             :     Word16 *st_old_wsp2,     /* i/o: weighted speech memory                                         qwsp */
     152             :     const Word16 *wsp,       /* i  : weighted speech for current frame and look-ahead               qwsp */
     153             :     Word16 mem_decim2[3],    /* i/o: wsp decimation filter memory                                   qwsp */
     154             :     const Word16 relE,       /* i  : relative frame energy                                          Q8  */
     155             :     const Word16 last_class, /* i  : frame classification of last frame                                 */
     156             :     const Word16 bwidth,     /* i  : bandwidth                                                          */
     157             :     const Word16 Opt_SC_VBR  /* i  : SC-VBR flag                                                        */
     158             : )
     159             : {
     160             :     Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2;
     161             :     Word16 tmp_mem[3];
     162             : 
     163             :     Word16 scale1[2 * DELTA_COH - 1];
     164             :     Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
     165             :     Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )], exp_sect[8], exp_sect1[8], exp_sect0;
     166             :     Word16 cor_buf[2 * LEN_X];
     167             :     Word16 *pt_exp1, *pt_exp2, *pt_exp3, *pt_exp4;
     168             :     Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6;
     169             :     Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4, *pt_cor5, *pt_cor6;
     170             :     Word16 thres1[6];
     171             :     Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1;
     172             :     Word16 ind_corX, ind1_corX;
     173             : 
     174             :     Word16 i, j, k, m, pit_min, pit_min1, sect0, subsect0, add_sect0, sub_sect0, old_tmp, old_tmp1, len_x, len_x1;
     175             :     Word16 len_temp;
     176             :     Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1];
     177             : 
     178             :     Word16 enr0[NSECT], enr0_exp[NSECT], enr0_1[NSECT], enr0_1_exp[NSECT], enr1, enr1_exp, enr2_exp;
     179             :     Word32 enr, enr2, Ltmp;
     180             :     Word16 fac, tmp16, tmp16_2;
     181             :     Word16 qCorX, qScaledX;
     182             :     Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean;
     183             :     const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1;
     184             : 
     185             :     Word16 pit_min_coding;
     186             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     187        3100 :     Flag Overflow = 0;
     188             : #endif
     189             : 
     190             :     /*--------------------------------------------------------------*
     191             :      * Initialization
     192             :      *--------------------------------------------------------------*/
     193        3100 :     len = len_12k8;
     194        3100 :     len1 = len1_12k8;
     195        3100 :     sublen = sublen_12k8;
     196        3100 :     sublen1 = sublen1_12k8;
     197        3100 :     pit_max = pit_max_12k8;
     198        3100 :     sec_length = sec_length_12k8;
     199        3100 :     sec_length1 = sec_length1_12k8;
     200             : 
     201        3100 :     test();
     202        3100 :     if ( ( LT_16( last_class, VOICED_TRANSITION ) ) && ( NE_16( bwidth, NB ) ) )
     203             :     {
     204             :         /*reset last pitch reinforcement in case of unvoiced or transitions: it avoids some pitch doublings*/
     205        1559 :         *old_thres = 0;
     206        1559 :         move16();
     207             :     }
     208             : 
     209        3100 :     pit_min_coding = PIT_MIN_EXTEND;
     210        3100 :     move16();
     211        3100 :     test();
     212        3100 :     test();
     213        3100 :     test();
     214        3100 :     test();
     215        3100 :     IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) ||
     216             :         ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 3277 ) ) ) ) ) /* 0.1 inQ15*/
     217             :     {
     218        1287 :         pit_min = PIT_MIN / OPL_DECIM;
     219        1287 :         move16();
     220        1287 :         pit_min1 = PIT_MIN_1 / OPL_DECIM;
     221        1287 :         move16();
     222        1287 :         subsect0 = 2;
     223        1287 :         move16();
     224        1287 :         sect0 = 1;
     225        1287 :         move16();
     226             :     }
     227             :     ELSE
     228             :     {
     229        1813 :         pit_min = PIT_MIN2 / OPL_DECIM;
     230        1813 :         move16();
     231        1813 :         pit_min1 = PIT_MIN2_1 / OPL_DECIM;
     232        1813 :         move16();
     233        1813 :         subsect0 = 0;
     234        1813 :         move16();
     235        1813 :         sect0 = 0;
     236        1813 :         move16();
     237             :     }
     238             : 
     239        3100 :     len_x = ( PIT_MAX / OPL_DECIM - pit_min + 1 );
     240        3100 :     move16();
     241        3100 :     len_x1 = ( PIT_MAX / OPL_DECIM - pit_min1 + 1 );
     242        3100 :     move16();
     243             : 
     244             :     /*--------------------------------------------------------------*
     245             :      * Find decimated weighted speech
     246             :      * Update wsp buffer with the memory
     247             :      * decimation of wsp[] to search pitch in LF and to reduce complexity
     248             :      * Extend the decimation of wsp to the end of the speech buffer
     249             :      * Update wsp memory
     250             :      *--------------------------------------------------------------*/
     251        3100 :     Copy( st_old_wsp2, old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
     252        3100 :     wsp2 = old_wsp2 + ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
     253             : 
     254        3100 :     LP_Decim2_Copy( wsp, wsp2, L_FRAME, mem_decim2 );
     255             : 
     256             :     /* Avoid uninitialized memory access */
     257        3100 :     set16_fx( wsp2 + L_FRAME / 2, 0, sizeof( old_wsp2 ) / sizeof( Word16 ) - ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ) - L_FRAME / 2 );
     258        3100 :     tmp_mem[0] = mem_decim2[0];
     259        3100 :     move16();
     260        3100 :     tmp_mem[1] = mem_decim2[1];
     261        3100 :     move16();
     262        3100 :     tmp_mem[2] = mem_decim2[2];
     263        3100 :     move16();
     264             : 
     265        3100 :     LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[( L_FRAME / 2 )], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/
     266             : 
     267        3100 :     Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
     268             : 
     269             :     /*-----------------------------------------------------------------*
     270             :      * Attenuate the correlation correction factor due to noise.
     271             :      * Reset correlation buffer outside the useful range.
     272             :      * Find the scaling functions for immediate neigbours and
     273             :      * further ones.
     274             :      *-----------------------------------------------------------------*/
     275             : 
     276        3100 :     corr_shift = shr( corr_shift, 1 );
     277             : 
     278        3100 :     set16_fx( scaled_buf, 0, DELTA_COH - 1 );
     279        3100 :     set16_fx( scaled_buf + ( DELTA_COH - 1 ) + len_x, 0, DELTA_COH - 1 );
     280        3100 :     set16_fx( scaled_buf + 2 * ( DELTA_COH - 1 ) + len_x + len_x1, 0, DELTA_COH - 1 );
     281        3100 :     set16_fx( scaled_buf_exp, 0, len_x + len_x1 + 3 * ( DELTA_COH - 1 ) );
     282             : 
     283        3100 :     pt1 = scale1 + DELTA_COH - 1;
     284        3100 :     pt2 = pt1;
     285        3100 :     tmp16 = mult( negate( *old_thres ), MAX_16 / DELTA_COH );
     286        3100 :     k = *old_thres;
     287        3100 :     move16();
     288       46500 :     FOR( i = 0; i < DELTA_COH; i++ )
     289             :     {
     290             :         /*
     291             :          * *pt1 = ( -(*old_thres)/DELTA_COH * i + *old_thres+1.0f );
     292             :          * To keep Q15 values, the following code does not add 1 to the result.
     293             :          * A scaling factor must be applied accordingly (see next use of scale1)
     294             :          */
     295       43400 :         *pt1 = k;
     296       43400 :         move16();
     297       43400 :         k = add( k, tmp16 );
     298       43400 :         *pt2-- = *pt1++;
     299       43400 :         move16();
     300             :     }
     301             : 
     302             :     /*-----------------------------------------------------------------------------*
     303             :      * Estimate the new pitch by extrapolating the old pitch value for 2 half-frames
     304             :      *-----------------------------------------------------------------------------*/
     305        3100 :     old_tmp = add( *old_pitch, *delta_pit );
     306        3100 :     old_tmp = s_min( old_tmp, PIT_MAX / OPL_DECIM );
     307        3100 :     old_tmp = s_max( old_tmp, pit_min );
     308        3100 :     old_tmp1 = add( old_tmp, *delta_pit );
     309        3100 :     old_tmp1 = s_min( old_tmp1, PIT_MAX / OPL_DECIM );
     310        3100 :     old_tmp1 = s_max( old_tmp1, pit_min );
     311             : 
     312             :     /*-----------------------------------------------------------------*
     313             :      * Loop for all three half-frames (current frame + look-ahead)
     314             :      *-----------------------------------------------------------------*/
     315        3100 :     pt_cor0 = scaled_buf + DELTA_COH - 1;
     316             : 
     317        3100 :     pt_cor2 = pt_cor0 - pit_min + old_tmp;
     318        3100 :     pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
     319             : 
     320       12400 :     FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */
     321             :     {
     322        9300 :         pt1 = wsp2 + i * 2 * ( L_SUBFR / OPL_DECIM ); /* *pt1 -> Q12 */
     323        9300 :         pt2 = pt1 - pit_min;                          /* *pt2 -> Q12 */
     324        9300 :         pt4 = pt1 - pit_min1;                         /* *pt4 -> Q12 */
     325             : 
     326        9300 :         enr = L_deposit_l( 1 );
     327             : 
     328        9300 :         pt_cor1 = pt_cor0;
     329        9300 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
     330             : 
     331        9300 :         pt_exp1 = scaled_buf_exp + DELTA_COH - 1;
     332        9300 :         pt_exp2 = pt_exp1;
     333        9300 :         pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x;
     334        9300 :         pt_exp4 = pt_exp3;
     335             : 
     336        9300 :         IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */
     337             :         {
     338        6200 :             pt3 = pt1;
     339        6200 :             pt5 = pt1;
     340             : 
     341       28426 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
     342             :             {
     343             :                 /*-----------------------------------------------------------------*
     344             :                  * Find fixed vector energy
     345             :                  *-----------------------------------------------------------------*/
     346             : 
     347             :                 /* 1st set */
     348       22226 :                 k = (Word16) ( pt1 - pt3 );
     349       22226 :                 move16();
     350             : 
     351      735226 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
     352             :                 {
     353      713000 :                     enr = L_mac0( enr, *pt3, *pt3 );
     354      713000 :                     pt3++;
     355             :                 }
     356             :                 /* keep Q15 normalized result */
     357       22226 :                 cnt = norm_l( enr );
     358       22226 :                 enr0[j] = extract_h( L_shl( enr, cnt ) );
     359       22226 :                 enr0_exp[j] = sub( 30, cnt );
     360       22226 :                 move16();
     361             : 
     362             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
     363       22226 :                 pt5 = pt3;
     364       22226 :                 enr2 = enr; /* sets to 'enr' in 1 clock */
     365       22226 :                 move32();
     366             : 
     367             :                 /* 2nd set */
     368       22226 :                 k = (Word16) ( pt1 - pt5 );
     369       22226 :                 move16();
     370             : 
     371      195826 :                 FOR( k = add( k, len1[j] ); k > 0; k-- )
     372             :                 {
     373      173600 :                     enr2 = L_mac0( enr2, *pt5, *pt5 );
     374      173600 :                     pt5++;
     375             :                 }
     376       22226 :                 cnt = norm_l( enr2 );
     377       22226 :                 enr0_1[j] = extract_h( L_shl( enr2, cnt ) );
     378       22226 :                 enr0_1_exp[j] = sub( 30, cnt );
     379       22226 :                 move16();
     380             :             }
     381             : 
     382             :             /*----------------------------------------------------------*
     383             :              * Find correlation for the non-overlapping pitch lag values
     384             :              *----------------------------------------------------------*/
     385        6200 :             exp_sect[subsect0] = 0;
     386        6200 :             move16();
     387        6200 :             pt_cor5 = pt_cor1;
     388        6200 :             pt_cor6 = pt_cor3;
     389             : 
     390        6200 :             tmp16 = exp_sect[subsect0];
     391        6200 :             move16();
     392             : 
     393        6200 :             k = (Word16) ( pt2 - pt1 + pit_max[subsect0] );
     394             : 
     395        6200 :             IF( k >= 0 )
     396             :             {
     397        6200 :                 len_temp = sublen[0];
     398        6200 :                 move16();
     399             : 
     400       26322 :                 FOR( ; k >= 0; k-- )
     401             :                 {
     402             :                     /* Keep Q15 normalized result */
     403             :                     /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */
     404             :                     /* Update exponent to reflect shr by 1 */
     405       20122 :                     *pt_cor1 = extract_h( L_shr( Dot_product12( pt1, pt2--, len_temp, pt_exp1 ), 1 ) );
     406             : 
     407             :                     /* save the biggest exponent */
     408       20122 :                     tmp16 = s_max( tmp16, *pt_exp1 );
     409             : 
     410       20122 :                     pt_cor1++;
     411       20122 :                     pt_exp1++;
     412             :                 }
     413             :             }
     414        6200 :             exp_sect[subsect0] = tmp16;
     415        6200 :             move16();
     416             : 
     417             :             /*----------------------------------------------------------*
     418             :              * For each subsection, find the correlation
     419             :              *----------------------------------------------------------*/
     420       44452 :             FOR( j = subsect0; j < NSUBSECT; j++ )
     421             :             {
     422       38252 :                 len_temp = sublen[j];
     423       38252 :                 move16();
     424             : 
     425       38252 :                 k = (Word16) ( pt2 - pt1 );
     426       38252 :                 move16();
     427       38252 :                 k = add( k, pit_max[j + 1] );
     428       38252 :                 exp_sect[j + 1] = 0;
     429       38252 :                 move16();
     430       38252 :                 exp_sect1[j] = 0;
     431       38252 :                 move16();
     432             : 
     433       38252 :                 IF( k >= 0 )
     434             :                 {
     435       38252 :                     ind = exp_sect[j + 1];
     436       38252 :                     move16();
     437       38252 :                     ind1 = exp_sect1[j];
     438       38252 :                     move16();
     439             : 
     440      657312 :                     FOR( ; k >= 0; k-- )
     441             :                     {
     442             :                         /* Keep Q15 normalized result */
     443             :                         /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */
     444             :                         /* Update exponent to reflect shr by 1 (done in Dot_product12_OL() for pt_cor3/pt_exp3) */
     445      619060 :                         *pt_cor1 = extract_h( L_shr( Dot_product12_OL( pt_cor3, pt1, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) );
     446             :                         /* The line above replaces:
     447             :                          * *pt_cor1 = shr(extract_h(Dot_product12(pt1, pt2, Sublen[j], pt_exp1)),1); move16();
     448             :                          * *pt_cor3 = shr(extract_h(Dot_product12(pt1, pt2--, Sublen1[j+i*7], pt_exp3)),1); move16();
     449             :                          */
     450             : 
     451             :                         /* save the biggest exponent */
     452      619060 :                         ind = s_max( ind, *pt_exp1 );
     453      619060 :                         ind1 = s_max( ind1, *pt_exp3 );
     454             : 
     455      619060 :                         pt_cor1++;
     456      619060 :                         pt_exp1++;
     457      619060 :                         pt_cor3++;
     458      619060 :                         pt_exp3++;
     459             :                     }
     460       38252 :                     exp_sect[j + 1] = ind;
     461       38252 :                     move16();
     462       38252 :                     exp_sect1[j] = ind1;
     463       38252 :                     move16();
     464             :                 } /* IF (k >= 0) */
     465             :             }     /* FOR (j = subsect0; ... */
     466             :         }
     467             :         ELSE /* 3rd half-frame (look-ahead) */
     468             :         {
     469        3100 :             pt6 = pt1 + L_LOOK_12k8 / OPL_DECIM - 1;
     470        3100 :             pt3 = pt6;
     471        3100 :             pt5 = pt6;
     472             : 
     473             :             /*-----------------------------------------------------------------*
     474             :              * For each section in both sets, find fixed vector energy
     475             :              *-----------------------------------------------------------------*/
     476             : 
     477       14213 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
     478             :             {
     479             :                 /* 1st set */
     480       11113 :                 k = (Word16) ( pt3 - pt6 );
     481       11113 :                 move16();
     482             : 
     483      367613 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
     484             :                 {
     485      356500 :                     enr = L_mac0( enr, *pt3, *pt3 );
     486      356500 :                     pt3--;
     487             :                 }
     488             : 
     489       11113 :                 cnt = norm_l( enr );
     490       11113 :                 enr0[j] = extract_h( L_shl( enr, cnt ) ); /*qwsp+cnt-16*/
     491       11113 :                 enr0_exp[j] = sub( 30, cnt );
     492       11113 :                 move16();
     493             : 
     494             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
     495       11113 :                 pt5 = pt3;
     496       11113 :                 enr2 = enr;
     497       11113 :                 move16();
     498             : 
     499             :                 /* 2nd set */
     500       11113 :                 k = (Word16) ( pt5 - pt6 );
     501       11113 :                 move16();
     502             : 
     503       97913 :                 FOR( k = add( k, len1[j] ); k > 0; k-- )
     504             :                 {
     505       86800 :                     enr2 = L_mac0( enr2, *pt5, *pt5 );
     506       86800 :                     pt5--;
     507             :                 }
     508             : 
     509       11113 :                 cnt = norm_l( enr2 );
     510       11113 :                 enr0_1[j] = extract_h( L_shl( enr2, cnt ) ); /*qwsp+cnt-16*/
     511       11113 :                 enr0_1_exp[j] = sub( 30, cnt );
     512       11113 :                 move16();
     513             :             }
     514             : 
     515             :             /* Set pointers */
     516        3100 :             IF( sect0 != 0 )
     517             :             {
     518        1287 :                 pt2 = pt6 - add( pit_max[1], 1 );
     519        1287 :                 k = sub( pit_max[2], pit_max[1] );
     520        1287 :                 move16();
     521             :             }
     522             :             ELSE
     523             :             {
     524        1813 :                 pt2 = pt6 - pit_min;
     525        1813 :                 k = 2;
     526        1813 :                 move16();
     527             :             }
     528             : 
     529             :             /*-----------------------------------------------------------------*
     530             :              * Find correlation for the non-overlapping pitch lag values
     531             :              *-----------------------------------------------------------------*/
     532        3100 :             exp_sect[subsect0] = 0;
     533        3100 :             move16();
     534        3100 :             pt_cor5 = pt_cor1;
     535        3100 :             pt_cor6 = pt_cor3;
     536             : 
     537        3100 :             tmp16 = exp_sect[subsect0];
     538        3100 :             move16();
     539             : 
     540        3100 :             IF( k > 0 )
     541             :             {
     542        3100 :                 len_temp = sublen[0];
     543        3100 :                 move16();
     544             : 
     545       13161 :                 FOR( ; k > 0; k-- )
     546             :                 {
     547             :                     /* Following lines are equivalent of Dot_product12() but with a backward incrementing */
     548       10061 :                     Ltmp = L_deposit_l( 1 );
     549      412501 :                     FOR( m = 0; m < len_temp; m++ )
     550             :                     {
     551      402440 :                         Ltmp = L_mac( Ltmp, pt6[-m], pt2[-m] );
     552             :                     }
     553             : 
     554             :                     /* Normalize acc in Q31 */
     555       10061 :                     tmp16_2 = norm_l( Ltmp );
     556       10061 :                     Ltmp = L_shl( Ltmp, tmp16_2 );
     557       10061 :                     *pt_exp1 = sub( 30, tmp16_2 );
     558       10061 :                     move16(); /* exponent = 0..30 */
     559             : 
     560             :                     /* Save result */
     561       10061 :                     *pt_cor1 = extract_h( L_shr( Ltmp, 1 ) );
     562             : 
     563             :                     /* Save the biggest exponent */
     564       10061 :                     tmp16 = s_max( tmp16, *pt_exp1 );
     565             : 
     566       10061 :                     pt_cor1++;
     567       10061 :                     pt_exp1++;
     568       10061 :                     pt2--;
     569             :                 }
     570        3100 :                 exp_sect[subsect0] = tmp16;
     571        3100 :                 move16();
     572             :             }
     573             : 
     574             :             /*-----------------------------------------------------------------*
     575             :              * For each subsection, find the correlation (overlapping pitch lag values)
     576             :              *-----------------------------------------------------------------*/
     577             : 
     578       22226 :             FOR( j = subsect0; j < NSUBSECT; j++ )
     579             :             {
     580       19126 :                 exp_sect[j + 1] = 0;
     581       19126 :                 move16();
     582       19126 :                 exp_sect1[j] = 0;
     583       19126 :                 move16();
     584             : 
     585       19126 :                 ind = exp_sect[j + 1];
     586       19126 :                 move16();
     587       19126 :                 ind1 = exp_sect1[j];
     588       19126 :                 move16();
     589             : 
     590       19126 :                 k = sub( pit_max[j + 1], pit_max[j] );
     591             : 
     592      328656 :                 FOR( ; k > 0; k-- )
     593             :                 {
     594      309530 :                     *pt_cor1 = extract_h( L_shr( Dot_product12_OL_back( pt_cor3, pt6, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) );
     595             : 
     596             :                     /* Save the biggest exponent */
     597      309530 :                     ind = s_max( ind, *pt_exp1 );
     598      309530 :                     ind1 = s_max( ind1, *pt_exp3 );
     599             : 
     600      309530 :                     pt_cor1++;
     601      309530 :                     pt_exp1++;
     602      309530 :                     pt_cor3++;
     603      309530 :                     pt_exp3++;
     604             :                 }
     605       19126 :                 exp_sect[j + 1] = ind;
     606       19126 :                 move16();
     607       19126 :                 exp_sect1[j] = ind1;
     608       19126 :                 move16();
     609             :             }
     610             :         } /* 3rd half-frame (look-ahead) */
     611             : 
     612             :         /* Scale all values in each section to the same exponent for upcoming Find_max() */
     613        9300 :         offset = 0;
     614        9300 :         move16();
     615        9300 :         offset1 = 0;
     616        9300 :         move16();
     617        9300 :         exp_sect1[7] = 0; /* padding */
     618        9300 :         move16();
     619       42639 :         FOR( j = sect0; j < NSECT; j++ )
     620             :         {
     621       33339 :             exp_sect0 = s_max( exp_sect[j * 2], exp_sect[j * 2 + 1] );
     622             : 
     623             :             /* scaling of exp for track 1 */
     624       33339 :             offset = add( offset, sec_length[j] );
     625       33339 :             k = (Word16) ( pt_cor0 - pt_cor5 );
     626       33339 :             move16();
     627      992112 :             FOR( k = add( k, offset ); k > 0; k-- )
     628             :             {
     629      958773 :                 cnt = sub( exp_sect0, *pt_exp2 );
     630      958773 :                 tmp16 = s_min( 15, cnt );
     631      958773 :                 if ( cnt > 0 )
     632             :                 {
     633      713355 :                     tmp16 = shr( *pt_cor5, tmp16 );
     634             :                 }
     635      958773 :                 if ( cnt > 0 )
     636             :                 {
     637      713355 :                     *pt_cor5 = tmp16;
     638      713355 :                     move16();
     639             :                 }
     640      958773 :                 *pt_exp2 = s_max( *pt_exp2, exp_sect0 );
     641      958773 :                 move16();
     642      958773 :                 pt_cor5++;
     643      958773 :                 pt_exp2++;
     644             :             }
     645             : 
     646       33339 :             exp_sect0 = s_max( exp_sect1[j * 2], exp_sect1[j * 2 + 1] );
     647             : 
     648             :             /* scaling of exp for track 2 */
     649       33339 :             offset1 = add( offset1, sec_length1[j] );
     650       33339 :             k = (Word16) ( pt_cor0 - pt_cor6 + ( DELTA_COH - 1 ) );
     651       33339 :             move16();
     652       33339 :             k = add( k, len_x );
     653      961929 :             FOR( k = add( k, offset1 ); k > 0; k-- )
     654             :             {
     655      928590 :                 cnt = sub( exp_sect0, *pt_exp4 );
     656      928590 :                 tmp16 = s_min( 15, cnt );
     657      928590 :                 if ( cnt > 0 )
     658             :                 {
     659      685130 :                     tmp16 = shr( *pt_cor6, tmp16 );
     660             :                 }
     661      928590 :                 if ( cnt > 0 )
     662             :                 {
     663      685130 :                     *pt_cor6 = tmp16;
     664      685130 :                     move16();
     665             :                 }
     666      928590 :                 *pt_exp4 = s_max( *pt_exp4, exp_sect0 );
     667      928590 :                 move16();
     668      928590 :                 pt_cor6++;
     669      928590 :                 pt_exp4++;
     670             :             }
     671             :         } /* FOR (j = sect0; ... */
     672             : 
     673        9300 :         Copy( pt_cor0, cor_buf, len_x ); /* Save unscaled correlation vector  */
     674        9300 :         Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 );
     675             : 
     676             :         /*-----------------------------------------------------------------*
     677             :          * Scale correlation function in the neighbourhood of
     678             :          * the extrapolated pitch
     679             :          *-----------------------------------------------------------------*/
     680        9300 :         pt_cor1 = pt_cor2 - ( DELTA_COH - 1 );
     681        9300 :         pt_cor3 = pt_cor4 - ( DELTA_COH - 1 );
     682        9300 :         pt2 = scale1;
     683             : 
     684      260400 :         FOR( k = 0; k < 2 * DELTA_COH - 1; k++ )
     685             :         {
     686             :             /* all Q15 here */
     687      251100 :             *pt_cor1 = add( *pt_cor1, mult( *pt_cor1, *pt2 ) );
     688      251100 :             move16();
     689      251100 :             *pt_cor3 = add( *pt_cor3, mult( *pt_cor3, *pt2++ ) );
     690      251100 :             move16();
     691             : 
     692      251100 :             pt_cor1++;
     693      251100 :             pt_cor3++;
     694             :         }
     695             : 
     696             :         /* Update for next half-frame & look-ahead */
     697        9300 :         pt_cor2 = pt_cor0 - pit_min + old_tmp1;
     698        9300 :         pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
     699             : 
     700             :         /*-----------------------------------------------------------------*
     701             :          * For each section, find maximum correlation and compute
     702             :          * normalized correlation
     703             :          *-----------------------------------------------------------------*/
     704             : 
     705        9300 :         pt_cor1 = pt_cor0;
     706        9300 :         pt_exp1 = scaled_buf_exp + DELTA_COH - 1;
     707        9300 :         offset = 0;
     708        9300 :         move16();
     709        9300 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
     710        9300 :         pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x;
     711        9300 :         offset1 = 0;
     712        9300 :         move16();
     713             : 
     714       42639 :         FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
     715             :         {
     716             :             /* 1st set */
     717       33339 :             offset_la = 0;
     718       33339 :             move16();
     719       33339 :             if ( EQ_16( i, 2 ) )
     720             :             {
     721       11113 :                 offset_la = sub( L_LOOK_12k8 / OPL_DECIM, len[j] );
     722             :             }
     723             : 
     724             :             /* 2nd set */
     725       33339 :             offset_la1 = 0;
     726       33339 :             move16();
     727       33339 :             if ( EQ_16( i, 2 ) )
     728             :             {
     729       11113 :                 offset_la1 = sub( L_LOOK_12k8 / OPL_DECIM, len1[j] );
     730             :             }
     731             : 
     732             :             /* 1st set of candidates */
     733       33339 :             ind = add( maximum_fx( pt_cor1, sec_length[j], &ftmp ), offset );
     734       33339 :             pitchX[i][j] = add( ind, pit_min );
     735       33339 :             move16();
     736       33339 :             pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector  */
     737             : 
     738       33339 :             enr1_exp = 0;
     739       33339 :             move16();
     740       33339 :             enr1 = add_o( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1, &Overflow );
     741             : 
     742       33339 :             enr2 = L_mult( enr0[j], enr1 );
     743       33339 :             enr2_exp = norm_l( enr2 );
     744       33339 :             enr2 = L_shl( enr2, enr2_exp );
     745       33339 :             enr2_exp = sub( 31, add( sub( 28, add( enr0_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) );
     746             : 
     747       33339 :             enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
     748       33339 :             enr1_exp = norm_l( enr2 );
     749       33339 :             enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/
     750       33339 :             enr1_exp = sub( enr2_exp, enr1_exp );        /*15-enr1_exp*/
     751             : 
     752       33339 :             Ltmp = L_mult0( cor_buf[ind], enr1 );
     753       33339 :             qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) );
     754       33339 :             corX[i][j] = extract_h( L_shr_o( Ltmp, sub( qCorX, 31 ), &Overflow ) );
     755       33339 :             qCorX = 31;
     756       33339 :             move16();
     757             : 
     758       33339 :             Ltmp = L_mult0( pt_cor0[ind], enr1 );
     759       33339 :             qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) );
     760       33339 :             scaledX[i][j] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) );
     761       33339 :             qScaledX = 12;
     762       33339 :             move16();
     763             : 
     764       33339 :             pt_cor1 += sec_length[j];
     765       33339 :             move16();
     766       33339 :             offset = add( offset, sec_length[j] );
     767             : 
     768             :             /* 2nd set of candidates */
     769       33339 :             ind1 = add( maximum_fx( pt_cor3, sec_length1[j], &ftmp ), offset1 );
     770       33339 :             pitchX[i][j + NSECT] = add( ind1, pit_min1 );
     771       33339 :             move16();
     772       33339 :             pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1;
     773       33339 :             move16(); /* selected moving vector  */
     774       33339 :             enr1_exp = 0;
     775       33339 :             move16();
     776       33339 :             enr1 = add_o( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1, &Overflow );
     777             : 
     778       33339 :             enr2 = L_mult( enr0_1[j], enr1 );
     779       33339 :             enr2_exp = norm_l( enr2 );
     780       33339 :             enr2 = L_shl( enr2, enr2_exp );
     781             : 
     782       33339 :             enr2_exp = sub( 31, add( sub( 28, add( enr0_1_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) );
     783       33339 :             enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
     784       33339 :             enr1_exp = norm_l( enr2 );
     785       33339 :             enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/
     786       33339 :             enr1_exp = sub( enr2_exp, enr1_exp );        /*15-enr1_exp*/
     787             : 
     788       33339 :             Ltmp = L_mult0( cor_buf[ind1 + len_x], enr1 );
     789             : 
     790       33339 :             qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) );
     791       33339 :             corX[i][j + NSECT] = extract_h( L_shr_o( Ltmp, qCorX - 31, &Overflow ) );
     792       33339 :             qCorX = 31;
     793       33339 :             move16();
     794             : 
     795       33339 :             Ltmp = L_mult0( pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x], enr1 );
     796       33339 :             qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) );
     797       33339 :             scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) );
     798             :             /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/
     799       33339 :             qScaledX = 12;
     800       33339 :             move16();
     801             : 
     802       33339 :             pt_cor3 += sec_length1[j];
     803       33339 :             move16();
     804       33339 :             offset1 = add( offset1, sec_length1[j] );
     805             : 
     806             :         } /* FOR j < NSECT */
     807             :     }     /* FOR i < NHFR */
     808             : 
     809             :     /*-----------------------------------------------------------------*
     810             :      * Favor a smaller delay if it happens that it has its multiple
     811             :      * in the longer-delay sections  (harmonics check)
     812             :      *-----------------------------------------------------------------*/
     813             : 
     814        9300 :     FOR( i = 0; i < 2; i++ ) /* loop for the 2 half-frames */
     815             :     {
     816        6200 :         fac = THRES0;
     817        6200 :         move16();
     818        6200 :         find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
     819        6200 :         find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     820        6200 :         test();
     821        6200 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
     822             :         {
     823        3626 :             find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     824             :         }
     825        6200 :         fac = THRES0;
     826        6200 :         move16();
     827        6200 :         find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
     828        6200 :         find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     829        6200 :         test();
     830        6200 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
     831             :         {
     832        3626 :             find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     833             :         }
     834             :     }
     835             : 
     836        3100 :     fac = THRES0;
     837        3100 :     move16();                                                                                                        /* the look-ahead */
     838        3100 :     find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
     839        3100 :     find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     840        3100 :     test();
     841        3100 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
     842             :     {
     843        1813 :         find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     844             :     }
     845        3100 :     fac = THRES0;
     846        3100 :     move16();
     847        3100 :     find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
     848        3100 :     find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
     849        3100 :     test();
     850        3100 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
     851             :     {
     852        1813 :         find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ /* Multiples in 2nd section */
     853             :     }
     854             : 
     855             :     /*-----------------------------------------------------------------*
     856             :      * Do 1st estimate for pitch values
     857             :      * Adjust the normalized correlation using estimated noise level
     858             :      * Compute the maximum scaling for the neighbour correlation
     859             :      * reinforcement
     860             :      *-----------------------------------------------------------------*/
     861        3100 :     add_sect0 = add( NSECT, sect0 );
     862        3100 :     sub_sect0 = sub( NSECT, sect0 );
     863       12400 :     FOR( i = 0; i < NHFR; i++ )
     864             :     {
     865             :         /* 1st set of pitch candidates */
     866        9300 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
     867        9300 :         ind_tmp[i] = ind;
     868        9300 :         move16();
     869        9300 :         pitch_tmp[i] = pitchX[i][ind];
     870        9300 :         move16();
     871        9300 :         cor_tmp[i] = add_o( corX[i][ind], corr_shift, &Overflow );
     872        9300 :         move16();
     873             : 
     874             :         /* Higher is the neighbour's correlation, higher is the weighting */
     875             :         /* operands are Q15, result is Q15 */
     876        9300 :         thres1[i] = mult( THRES1, cor_tmp[i] );
     877        9300 :         move16();
     878             : 
     879             :         /* 2nd set of pitch candidates */
     880        9300 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
     881        9300 :         ind_tmp[i + NHFR] = ind1;
     882        9300 :         move16();
     883        9300 :         pitch_tmp[i + NHFR] = pitchX[i][ind1];
     884        9300 :         move16();
     885        9300 :         cor_tmp[i + NHFR] = add_o( corX[i][ind1], corr_shift, &Overflow );
     886        9300 :         move16();
     887             : 
     888             :         /* Higher is the neighbour's correlation, higher is the weighting */
     889             :         /* operands are Q15, result is Q15 */
     890        9300 :         thres1[i + NHFR] = mult( THRES1, cor_tmp[i + NHFR] );
     891        9300 :         move16();
     892             :     }
     893             :     /*-----------------------------------------------------------------*
     894             :      * Take into account previous and next pitch values of the present
     895             :      * frame and look-ahead. Choose the pitch lags and normalize
     896             :      * correlations for each half-frame & look-ahead
     897             :      *-----------------------------------------------------------------*/
     898             : 
     899        3100 :     pitch_neighbour_fx( sect0, pitch_tmp, pitchX, cor_tmp, scaledX, thres1, ind_tmp );
     900       12400 :     FOR( i = 0; i < NHFR; i++ )
     901             :     {
     902        9300 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
     903        9300 :         ind_corX = add( maximum_fx( corX[i] + sect0, sub_sect0, &ftmp ), sect0 );
     904             : 
     905        9300 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
     906        9300 :         ind1_corX = add( maximum_fx( corX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
     907             : 
     908        9300 :         if ( GT_16( scaledX[i][ind1], scaledX[i][ind] ) )
     909             :         {
     910        3973 :             ind = ind1;
     911        3973 :             move16();
     912             :         }
     913        9300 :         test();
     914        9300 :         if ( Opt_SC_VBR && GT_16( corX[i][ind1_corX], corX[i][ind_corX] ) )
     915             :         {
     916           0 :             ind_corX = ind1_corX;
     917           0 :             move16();
     918             :         }
     919        9300 :         test();
     920        9300 :         test();
     921        9300 :         test();
     922        9300 :         IF( Opt_SC_VBR && ( LT_16( mult( pitchX[i][ind], 13107 /*0.4 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
     923             :             ( GT_16( mult( pitchX[i][ind], 19661 /*0.6 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
     924             :             ( GE_16( corX[i][ind_corX], 29491 /*0.9 in Q15*/ ) ) )
     925             :         {
     926           0 :             pitch[i] = pitchX[i][ind_corX];
     927           0 :             move16();
     928           0 :             voicing[i] = corX[i][ind_corX];
     929           0 :             move16();
     930             :         }
     931             :         ELSE
     932             :         {
     933        9300 :             pitch[i] = pitchX[i][ind];
     934        9300 :             move16();
     935        9300 :             voicing[i] = corX[i][ind];
     936        9300 :             move16();
     937             :         }
     938             :     }
     939             : 
     940             :     /*-----------------------------------------------------------------*
     941             :      * Increase the threshold for correlation reinforcement with
     942             :      * the past if correlation high and pitch stable
     943             :      *-----------------------------------------------------------------*/
     944             : 
     945             :     /* all Q15 here */
     946             :     /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */
     947        3100 :     Ltmp = L_mult( voicing[0], 16384 );
     948        3100 :     Ltmp = L_mac( Ltmp, voicing[1], 16384 );
     949        3100 :     cor_mean = round_fx( L_add( Ltmp, corr_shift ) );
     950             : 
     951             :     /* pitch unstable in present frame or from previous frame or normalized correlation too low */
     952        3100 :     coh_flag = pitch_coherence_fx( pitch[0], pitch[1], COH_FAC, DELTA_COH );
     953        3100 :     move16();
     954        3100 :     coh_flag1 = pitch_coherence_fx( pitch[0], *old_pitch, COH_FAC, DELTA_COH );
     955        3100 :     move16();
     956             : 
     957        3100 :     test();
     958        3100 :     test();
     959        3100 :     test();
     960        3100 :     IF( ( coh_flag == 0 ) || ( coh_flag1 == 0 ) || ( LT_16( cor_mean, CORR_TH0 ) ) || ( LT_16( relE, THR_relE ) ) )
     961             :     {
     962             :         /* Reset the threshold */
     963        1326 :         *old_thres = 0;
     964        1326 :         move16();
     965             :     }
     966             :     ELSE
     967             :     {
     968             :         /* The threshold increase is directly dependent on normalized correlation */
     969             :         /* *old_thres += (0.16f * cor_mean); */
     970        1774 :         *old_thres = round_fx( L_mac( L_deposit_h( *old_thres ), 5243, cor_mean ) );
     971             :     }
     972             : 
     973        3100 :     *old_thres = s_min( *old_thres, THRES3 );
     974        3100 :     move16();
     975             : 
     976        3100 :     IF( GT_16( voicing[1], voicing[0] ) )
     977             :     {
     978        1498 :         *old_corr = voicing[1];
     979        1498 :         move16();
     980             :     }
     981             :     ELSE
     982             :     {
     983        1602 :         *old_corr = cor_mean;
     984        1602 :         move16();
     985             :     }
     986             : 
     987             :     /*-----------------------------------------------------------------*
     988             :      * Extrapolate the pitch value for the next frame by estimating
     989             :      * the pitch evolution. This value is added to the old_pitch
     990             :      * in the next frame and is then used when the normalized
     991             :      * correlation is reinforced by the past estimate
     992             :      *-----------------------------------------------------------------*/
     993        3100 :     tmp_buf[0] = *old_pitch;
     994        3100 :     move16();
     995       12400 :     FOR( i = 0; i < NHFR; i++ )
     996             :     {
     997        9300 :         tmp_buf[i + 1] = pitch[i];
     998        9300 :         move16();
     999             :     }
    1000             : 
    1001        3100 :     *delta_pit = 0;
    1002        3100 :     move16();
    1003        3100 :     cnt = 0;
    1004        3100 :     move16();
    1005             : 
    1006       12400 :     FOR( i = 0; i < NHFR; i++ )
    1007             :     {
    1008        9300 :         diff = sub( tmp_buf[i + 1], tmp_buf[i] );
    1009        9300 :         move16();
    1010        9300 :         coh_flag = pitch_coherence_fx( tmp_buf[i], tmp_buf[i + 1], COH_FAC, DELTA_COH );
    1011             : 
    1012        9300 :         if ( coh_flag != 0 )
    1013             :         {
    1014        7827 :             *delta_pit = add( *delta_pit, diff );
    1015        7827 :             move16();
    1016             :         }
    1017        9300 :         cnt = add( cnt, coh_flag );
    1018             :     }
    1019        3100 :     if ( EQ_16( cnt, 2 ) )
    1020             :     {
    1021             :         /* *delta_pit /= 2; */
    1022         479 :         *delta_pit = shr( *delta_pit, 1 );
    1023         479 :         move16();
    1024             :     }
    1025        3100 :     IF( EQ_16( cnt, 3 ) )
    1026             :     {
    1027        2188 :         k = *delta_pit;
    1028        2188 :         move16();
    1029             :         /* *delta_pit /= 3; */
    1030        2188 :         if ( k < 0 )
    1031             :         {
    1032         488 :             *delta_pit = mult( *delta_pit, -32768 );
    1033         488 :             move16();
    1034             :         }
    1035        2188 :         tmp16 = mult( *delta_pit, 10923 );
    1036        2188 :         if ( k < 0 )
    1037             :         {
    1038         488 :             tmp16 = mult( tmp16, -32768 );
    1039             :         }
    1040        2188 :         *delta_pit = tmp16;
    1041        2188 :         move16();
    1042             :     }
    1043             : 
    1044             :     /*--------------------------------------------------------------*
    1045             :      * Update old pitch, upsample pitch,
    1046             :      *--------------------------------------------------------------*/
    1047             : 
    1048        3100 :     *old_pitch = pitch[1];
    1049        3100 :     move16();
    1050             : 
    1051       12400 :     FOR( i = 0; i < NHFR; i++ )
    1052             :     {
    1053             :         /* compensate decimation */
    1054        9300 :         pitch[i] = i_mult2( pitch[i], OPL_DECIM );
    1055        9300 :         move16();
    1056             :     }
    1057             : 
    1058        3100 :     return;
    1059             : }
    1060             : 
    1061     1129000 : void pitch_ol_ivas_fx(
    1062             :     Word16 pitch[3],         /* o  : open loop pitch lag for each half-frame in range [29,231]      Q0  */
    1063             :     Word16 voicing[3],       /* o  : maximum normalized correlation for each half-frame in [0,1.0[  Q15 */
    1064             :     Word16 *old_pitch,       /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1])  Q0  */
    1065             :     Word16 *old_corr,        /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean)        Q15 */
    1066             :     Word16 corr_shift,       /* i  : normalized correlation correction                              Q15 */
    1067             :     Word16 *old_thres,       /* i/o: maximum correlation weighting with respect to past frame pitch Q14 */
    1068             :     Word16 *delta_pit,       /* i/o: old pitch extrapolation correction in range [-14,+14]          Q0  */
    1069             :     Word16 *st_old_wsp2,     /* i/o: weighted speech memory                                         qwsp */
    1070             :     const Word16 *wsp,       /* i  : weighted speech for current frame and look-ahead               qwsp */
    1071             :     Word16 mem_decim2[3],    /* i/o: wsp decimation filter memory                                   qwsp */
    1072             :     const Word16 relE,       /* i  : relative frame energy                                          Q8  */
    1073             :     const Word16 last_class, /* i  : frame classification of last frame                                 */
    1074             :     const Word16 bwidth,     /* i  : bandwidth                                                          */
    1075             :     const Word16 Opt_SC_VBR, /* i  : SC-VBR flag                                                        */
    1076             :     Word16 qwsp              /* i  : Q factor for wsp                                               Q0  */
    1077             : )
    1078             : {
    1079             :     Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2;
    1080             :     Word16 tmp_mem[3];
    1081             : 
    1082             :     Word16 scale1[2 * DELTA_COH - 1];
    1083             :     Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
    1084             :     Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
    1085             :     Word16 cor_buf[2 * LEN_X], cor_buf_exp[2 * LEN_X];
    1086             :     Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6;
    1087             :     Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4;
    1088             :     Word16 *pt_cor0_exp, *pt_cor1_exp, *pt_cor2_exp, *pt_cor3_exp, *pt_cor4_exp;
    1089             :     Word16 thres1[6];
    1090             :     Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1;
    1091             :     Word16 ind_corX, ind1_corX;
    1092             : 
    1093             :     Word16 i, j, k, m, pit_min, pit_min1, sect0, subsect0, add_sect0, sub_sect0, old_tmp, old_tmp1, len_x, len_x1;
    1094             :     Word16 len_temp;
    1095             :     Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1];
    1096             : 
    1097             :     Word16 enr0_exp[NSECT], enr0_1_exp[NSECT], enr1_exp;
    1098             :     Word32 enr0[NSECT], enr0_1[NSECT], enr1;
    1099             :     Word64 temp, temp1;
    1100             :     Word32 Ltmp;
    1101             :     Word16 fac, tmp16, tmp16_2;
    1102             :     Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean;
    1103             :     const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1;
    1104             : 
    1105             :     Word16 pit_min_coding;
    1106             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1107     1129000 :     Flag Overflow = 0;
    1108             : #endif
    1109             :     Word16 new_q;
    1110     1129000 :     new_q = sub( 63, shl( qwsp, 1 ) );
    1111             : 
    1112             :     /*--------------------------------------------------------------*
    1113             :      * Initialization
    1114             :      *--------------------------------------------------------------*/
    1115     1129000 :     len = len_12k8;
    1116     1129000 :     len1 = len1_12k8;
    1117     1129000 :     sublen = sublen_12k8;
    1118     1129000 :     sublen1 = sublen1_12k8;
    1119     1129000 :     pit_max = pit_max_12k8;
    1120     1129000 :     sec_length = sec_length_12k8;
    1121     1129000 :     sec_length1 = sec_length1_12k8;
    1122             : 
    1123     1129000 :     test();
    1124     1129000 :     if ( ( LT_16( last_class, VOICED_TRANSITION ) ) && ( NE_16( bwidth, NB ) ) )
    1125             :     {
    1126             :         /*reset last pitch reinforcement in case of unvoiced or transitions: it avoids some pitch doublings*/
    1127      652505 :         *old_thres = 0;
    1128      652505 :         move16();
    1129             :     }
    1130             : 
    1131     1129000 :     pit_min_coding = PIT_MIN_EXTEND;
    1132     1129000 :     move16();
    1133     1129000 :     test();
    1134     1129000 :     test();
    1135     1129000 :     test();
    1136     1129000 :     test();
    1137     1129000 :     IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) ||
    1138             :         ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 1638 /* 0.1 in Q14*/ ) ) ) ) )
    1139             :     {
    1140      498822 :         pit_min = PIT_MIN / OPL_DECIM;
    1141      498822 :         move16();
    1142      498822 :         pit_min1 = PIT_MIN_1 / OPL_DECIM;
    1143      498822 :         move16();
    1144      498822 :         subsect0 = 2;
    1145      498822 :         move16();
    1146      498822 :         sect0 = 1;
    1147      498822 :         move16();
    1148             :     }
    1149             :     ELSE
    1150             :     {
    1151      630178 :         pit_min = PIT_MIN2 / OPL_DECIM;
    1152      630178 :         move16();
    1153      630178 :         pit_min1 = PIT_MIN2_1 / OPL_DECIM;
    1154      630178 :         move16();
    1155      630178 :         subsect0 = 0;
    1156      630178 :         move16();
    1157      630178 :         sect0 = 0;
    1158      630178 :         move16();
    1159             :     }
    1160             : 
    1161     1129000 :     len_x = ( PIT_MAX / OPL_DECIM - pit_min + 1 );
    1162     1129000 :     move16();
    1163     1129000 :     len_x1 = ( PIT_MAX / OPL_DECIM - pit_min1 + 1 );
    1164     1129000 :     move16();
    1165             : 
    1166             :     /*--------------------------------------------------------------*
    1167             :      * Find decimated weighted speech
    1168             :      * Update wsp buffer with the memory
    1169             :      * decimation of wsp[] to search pitch in LF and to reduce complexity
    1170             :      * Extend the decimation of wsp to the end of the speech buffer
    1171             :      * Update wsp memory
    1172             :      *--------------------------------------------------------------*/
    1173     1129000 :     Copy( st_old_wsp2, old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
    1174     1129000 :     wsp2 = old_wsp2 + ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
    1175             : 
    1176     1129000 :     LP_Decim2_Copy( wsp, wsp2, L_FRAME, mem_decim2 );
    1177             : 
    1178             :     /* Avoid uninitialized memory access */
    1179     1129000 :     set16_fx( wsp2 + L_FRAME / 2, 0, sizeof( old_wsp2 ) / sizeof( Word16 ) - ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ) - L_FRAME / 2 );
    1180     1129000 :     tmp_mem[0] = mem_decim2[0];
    1181     1129000 :     move16();
    1182     1129000 :     tmp_mem[1] = mem_decim2[1];
    1183     1129000 :     move16();
    1184     1129000 :     tmp_mem[2] = mem_decim2[2];
    1185     1129000 :     move16();
    1186             : 
    1187     1129000 :     LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[L_FRAME / 2], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/
    1188             : 
    1189     1129000 :     Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
    1190             : 
    1191             :     /*-----------------------------------------------------------------*
    1192             :      * Attenuate the correlation correction factor due to noise.
    1193             :      * Reset correlation buffer outside the useful range.
    1194             :      * Find the scaling functions for immediate neigbours and
    1195             :      * further ones.
    1196             :      *-----------------------------------------------------------------*/
    1197             : 
    1198     1129000 :     corr_shift = shr( corr_shift, 1 );
    1199             : 
    1200     1129000 :     set16_fx( scaled_buf, 0, DELTA_COH - 1 );
    1201     1129000 :     set16_fx( scaled_buf + ( DELTA_COH - 1 ) + len_x, 0, DELTA_COH - 1 );
    1202     1129000 :     set16_fx( scaled_buf + 2 * ( DELTA_COH - 1 ) + len_x + len_x1, 0, DELTA_COH - 1 );
    1203     1129000 :     set16_fx( scaled_buf_exp, 0, len_x + len_x1 + 3 * ( DELTA_COH - 1 ) );
    1204             : 
    1205     1129000 :     pt1 = scale1 + DELTA_COH - 1;
    1206     1129000 :     pt2 = pt1;
    1207     1129000 :     tmp16 = mult( *old_thres, -32768 / DELTA_COH ); // Q14
    1208     1129000 :     k = add( *old_thres, ONE_IN_Q14 );              // Q14
    1209    16935000 :     FOR( i = 0; i < DELTA_COH; i++ )
    1210             :     {
    1211    15806000 :         *pt1 = k;        // Q14
    1212    15806000 :         *pt2-- = *pt1++; // Q14
    1213    15806000 :         move16();
    1214    15806000 :         move16();
    1215             : 
    1216    15806000 :         k = add( k, tmp16 ); // Q14
    1217             :     }
    1218             : 
    1219             :     /*-----------------------------------------------------------------------------*
    1220             :      * Estimate the new pitch by extrapolating the old pitch value for 2 half-frames
    1221             :      *-----------------------------------------------------------------------------*/
    1222     1129000 :     old_tmp = add( *old_pitch, *delta_pit );
    1223     1129000 :     old_tmp = s_min( old_tmp, PIT_MAX / OPL_DECIM );
    1224     1129000 :     old_tmp = s_max( old_tmp, pit_min );
    1225     1129000 :     old_tmp1 = add( old_tmp, *delta_pit );
    1226     1129000 :     old_tmp1 = s_min( old_tmp1, PIT_MAX / OPL_DECIM );
    1227     1129000 :     old_tmp1 = s_max( old_tmp1, pit_min );
    1228             : 
    1229             :     /*-----------------------------------------------------------------*
    1230             :      * Loop for all three half-frames (current frame + look-ahead)
    1231             :      *-----------------------------------------------------------------*/
    1232     1129000 :     pt_cor0 = scaled_buf + DELTA_COH - 1;
    1233     1129000 :     pt_cor0_exp = scaled_buf_exp + DELTA_COH - 1;
    1234             : 
    1235     1129000 :     pt_cor2 = pt_cor0 - pit_min + old_tmp;
    1236     1129000 :     pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp;
    1237             : 
    1238     1129000 :     pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
    1239     1129000 :     pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
    1240             : 
    1241     4516000 :     FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */
    1242             :     {
    1243     3387000 :         pt1 = wsp2 + i * 2 * ( L_SUBFR / OPL_DECIM ); /* *pt1 -> Q12 */
    1244     3387000 :         pt2 = pt1 - pit_min;                          /* *pt2 -> Q12 */
    1245     3387000 :         pt4 = pt1 - pit_min1;                         /* *pt4 -> Q12 */
    1246             : 
    1247     3387000 :         temp = 0;
    1248     3387000 :         move64();
    1249             : 
    1250     3387000 :         pt_cor1 = pt_cor0;
    1251     3387000 :         pt_cor1_exp = pt_cor0_exp;
    1252             : 
    1253     3387000 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
    1254     3387000 :         pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x;
    1255             : 
    1256     3387000 :         IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */
    1257             :         {
    1258     2258000 :             pt3 = pt1;
    1259     2258000 :             pt5 = pt1;
    1260             : 
    1261    10292356 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
    1262             :             {
    1263             :                 /*-----------------------------------------------------------------*
    1264             :                  * Find fixed vector energy
    1265             :                  *-----------------------------------------------------------------*/
    1266             : 
    1267             :                 /* 1st set */
    1268     8034356 :                 k = (Word16) ( pt1 - pt3 );
    1269     8034356 :                 move16();
    1270   267704356 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
    1271             :                 {
    1272   259670000 :                     temp = W_mac0_16_16( temp, *pt3, *pt3 ); // 2*qwsp
    1273   259670000 :                     pt3++;
    1274             :                 }
    1275     8034356 :                 IF( temp == 0 )
    1276             :                 {
    1277      612388 :                     enr0[j] = 21474836; // 0.01 in Q31
    1278      612388 :                     enr0_exp[j] = 0;
    1279      612388 :                     move32();
    1280      612388 :                     move16();
    1281             :                 }
    1282             :                 ELSE
    1283             :                 {
    1284     7421968 :                     cnt = W_norm( temp );
    1285     7421968 :                     enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32
    1286     7421968 :                     enr0_exp[j] = sub( new_q, cnt );             // 31-(2*qwsp+cnt-32)
    1287     7421968 :                     move32();
    1288     7421968 :                     move16();
    1289             :                 }
    1290             : 
    1291             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
    1292     8034356 :                 pt5 = pt3;
    1293             : 
    1294             :                 /* 2nd set */
    1295     8034356 :                 k = (Word16) ( pt1 - pt5 );
    1296     8034356 :                 move16();
    1297             : 
    1298     8034356 :                 temp1 = temp;
    1299     8034356 :                 move64();
    1300    71258356 :                 FOR( k = ( k + len1[j] ); k > 0; k-- )
    1301             :                 {
    1302    63224000 :                     temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp
    1303    63224000 :                     pt5++;
    1304             :                 }
    1305     8034356 :                 IF( temp1 == 0 )
    1306             :                 {
    1307      611930 :                     enr0_1[j] = 21474836; // 0.01 in Q31
    1308      611930 :                     enr0_1_exp[j] = 0;
    1309      611930 :                     move32();
    1310      611930 :                     move16();
    1311             :                 }
    1312             :                 ELSE
    1313             :                 {
    1314     7422426 :                     cnt = W_norm( temp1 );
    1315     7422426 :                     enr0_1[j] = W_extract_h( W_shl( temp1, cnt ) ); // 2*qwsp+cnt-32
    1316     7422426 :                     enr0_1_exp[j] = sub( new_q, cnt );              // 31-(2*qwsp+cnt-32)
    1317     7422426 :                     move32();
    1318     7422426 :                     move16();
    1319             :                 }
    1320             :             }
    1321             : 
    1322             :             /*----------------------------------------------------------*
    1323             :              * Find correlation for the non-overlapping pitch lag values
    1324             :              *----------------------------------------------------------*/
    1325             : 
    1326     2258000 :             k = (Word16) ( pt2 - pt1 + pit_max[subsect0] );
    1327     2258000 :             move16();
    1328             : 
    1329     9766932 :             FOR( ; k >= 0; k-- )
    1330             :             {
    1331     7508932 :                 temp = 0;
    1332     7508932 :                 move64();
    1333   307866212 :                 FOR( m = 0; m < sublen[0]; m++ )
    1334             :                 {
    1335   300357280 :                     temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1336             :                 }
    1337     7508932 :                 cnt = W_norm( temp );
    1338     7508932 :                 *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1339     7508932 :                 *pt_cor1_exp = sub( new_q, cnt );                          // 15-(2*qwsp+cnt-32-16)
    1340     7508932 :                 move16();
    1341     7508932 :                 move16();
    1342             : 
    1343     7508932 :                 pt2--;
    1344     7508932 :                 pt_cor1++;
    1345     7508932 :                 pt_cor1_exp++;
    1346             :             }
    1347             : 
    1348             :             /*----------------------------------------------------------*
    1349             :              * For each subsection, find the correlation
    1350             :              *----------------------------------------------------------*/
    1351    16068712 :             FOR( j = subsect0; j < NSUBSECT; j++ )
    1352             :             {
    1353    13810712 :                 len_temp = sublen[j];
    1354    13810712 :                 move16();
    1355             : 
    1356    13810712 :                 k = (Word16) ( pt2 - pt1 );
    1357    13810712 :                 move16();
    1358    13810712 :                 k = add( k, pit_max[j + 1] );
    1359             : 
    1360             :                 /* Keep Q15 normalized result */
    1361    13810712 :                 IF( LT_16( sublen[j], sublen1[j] ) )
    1362             :                 {
    1363    74514000 :                     FOR( ; k >= 0; k-- )
    1364             :                     {
    1365    69998000 :                         temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp
    1366  3843116000 :                         FOR( m = 1; m < sublen[j]; m++ )
    1367             :                         {
    1368  3773118000 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1369             :                         }
    1370    69998000 :                         cnt = W_norm( temp );
    1371    69998000 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1372    69998000 :                         *pt_cor1_exp = sub( new_q, cnt );
    1373    69998000 :                         move16();
    1374    69998000 :                         move16();
    1375             : 
    1376  1149322000 :                         FOR( ; m < sublen1[j]; m++ )
    1377             :                         {
    1378  1079324000 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1379             :                         }
    1380    69998000 :                         cnt = W_norm( temp );
    1381    69998000 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1382    69998000 :                         *pt_cor3_exp = sub( new_q, cnt );
    1383    69998000 :                         move16();
    1384    69998000 :                         move16();
    1385             : 
    1386    69998000 :                         pt_cor1++;
    1387    69998000 :                         pt_cor1_exp++;
    1388    69998000 :                         pt_cor3++;
    1389    69998000 :                         pt_cor3_exp++;
    1390    69998000 :                         pt2--;
    1391             :                     }
    1392             :                 }
    1393             :                 ELSE
    1394             :                 {
    1395   164152272 :                     FOR( ; k >= 0; k-- )
    1396             :                     {
    1397   154857560 :                         temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp
    1398 14277942400 :                         FOR( m = 1; m < sublen1[j]; m++ )
    1399             :                         {
    1400 14123084840 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1401             :                         }
    1402   154857560 :                         cnt = W_norm( temp );
    1403   154857560 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1404   154857560 :                         *pt_cor3_exp = sub( new_q, cnt );
    1405   154857560 :                         move16();
    1406   154857560 :                         move16();
    1407             : 
    1408  1663201560 :                         FOR( ; m < sublen[j]; m++ )
    1409             :                         {
    1410  1508344000 :                             temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
    1411             :                         }
    1412   154857560 :                         cnt = W_norm( temp );
    1413   154857560 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1414   154857560 :                         *pt_cor1_exp = sub( new_q, cnt );
    1415   154857560 :                         move16();
    1416   154857560 :                         move16();
    1417             : 
    1418   154857560 :                         pt_cor1++;
    1419   154857560 :                         pt_cor1_exp++;
    1420   154857560 :                         pt_cor3++;
    1421   154857560 :                         pt_cor3_exp++;
    1422   154857560 :                         pt2--;
    1423             :                     }
    1424             :                 }
    1425             :             } /* FOR (j = subsect0; ... */
    1426             :         }
    1427             :         ELSE /* 3rd half-frame (look-ahead) */
    1428             :         {
    1429     1129000 :             pt6 = pt1 + L_LOOK_12k8 / OPL_DECIM - 1;
    1430     1129000 :             pt3 = pt6;
    1431     1129000 :             pt5 = pt6;
    1432             : 
    1433             :             /*-----------------------------------------------------------------*
    1434             :              * For each section in both sets, find fixed vector energy
    1435             :              *-----------------------------------------------------------------*/
    1436     5146178 :             FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
    1437             :             {
    1438             :                 /* 1st set */
    1439     4017178 :                 k = (Word16) ( pt3 - pt6 );
    1440     4017178 :                 move16();
    1441             : 
    1442   133852178 :                 FOR( k = add( k, len[j] ); k > 0; k-- )
    1443             :                 {
    1444   129835000 :                     temp = W_mac0_16_16( temp, *pt3, *pt3 );
    1445   129835000 :                     pt3--;
    1446             :                 }
    1447     4017178 :                 IF( temp == 0 )
    1448             :                 {
    1449      298185 :                     enr0[j] = 21474836; // 0.01 in Q31
    1450      298185 :                     enr0_exp[j] = 0;
    1451      298185 :                     move32();
    1452      298185 :                     move16();
    1453             :                 }
    1454             :                 ELSE
    1455             :                 {
    1456     3718993 :                     cnt = W_norm( temp );
    1457     3718993 :                     enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32
    1458     3718993 :                     enr0_exp[j] = sub( new_q, cnt );             // 31-(2*qwsp+cnt-32)
    1459     3718993 :                     move32();
    1460     3718993 :                     move16();
    1461             :                 }
    1462             : 
    1463             :                 /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
    1464     4017178 :                 pt5 = pt3;
    1465     4017178 :                 temp1 = temp;
    1466     4017178 :                 move64();
    1467             : 
    1468             :                 /* 2nd set */
    1469     4017178 :                 k = (Word16) ( pt5 - pt6 );
    1470     4017178 :                 move16();
    1471    35629178 :                 FOR( k = add( k, len1[j] ); k > 0; k-- )
    1472             :                 {
    1473    31612000 :                     temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp
    1474    31612000 :                     pt5--;
    1475             :                 }
    1476     4017178 :                 IF( temp1 == 0 )
    1477             :                 {
    1478      297998 :                     enr0_1[j] = 21474836; // 0.01 in Q31
    1479      297998 :                     enr0_1_exp[j] = 0;
    1480      297998 :                     move32();
    1481      297998 :                     move16();
    1482             :                 }
    1483             :                 ELSE
    1484             :                 {
    1485     3719180 :                     cnt = W_norm( temp1 );
    1486     3719180 :                     temp1 = W_shl( temp1, cnt );       // 2*qwsp+cnt
    1487     3719180 :                     enr0_1[j] = W_extract_h( temp1 );  // 2*qwsp+cnt-32
    1488     3719180 :                     enr0_1_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32)
    1489     3719180 :                     move32();
    1490     3719180 :                     move16();
    1491             :                 }
    1492             :             }
    1493             : 
    1494             :             /* Set pointers: same as IF/ELSE block */
    1495     1129000 :             pt2 = pt6 - pit_min;
    1496     1129000 :             k = 2;
    1497     1129000 :             move16();
    1498     1129000 :             IF( sect0 != 0 )
    1499             :             {
    1500      498822 :                 pt2 = pt6 - add( pit_max[1], 1 );
    1501      498822 :                 k = sub( pit_max[2], pit_max[1] );
    1502      498822 :                 move16();
    1503             :             }
    1504             : 
    1505             :             /*-----------------------------------------------------------------*
    1506             :              * Find correlation for the non-overlapping pitch lag values
    1507             :              *-----------------------------------------------------------------*/
    1508             : 
    1509     1129000 :             len_temp = sublen[0];
    1510     1129000 :             move16();
    1511             : 
    1512     4883466 :             FOR( ; k > 0; k-- )
    1513             :             {
    1514     3754466 :                 temp = 0;
    1515     3754466 :                 move64();
    1516   153933106 :                 FOR( m = 0; m < len_temp; m++ )
    1517             :                 {
    1518   150178640 :                     temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1519             :                 }
    1520     3754466 :                 tmp16_2 = W_norm( temp );
    1521     3754466 :                 *pt_cor1 = extract_h( W_extract_h( W_shl( temp, tmp16_2 ) ) ); // 2*qwsp+tmp16_2
    1522     3754466 :                 *pt_cor1_exp = sub( new_q, tmp16_2 );                          // 2*qwsp+tmp16_2-32-16
    1523     3754466 :                 move16();
    1524     3754466 :                 move16();
    1525             : 
    1526     3754466 :                 pt_cor1++;
    1527     3754466 :                 pt_cor1_exp++;
    1528     3754466 :                 pt2--;
    1529             :             }
    1530             : 
    1531             :             /*-----------------------------------------------------------------*
    1532             :              * For each subsection, find the correlation (overlapping pitch lag values)
    1533             :              *-----------------------------------------------------------------*/
    1534             : 
    1535     8034356 :             FOR( j = subsect0; j < NSUBSECT; j++ )
    1536             :             {
    1537     6905356 :                 k = sub( pit_max[j + 1], pit_max[j] );
    1538             : 
    1539     6905356 :                 IF( LT_16( sublen[j], sublen1[j] ) )
    1540             :                 {
    1541    37257000 :                     FOR( ; k > 0; k-- )
    1542             :                     {
    1543    34999000 :                         temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp
    1544  1921558000 :                         FOR( m = 1; m < sublen[j]; m++ )
    1545             :                         {
    1546  1886559000 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1547             :                         }
    1548    34999000 :                         cnt = W_norm( temp );
    1549    34999000 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1550    34999000 :                         *pt_cor1_exp = sub( new_q, cnt );
    1551    34999000 :                         move16();
    1552    34999000 :                         move16();
    1553             : 
    1554   574661000 :                         FOR( ; m < sublen1[j]; m++ )
    1555             :                         {
    1556   539662000 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1557             :                         }
    1558    34999000 :                         cnt = W_norm( temp );
    1559    34999000 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1560    34999000 :                         *pt_cor3_exp = sub( new_q, cnt );
    1561    34999000 :                         move16();
    1562    34999000 :                         move16();
    1563             : 
    1564    34999000 :                         pt_cor1++;
    1565    34999000 :                         pt_cor1_exp++;
    1566    34999000 :                         pt_cor3++;
    1567    34999000 :                         pt_cor3_exp++;
    1568    34999000 :                         pt2--;
    1569             :                     }
    1570             :                 }
    1571             :                 ELSE
    1572             :                 {
    1573    82076136 :                     FOR( ; k > 0; k-- )
    1574             :                     {
    1575    77428780 :                         temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp
    1576  7138971200 :                         FOR( m = 1; m < sublen1[j]; m++ )
    1577             :                         {
    1578  7061542420 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1579             :                         }
    1580    77428780 :                         cnt = W_norm( temp );
    1581    77428780 :                         *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1582    77428780 :                         *pt_cor3_exp = sub( new_q, cnt );
    1583    77428780 :                         move16();
    1584    77428780 :                         move16();
    1585             : 
    1586   831600780 :                         FOR( ; m < sublen[j]; m++ )
    1587             :                         {
    1588   754172000 :                             temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
    1589             :                         }
    1590    77428780 :                         cnt = W_norm( temp );
    1591    77428780 :                         *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
    1592    77428780 :                         *pt_cor1_exp = sub( new_q, cnt );
    1593    77428780 :                         move16();
    1594    77428780 :                         move16();
    1595             : 
    1596    77428780 :                         pt_cor1++;
    1597    77428780 :                         pt_cor1_exp++;
    1598    77428780 :                         pt_cor3++;
    1599    77428780 :                         pt_cor3_exp++;
    1600    77428780 :                         pt2--;
    1601             :                     }
    1602             :                 }
    1603             :             }
    1604             :         } /* 3rd half-frame (look-ahead) */
    1605             : 
    1606             :         /* Scale all values in each section to the same exponent for upcoming Find_max() */
    1607     3387000 :         Copy( pt_cor0, cor_buf, len_x );         /* Save unscaled correlation vector  */
    1608     3387000 :         Copy( pt_cor0_exp, cor_buf_exp, len_x ); /* Save unscaled correlation vector  */
    1609     3387000 :         Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 );
    1610     3387000 :         Copy( pt_cor0_exp + ( DELTA_COH - 1 ) + len_x, cor_buf_exp + len_x, len_x1 );
    1611             : 
    1612             :         /*-----------------------------------------------------------------*
    1613             :          * Scale correlation function in the neighbourhood of
    1614             :          * the extrapolated pitch
    1615             :          *-----------------------------------------------------------------*/
    1616     3387000 :         pt_cor1 = pt_cor2 - ( DELTA_COH - 1 );
    1617     3387000 :         pt_cor1_exp = pt_cor2_exp - ( DELTA_COH - 1 );
    1618     3387000 :         pt_cor3 = pt_cor4 - ( DELTA_COH - 1 );
    1619     3387000 :         pt_cor3_exp = pt_cor4_exp - ( DELTA_COH - 1 );
    1620     3387000 :         pt2 = scale1;
    1621             : 
    1622    94836000 :         FOR( k = 0; k < 2 * DELTA_COH - 1; k++ )
    1623             :         {
    1624    91449000 :             *pt_cor1 = mult( *pt_cor1, *pt2 );     // *pt_cor1_exp+1
    1625    91449000 :             *pt_cor1_exp = add( *pt_cor1_exp, 1 ); // *pt_cor1_exp+1
    1626    91449000 :             move16();
    1627    91449000 :             move16();
    1628             : 
    1629    91449000 :             *pt_cor3 = mult( *pt_cor3, *pt2++ );   // *pt_cor3_exp+1
    1630    91449000 :             *pt_cor3_exp = add( *pt_cor3_exp, 1 ); // *pt_cor1_exp+1
    1631    91449000 :             move16();
    1632    91449000 :             move16();
    1633             : 
    1634    91449000 :             pt_cor1++;
    1635    91449000 :             pt_cor1_exp++;
    1636    91449000 :             pt_cor3++;
    1637    91449000 :             pt_cor3_exp++;
    1638             :         }
    1639             : 
    1640             :         /* Update for next half-frame & look-ahead */
    1641     3387000 :         pt_cor2 = pt_cor0 - pit_min + old_tmp1;
    1642     3387000 :         pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp1;
    1643             : 
    1644     3387000 :         pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
    1645     3387000 :         pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
    1646             : 
    1647             :         /*-----------------------------------------------------------------*
    1648             :          * For each section, find maximum correlation and compute
    1649             :          * normalized correlation
    1650             :          *-----------------------------------------------------------------*/
    1651             : 
    1652     3387000 :         pt_cor1 = pt_cor0;
    1653     3387000 :         pt_cor1_exp = pt_cor0_exp;
    1654     3387000 :         offset = 0;
    1655     3387000 :         move16();
    1656     3387000 :         pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
    1657     3387000 :         pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x;
    1658     3387000 :         offset1 = 0;
    1659     3387000 :         move16();
    1660             : 
    1661    15438534 :         FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
    1662             :         {
    1663             :             /* 1st set */
    1664    12051534 :             offset_la = 0;
    1665    12051534 :             move16();
    1666    12051534 :             if ( EQ_16( i, 2 ) )
    1667             :             {
    1668     4017178 :                 offset_la = sub( L_LOOK_12k8 / OPL_DECIM, len[j] );
    1669             :             }
    1670             : 
    1671             :             /* 2nd set */
    1672    12051534 :             offset_la1 = 0;
    1673    12051534 :             move16();
    1674    12051534 :             if ( EQ_16( i, 2 ) )
    1675             :             {
    1676     4017178 :                 offset_la1 = sub( L_LOOK_12k8 / OPL_DECIM, len1[j] );
    1677             :             }
    1678             : 
    1679             :             /* 1st set of candidates */
    1680    12051534 :             ind = add( maximum_exp_fx( pt_cor1, pt_cor1_exp, sec_length[j] ), offset );
    1681    12051534 :             pitchX[i][j] = add( ind, pit_min );
    1682    12051534 :             move16();
    1683    12051534 :             pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector  */
    1684             : 
    1685    12051534 :             enr1_exp = 0;
    1686    12051534 :             move16();
    1687             : 
    1688             :             /* enr1 = dotp( pt2, pt2, len[j] ) + 0.01f; */
    1689    12051534 :             temp = 167772 /*0.01f in Q24*/;
    1690    12051534 :             move64();
    1691   822651894 :             FOR( m = 0; m < len[j]; m++ )
    1692             :             {
    1693   810600360 :                 temp = W_mac0_16_16( temp, pt2[m], pt2[m] ); // 2*qwsp
    1694             :             }
    1695    12051534 :             temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24
    1696    12051534 :             enr1_exp = W_norm( temp );
    1697    12051534 :             enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32
    1698    12051534 :             enr1_exp = sub( 39, enr1_exp );                // 31-(enr1_exp+24-32)
    1699             : 
    1700    12051534 :             enr1 = Mpy_32_32( enr0[j], enr1 );
    1701    12051534 :             enr1_exp = add( enr0_exp[j], enr1_exp );
    1702             : 
    1703    12051534 :             enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
    1704             : 
    1705    12051534 :             Ltmp = Mpy_32_16_1( enr1, cor_buf[ind] );
    1706    12051534 :             corX[i][j] = extract_h( L_shl_o( Ltmp, add( enr1_exp, cor_buf_exp[ind] ), &Overflow ) ); // Q15
    1707    12051534 :             move16();
    1708             : 
    1709    12051534 :             Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind] );
    1710    12051534 :             scaledX[i][j] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind] ), 3 ) ) ); // Q12
    1711    12051534 :             move16();
    1712             : 
    1713    12051534 :             pt_cor1 += sec_length[j];
    1714    12051534 :             pt_cor1_exp += sec_length[j];
    1715    12051534 :             offset = add( offset, sec_length[j] );
    1716             : 
    1717             :             /* 2nd set of candidates */
    1718    12051534 :             ind1 = add( maximum_exp_fx( pt_cor3, pt_cor3_exp, sec_length1[j] ), offset1 );
    1719    12051534 :             pitchX[i][j + NSECT] = add( ind1, pit_min1 );
    1720    12051534 :             move16();
    1721    12051534 :             pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1;
    1722    12051534 :             move16(); /* selected moving vector  */
    1723    12051534 :             enr1_exp = 0;
    1724    12051534 :             move16();
    1725             : 
    1726             :             /* enr1 = dotp(pt4, pt4, len1[j]) + 0.01f; */
    1727    12051534 :             temp = 167772 /*0.01f in Q24*/;
    1728    12051534 :             move64();
    1729   917487894 :             FOR( m = 0; m < len1[j]; m++ )
    1730             :             {
    1731   905436360 :                 temp = W_mac0_16_16( temp, pt4[m], pt4[m] ); // 2*qwsp
    1732             :             }
    1733    12051534 :             temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24
    1734    12051534 :             enr1_exp = W_norm( temp );
    1735    12051534 :             enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32
    1736    12051534 :             enr1_exp = sub( 39, enr1_exp );                // 31-(enr1_exp+24-32)
    1737             : 
    1738    12051534 :             enr1 = Mpy_32_32( enr0_1[j], enr1 );
    1739    12051534 :             enr1_exp = add( enr0_1_exp[j], enr1_exp );
    1740             : 
    1741    12051534 :             enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr1_exp*/
    1742             : 
    1743    12051534 :             Ltmp = Mpy_32_16_1( enr1, cor_buf[ind1 + len_x] );
    1744    12051534 :             corX[i][j + NSECT] = extract_h( L_shl_o( Ltmp, add( enr1_exp, cor_buf_exp[ind1 + len_x] ), &Overflow ) ); // Q15
    1745    12051534 :             move16();
    1746             : 
    1747    12051534 :             Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x] );
    1748    12051534 :             scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind1 + ( DELTA_COH - 1 ) + len_x] ), 3 ) ) ); // Q12
    1749    12051534 :             move16();
    1750             :             /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/
    1751             : 
    1752    12051534 :             pt_cor3 += sec_length1[j];
    1753    12051534 :             pt_cor3_exp += sec_length1[j];
    1754    12051534 :             offset1 = add( offset1, sec_length1[j] );
    1755             : 
    1756             :         } /* FOR j < NSECT */
    1757             :     }     /* FOR i < NHFR */
    1758             : 
    1759             :     /*-----------------------------------------------------------------*
    1760             :      * Favor a smaller delay if it happens that it has its multiple
    1761             :      * in the longer-delay sections  (harmonics check)
    1762             :      *-----------------------------------------------------------------*/
    1763             : 
    1764     3387000 :     FOR( i = 0; i < 2; i++ ) /* loop for the 2 half-frames */
    1765             :     {
    1766     2258000 :         fac = THRES0;
    1767     2258000 :         move16();
    1768     2258000 :         find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
    1769     2258000 :         find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1770     2258000 :         test();
    1771     2258000 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
    1772             :         {
    1773     1260356 :             find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1774             :         }
    1775     2258000 :         fac = THRES0;
    1776     2258000 :         move16();
    1777     2258000 :         find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
    1778     2258000 :         find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1779     2258000 :         test();
    1780     2258000 :         IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
    1781             :         {
    1782     1260356 :             find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1783             :         }
    1784             :     }
    1785             : 
    1786     1129000 :     fac = THRES0;
    1787     1129000 :     move16();                                                                                                        /* the look-ahead */
    1788     1129000 :     find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
    1789     1129000 :     find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1790     1129000 :     test();
    1791     1129000 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
    1792             :     {
    1793      630178 :         find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1794             :     }
    1795     1129000 :     fac = THRES0;
    1796     1129000 :     move16();
    1797     1129000 :     find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, 2, 2 );         /* Multiples in 3rd section */
    1798     1129000 :     find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
    1799     1129000 :     test();
    1800     1129000 :     IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
    1801             :     {
    1802      630178 :         find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ /* Multiples in 2nd section */
    1803             :     }
    1804             : 
    1805             :     /*-----------------------------------------------------------------*
    1806             :      * Do 1st estimate for pitch values
    1807             :      * Adjust the normalized correlation using estimated noise level
    1808             :      * Compute the maximum scaling for the neighbour correlation
    1809             :      * reinforcement
    1810             :      *-----------------------------------------------------------------*/
    1811     1129000 :     add_sect0 = add( NSECT, sect0 );
    1812     1129000 :     sub_sect0 = sub( NSECT, sect0 );
    1813     4516000 :     FOR( i = 0; i < NHFR; i++ )
    1814             :     {
    1815             :         /* 1st set of pitch candidates */
    1816     3387000 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
    1817     3387000 :         ind_tmp[i] = ind;
    1818     3387000 :         move16();
    1819     3387000 :         pitch_tmp[i] = pitchX[i][ind];
    1820     3387000 :         move16();
    1821     3387000 :         cor_tmp[i] = add_o( corX[i][ind], corr_shift, &Overflow );
    1822     3387000 :         move16();
    1823             : 
    1824             :         /* Higher is the neighbour's correlation, higher is the weighting */
    1825             :         /* operands are Q15, result is Q15 */
    1826     3387000 :         thres1[i] = mult( THRES1, cor_tmp[i] );
    1827     3387000 :         move16();
    1828             : 
    1829             :         /* 2nd set of pitch candidates */
    1830     3387000 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
    1831     3387000 :         ind_tmp[i + NHFR] = ind1;
    1832     3387000 :         move16();
    1833     3387000 :         pitch_tmp[i + NHFR] = pitchX[i][ind1];
    1834     3387000 :         move16();
    1835     3387000 :         cor_tmp[i + NHFR] = add_o( corX[i][ind1], corr_shift, &Overflow );
    1836     3387000 :         move16();
    1837             : 
    1838             :         /* Higher is the neighbour's correlation, higher is the weighting */
    1839             :         /* operands are Q15, result is Q15 */
    1840     3387000 :         thres1[i + NHFR] = mult( THRES1, cor_tmp[i + NHFR] );
    1841     3387000 :         move16();
    1842             :     }
    1843             :     /*-----------------------------------------------------------------*
    1844             :      * Take into account previous and next pitch values of the present
    1845             :      * frame and look-ahead. Choose the pitch lags and normalize
    1846             :      * correlations for each half-frame & look-ahead
    1847             :      *-----------------------------------------------------------------*/
    1848             : 
    1849     1129000 :     pitch_neighbour_fx( sect0, pitch_tmp, pitchX, cor_tmp, scaledX, thres1, ind_tmp );
    1850     4516000 :     FOR( i = 0; i < NHFR; i++ )
    1851             :     {
    1852     3387000 :         ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
    1853     3387000 :         ind_corX = add( maximum_fx( corX[i] + sect0, sub_sect0, &ftmp ), sect0 );
    1854             : 
    1855     3387000 :         ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
    1856     3387000 :         ind1_corX = add( maximum_fx( corX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
    1857             : 
    1858     3387000 :         if ( GT_16( scaledX[i][ind1], scaledX[i][ind] ) )
    1859             :         {
    1860     1340249 :             ind = ind1;
    1861     1340249 :             move16();
    1862             :         }
    1863     3387000 :         test();
    1864     3387000 :         if ( Opt_SC_VBR && GT_16( corX[i][ind1_corX], corX[i][ind_corX] ) )
    1865             :         {
    1866           0 :             ind_corX = ind1_corX;
    1867           0 :             move16();
    1868             :         }
    1869     3387000 :         test();
    1870     3387000 :         test();
    1871     3387000 :         test();
    1872     3387000 :         IF( Opt_SC_VBR && ( LT_16( mult( pitchX[i][ind], 13107 /*0.4 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
    1873             :             ( GT_16( mult( pitchX[i][ind], 19661 /*0.6 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
    1874             :             ( GE_16( corX[i][ind_corX], 29491 /*0.9 in Q15*/ ) ) )
    1875             :         {
    1876           0 :             pitch[i] = pitchX[i][ind_corX];
    1877           0 :             move16();
    1878           0 :             voicing[i] = corX[i][ind_corX];
    1879           0 :             move16();
    1880             :         }
    1881             :         ELSE
    1882             :         {
    1883     3387000 :             pitch[i] = pitchX[i][ind];
    1884     3387000 :             move16();
    1885     3387000 :             voicing[i] = corX[i][ind];
    1886     3387000 :             move16();
    1887             :         }
    1888             :     }
    1889             : 
    1890             :     /*-----------------------------------------------------------------*
    1891             :      * Increase the threshold for correlation reinforcement with
    1892             :      * the past if correlation high and pitch stable
    1893             :      *-----------------------------------------------------------------*/
    1894             : 
    1895             :     /* all Q15 here */
    1896             :     /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */
    1897     1129000 :     Ltmp = L_mult( voicing[0], 16384 /*.5 Q15*/ );
    1898     1129000 :     Ltmp = L_mac( Ltmp, voicing[1], 16384 /*.5 Q15*/ );
    1899     1129000 :     cor_mean = round_fx( L_add( Ltmp, corr_shift ) );
    1900             : 
    1901             :     /* pitch unstable in present frame or from previous frame or normalized correlation too low */
    1902     1129000 :     coh_flag = pitch_coherence_fx( pitch[0], pitch[1], COH_FAC, DELTA_COH );
    1903     1129000 :     move16();
    1904     1129000 :     coh_flag1 = pitch_coherence_fx( pitch[0], *old_pitch, COH_FAC, DELTA_COH );
    1905     1129000 :     move16();
    1906             : 
    1907     1129000 :     test();
    1908     1129000 :     test();
    1909     1129000 :     test();
    1910     1129000 :     IF( ( coh_flag == 0 ) || ( coh_flag1 == 0 ) || ( LT_16( cor_mean, CORR_TH0 ) ) || ( LT_16( relE, THR_relE ) ) )
    1911             :     {
    1912             :         /* Reset the threshold */
    1913      624607 :         *old_thres = 0;
    1914      624607 :         move16();
    1915             :     }
    1916             :     ELSE
    1917             :     {
    1918             :         /* The threshold increase is directly dependent on normalized correlation */
    1919             :         /* *old_thres += (0.16f * cor_mean); */
    1920      504393 :         *old_thres = round_fx( L_mac0( L_deposit_h( *old_thres ), 5243 /* 0.16f in Q15 */, cor_mean ) ); // Q14
    1921      504393 :         move16();
    1922             :     }
    1923             : 
    1924     1129000 :     *old_thres = s_min( *old_thres, 11469 /* 0.7f in Q14 */ ); // Q14
    1925     1129000 :     move16();
    1926             : 
    1927     1129000 :     IF( GT_16( voicing[1], voicing[0] ) )
    1928             :     {
    1929      537079 :         *old_corr = voicing[1];
    1930      537079 :         move16();
    1931             :     }
    1932             :     ELSE
    1933             :     {
    1934      591921 :         *old_corr = cor_mean;
    1935      591921 :         move16();
    1936             :     }
    1937             : 
    1938             :     /*-----------------------------------------------------------------*
    1939             :      * Extrapolate the pitch value for the next frame by estimating
    1940             :      * the pitch evolution. This value is added to the old_pitch
    1941             :      * in the next frame and is then used when the normalized
    1942             :      * correlation is reinforced by the past estimate
    1943             :      *-----------------------------------------------------------------*/
    1944     1129000 :     tmp_buf[0] = *old_pitch;
    1945     1129000 :     move16();
    1946     4516000 :     FOR( i = 0; i < NHFR; i++ )
    1947             :     {
    1948     3387000 :         tmp_buf[i + 1] = pitch[i];
    1949     3387000 :         move16();
    1950             :     }
    1951             : 
    1952     1129000 :     *delta_pit = 0;
    1953     1129000 :     move16();
    1954     1129000 :     cnt = 0;
    1955     1129000 :     move16();
    1956             : 
    1957     4516000 :     FOR( i = 0; i < NHFR; i++ )
    1958             :     {
    1959     3387000 :         diff = sub( tmp_buf[i + 1], tmp_buf[i] );
    1960     3387000 :         move16();
    1961     3387000 :         coh_flag = pitch_coherence_fx( tmp_buf[i], tmp_buf[i + 1], COH_FAC, DELTA_COH );
    1962             : 
    1963     3387000 :         if ( coh_flag != 0 )
    1964             :         {
    1965     2468316 :             *delta_pit = add( *delta_pit, diff );
    1966     2468316 :             move16();
    1967             :         }
    1968     3387000 :         cnt = add( cnt, coh_flag );
    1969             :     }
    1970     1129000 :     if ( EQ_16( cnt, 2 ) )
    1971             :     {
    1972             :         /* *delta_pit /= 2; */
    1973      273523 :         *delta_pit = shr( *delta_pit, 1 );
    1974      273523 :         move16();
    1975             :     }
    1976     1129000 :     IF( EQ_16( cnt, 3 ) )
    1977             :     {
    1978      579988 :         k = *delta_pit;
    1979      579988 :         move16();
    1980             :         /* *delta_pit /= 3; */
    1981      579988 :         if ( k < 0 )
    1982             :         {
    1983      134877 :             *delta_pit = mult( *delta_pit, -32768 /*-1 Q15*/ );
    1984      134877 :             move16();
    1985             :         }
    1986      579988 :         tmp16 = mult( *delta_pit, 10923 /*1/3 Q15*/ );
    1987      579988 :         if ( k < 0 )
    1988             :         {
    1989      134877 :             tmp16 = mult( tmp16, -32768 /*-1 Q15*/ );
    1990             :         }
    1991      579988 :         *delta_pit = tmp16;
    1992      579988 :         move16();
    1993             :     }
    1994             : 
    1995             :     /*--------------------------------------------------------------*
    1996             :      * Update old pitch, upsample pitch,
    1997             :      *--------------------------------------------------------------*/
    1998             : 
    1999     1129000 :     *old_pitch = pitch[1];
    2000     1129000 :     move16();
    2001             : 
    2002     4516000 :     FOR( i = 0; i < NHFR; i++ )
    2003             :     {
    2004             :         /* compensate decimation */
    2005     3387000 :         pitch[i] = i_mult2( pitch[i], OPL_DECIM );
    2006     3387000 :         move16();
    2007             :     }
    2008             : 
    2009     1129000 :     return;
    2010             : }
    2011             : 
    2012             : 
    2013             : /*-----------------------------------------------------------------*
    2014             :  * find_mult_fx
    2015             :  *
    2016             :  * Verifies whether max pitch delays in higher sections have multiples
    2017             :  * in lower sections
    2018             :  *-----------------------------------------------------------------*/
    2019    17377146 : static void find_mult_fx(
    2020             :     Word16 *fac,       /* i/o: correlation scaling factor Q12              */
    2021             :     Word16 pitch0,     /* i  : pitch of max correlation in the c section   */
    2022             :     Word16 pitch1,     /* i  : pitch of max correlation in the longer-delay section*/
    2023             :     Word16 pit_max0,   /* i  : max pitch delay in the longer-delay section */
    2024             :     Word16 *corr,      /* i/o: max correlation in the shorter-delay section Q12    */
    2025             :     Word16 *old_pitch, /* i  : pitch from previous frame                   */
    2026             :     Word16 *old_corr,  /* i  : max correlation from previous frame         */
    2027             :     Word16 delta,      /* i  : initial multiples search range              */
    2028             :     Word16 step        /* i  : increment in range of multiples search      */
    2029             : )
    2030             : {
    2031             :     Word16 pit_min;
    2032             :     Word32 L_tmp;
    2033             : 
    2034    17377146 :     pit_min = shl( pitch0, 1 ); /* double the higher section pitch */
    2035             : 
    2036    38240712 :     WHILE( LE_16( pit_min, add( pit_max0, delta ) ) ) /* check for section boundary */
    2037             :     {
    2038    20863566 :         IF( LE_16( abs_s( sub( pit_min, pitch1 ) ), delta ) ) /* if multiple in the allowed range */
    2039             :         {
    2040     6260780 :             L_tmp = L_shl( L_mult( *corr, *fac ), 3 );
    2041             : 
    2042             :             /* if ( *old_corr < 0.6f || (float)pitch0 > (float)*old_pitch * 0.4f ) */
    2043     6260780 :             IF( s_max( sub( 19660 /*.6 Q15*/, *old_corr ), sub( pitch0, mult( *old_pitch, 13107 /*.4 Q15*/ ) ) ) > 0 )
    2044             :             {
    2045             :                 /* reinforce the normalized correlation */
    2046             :                 /* operands are Q12, result is Q12 */
    2047     5790995 :                 *corr = extract_h( L_tmp );
    2048             :             }
    2049             :             /* operands are Q12, result is Q12 */
    2050     6260780 :             *fac = extract_h( L_shl( L_mult( *fac, THRES0 ), 3 ) );
    2051             :         }
    2052    20863566 :         pit_min = add( pit_min, pitch0 ); /* next multiple */
    2053    20863566 :         delta = add( delta, step );       /* the incertitude to the allowed range */
    2054             :     }
    2055    17377146 : }
    2056             : 
    2057             : /*---------------------------------------------------------------------------*
    2058             :  * pitch_neighbour_fx
    2059             :  *
    2060             :  * Verifies if the maximum correlation pitch lag is coherent with neighbour
    2061             :  * values
    2062             :  *---------------------------------------------------------------------------*/
    2063     1132100 : static void pitch_neighbour_fx(
    2064             :     Word16 sect0,               /* i  : indicates whether section 0 (below PIT_MIN) is used       */
    2065             :     Word16 pitch_tmp[],         /* i  : estimated pitch values for each half-frame & look-ahead   */
    2066             :     Word16 pitch[3][2 * NSECT], /* i  : tested pitch values for each half-frame & look-ahead      */
    2067             :     Word16 corr_tmp[],          /* i  : raw normalized correlation (before different scalings) Q15*/
    2068             :     Word16 corr[3][2 * NSECT],  /* i/o: normalized correlation for each half-frame & look-ahead Q12 */
    2069             :     Word16 thres1[2 * NHFR],    /* i  : maximum scaling for the immediate neighbours Q15          */
    2070             :     Word16 ind_tmp[2 * NHFR]    /* i  : best section index for each half-frame & look-ahead       */
    2071             : )
    2072             : {
    2073             :     Word16 delta, i, j, k, K, coh_flag, fac;
    2074             : 
    2075             :     /*---------------------
    2076             :      * 1st set of sections
    2077             :      ---------------------*/
    2078     5160391 :     FOR( k = sect0; k < NSECT; k++ ) /* loop for each section */
    2079             :     {
    2080     4028291 :         K = 3;
    2081     4028291 :         move16();
    2082     4028291 :         if ( EQ_16( k, ( NSECT - 1 ) ) ) /* the number of tests depends on the section */
    2083             :         {
    2084     1132100 :             K = 2;
    2085     1132100 :             move16();
    2086             :         }
    2087             :         /*pt = &pitch[i][k] and pt = &corr[i][k]*/
    2088    14981064 :         FOR( i = 0; i < K; i++ ) /* for the 2 half-frames and look-ahead */
    2089             :         {
    2090             :             /* Compare pitch values of the present frame */
    2091    41546892 :             FOR( j = 0; j < K; j++ ) /* Verify pitch coherence with neighbours (including past pitch) */
    2092             :             {
    2093    30594119 :                 IF( NE_16( j, i ) ) /* Exclude itself, of course */
    2094             :                 {
    2095    19641346 :                     IF( GE_16( corr_tmp[j], CORR_TH1 ) ) /* reinforcement can happen only if the correlation is high enough */
    2096             :                     {
    2097    14633506 :                         delta = abs_s( sub( pitch[i][k], pitch_tmp[j] ) ); /* Find difference of pitch values */
    2098    14633506 :                         coh_flag = pitch_coherence_fx( pitch[i][k], pitch_tmp[j], COH_FAC, DELTA_COH );
    2099             : 
    2100    14633506 :                         IF( coh_flag != 0 )
    2101             :                         {
    2102             :                             /* Favour stability across sections, favour closer values */
    2103     5277084 :                             IF( EQ_16( ind_tmp[j], k ) )
    2104             :                             {
    2105             :                                 /* corr[i][k] *= ( -thres1[j]/DELTA1 * delta + thres1[j]+1 ); */
    2106             :                                 /* operands are Q15, except corr[i][k] which is Q12 */
    2107     3993395 :                                 fac = mult( negate( thres1[j] ), MAX_16 / DELTA_COH );
    2108     3993395 :                                 fac = add( i_mult2( fac, delta ), thres1[j] );
    2109             :                             }
    2110             :                             ELSE
    2111             :                             {
    2112             :                                 /* corr[i][k] *= ( -thres1[j]/DELTA1 * 0.625f * delta + 0.625f * thres1[j] +1.0f ); */
    2113     1283689 :                                 fac = mult( negate( thres1[j] ), 20479 / DELTA_COH );
    2114     1283689 :                                 fac = add( i_mult2( fac, delta ), mult( 20479 /*.625 Q15*/, thres1[j] ) );
    2115             :                             }
    2116     5277084 :                             corr[i][k] = add_sat( corr[i][k], mult( fac, corr[i][k] ) );
    2117     5277084 :                             move16();
    2118             :                         }
    2119             :                     }
    2120             :                 }
    2121             :             }
    2122             :         }
    2123             :     }
    2124             : 
    2125             :     /*---------------------
    2126             :      * 2nd set of sections
    2127             :      ---------------------*/
    2128     5160391 :     FOR( k = sect0; k < NSECT; k++ ) /* loop for each section */
    2129             :     {
    2130     4028291 :         K = 3;
    2131     4028291 :         move16();
    2132     4028291 :         if ( EQ_16( k, ( NSECT - 1 ) ) ) /* the number of tests depends on the section */
    2133             :         {
    2134     1132100 :             K = 2;
    2135     1132100 :             move16();
    2136             :         }
    2137             :         /*pt = &pitch[i][k] and pt = &corr[i][k]*/
    2138    14981064 :         FOR( i = 0; i < K; i++ ) /* BRANCH(1); for the 2 half-frames and look-ahead */
    2139             :         {
    2140             :             /* Compare pitch values of the present frame */
    2141    41546892 :             FOR( j = 0; j < K; j++ ) /* Verify pitch coherence with neighbours (including past pitch) */
    2142             :             {
    2143    30594119 :                 IF( NE_16( j, i ) ) /* Exclude itself, of course */
    2144             :                 {
    2145    19641346 :                     IF( GE_16( corr_tmp[j + NHFR], CORR_TH1 ) ) /* reinforcement can happen only if the correlation is high enough */
    2146             :                     {
    2147    14316901 :                         delta = abs_s( sub( pitch[i][NSECT + k], pitch_tmp[j + NHFR] ) ); /* Find difference of pitch values */
    2148    14316901 :                         coh_flag = pitch_coherence_fx( pitch[i][NSECT + k], pitch_tmp[j + NHFR], COH_FAC, DELTA_COH );
    2149             : 
    2150    14316901 :                         IF( coh_flag != 0 )
    2151             :                         {
    2152             :                             /* Favour stability across sections, favour closer values */
    2153     5394646 :                             IF( EQ_16( ind_tmp[j + NHFR], add( NSECT, k ) ) )
    2154             :                             {
    2155             :                                 /* corr[i][k] *= ( -thres1[j+NHFR]/DELTA1 * delta + thres1[j+NHFR]+1 ); */
    2156             :                                 /* operands are Q15, except corr[i][NSECT+k] which is Q12 */
    2157     4091497 :                                 fac = mult( negate( thres1[j + NHFR] ), MAX_16 / DELTA_COH );
    2158     4091497 :                                 fac = add( extract_l( L_shr( L_mult( fac, delta ), 1 ) ), thres1[j + NHFR] );
    2159     4091497 :                                 corr[i][NSECT + k] = add_sat( corr[i][NSECT + k], mult( fac, corr[i][NSECT + k] ) );
    2160     4091497 :                                 move16();
    2161             :                             }
    2162             :                             ELSE
    2163             :                             {
    2164             :                                 /* corr[i][k] *= ( -thres1[j+NHFR]/DELTA1 * 0.625f * delta + 0.625f * thres1[j+NHFR] +1.0f ); */
    2165     1303149 :                                 fac = mult( negate( thres1[j + NHFR] ), 20479 / DELTA_COH );
    2166     1303149 :                                 fac = add( extract_l( L_shr( L_mult( fac, delta ), 1 ) ), mult( 20479, thres1[j + NHFR] ) );
    2167     1303149 :                                 corr[i][NSECT + k] = add( corr[i][NSECT + k], mult( fac, corr[i][NSECT + k] ) );
    2168     1303149 :                                 move16();
    2169             :                             }
    2170             :                         }
    2171             :                     }
    2172             :                 }
    2173             :             }
    2174             :         }
    2175             :     }
    2176     1132100 : }
    2177             : 
    2178             : /*-----------------------------------------------------------------*
    2179             :  * pitch_coherence_fx
    2180             :  *
    2181             :  * Verify if pitch evolution is smooth
    2182             :  *-----------------------------------------------------------------*/
    2183    34610907 : static Word16 pitch_coherence_fx(
    2184             :     Word16 pitch0,  /* i  : first pitch to compare        */
    2185             :     Word16 pitch1,  /* i  : 2nd pitch to compare          */
    2186             :     Word16 fac_max, /* i  : max ratio of both values Q12  */
    2187             :     Word16 diff_max /* i  : max difference of both values */
    2188             : )
    2189             : {
    2190             :     Word16 smaller, larger;
    2191             :     Word16 pc;
    2192             : 
    2193    34610907 :     smaller = s_min( pitch0, pitch1 );
    2194    34610907 :     larger = s_max( pitch0, pitch1 );
    2195             : 
    2196    34610907 :     pc = 0;
    2197    34610907 :     move16();
    2198    34610907 :     test();
    2199    49951657 :     if ( ( LE_16( larger, extract_h( L_shl( L_mult( fac_max, smaller ), 3 ) ) ) ) && /* Changed to <= to keep BE */
    2200    15340750 :          ( LT_16( sub( larger, smaller ), diff_max ) ) )
    2201             :     {
    2202    14733977 :         pc = 1;
    2203    14733977 :         move16();
    2204             :     }
    2205             : 
    2206    34610907 :     return pc;
    2207             : }
    2208             : 
    2209             : /*-----------------------------------------------------------------*
    2210             :  * LP_Decim2_Copy:
    2211             :  *
    2212             :  * Decimate a vector by 2 with 2nd order fir filter.
    2213             :  *-----------------------------------------------------------------*/
    2214     2264200 : static void LP_Decim2_Copy(
    2215             :     const Word16 x[], /* i:   signal to process */
    2216             :     Word16 y[],       /* o:   signal to process */
    2217             :     Word16 l,         /* i  : size of filtering */
    2218             :     Word16 mem[]      /* i/o: memory (size=3)   */
    2219             : )
    2220             : {
    2221             :     Word16 *p_x, x_buf[L_FRAME + L_MEM];
    2222             :     Word16 i, j, k;
    2223             :     Word32 L_tmp;
    2224             : 
    2225             :     /* copy initial filter states into buffer */
    2226     2264200 :     p_x = x_buf;
    2227     9056800 :     FOR( i = 0; i < L_MEM; i++ )
    2228             :     {
    2229     6792600 :         *p_x++ = mem[i];
    2230     6792600 :         move16();
    2231             :     }
    2232   418877000 :     FOR( i = 0; i < l; i++ )
    2233             :     {
    2234   416612800 :         *p_x++ = x[i];
    2235   416612800 :         move16();
    2236             :     }
    2237     2264200 :     if ( s_and( l, 1 ) ) /* Fix for valgrind error in case l is odd. Anyway this function will be removed. */
    2238             :     {
    2239           0 :         *p_x = *( p_x - 1 );
    2240           0 :         move16();
    2241             :     }
    2242             : 
    2243     9056800 :     FOR( i = 0; i < L_MEM; i++ )
    2244             :     {
    2245     6792600 :         mem[i] = x[l - L_MEM + i];
    2246     6792600 :         move16();
    2247             :     }
    2248     2264200 :     p_x = x_buf;
    2249     2264200 :     j = 0;
    2250     2264200 :     move16();
    2251   210570600 :     FOR( i = 0; i < l; i += 2 )
    2252             :     {
    2253   208306400 :         L_tmp = L_mult( *p_x, h_fir_fx[0] );
    2254  1041532000 :         FOR( k = 1; k < L_FIR_PO; k++ )
    2255             :         {
    2256   833225600 :             L_tmp = L_mac( L_tmp, p_x[k], h_fir_fx[k] );
    2257             :         }
    2258   208306400 :         p_x += 2;
    2259             : 
    2260   208306400 :         y[j++] = round_fx( L_tmp );
    2261   208306400 :         move16();
    2262             :     }
    2263     2264200 : }
    2264             : /*---------------------------------------------------------------------*
    2265             :  * Dot_product12_OL
    2266             :  *
    2267             :  * two different length dot products of x and y
    2268             :  *---------------------------------------------------------------------*/
    2269      619060 : static Word32 Dot_product12_OL(                   /* o  : Q31: normalized result (1 < val <= -1) */
    2270             :                                 Word16 *sum1,     /* o  : Q31: normalized result 2 */
    2271             :                                 const Word16 x[], /* i  : 12bits: x vector */
    2272             :                                 const Word16 y[], /* i  : 12bits: y vector */
    2273             :                                 const Word16 lg,  /* i  : vector length */
    2274             :                                 const Word16 lg2, /* i  : vector length 2 */
    2275             :                                 Word16 *exp,      /* o  : exponent of result (0..+30) */
    2276             :                                 Word16 *exp2      /* o  : exponent of result 2 (0..+30) */
    2277             : )
    2278             : {
    2279             :     Word16 i, sft;
    2280             :     Word32 L_sum, L_sum2;
    2281             : 
    2282      619060 :     L_sum = L_mac( 1, x[0], y[0] );
    2283      619060 :     IF( LE_16( lg, lg2 ) )
    2284             :     {
    2285    39096800 :         FOR( i = 1; i < lg; i++ )
    2286             :         {
    2287    38632740 :             L_sum = L_mac( L_sum, x[i], y[i] );
    2288             :         }
    2289             :         /* sets to 'L_sum' in 1 clock */
    2290      464060 :         L_sum2 = L_sum;
    2291      464060 :         move32();
    2292     3427660 :         FOR( ; i < lg2; i++ )
    2293             :         {
    2294     2963600 :             L_sum2 = L_mac( L_sum2, x[i], y[i] );
    2295             :         }
    2296             :     }
    2297             :     ELSE
    2298             :     {
    2299    10726000 :         FOR( i = 1; i < lg2; i++ )
    2300             :         {
    2301    10571000 :             L_sum = L_mac( L_sum, x[i], y[i] );
    2302             :         }
    2303             :         /* sets to 'L_sum' in 1 clock */
    2304      155000 :         L_sum2 = L_sum;
    2305      155000 :         move32();
    2306     4296600 :         FOR( ; i < lg; i++ )
    2307             :         {
    2308     4141600 :             L_sum = L_mac( L_sum, x[i], y[i] );
    2309             :         }
    2310             :     }
    2311             : 
    2312             :     /* Q31 */
    2313      619060 :     sft = norm_l( L_sum );
    2314      619060 :     L_sum = L_shl( L_sum, sft );
    2315      619060 :     *exp = sub( 30, sft );
    2316      619060 :     move16(); /* exponent = 0..30 */
    2317             : 
    2318      619060 :     sft = norm_l( L_sum2 );
    2319      619060 :     L_sum2 = L_shl( L_sum2, sft );
    2320      619060 :     *exp2 = sub( 30, sft );
    2321      619060 :     move16(); /* exponent = 0..30 */
    2322             : 
    2323      619060 :     *sum1 = extract_h( L_shr( L_sum2, 1 ) );
    2324      619060 :     move16();
    2325      619060 :     return L_sum;
    2326             : }
    2327             : 
    2328             : /*---------------------------------------------------------------------*
    2329             :  * Dot_product12_OL_back()
    2330             :  *
    2331             :  * two different length dot products of x and y, computed backward
    2332             :  *---------------------------------------------------------------------*/
    2333      309530 : static Word32 Dot_product12_OL_back(                   /* o  : Q31: normalized result (1 < val <= -1) */
    2334             :                                      Word16 *sum1,     /* o  : Q31: normalized result 2 */
    2335             :                                      const Word16 x[], /* i  : 12bits: x vector */
    2336             :                                      const Word16 y[], /* i  : 12bits: y vector */
    2337             :                                      const Word16 lg,  /* i  : vector length */
    2338             :                                      const Word16 lg2, /* i  : vector length 2 */
    2339             :                                      Word16 *exp,      /* o  : exponent of result (0..+30) */
    2340             :                                      Word16 *exp2      /* o  : exponent of result 2 (0..+30) */
    2341             : )
    2342             : {
    2343             :     Word16 i, sft;
    2344             :     Word32 L_sum, L_sum2;
    2345             : 
    2346      309530 :     L_sum = L_mac( 1, x[0], y[0] );
    2347      309530 :     IF( LE_16( lg, lg2 ) )
    2348             :     {
    2349    19548400 :         FOR( i = 1; i < lg; i++ )
    2350             :         {
    2351    19316370 :             L_sum = L_mac( L_sum, x[-i], y[-i] );
    2352             :         }
    2353             :         /* sets to 'L_sum' in 1 clock */
    2354      232030 :         L_sum2 = L_sum;
    2355      232030 :         move32();
    2356     1713830 :         FOR( ; i < lg2; i++ )
    2357             :         {
    2358     1481800 :             L_sum2 = L_mac( L_sum2, x[-i], y[-i] );
    2359             :         }
    2360             :     }
    2361             :     ELSE
    2362             :     {
    2363     5363000 :         FOR( i = 1; i < lg2; i++ )
    2364             :         {
    2365     5285500 :             L_sum = L_mac( L_sum, x[-i], y[-i] );
    2366             :         }
    2367             :         /* sets to 'L_sum' in 1 clock */
    2368       77500 :         L_sum2 = L_sum;
    2369       77500 :         move32();
    2370     2148300 :         FOR( ; i < lg; i++ )
    2371             :         {
    2372     2070800 :             L_sum = L_mac( L_sum, x[-i], y[-i] );
    2373             :         }
    2374             :     }
    2375             : 
    2376             :     /* Q31 */
    2377      309530 :     sft = norm_l( L_sum );
    2378      309530 :     L_sum = L_shl( L_sum, sft );
    2379      309530 :     *exp = sub( 30, sft );
    2380      309530 :     move16(); /* exponent = 0..30 */
    2381             : 
    2382      309530 :     sft = norm_l( L_sum2 );
    2383      309530 :     L_sum2 = L_shl( L_sum2, sft );
    2384      309530 :     *exp2 = sub( 30, sft );
    2385      309530 :     move16(); /* exponent = 0..30 */
    2386             : 
    2387      309530 :     *sum1 = extract_h( L_shr( L_sum2, 1 ) );
    2388      309530 :     move16();
    2389      309530 :     return L_sum;
    2390             : }
    2391             : 
    2392           0 : void pitchDoubling_det_fx(
    2393             :     Word16 *wspeech,
    2394             :     Word16 *pitch_ol,
    2395             :     Word16 *T_op_fr,
    2396             :     Word16 *voicing_fr )
    2397             : {
    2398             :     Word16 new_op_fr[2];
    2399             :     Word16 new_voicing[2];
    2400             :     Word16 new_Top[2];
    2401             :     Word16 m, T;
    2402             : 
    2403             : 
    2404             :     /*save initial values*/
    2405             : 
    2406           0 :     new_Top[0] = pitch_ol[0];
    2407           0 :     move16();
    2408           0 :     new_Top[1] = pitch_ol[1];
    2409           0 :     move16();
    2410             : 
    2411           0 :     FOR( m = 2; m < 5; m++ )
    2412             :     {
    2413             : 
    2414             :         /* T= pitch_ol[0]/m; */
    2415           0 :         T = mult( pitch_ol[0], One_div_fx[m - 1] );
    2416             : 
    2417           0 :         IF( GE_16( T, PIT_MIN_12k8 ) )
    2418             :         {
    2419           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[0] ), &new_voicing[0], 0, wspeech, 2 );
    2420           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[1] ), &new_voicing[1], L_SUBFR, wspeech, 2 );
    2421             :             /* IF(sub(add(new_voicing[0],new_voicing[1]),add(voicing_fr[0],voicing_fr[1]))>0 */
    2422           0 :             IF( L_msu( L_msu( L_mac( L_mult( new_voicing[0], 8192 ), new_voicing[1], 8192 ), voicing_fr[0], 8192 ), voicing_fr[1], 8192 ) > 0 )
    2423             :             {
    2424           0 :                 new_Top[0] = T;
    2425           0 :                 move16();
    2426           0 :                 T_op_fr[0] = new_op_fr[0];
    2427           0 :                 move16();
    2428           0 :                 T_op_fr[1] = new_op_fr[1];
    2429           0 :                 move16();
    2430           0 :                 voicing_fr[0] = new_voicing[0];
    2431           0 :                 move16();
    2432           0 :                 voicing_fr[1] = new_voicing[1];
    2433           0 :                 move16();
    2434             :             }
    2435             :         }
    2436             : 
    2437             :         /* T= pitch_ol[1]/m; */
    2438           0 :         T = mult( pitch_ol[1], One_div_fx[m - 1] );
    2439             : 
    2440           0 :         IF( GE_16( T, PIT_MIN_12k8 ) )
    2441             :         {
    2442           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[0] ), &new_voicing[0], 2 * L_SUBFR, wspeech, 2 );
    2443           0 :             pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[1] ), &new_voicing[1], 3 * L_SUBFR, wspeech, 2 );
    2444             :             /* IF(sub(add(new_voicing[0],new_voicing[1]),add(voicing_fr[2],voicing_fr[3]))>0) */
    2445           0 :             IF( L_msu( L_msu( L_mac( L_mult( new_voicing[0], 8192 ), new_voicing[1], 8192 ), voicing_fr[2], 8192 ), voicing_fr[3], 8192 ) > 0 )
    2446             :             {
    2447           0 :                 new_Top[1] = T;
    2448           0 :                 move16();
    2449           0 :                 T_op_fr[2] = new_op_fr[0];
    2450           0 :                 move16();
    2451           0 :                 T_op_fr[3] = new_op_fr[1];
    2452           0 :                 move16();
    2453           0 :                 voicing_fr[2] = new_voicing[0];
    2454           0 :                 move16();
    2455           0 :                 voicing_fr[3] = new_voicing[1];
    2456           0 :                 move16();
    2457             :             }
    2458             :         }
    2459             :     }
    2460             : 
    2461           0 :     pitch_ol[0] = new_Top[0];
    2462           0 :     move16();
    2463           0 :     pitch_ol[1] = new_Top[1];
    2464           0 :     move16();
    2465             : 
    2466           0 : } /*end of pitch doubling detection*/

Generated by: LCOV version 1.14