LCOV - code coverage report
Current view: top level - lib_enc - ppp_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 0 411 0.0 %
Date: 2025-09-14 03:13:15 Functions: 0 6 0.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 "rom_com_fx.h"
       9             : #include "rom_com.h"     /* Common constants                       */
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "prot_fx_enc.h" /* Function prototypes                    */
      12             : #include "basop_util.h"  /* Function prototypes                    */
      13             : 
      14             : /*-------------------------------------------------------------------*
      15             :  * Local constants
      16             :  *-------------------------------------------------------------------*/
      17             : #define ERB_CBSIZE1 64
      18             : #define ERB_CBSIZE2 64
      19             : #define P_CBSIZE    64
      20             : 
      21             : /*-------------------------------------------------------------------*
      22             :  * Local functions
      23             :  *--------------------------------------------------------------------*/
      24             : static Word16 DTFS_quant_cw_fx( DTFS_STRUCTURE *X_fx, Word16 pl, const Word16 *curr_lpc_fx, Word16 *POWER_IDX, Word16 *AMP_IDX, Word16 *lastLgainE_fx, Word16 *lastHgainE_fx, Word16 *lasterbE_fx, Word16 *sin_tab, Word16 *cos_tab );
      25             : static Word16 DTFS_alignment_fine_new_fx( DTFS_STRUCTURE X1_fx, DTFS_STRUCTURE X2_fx, Word16 *S_fx, Word16 *C_fx );
      26             : static void erb_diff_fx( const Word16 *prev_erb, Word16 pl, const Word16 *curr_erb, Word16 l, const Word16 *curr_lsp, Word16 *index, Word16 num_erb );
      27             : 
      28             : 
      29             : /*=======================================================================================*/
      30             : /* FUNCTION      :  ppp_quarter_encoder_fx()                                             */
      31             : /*---------------------------------------------------------------------------------------*/
      32             : /* PURPOSE       :  Quarter rate PPP encoder main routine                                */
      33             : /*---------------------------------------------------------------------------------------*/
      34             : /* INPUT ARGUMENTS  :                                                                    */
      35             : /*   _ (Word16 []) curr_lpc_fx: LPC coefficients, Q12                                    */
      36             : /*   _ (struct DTFS_STRUCTURE_FX) CURRCW_NQ_FX :  prototype in Cartesian domain          */
      37             : /*                (Word16) lag_fx: length of prototype                                                                   */
      38             : /*                (Word16 []) a/b: harmonics, normalized                                                                 */
      39             : /*                (Word16) Q: norm factor of a                                                                                   */
      40             : /*   _ (struct DTFS_STRUCTURE_FX) PREV_CW_E_FX :  past dtfs in Cartesian domain          */
      41             : /*                (Word16) lag: length of prototype                                                                              */
      42             : /*                (Word16 []) a/b: harmonics, normalized                                                                 */
      43             : /*                (Word16) Q: norm factor of a                                                                                   */
      44             : /*   _ (Word16)   prevCW_lag_fx: Previous lag, Q0                                                                                */
      45             : /*   _ (Word16 *)               exc : Global input (Q0)                                                                                  */
      46             : /*   _ (Word16 []) sinTab, Q15 : sin(2pi/4L*n), n=0,1,...,4L-1                           */
      47             : /*   _ (Word16 []) cosTab, Q15 : cos(2pi/4L*n), n=0,1,...,4L-1                           */
      48             : /*---------------------------------------------------------------------------------------*/
      49             : /* OUTPUT ARGUMENTS :                                                                                    */
      50             : /*   _ (Word16) pidx: Power index                                                                        */
      51             : /*   _ (Word16[]) aidx: Amplitude indices, 2 words                                                       */
      52             : /*   _ (struct DTFS_fx *) CURRCW_Q_FX :  quantized prototype in Cartesian domain                 */
      53             : /*                (Word16) lag_fx: length of prototype in time domain                                    */
      54             : /*                (Word16 []) a/b: harmonics, normalized                                                                 */
      55             : /*                (Word16) Q: norm factor of a                                                                                   */
      56             : /*   _ (struct DTFS_fx *) TARGETCW_FX : Target prototype in Cartesian domain                     */
      57             : /*                (Word16) lag_fx: length of prototype in time domain                                    */
      58             : /*                (Word16 []) a/b: harmonics, normalized                                                                 */
      59             : /*                (Word16) Q: norm factor of a                                           */
      60             : /*---------------------------------------------------------------------------------------*/
      61             : /* INPUT/OUTPUT ARGUMENTS :                                                                                                                              */
      62             : /*   _ (Word16[]) lasterbE_fx: ERB history for differential                              */
      63             : /*                quantization, Q13                                                      */
      64             : /*   _ (Word16) lastLgainE_fx: low band power history, log domain,                                               */
      65             : /*                                                            Q11                        */
      66             : /*   _ (Word16) lastHgainE_fx: high band power history, log domain,                                              */
      67             : /*                                                            Q11                        */
      68             : /*---------------------------------------------------------------------------------------*/
      69             : /* RETURN ARGUMENTS :                                                                    */
      70             : /*   _ (Word16) returnFlag: flag indicating success/failure                                                              */
      71             : /*                   (TRUE/FALSE)                                                        */
      72             : /*---------------------------------------------------------------------------------------*/
      73             : /* CALLED FROM : TX                                                                      */
      74             : /*=======================================================================================*/
      75             : 
      76           0 : ivas_error ppp_quarter_encoder_fx(
      77             :     Word16 *returnFlag,           /* o  : return value                            */
      78             :     DTFS_STRUCTURE *CURRCW_Q_FX,  /* o  : Quantized (amp/phase) DTFS                            */
      79             :     DTFS_STRUCTURE *TARGETCW_FX,  /* o  : DTFS with quant phase but unquant Amp */
      80             :     Word16 prevCW_lag,            /* i  : previous lag                                                  */
      81             :     DTFS_STRUCTURE vCURRCW_NQ_FX, /* i  : Unquantized DTFS                                              */
      82             :     const Word16 *curr_lpc_fx,    /* i  : LPCS                                                                  */
      83             :     Word16 *lastLgainE_fx,        /* i/o: last low band gain                                            */
      84             :     Word16 *lastHgainE_fx,        /* i/o: last high band gain                                           */
      85             :     Word16 *lasterbE_fx,          /* i/o: last ERB vector                                                       */
      86             :     DTFS_STRUCTURE PREV_CW_E_FX,  /* i  : past DTFS                                                             */
      87             :     Word16 *S_fx,                 /* i  : sin table, Q15                          */
      88             :     Word16 *C_fx,                 /* i  : cos table, Q15                          */
      89             :     BSTR_ENC_HANDLE hBstr         /* i/o: encoder bitstream handle                */
      90             : )
      91             : {
      92             :     DTFS_STRUCTURE *PREVDTFS_FX;
      93             :     Word16 tmp_fx, temp_pl_fx, temp_l_fx;
      94             :     Word16 temp;
      95             :     Word16 l;
      96             :     Word16 POWER_IDX_FX;  /* Codebook index for the power quantization for PPP */
      97             :     Word16 AMP_IDX_fx[2]; /* Codebook index for the Amplitude quantization for PPP */
      98           0 :     Word16 Erot_fx = 0;
      99             :     /* Word16 S_fx[PIT_MAX*4+1], C_fx[PIT_MAX*4+1];*/
     100             :     Word32 Ltempd, Ltempn;
     101             :     Word32 L_tmp, L_tmp1;
     102             :     Word16 tmp, exp;
     103             :     ivas_error error;
     104             : 
     105           0 :     error = IVAS_ERR_OK;
     106           0 :     *returnFlag = 1;
     107           0 :     move16();
     108           0 :     move16();
     109           0 :     IF( ( error = DTFS_new_fx( &PREVDTFS_FX ) ) != IVAS_ERR_OK )
     110             :     {
     111           0 :         IVAS_ERROR( error, "Error creating DTFS structure" );
     112             :     }
     113           0 :     DTFS_copy_fx( CURRCW_Q_FX, vCURRCW_NQ_FX );
     114           0 :     DTFS_copy_fx( PREVDTFS_FX, PREV_CW_E_FX );
     115             : 
     116           0 :     l = CURRCW_Q_FX->lag_fx;
     117           0 :     move16();
     118           0 :     temp_l_fx = CURRCW_Q_FX->lag_fx;
     119           0 :     move16();
     120           0 :     temp_pl_fx = prevCW_lag;
     121           0 :     move16();
     122             : 
     123           0 :     DTFS_adjustLag_fx( PREVDTFS_FX, l );
     124             : 
     125             : 
     126             :     /* z = ((L_FRAME-temp_l)*(temp_l+temp_pl))/(2*temp_l*temp_pl); */
     127             :     /* Erot = (float) (temp_l - rint_new(temp_l*(z - floor(z)))); */
     128           0 :     temp = sub( L_FRAME, temp_l_fx ); /*Q0 */
     129           0 :     exp = norm_s( temp_pl_fx );
     130           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), temp_pl_fx ); /*Q(29-exp) */
     131           0 :     L_tmp = L_mult( temp, tmp );                         /*Q(31-exp); +1 due to /2 */
     132           0 :     L_tmp = L_shl( L_tmp, sub( exp, 15 ) );              /*Q16 */
     133             : 
     134           0 :     exp = norm_s( temp_l_fx );
     135           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), temp_l_fx ); /*Q(29-exp) */
     136           0 :     L_tmp1 = L_mult( temp, tmp );                       /*Q(31-exp); +1 due to /2 */
     137           0 :     L_tmp1 = L_shl( L_tmp1, sub( exp, 15 ) );           /*Q16 */
     138             : 
     139           0 :     L_tmp = L_add( L_tmp, L_tmp1 ); /*Q16 */
     140             : 
     141           0 :     tmp = lshr( extract_l( L_tmp ), 1 ); /*Q15 */
     142           0 :     L_tmp = L_mult( temp_l_fx, tmp );    /*Q16 */
     143           0 :     temp = rint_new_fx( L_tmp );
     144           0 :     Erot_fx = sub( temp_l_fx, temp ); /*Q0 */
     145             : 
     146           0 :     GetSinCosTab_fx( CURRCW_Q_FX->lag_fx, S_fx, C_fx ); /*get cos and sin tables for lag */
     147           0 :     Q2phaseShift_fx( PREVDTFS_FX, shl( Erot_fx, 2 ), CURRCW_Q_FX->lag_fx, S_fx, C_fx );
     148             : 
     149           0 :     DTFS_copy_fx( TARGETCW_FX, *CURRCW_Q_FX );
     150             :     /* Amplitude Quantization */
     151           0 :     DTFS_car2pol_fx( CURRCW_Q_FX ); /* at this point currCW_q=curr_nq */
     152             : 
     153             :     /*As the upper cut of freqencies are normalized to 12800, we have to multiply upper cut off freq by
     154             :             2.56(1/12800 in Q15) */
     155           0 :     Ltempn = L_mult( CURRCW_Q_FX->upper_cut_off_freq_fx, 10486 );      /* Q0+Q27 = Q28 */
     156           0 :     CURRCW_Q_FX->upper_cut_off_freq_fx = (Word16) L_shr( Ltempn, 13 ); /*Q15 */
     157           0 :     move16();
     158           0 :     Ltempn = L_mult( CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx, 10486 );      /* Q0+Q27 = Q28 */
     159           0 :     CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx = (Word16) L_shr( Ltempn, 13 ); /*Q15 */
     160           0 :     move16();
     161             : 
     162           0 :     *returnFlag = DTFS_quant_cw_fx( CURRCW_Q_FX, prevCW_lag, curr_lpc_fx, &POWER_IDX_FX,
     163             :                                     AMP_IDX_fx, lastLgainE_fx, lastHgainE_fx, lasterbE_fx, S_fx, C_fx );
     164           0 :     move16();
     165             : 
     166             :     /*De-normalize cut off frequencies */
     167           0 :     Ltempn = L_shl( (Word32) CURRCW_Q_FX->upper_cut_off_freq_fx, 13 ); /*Q28 */
     168           0 :     CURRCW_Q_FX->upper_cut_off_freq_fx = (Word16) find_remd( Ltempn, 20971, &Ltempd );
     169           0 :     move16();
     170           0 :     Ltempn = L_shl( (Word32) CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx, 13 ); /*Q28 */
     171           0 :     CURRCW_Q_FX->upper_cut_off_freq_of_interest_fx = (Word16) find_remd( Ltempn, 20971, &Ltempd );
     172           0 :     move16();
     173             : 
     174           0 :     push_indice( hBstr, IND_AMP0, AMP_IDX_fx[0], 6 );
     175           0 :     push_indice( hBstr, IND_AMP1, AMP_IDX_fx[1], 6 );
     176           0 :     push_indice( hBstr, IND_POWER, POWER_IDX_FX, 6 );
     177             : 
     178             :     /*Phase copying is done through copy_phase instead of car2pol and pol2car */
     179           0 :     copy_phase_fx( TARGETCW_FX, *CURRCW_Q_FX, TARGETCW_FX );
     180             :     /*Phase copying is done through copy_phase instead of car2pol and pol2car */
     181           0 :     copy_phase_fx( PREVDTFS_FX, *CURRCW_Q_FX, CURRCW_Q_FX );
     182             :     /* Copying phase spectrum over */
     183             :     /*mvr2r(PREVDTFS->b, CURRCW_Q->b, (short)(CURRCW_Q->lag>>1)+1 ); */
     184             : 
     185             :     /*DTFS_pol2car(CURRCW_Q); */
     186             :     /*DTFS_pol2car(TARGETCW); */
     187             : 
     188           0 :     tmp_fx = DTFS_alignment_fine_new_fx( *TARGETCW_FX, *CURRCW_Q_FX, S_fx, C_fx );
     189             : 
     190           0 :     test();
     191           0 :     IF( GT_16( tmp_fx, 28 - 12 ) || LT_16( tmp_fx, -12 ) )
     192             :     {
     193           0 :         tmp_fx = 0;
     194           0 :         move16();
     195           0 :         *returnFlag = 0;
     196           0 :         move16();
     197             :     }
     198             : 
     199             :     /*DTFS_phaseShift( CURRCW_Q,(float)(PI2*tmp/CURRCW_Q->lag) ); */
     200           0 :     Q2phaseShift_fx( CURRCW_Q_FX, tmp_fx, CURRCW_Q_FX->lag_fx, S_fx, C_fx );
     201             : 
     202           0 :     push_indice( hBstr, IND_GLOBAL_ALIGNMENT, shr( add( tmp_fx, 12 ), 2 ), 3 );
     203             : 
     204           0 :     free( PREVDTFS_FX );
     205           0 :     return error;
     206             : }
     207             : 
     208             : /*-------------------------------------------------------------------*
     209             :  * set_ppp_mode_fx()
     210             :  *
     211             :  * Determine if the current frame should be coded by PPP or not
     212             :  * Impose PPP - CELP - CELP pattern
     213             :  *-------------------------------------------------------------------*/
     214           0 : void set_ppp_mode_fx(
     215             :     Encoder_State *st_fx,         /* i/o: state structure */
     216             :     const Word16 noisy_speech_HO, /* i  : SC-VBR noisy speech HO flag */
     217             :     const Word16 clean_speech_HO, /* i  : SC-VBR clean speech HO flag */
     218             :     const Word16 NB_speech_HO,    /* i  : SC-VBR NB speech HO flag */
     219             :     const Word16 localVAD_he      /* i  : HE-SAD flag without hangover */
     220             : )
     221             : {
     222             : 
     223           0 :     SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR;
     224             : 
     225           0 :     test();
     226           0 :     test();
     227           0 :     test();
     228           0 :     test();
     229           0 :     test();
     230             : 
     231           0 :     if ( EQ_16( st_fx->vad_flag, 1 ) &&
     232           0 :          ( EQ_16( noisy_speech_HO, 1 ) || EQ_16( clean_speech_HO, 1 ) || EQ_16( NB_speech_HO, 1 ) ) &&
     233           0 :          ( st_fx->localVAD == 0 || localVAD_he == 0 ) )
     234             : 
     235             :     {
     236           0 :         st_fx->coder_type = UNVOICED;
     237           0 :         move16();
     238             :     }
     239             : 
     240           0 :     test();
     241           0 :     test();
     242           0 :     if ( EQ_16( st_fx->coder_type, INACTIVE ) && ( st_fx->vad_flag == 0 ) && EQ_16( hSC_VBR->last_nelp_mode, 1 ) ) /* avoid HO frame go to GSC */
     243             :     {
     244           0 :         st_fx->coder_type = UNVOICED;
     245           0 :         move16();
     246             :     }
     247             : 
     248             : 
     249             :     /* force the coder to NELP mode during the first five frames */
     250             :     /* this will indicate the decoder that the coder is operating in the VBR mode */
     251           0 :     IF( LT_16( st_fx->ini_frame, 5 ) )
     252             :     {
     253           0 :         st_fx->coder_type = UNVOICED;
     254           0 :         move16();
     255           0 :         st_fx->vad_flag = 1;
     256           0 :         move16();
     257             :     }
     258             :     /* Pattern PPP-CELP-CELP (pppcountE holds number of consecutive PPP frames) */
     259           0 :     test();
     260           0 :     IF( NE_16( st_fx->coder_type, VOICED ) || EQ_16( st_fx->last_coder_type, TRANSITION ) )
     261             :     {
     262             :         /* ensure no transient to PPP transition */
     263           0 :         hSC_VBR->pppcountE = 0;
     264           0 :         move16();
     265             :     }
     266             :     ELSE
     267             :     {
     268             :         /* current mode is voiced */
     269           0 :         hSC_VBR->pppcountE = add( hSC_VBR->pppcountE, 1 );
     270           0 :         test();
     271           0 :         test();
     272           0 :         test();
     273           0 :         test();
     274           0 :         IF( ( EQ_16( hSC_VBR->pppcountE, 1 ) && NE_16( hSC_VBR->last_last_ppp_mode, 1 ) && hSC_VBR->rate_control == 0 ) ||
     275             :             ( EQ_16( hSC_VBR->pppcountE, 1 ) && hSC_VBR->mode_QQF != 0 ) )
     276             :         {
     277           0 :             hSC_VBR->ppp_mode = 1;
     278           0 :             move16();
     279           0 :             st_fx->core_brate = PPP_NELP_2k80;
     280           0 :             move32();
     281             :         }
     282           0 :         ELSE IF( EQ_16( hSC_VBR->pppcountE, 2 ) )
     283             :         {
     284           0 :             test();
     285           0 :             IF( hSC_VBR->last_ppp_mode != 0 && hSC_VBR->mode_QQF == 0 )
     286             :             {
     287             :                 /* QFF mode */
     288           0 :                 hSC_VBR->ppp_mode = 0;
     289           0 :                 move16();
     290             :             }
     291             :             ELSE
     292             :             {
     293             :                 /* QQF Mode */
     294           0 :                 hSC_VBR->ppp_mode = 1;
     295           0 :                 move16();
     296           0 :                 st_fx->core_brate = PPP_NELP_2k80;
     297           0 :                 move32();
     298             :             }
     299             :         }
     300             :         ELSE
     301             :         {
     302           0 :             hSC_VBR->ppp_mode = 0;
     303           0 :             move16();
     304           0 :             hSC_VBR->pppcountE = 0;
     305           0 :             move16();
     306             :         }
     307             :     }
     308             : 
     309             : 
     310           0 :     test();
     311           0 :     IF( hSC_VBR->ppp_mode == 0 && EQ_16( hSC_VBR->set_ppp_generic, 1 ) )
     312             :     {
     313           0 :         hSC_VBR->set_ppp_generic = 0;
     314           0 :         move16();
     315           0 :         st_fx->coder_type = GENERIC;
     316           0 :         move16();
     317             :     }
     318             : 
     319           0 :     IF( EQ_16( st_fx->last_core, HQ_CORE ) )
     320             :     {
     321           0 :         hSC_VBR->ppp_mode = 0;
     322           0 :         move16();
     323           0 :         hSC_VBR->set_ppp_generic = 0;
     324           0 :         move16();
     325           0 :         st_fx->coder_type = TRANSITION;
     326           0 :         move16();
     327             :     }
     328             : 
     329           0 :     test();
     330           0 :     test();
     331           0 :     test();
     332           0 :     test();
     333           0 :     IF( ( hSC_VBR->last_ppp_mode != 0 ) && ( hSC_VBR->ppp_mode == 0 ) && ( st_fx->sp_aud_decision1 != 0 ) && ( st_fx->bwidth == NB ) && ( st_fx->Opt_SC_VBR != 0 ) ) /*if it were about to go from ppp->HQ*/
     334             :     {
     335           0 :         hSC_VBR->avoid_HQ_VBR_NB = 1;
     336           0 :         move16();
     337           0 :         st_fx->coder_type = GENERIC;
     338           0 :         move16();
     339             :     }
     340             : 
     341           0 :     test();
     342           0 :     test();
     343           0 :     test();
     344           0 :     IF( ( hSC_VBR->last_nelp_mode != 0 ) && ( st_fx->sp_aud_decision1 != 0 ) && ( st_fx->bwidth == NB ) && ( st_fx->Opt_SC_VBR != 0 ) ) /*if it were about to go from nelp->HQ*/
     345             :     {
     346           0 :         hSC_VBR->avoid_HQ_VBR_NB = 1;
     347           0 :         move16();
     348           0 :         st_fx->coder_type = GENERIC;
     349           0 :         move16();
     350             :     }
     351             : 
     352             : 
     353           0 :     test();
     354           0 :     test();
     355           0 :     test();
     356           0 :     if ( ( GT_16( st_fx->old_pitch_buf_fx[( 2 * NB_SUBFR ) - 1], PPP_LAG_THRLD_Q6 ) ||
     357           0 :            GT_16( st_fx->pitch[1], PPP_LAG_THRLD ) || !st_fx->last_Opt_SC_VBR ) &&
     358           0 :          EQ_16( hSC_VBR->ppp_mode, 1 ) )
     359             :     {
     360           0 :         hSC_VBR->ppp_mode = 0;
     361           0 :         move16();
     362           0 :         st_fx->core_brate = ACELP_7k20;
     363           0 :         move32();
     364             :     }
     365             : 
     366             : 
     367           0 :     return;
     368             : }
     369             : 
     370             : /*===================================================================*/
     371             : /* FUNCTION      :  Word16 DTFS_quant_cw_fx ()                       */
     372             : /*-------------------------------------------------------------------*/
     373             : /* PURPOSE       :  Quantize QPPP prototype                          */
     374             : /*-------------------------------------------------------------------*/
     375             : /* INPUT ARGUMENTS  :                                                */
     376             : /*   _ (Word16) pl: previous lag                                     */
     377             : /*   _ (Word16 []) curr_lpc_fx: LPC coefficients, Q12                */
     378             : /*   _ (Word16 []) sin_tab: sine table based on lag, Q15             */
     379             : /*   _ (Word16 []) cos_tab: cosine table based on lag, Q15           */
     380             : /*-------------------------------------------------------------------*/
     381             : /* OUTPUT ARGUMENTS :                                                */
     382             : /*   _ (Word16) POWER_IDX: Power index                               */
     383             : /*   _ (Word16[]) AMP_IDX: Amplitude indices                         */
     384             : /*-------------------------------------------------------------------*/
     385             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     386             : /*   _ (struct DTFS_fx) X_fx :  prototype in polar domain            */
     387             : /*                (Word16) lag_fx: length of prototype in time domain*/
     388             : /*                (Word16 []) a: amplitude of harmonics, normalized  */
     389             : /*                (Word16) Q: norm factor of a                       */
     390             : /*   _ (Word16[]) lasterb_fx: ERB history for differential           */
     391             : /*                quantization, Q13                                  */
     392             : /*   _ (Word16) Lgain_fx: low band power history, log domain, Q11    */
     393             : /*   _ (Word16) Hgain_fx: high band power history, log domain, Q11   */
     394             : /*-------------------------------------------------------------------*/
     395             : /* RETURN ARGUMENTS :                                                */
     396             : /*   _ (Word16) flag: flag indicating success/failure (TRUE/FALSE)   */
     397             : /*-------------------------------------------------------------------*/
     398             : /* CALLED FROM : TX                                                  */
     399             : /*===================================================================*/
     400             : /* NOTE: Frequencies is normalized by 12800, i.e. 1=12800Hz          */
     401             : /*===================================================================*/
     402           0 : static Word16 DTFS_quant_cw_fx(
     403             :     DTFS_STRUCTURE *X_fx,      /* i/o: DTFS unquant inp, quant out  */
     404             :     Word16 pl,                 /* i  : Previous lag                 */
     405             :     const Word16 *curr_lpc_fx, /* i  : LPC                          */
     406             :     Word16 *POWER_IDX,         /* o  : Power index                  */
     407             :     Word16 *AMP_IDX,           /* o  : Amplitude index              */
     408             :     Word16 *lastLgainE_fx,     /* i/o: last frame lowband gain      */
     409             :     Word16 *lastHgainE_fx,     /* i/o: last frame highband gain     */
     410             :     Word16 *lasterbE_fx,       /* i/o: last frame ERB vector        */
     411             :     Word16 *sin_tab,
     412             :     Word16 *cos_tab )
     413             : 
     414             : {
     415           0 :     Word16 num_erb = 0;
     416           0 :     move16();
     417           0 :     const Word16 *PowerCB_fx = NULL;
     418             :     Word16 tmp, w[2], target[2], j, slot[NUM_ERB_WB], flag;
     419             :     Word16 n, d1, d2, exp;
     420             :     Word32 minerror, Ltemp, logLag_fx, L_tmp;
     421             :     Word16 erb_uq[NUM_ERB_WB], Qh, Ql;
     422             :     /* Word40 Lacc_40; */
     423             :     Word32 Lacc;
     424             :     Word16 mfreq[NUM_ERB_WB];
     425             :     Word16 Q;
     426             : 
     427             :     Word16 curr_erb_fx[NUM_ERB_WB];
     428             : 
     429             : 
     430             :     /* upper_cute_off_freq are normalized to 12800 */
     431             : 
     432           0 :     IF( EQ_16( X_fx->upper_cut_off_freq_fx, 0x2800 ) ) /* 4000 hz normalized to 12800 in Q15 */
     433             :     {
     434           0 :         num_erb = NUM_ERB_NB;
     435           0 :         move16();
     436           0 :         PowerCB_fx = PowerCB_NB_fx;
     437           0 :         move16();
     438             :     }
     439           0 :     ELSE IF( EQ_16( X_fx->upper_cut_off_freq_fx, 0x4000 ) ) /* 6400 hz normalized to 12800 in Q15 */
     440             :     {
     441           0 :         num_erb = NUM_ERB_WB;
     442           0 :         move16();
     443           0 :         PowerCB_fx = PowerCB_WB_fx;
     444             :     }
     445             : 
     446             :     /*  Get weighting and target */
     447           0 :     quant_target_fx( X_fx, curr_lpc_fx, w, target, sin_tab, cos_tab );
     448             : 
     449             :     /* Power Quantization in log domain */
     450           0 :     target[0] = sub( target[0], *lastLgainE_fx );
     451           0 :     move16();
     452           0 :     target[1] = sub( target[1], *lastHgainE_fx );
     453           0 :     move16();
     454             : 
     455           0 :     minerror = L_add( EVS_LW_MAX, 0 );
     456           0 :     *POWER_IDX = 0;
     457           0 :     move16();
     458             : 
     459           0 :     j = 0;
     460           0 :     move16();
     461           0 :     FOR( n = 0; n < P_CBSIZE * 2; n += 2 )
     462             :     {
     463             :         /*     n=shl(j,1);  n=offset to current codebook entry */
     464           0 :         d1 = sub( target[0], PowerCB_fx[n] );
     465           0 :         d2 = sub( target[1], PowerCB_fx[n + 1] );
     466           0 :         Ltemp = L_mult( w[0], abs_s( d1 ) );
     467           0 :         Ltemp = L_mac( Ltemp, w[1], abs_s( d2 ) ); /*  Ltemp=error */
     468             : 
     469           0 :         test();
     470           0 :         IF( d1 >= 0 && d2 >= 0 )
     471             :         {
     472           0 :             Ltemp = Mult_32_16( Ltemp, 0x6666 ); /*  *=0.8 */
     473             :         }
     474           0 :         IF( LT_32( Ltemp, minerror ) )
     475             :         {
     476           0 :             minerror = L_add( Ltemp, 0 );
     477           0 :             *POWER_IDX = j;
     478           0 :             move16();
     479             :         }
     480           0 :         j = add( j, 1 );
     481             :     }
     482           0 :     DTFS_to_erb_fx( *X_fx, curr_erb_fx );
     483             : 
     484           0 :     FOR( j = 0; j < num_erb; j++ )
     485             :     {
     486           0 :         erb_uq[j] = curr_erb_fx[j];
     487           0 :         move16();
     488             :     }
     489           0 :     erb_slot_fx( X_fx->lag_fx, slot, mfreq, num_erb );
     490             :     /* Amplitude Quantization */
     491             : 
     492             : 
     493           0 :     erb_diff_fx( lasterbE_fx, pl, curr_erb_fx, X_fx->lag_fx, curr_lpc_fx, AMP_IDX, num_erb );
     494             : 
     495             : 
     496             :     /*  Dequantization of prototype */
     497             :     /*  PORTING: Removing the references */
     498             :     /* DTFS_dequant_cw_fx(pl, *POWER_IDX, AMP_IDX,lastLgainE_fx,lastHgainE_fx, lasterbE_fx,X_fx,num_erb,curr_erb_fx); */
     499             : 
     500             :     /* Determine IF the amplitude quantization is good enough */
     501           0 :     erb_add_fx( curr_erb_fx, X_fx->lag_fx, lasterbE_fx, pl, AMP_IDX, num_erb );
     502             : 
     503           0 :     curr_erb_fx[0] = mult_r( curr_erb_fx[1], 9830 );
     504           0 :     move16();                                                            /* 0.3 inQ15 leaves curr_erb in Q13 */
     505           0 :     curr_erb_fx[num_erb - 2] = mult_r( curr_erb_fx[num_erb - 3], 9830 ); /* Q13 */
     506             : 
     507           0 :     curr_erb_fx[num_erb - 1] = 0;
     508           0 :     move16();
     509           0 :     flag = 1;
     510           0 :     move16();
     511             : 
     512           0 :     Ltemp = L_deposit_l( 0 );
     513           0 :     n = 0;
     514           0 :     move16();
     515           0 :     FOR( j = 1; j < 10; j++ )
     516             :     {
     517           0 :         IF( slot[j] != 0 )
     518             :         {
     519           0 :             Ltemp = L_add( Ltemp, abs_s( sub( erb_uq[j], curr_erb_fx[j] ) ) ); /*  Q13 */
     520           0 :             n = add( n, 1 );                                                   /*  n++ */
     521             :         }
     522             :     }
     523             : 
     524           0 :     exp = norm_s( n );
     525           0 :     tmp = div_s( shl( 1, sub( 14, exp ) ), n ); /* 29 - exp */
     526           0 :     Lacc = L_shl( Mult_32_16( Ltemp, tmp ), exp + 4 );
     527             : 
     528           0 :     tmp = round_fx( Lacc ); /*  tmp in Q15 */
     529             : 
     530           0 :     test();
     531           0 :     if ( GT_16( tmp, 0x3C29 ) && GT_16( target[0], -819 ) )
     532             :     {
     533           0 :         flag = 0; /* Bumping up */
     534           0 :         move16();
     535             :     }
     536             : 
     537             :     /* mfreq normalized (2.56) in Q15 */
     538           0 :     DTFS_erb_inv_fx( curr_erb_fx, slot, mfreq, X_fx, num_erb );
     539             : 
     540             : 
     541             :     /* Back up the lasterbD memory after power normalization */
     542           0 :     DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, 1, 0, &Ql, X_fx );
     543           0 :     DTFS_setEngyHarm_fx( 2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, 1, 0, &Qh, X_fx );
     544             : 
     545             :     /* Need to unify the Q factors of both bands */
     546           0 :     X_fx->Q = s_min( Ql, Qh ); /*  set Q factor to be the smaller one */
     547           0 :     n = sub( Ql, Qh );         /*  compare band Q factors */
     548             : 
     549             : 
     550             :     /* This logic adjusts difference between Q formats of both bands */
     551             : 
     552           0 :     IF( n < 0 )
     553           0 :     rshiftHarmBand_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, n );
     554           0 :     ELSE IF( n > 0 )
     555           0 :         rshiftHarmBand_fx( X_fx, 0, 2828, sub( Qh, Ql ) );
     556             : 
     557           0 :     tmp = shl( *POWER_IDX, 1 );                              /*  tmp=2*POWER_IDX */
     558           0 :     *lastLgainE_fx = add( *lastLgainE_fx, PowerCB_fx[tmp] ); /*  Q11 */
     559           0 :     move16();
     560           0 :     *lastHgainE_fx = add( *lastHgainE_fx, PowerCB_fx[tmp + 1] ); /*  Q11 */
     561           0 :     move16();
     562             : 
     563           0 :     Ltemp = log10_fx( X_fx->lag_fx );        /*  Ltemp=10*log10(lag), Q23 */
     564           0 :     logLag_fx = Mult_32_16( Ltemp, 0x6666 ); /*  logLag=log10(lag), Q26 */
     565             : 
     566           0 :     Ltemp = L_sub( L_shr( L_deposit_h( *lastLgainE_fx ), 1 ), logLag_fx ); /*  Ltemp=Lgain-log10(lag), Q26 */
     567             : 
     568           0 :     L_tmp = pow_10( Ltemp, &Q ); /*  Lacc=10^Lgain/lag, Q15 */
     569           0 :     n = norm_l( L_tmp );
     570           0 :     Ltemp = (Word32) L_shl( L_tmp, n ); /*  Ltemp in Q(15+n) */
     571             : 
     572             : 
     573           0 :     DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, Ltemp, add( Q, n ), &Ql, X_fx );
     574             : 
     575           0 :     Ltemp = L_sub( L_shr( L_deposit_h( *lastHgainE_fx ), 1 ), logLag_fx ); /*  Ltemp=Hgain-log10(lag), Q26 */
     576             : 
     577             :     /* Ltemp = L_shr(Ltemp,1); */
     578           0 :     L_tmp = pow_10( Ltemp, &Q ); /*  Lacc=10^Lgain/lag, Q15 */
     579           0 :     n = norm_l( L_tmp );
     580           0 :     Ltemp = (Word32) L_shl( L_tmp, n ); /*  Ltemp in Q(15+n) */
     581             : 
     582           0 :     DTFS_setEngyHarm_fx( 2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, Ltemp, add( Q, n ), &Qh, X_fx );
     583             :     /* Need to unify the Q factors of both bands */
     584           0 :     X_fx->Q = s_min( Ql, Qh ); /*  set Q factor to be the smaller one */
     585           0 :     n = sub( Ql, Qh );         /*  compare band Q factors */
     586             : 
     587           0 :     IF( n < 0 )
     588             :     {
     589           0 :         rshiftHarmBand_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, n );
     590             :     }
     591           0 :     ELSE IF( n > 0 )
     592             :     {
     593           0 :         rshiftHarmBand_fx( X_fx, 0, 2828, sub( Qh, Ql ) );
     594             :     }
     595           0 :     return flag;
     596             : }
     597             : /*===================================================================*/
     598             : /* FUNCTION      :    DTFS_alignment_fine_new_fx ()                  */
     599             : /*-------------------------------------------------------------------*/
     600             : /* PURPOSE       :  search for alignment                             */
     601             : /*-------------------------------------------------------------------*/
     602             : /* INPUT ARGUMENTS  :                                                */
     603             : /*   _ (struct DTFS_fx) X1_fx :  a/b in X1_fx.Q                      */
     604             : /*   _ (struct DTFS_fx) X2_fx :  a/b in X2_fx.Q                      */
     605             : /*   _ (Word16 *) S_fx: sin(2pi*n/(4*lag)) table, Q15                */
     606             : /*   _ (Word16 *) C_fx: cos(2pi*n/(4*lag)) table, Q15                */
     607             : /*-------------------------------------------------------------------*/
     608             : /* OUTPUT ARGUMENTS :                                                */
     609             : /*   _ (Word16) fshift_fx :           Q2                             */
     610             : /*-------------------------------------------------------------------*/
     611             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     612             : /*                    _ None                                         */
     613             : /*-------------------------------------------------------------------*/
     614             : /* RETURN ARGUMENTS : _ None.                                        */
     615             : /*-------------------------------------------------------------------*/
     616             : /* CALLED FROM : TX                                                  */
     617             : /*===================================================================*/
     618             : 
     619           0 : static Word16 DTFS_alignment_fine_new_fx( DTFS_STRUCTURE X1_fx, DTFS_STRUCTURE X2_fx, Word16 *S_fx, Word16 *C_fx )
     620             : {
     621             :     Word16 temp, temp1, k, Qcorr, Qmaxcorr;
     622             :     Word16 n, fshift_fx, HalfLag, ab1[MAXLAG_WI], ab2[MAXLAG_WI];
     623             :     Word32 corr_fx;
     624             :     Word32 maxcorr_fx, wcorr_fx, diff_corr;
     625             : #ifndef ISSUE_1867_replace_overflow_libenc
     626             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     627             :     Flag Overflow = 0;
     628             :     move16();
     629             : #endif
     630             : #endif
     631           0 :     IF( LT_16( X1_fx.lag_fx, X2_fx.lag_fx ) )
     632             :     {
     633           0 :         DTFS_zeroPadd_fx( X2_fx.lag_fx, &X1_fx );
     634             :     }
     635             : 
     636           0 :     maxcorr_fx = L_add( MIN_32, 0 );
     637           0 :     Qmaxcorr = 0;
     638           0 :     move16();
     639           0 :     HalfLag = s_min( shr( X2_fx.lag_fx, 1 ), X2_fx.nH_fx );
     640             : 
     641           0 :     FOR( k = 0; k <= HalfLag; k++ )
     642             :     {
     643           0 :         ab1[k] = round_fx( L_mac( L_mult( X1_fx.a_fx[k], X2_fx.a_fx[k] ), X1_fx.b_fx[k], X2_fx.b_fx[k] ) );
     644           0 :         move16();
     645           0 :         ab2[k] = round_fx( L_msu( L_mult( X1_fx.b_fx[k], X2_fx.a_fx[k] ), X1_fx.a_fx[k], X2_fx.b_fx[k] ) );
     646           0 :         move16();
     647             :     }
     648             : 
     649             : 
     650           0 :     fshift_fx = 0;
     651           0 :     move16();
     652           0 :     FOR( n = -76; n <= 80; n += 4 )
     653             :     {
     654             :         /*  n is Q2 */
     655           0 :         corr_fx = L_deposit_l( 0 );
     656           0 :         temp = 0;
     657           0 :         move16();
     658           0 :         temp1 = n;
     659           0 :         move16();
     660             : 
     661           0 :         IF( n < 0 )
     662             :         {
     663           0 :             temp1 = add( temp1, shl( X2_fx.lag_fx, 2 ) ); /*  avoid negative */
     664             :         }
     665             : 
     666           0 :         FOR( k = 0; k <= HalfLag; k++ )
     667             :         {
     668             : #ifdef ISSUE_1867_replace_overflow_libenc
     669           0 :             corr_fx = L_mac_sat( corr_fx, ab1[k], C_fx[temp % ( 4 * X2_fx.lag_fx )] );
     670           0 :             corr_fx = L_mac_sat( corr_fx, ab2[k], S_fx[temp % ( 4 * X2_fx.lag_fx )] );
     671           0 :             temp = add_sat( temp, temp1 );
     672             : #else
     673             :             corr_fx = L_mac_o( corr_fx, ab1[k], C_fx[temp % ( 4 * X2_fx.lag_fx )], &Overflow );
     674             :             corr_fx = L_mac_o( corr_fx, ab2[k], S_fx[temp % ( 4 * X2_fx.lag_fx )], &Overflow );
     675             :             temp = add_o( temp, temp1, &Overflow );
     676             : #endif
     677             :         }
     678           0 :         temp = sub( 32767, extract_l( L_shr( L_mult( 82, abs_s( n ) ), 1 ) ) ); /*  Q15 */
     679           0 :         Qcorr = norm_l( corr_fx );
     680           0 :         if ( corr_fx == 0 )
     681             :         {
     682           0 :             Qcorr = 31;
     683           0 :             move16();
     684             :         }
     685             : 
     686             : #ifdef ISSUE_1867_replace_overflow_libenc
     687           0 :         temp1 = round_fx_sat( (Word32) L_shl_sat( corr_fx, Qcorr ) ); /*  Q(Qcorr-16) */
     688           0 :         wcorr_fx = L_mult_sat( temp1, temp );                         /*  Q(Qcorr-16+15+1)=Q(Qcorr) */
     689             : #else
     690             :         temp1 = round_fx_o( (Word32) L_shl_o( corr_fx, Qcorr, &Overflow ), &Overflow );                           /*  Q(Qcorr-16) */
     691             :         wcorr_fx = L_mult_o( temp1, temp, &Overflow );                                                            /*  Q(Qcorr-16+15+1)=Q(Qcorr) */
     692             : #endif
     693             : 
     694           0 :         IF( GE_16( Qmaxcorr, Qcorr ) )
     695             :         {
     696             : #ifdef ISSUE_1867_replace_overflow_libenc
     697           0 :             diff_corr = L_sub_sat( wcorr_fx, L_shl_sat( maxcorr_fx, sub( Qcorr, Qmaxcorr ) ) ); /*  Qcorr */
     698             : #else
     699             :             diff_corr = L_sub_o( wcorr_fx, L_shl_o( maxcorr_fx, sub( Qcorr, Qmaxcorr ), &Overflow ), &Overflow ); /*  Qcorr */
     700             : #endif
     701             :         }
     702             :         ELSE
     703             :         {
     704             : #ifdef ISSUE_1867_replace_overflow_libenc
     705           0 :             diff_corr = L_sub_sat( L_shl_sat( wcorr_fx, sub( Qmaxcorr, Qcorr ) ), maxcorr_fx ); /*  Qmaxcorr */
     706             : #else
     707             :             diff_corr = L_sub_o( L_shl_o( wcorr_fx, sub( Qmaxcorr, Qcorr ), &Overflow ), maxcorr_fx, &Overflow ); /*  Qmaxcorr */
     708             : #endif
     709             :         }
     710             : 
     711           0 :         if ( diff_corr > 0 )
     712             :         {
     713           0 :             fshift_fx = n;
     714           0 :             move16();
     715             : #ifdef ISSUE_1867_replace_overflow_libenc
     716           0 :             maxcorr_fx = (Word32) L_shl_sat( corr_fx, Qcorr ); /*  Qcorr */
     717             : #else
     718             :             maxcorr_fx = (Word32) L_shl_o( corr_fx, Qcorr, &Overflow );                                           /*  Qcorr */
     719             : #endif
     720           0 :             Qmaxcorr = Qcorr;
     721           0 :             move16();
     722             :         }
     723             :     }
     724             : 
     725           0 :     return fshift_fx;
     726             : }
     727             : /*===================================================================*/
     728             : /* FUNCTION      :  LPCPowSpect_fx ()                                */
     729             : /*-------------------------------------------------------------------*/
     730             : /* PURPOSE       :  Compute LPC power spectrum                       */
     731             : /*-------------------------------------------------------------------*/
     732             : /* INPUT ARGUMENTS  :                                                */
     733             : /*   _ (Word16 []) freq :  ERB frequency bounds, Q15                 */
     734             : /*   _ (Word16 []) LPC :  LPC coefficients, Q12                      */
     735             : /*   _ (Word16)  Nf:  number of ERB bins, Q0                         */
     736             : /*   _ (Word16) Np :  order of LPC, Q0                               */
     737             : /*-------------------------------------------------------------------*/
     738             : /* OUTPUT ARGUMENTS :                                                */
     739             : /*   _ (Word16 []) out : LPC power spectrum, Q7                      */
     740             : /*-------------------------------------------------------------------*/
     741             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     742             : /*                    _ None                                         */
     743             : /*-------------------------------------------------------------------*/
     744             : /* RETURN ARGUMENTS : _ None.                                        */
     745             : /*-------------------------------------------------------------------*/
     746             : /* CALLED FROM : TX                                                  */
     747             : /*===================================================================*/
     748             : /* NOTE: Frequency is normalized by 12800, i.e. 1=12800Hz            */
     749             : /*===================================================================*/
     750           0 : static void LPCPowSpect_fx(
     751             :     const Word16 *freq, /* i  : ERB frequencies    */
     752             :     const Word16 Nf,    /* i  : Number of ERBs     */
     753             :     const Word16 *LPC,  /* i  : LPC coefficients   */
     754             :     const Word16 Np,    /* i  : Number of LPCs     */
     755             :     Word16 *out         /* o  : LPC power spectrum */
     756             : )
     757             : {
     758             :     Word16 i, k;
     759             :     Word16 w; /*  Q9 */
     760             :     Word16 t1, dt;
     761             :     /*Word16 t2; */
     762             :     Word16 dh, dl;
     763             :     Word32 Re, Im; /*  Q27 */
     764             :     Word32 Ltemp, Lw;
     765             :     Word32 Lacc;
     766             :     Word16 tmp, exp;
     767             : #ifndef ISSUE_1867_replace_overflow_libenc
     768             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     769             :     Flag Overflow = 0;
     770             :     move16();
     771             : #endif
     772             : #endif
     773           0 :     FOR( k = 0; k < Nf; k++ )
     774             :     {
     775             : 
     776           0 :         Re = L_add( 0x8000000, 0 ); /*  Re=1.0, Q27 */
     777           0 :         Im = L_deposit_l( 0 );
     778           0 :         Lw = L_deposit_l( freq[k] ); /*  Q15 */
     779           0 :         FOR( i = 0; i < Np; i++ )
     780             :         {
     781           0 :             Ltemp = L_shl( Lw, 10 ); /*  Ltemp in Q25 */
     782           0 :             w = extract_h( Ltemp );  /*  w in Q9 */
     783           0 :             dl = extract_l( Ltemp ); /*  dl has 6 bits left-over     */
     784           0 :             w = s_and( w, 511 );
     785           0 :             t1 = cos_table[w];
     786             :             /* t2=cos_table[s_and(add(w,1),511)]; */
     787             :             /*dt=sub(t2,t1); */ /*  dt=t2-t1, Q15 */
     788           0 :             dt = cos_diff_table[w];
     789             : 
     790           0 :             IF( dl < 0 )
     791             :             {
     792           0 :                 Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     793           0 :                 Ltemp = Mult_32_16( Ltemp, dt );
     794           0 :                 Ltemp = L_shl( Ltemp, 1 );
     795             :             }
     796             :             ELSE
     797             :             {
     798           0 :                 Ltemp = (Word32) L_mult0( dt, dl ); /*  Ltemp in Q31 */
     799             :             }
     800             : 
     801           0 :             t1 = add( t1, (Word16) L_shr( Ltemp, 16 ) ); /*  t1 is interpolated cos(w) */
     802           0 :             Ltemp = L_shr( L_mult( LPC[i], t1 ), 1 );    /*  Ltemp in Q27 */
     803             : #ifdef ISSUE_1867_replace_overflow_libenc
     804           0 :             Re = L_add_sat( Re, Ltemp );     /*  Re=1-sum(LPC[i]*cos(Lw)); */
     805           0 :             Ltemp = L_add_sat( Lw, 0x6000 ); /*  add 0.75, which is 3pi/2 to convert sin to cos */
     806           0 :             Ltemp = L_shl_sat( Ltemp, 10 );  /*  Q25 */
     807             : #else
     808             :             Re = L_add_o( Re, Ltemp, &Overflow );                                                                 /*  Re=1-sum(LPC[i]*cos(Lw)); */
     809             :             Ltemp = L_add_o( Lw, 0x6000, &Overflow );                                                             /*  add 0.75, which is 3pi/2 to convert sin to cos */
     810             :             Ltemp = L_shl_o( Ltemp, 10, &Overflow );                                                              /*  Q25 */
     811             : #endif
     812           0 :             w = extract_h( Ltemp );  /*  w is equivalent cos index */
     813           0 :             dl = extract_l( Ltemp ); /*  dl is 6 bit left-over for interpolation */
     814           0 :             w = s_and( w, 511 );
     815           0 :             t1 = cos_table[w];
     816             :             /*t2=cos_table[s_and(add(w,1),511)]; */
     817             :             /*dt=sub(t2,t1); */ /*  dt=t2-t1, Q15 */
     818           0 :             dt = cos_diff_table[w];
     819             : 
     820           0 :             IF( dl < 0 )
     821             :             {
     822           0 :                 Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     823           0 :                 Ltemp = Mult_32_16( Ltemp, dt );
     824           0 :                 Ltemp = L_shl( Ltemp, 1 );
     825             :             }
     826             :             ELSE
     827             :             {
     828           0 :                 Ltemp = (Word32) L_mult0( dt, dl ); /*  Ltemp in Q31 */
     829             :             }
     830             : 
     831           0 :             t1 = add( t1, (Word16) L_shr( Ltemp, 16 ) ); /*  t1 is interpolated cos(w) */
     832           0 :             Ltemp = L_shr( L_mult( LPC[i], t1 ), 1 );    /*  Ltemp in Q27 */
     833             : #ifdef ISSUE_1867_replace_overflow_libenc
     834           0 :             Im = L_sub_sat( Im, Ltemp );   /*  Im=sum(LPC[i]*sin(Lw)) */
     835           0 :             Lw = L_add_sat( Lw, freq[k] ); /*  Lw=(i+1)*freq[k] */
     836             : #else
     837             :             Im = L_sub_o( Im, Ltemp, &Overflow );                                                                 /*  Im=sum(LPC[i]*sin(Lw)) */
     838             :             Lw = L_add_o( Lw, freq[k], &Overflow );                                                               /*  Lw=(i+1)*freq[k] */
     839             : #endif
     840             :         }
     841             :         /* If necessary, we can block-normalize Re and Im to improve precision */
     842           0 :         dh = extract_h( Re );
     843           0 :         dl = extract_l( Re );
     844             : 
     845           0 :         IF( dl < 0 )
     846             :         {
     847           0 :             Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     848           0 :             Ltemp = Mult_32_16( Ltemp, dh );
     849           0 :             Lacc = L_shl( Ltemp, 1 );
     850             :         }
     851             :         ELSE
     852           0 :             Lacc = L_mult0( dh, dl );
     853             : 
     854             : #ifdef ISSUE_1867_replace_overflow_libenc
     855           0 :         Lacc = L_add_sat( L_shr( Lacc, 15 ), L_shr( L_mult_sat( dh, dh ), 1 ) ); /*  Lacc=Re*Re */
     856             : #else
     857             :         Lacc = L_add_o( L_shr( Lacc, 15 ), L_shr( L_mult_o( dh, dh, &Overflow ), 1 ), &Overflow );                /*  Lacc=Re*Re */
     858             : #endif
     859           0 :         dh = extract_h( Im );
     860           0 :         dl = extract_l( Im );
     861             : 
     862           0 :         IF( dl < 0 )
     863             :         {
     864           0 :             Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     865           0 :             Ltemp = Mult_32_16( Ltemp, dh );
     866           0 :             Ltemp = L_shl( Ltemp, 1 );
     867             :         }
     868             :         ELSE
     869           0 :             Ltemp = (Word32) L_mult0( dh, dl );
     870             : 
     871           0 :         Lacc = L_add( Lacc, L_shr( Ltemp, 15 ) );
     872           0 :         Lacc = L_add( Lacc, L_shr( L_mult( dh, dh ), 1 ) ); /*  Lacc=Re^2+Im^2, Q22        */
     873             : 
     874           0 :         exp = norm_l( Lacc );
     875           0 :         tmp = round_fx_sat( L_shl( Lacc, exp ) );
     876           0 :         exp = sub( sub( 30, exp ), 22 );
     877             : 
     878             :         /* tmp may potentially become negative, when Lacc is a very large value */
     879           0 :         IF( tmp > 0 )
     880             :         {
     881           0 :             tmp = div_s( 16384, tmp ); /* 15+exp1 */
     882             :         }
     883             :         ELSE
     884             :         {
     885           0 :             tmp = 0;
     886           0 :             move16();
     887             :         }
     888           0 :         Ltemp = L_deposit_h( tmp );
     889             : #ifdef ISSUE_1867_replace_overflow_libenc
     890           0 :         out[k] = round_fx_sat( L_shl_sat( Ltemp, negate( add( exp, 8 ) ) ) );
     891             : #else
     892             :         out[k] = round_fx_o( L_shl_o( Ltemp, negate( add( exp, 8 ) ), &Overflow ), &Overflow );
     893             : #endif
     894           0 :         move16();
     895             : 
     896             :         /* out[k] = shl(tmp,-exp-8); in Q7 */
     897             :     }
     898           0 :     return;
     899             : }
     900             : 
     901             : /*===================================================================*/
     902             : /* FUNCTION      :  erb_diff_fx ()                                   */
     903             : /*-------------------------------------------------------------------*/
     904             : /* PURPOSE       :  Quantize erb amplitude for QPPP                  */
     905             : /*-------------------------------------------------------------------*/
     906             : /* INPUT ARGUMENTS  :                                                */
     907             : /*   _ (Word16) pl :  previous pitch lag, Q0                         */
     908             : /*   _ (Word16) l :   current pitch lag, Q0                          */
     909             : /*   _ (Word16 []) prev_erb : Previous erb amplitude, Q13            */
     910             : /*   _ (Word16 []) curr_erb : Current erb amplitude, Q13             */
     911             : /*   _ (Word16 []) curr_lsp : LSP coefficients, Q12                  */
     912             : /*   _ (Word16 [])  num_erb : Number of ERBs  , Q0                   */
     913             : /*-------------------------------------------------------------------*/
     914             : /* OUTPUT ARGUMENTS :                                                */
     915             : /*   _ (Word16 []) index: quantized differential erb index           */
     916             : /*-------------------------------------------------------------------*/
     917             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     918             : /*                    _ None                                         */
     919             : /*-------------------------------------------------------------------*/
     920             : /* RETURN ARGUMENTS : _ None.                                        */
     921             : /*-------------------------------------------------------------------*/
     922             : /* CALLED FROM : TX                                                  */
     923             : /*===================================================================*/
     924           0 : static void erb_diff_fx(
     925             :     const Word16 *prev_erb, /* i  : previous ERB              */
     926             :     Word16 pl,              /* i  : previous lag              */
     927             :     const Word16 *curr_erb, /* i  : current ERB               */
     928             :     Word16 l,               /* i  : current lag               */
     929             :     const Word16 *curr_lsp, /* i  : current LSP coefficients  */
     930             :     Word16 *index,          /* 0  : ERB index                 */
     931             :     Word16 num_erb          /* i  : Number of ERBs            */
     932             : )
     933             : {
     934             :     Word16 i;
     935             :     Word16 pslot[NUM_ERB_WB], cslot[NUM_ERB_WB];
     936             :     Word16 tmp, t_prev_erb[NUM_ERB_WB], LPC[M + 1], mfreq[NUM_ERB_WB], PowSpect[NUM_ERB_WB], dif_erb[NUM_ERB_WB];
     937           0 :     const Word16 *AmpCB1_fx = NULL;
     938             : 
     939           0 :     IF( EQ_16( num_erb, NUM_ERB_NB ) )
     940             :     {
     941           0 :         AmpCB1_fx = AmpCB1_NB_fx;
     942           0 :         move16();
     943             :     }
     944           0 :     ELSE IF( EQ_16( num_erb, NUM_ERB_WB ) )
     945             :     {
     946           0 :         AmpCB1_fx = AmpCB1_WB_fx;
     947           0 :         move16();
     948             :     }
     949           0 :     erb_slot_fx( l, cslot, mfreq, num_erb ); /* cslot in Qo and mfreq in Q15 */
     950           0 :     erb_slot_fx( pl, pslot, t_prev_erb, num_erb );
     951             : 
     952           0 :     FOR( i = 0; i < M + 1; i++ )
     953             :     {
     954           0 :         LPC[i] = mult_r( curr_lsp[i], pwf78_fx[i] );
     955           0 :         move16();
     956             :     }
     957             : 
     958           0 :     LPCPowSpect_fx( mfreq, num_erb, LPC, M + 1, PowSpect ); /* Powspect in Q7 */
     959             : 
     960           0 :     FOR( i = 0; i < num_erb; i++ )
     961             :     {
     962           0 :         if ( cslot[i] == 0 )
     963             :         {
     964           0 :             PowSpect[i] = 0;
     965           0 :             move16();
     966             :         }
     967             :     }
     968           0 :     FOR( i = 0; i < num_erb; i++ )
     969             :     {
     970           0 :         t_prev_erb[i] = prev_erb[i];
     971           0 :         move16();
     972             :     }
     973           0 :     IF( GT_16( pl, l ) )
     974             :     {
     975           0 :         tmp = t_prev_erb[0];
     976           0 :         move16();
     977           0 :         FOR( i = 0; i < num_erb; i++ )
     978             :         {
     979           0 :             IF( pslot[i] != 0 )
     980             :             {
     981           0 :                 tmp = t_prev_erb[i];
     982           0 :                 move16();
     983             :             }
     984             :             ELSE
     985             :             {
     986           0 :                 t_prev_erb[i] = tmp;
     987           0 :                 move16();
     988             :             }
     989             :         }
     990             :     }
     991           0 :     ELSE IF( GT_16( l, pl ) )
     992             :     {
     993           0 :         tmp = t_prev_erb[num_erb - 1];
     994           0 :         move16();
     995             : 
     996           0 :         FOR( i = num_erb - 1; i >= 0; i-- )
     997             :         {
     998           0 :             IF( pslot[i] != 0 )
     999             :             {
    1000           0 :                 tmp = t_prev_erb[i];
    1001           0 :                 move16();
    1002             :             }
    1003             :             ELSE
    1004             :             {
    1005           0 :                 t_prev_erb[i] = tmp;
    1006           0 :                 move16();
    1007             :             }
    1008             :         }
    1009             :     }
    1010           0 :     FOR( i = 0; i < num_erb; i++ )
    1011             :     {
    1012           0 :         dif_erb[i] = sub( curr_erb[i], t_prev_erb[i] );
    1013           0 :         move16();
    1014             :     }
    1015             : 
    1016             :     /* First Band Amplitude Search */
    1017           0 :     index[0] = erb_diff_search_fx( t_prev_erb, curr_erb, dif_erb,
    1018             :                                    PowSpect, AmpCB1_fx,
    1019             :                                    ERB_CBSIZE1, 10, 1 );
    1020           0 :     move16();
    1021           0 :     IF( EQ_16( num_erb, NUM_ERB_NB ) )
    1022             :     {
    1023             :         /* Second Band Amplitude Search */
    1024           0 :         index[1] = erb_diff_search_fx( t_prev_erb, curr_erb, dif_erb,
    1025             :                                        PowSpect, AmpCB2_NB_fx,
    1026             :                                        ERB_CBSIZE2, 9, 11 );
    1027           0 :         move16();
    1028             :     }
    1029           0 :     ELSE IF( EQ_16( num_erb, NUM_ERB_WB ) )
    1030             :     {
    1031             :         /* Second Band Amplitude Search */
    1032           0 :         index[1] = erb_diff_search_fx( t_prev_erb, curr_erb, dif_erb,
    1033             :                                        PowSpect, AmpCB2_WB_fx,
    1034             :                                        ERB_CBSIZE2, 11, 11 );
    1035           0 :         move16();
    1036             :     }
    1037           0 : }

Generated by: LCOV version 1.14