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

Generated by: LCOV version 1.14