LCOV - code coverage report
Current view: top level - lib_enc - ppp_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 0 415 0.0 %
Date: 2025-05-03 01:55:50 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             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     626           0 :     Flag Overflow = 0;
     627           0 :     move16();
     628             : #endif
     629           0 :     IF( LT_16( X1_fx.lag_fx, X2_fx.lag_fx ) )
     630             :     {
     631           0 :         DTFS_zeroPadd_fx( X2_fx.lag_fx, &X1_fx );
     632             :     }
     633             : 
     634           0 :     maxcorr_fx = L_add( MIN_32, 0 );
     635           0 :     Qmaxcorr = 0;
     636           0 :     move16();
     637           0 :     HalfLag = s_min( shr( X2_fx.lag_fx, 1 ), X2_fx.nH_fx );
     638             : 
     639           0 :     FOR( k = 0; k <= HalfLag; k++ )
     640             :     {
     641           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] ) );
     642           0 :         move16();
     643           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] ) );
     644           0 :         move16();
     645             :     }
     646             : 
     647             : 
     648           0 :     fshift_fx = 0;
     649           0 :     move16();
     650           0 :     FOR( n = -76; n <= 80; n += 4 )
     651             :     {
     652             :         /*  n is Q2 */
     653           0 :         corr_fx = L_deposit_l( 0 );
     654           0 :         temp = 0;
     655           0 :         move16();
     656           0 :         temp1 = n;
     657           0 :         move16();
     658             : 
     659           0 :         IF( n < 0 )
     660             :         {
     661           0 :             temp1 = add( temp1, shl( X2_fx.lag_fx, 2 ) ); /*  avoid negative */
     662             :         }
     663             : 
     664           0 :         FOR( k = 0; k <= HalfLag; k++ )
     665             :         {
     666           0 :             corr_fx = L_mac_o( corr_fx, ab1[k], C_fx[temp % ( 4 * X2_fx.lag_fx )], &Overflow );
     667           0 :             corr_fx = L_mac_o( corr_fx, ab2[k], S_fx[temp % ( 4 * X2_fx.lag_fx )], &Overflow );
     668           0 :             temp = add_o( temp, temp1, &Overflow );
     669             :         }
     670           0 :         temp = sub( 32767, extract_l( L_shr( L_mult( 82, abs_s( n ) ), 1 ) ) ); /*  Q15 */
     671           0 :         Qcorr = norm_l( corr_fx );
     672           0 :         if ( corr_fx == 0 )
     673             :         {
     674           0 :             Qcorr = 31;
     675           0 :             move16();
     676             :         }
     677             : 
     678           0 :         temp1 = round_fx_o( (Word32) L_shl_o( corr_fx, Qcorr, &Overflow ), &Overflow ); /*  Q(Qcorr-16) */
     679           0 :         wcorr_fx = L_mult_o( temp1, temp, &Overflow );                                  /*  Q(Qcorr-16+15+1)=Q(Qcorr) */
     680             : 
     681           0 :         IF( GE_16( Qmaxcorr, Qcorr ) )
     682             :         {
     683           0 :             diff_corr = L_sub_o( wcorr_fx, L_shl_o( maxcorr_fx, sub( Qcorr, Qmaxcorr ), &Overflow ), &Overflow ); /*  Qcorr */
     684             :         }
     685             :         ELSE
     686             :         {
     687           0 :             diff_corr = L_sub_o( L_shl_o( wcorr_fx, sub( Qmaxcorr, Qcorr ), &Overflow ), maxcorr_fx, &Overflow ); /*  Qmaxcorr */
     688             :         }
     689             : 
     690           0 :         if ( diff_corr > 0 )
     691             :         {
     692           0 :             fshift_fx = n;
     693           0 :             move16();
     694           0 :             maxcorr_fx = (Word32) L_shl_o( corr_fx, Qcorr, &Overflow ); /*  Qcorr */
     695           0 :             Qmaxcorr = Qcorr;
     696           0 :             move16();
     697             :         }
     698             :     }
     699             : 
     700           0 :     return fshift_fx;
     701             : }
     702             : /*===================================================================*/
     703             : /* FUNCTION      :  LPCPowSpect_fx ()                                */
     704             : /*-------------------------------------------------------------------*/
     705             : /* PURPOSE       :  Compute LPC power spectrum                       */
     706             : /*-------------------------------------------------------------------*/
     707             : /* INPUT ARGUMENTS  :                                                */
     708             : /*   _ (Word16 []) freq :  ERB frequency bounds, Q15                 */
     709             : /*   _ (Word16 []) LPC :  LPC coefficients, Q12                      */
     710             : /*   _ (Word16)  Nf:  number of ERB bins, Q0                         */
     711             : /*   _ (Word16) Np :  order of LPC, Q0                               */
     712             : /*-------------------------------------------------------------------*/
     713             : /* OUTPUT ARGUMENTS :                                                */
     714             : /*   _ (Word16 []) out : LPC power spectrum, Q7                      */
     715             : /*-------------------------------------------------------------------*/
     716             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     717             : /*                    _ None                                         */
     718             : /*-------------------------------------------------------------------*/
     719             : /* RETURN ARGUMENTS : _ None.                                        */
     720             : /*-------------------------------------------------------------------*/
     721             : /* CALLED FROM : TX                                                  */
     722             : /*===================================================================*/
     723             : /* NOTE: Frequency is normalized by 12800, i.e. 1=12800Hz            */
     724             : /*===================================================================*/
     725           0 : static void LPCPowSpect_fx(
     726             :     const Word16 *freq, /* i  : ERB frequencies    */
     727             :     const Word16 Nf,    /* i  : Number of ERBs     */
     728             :     const Word16 *LPC,  /* i  : LPC coefficients   */
     729             :     const Word16 Np,    /* i  : Number of LPCs     */
     730             :     Word16 *out         /* o  : LPC power spectrum */
     731             : )
     732             : {
     733             :     Word16 i, k;
     734             :     Word16 w; /*  Q9 */
     735             :     Word16 t1, dt;
     736             :     /*Word16 t2; */
     737             :     Word16 dh, dl;
     738             :     Word32 Re, Im; /*  Q27 */
     739             :     Word32 Ltemp, Lw;
     740             :     Word32 Lacc;
     741             :     Word16 tmp, exp;
     742             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     743           0 :     Flag Overflow = 0;
     744           0 :     move16();
     745             : #endif
     746           0 :     FOR( k = 0; k < Nf; k++ )
     747             :     {
     748             : 
     749           0 :         Re = L_add( 0x8000000, 0 ); /*  Re=1.0, Q27 */
     750           0 :         Im = L_deposit_l( 0 );
     751           0 :         Lw = L_deposit_l( freq[k] ); /*  Q15 */
     752           0 :         FOR( i = 0; i < Np; i++ )
     753             :         {
     754           0 :             Ltemp = L_shl( Lw, 10 ); /*  Ltemp in Q25 */
     755           0 :             w = extract_h( Ltemp );  /*  w in Q9 */
     756           0 :             dl = extract_l( Ltemp ); /*  dl has 6 bits left-over     */
     757           0 :             w = s_and( w, 511 );
     758           0 :             t1 = cos_table[w];
     759             :             /* t2=cos_table[s_and(add(w,1),511)]; */
     760             :             /*dt=sub(t2,t1); */ /*  dt=t2-t1, Q15 */
     761           0 :             dt = cos_diff_table[w];
     762             : 
     763           0 :             IF( dl < 0 )
     764             :             {
     765           0 :                 Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     766           0 :                 Ltemp = Mult_32_16( Ltemp, dt );
     767           0 :                 Ltemp = L_shl( Ltemp, 1 );
     768             :             }
     769             :             ELSE
     770             :             {
     771           0 :                 Ltemp = (Word32) L_mult0( dt, dl ); /*  Ltemp in Q31 */
     772             :             }
     773             : 
     774           0 :             t1 = add( t1, (Word16) L_shr( Ltemp, 16 ) ); /*  t1 is interpolated cos(w) */
     775           0 :             Ltemp = L_shr( L_mult( LPC[i], t1 ), 1 );    /*  Ltemp in Q27 */
     776           0 :             Re = L_add_o( Re, Ltemp, &Overflow );        /*  Re=1-sum(LPC[i]*cos(Lw)); */
     777           0 :             Ltemp = L_add_o( Lw, 0x6000, &Overflow );    /*  add 0.75, which is 3pi/2 to convert sin to cos */
     778           0 :             Ltemp = L_shl_o( Ltemp, 10, &Overflow );     /*  Q25 */
     779           0 :             w = extract_h( Ltemp );                      /*  w is equivalent cos index */
     780           0 :             dl = extract_l( Ltemp );                     /*  dl is 6 bit left-over for interpolation */
     781           0 :             w = s_and( w, 511 );
     782           0 :             t1 = cos_table[w];
     783             :             /*t2=cos_table[s_and(add(w,1),511)]; */
     784             :             /*dt=sub(t2,t1); */ /*  dt=t2-t1, Q15 */
     785           0 :             dt = cos_diff_table[w];
     786             : 
     787           0 :             IF( dl < 0 )
     788             :             {
     789           0 :                 Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     790           0 :                 Ltemp = Mult_32_16( Ltemp, dt );
     791           0 :                 Ltemp = L_shl( Ltemp, 1 );
     792             :             }
     793             :             ELSE
     794             :             {
     795           0 :                 Ltemp = (Word32) L_mult0( dt, dl ); /*  Ltemp in Q31 */
     796             :             }
     797             : 
     798           0 :             t1 = add( t1, (Word16) L_shr( Ltemp, 16 ) ); /*  t1 is interpolated cos(w) */
     799           0 :             Ltemp = L_shr( L_mult( LPC[i], t1 ), 1 );    /*  Ltemp in Q27 */
     800           0 :             Im = L_sub_o( Im, Ltemp, &Overflow );        /*  Im=sum(LPC[i]*sin(Lw)) */
     801           0 :             Lw = L_add_o( Lw, freq[k], &Overflow );      /*  Lw=(i+1)*freq[k] */
     802             :         }
     803             :         /* If necessary, we can block-normalize Re and Im to improve precision */
     804           0 :         dh = extract_h( Re );
     805           0 :         dl = extract_l( Re );
     806             : 
     807           0 :         IF( dl < 0 )
     808             :         {
     809           0 :             Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     810           0 :             Ltemp = Mult_32_16( Ltemp, dh );
     811           0 :             Lacc = L_shl( Ltemp, 1 );
     812             :         }
     813             :         ELSE
     814           0 :             Lacc = L_mult0( dh, dl );
     815             : 
     816           0 :         Lacc = L_add_o( L_shr( Lacc, 15 ), L_shr( L_mult_o( dh, dh, &Overflow ), 1 ), &Overflow ); /*  Lacc=Re*Re */
     817           0 :         dh = extract_h( Im );
     818           0 :         dl = extract_l( Im );
     819             : 
     820           0 :         IF( dl < 0 )
     821             :         {
     822           0 :             Ltemp = L_shl( L_add( 65536, dl ), 14 ); /*  */
     823           0 :             Ltemp = Mult_32_16( Ltemp, dh );
     824           0 :             Ltemp = L_shl( Ltemp, 1 );
     825             :         }
     826             :         ELSE
     827           0 :             Ltemp = (Word32) L_mult0( dh, dl );
     828             : 
     829           0 :         Lacc = L_add( Lacc, L_shr( Ltemp, 15 ) );
     830           0 :         Lacc = L_add( Lacc, L_shr( L_mult( dh, dh ), 1 ) ); /*  Lacc=Re^2+Im^2, Q22        */
     831             : 
     832           0 :         exp = norm_l( Lacc );
     833           0 :         tmp = round_fx_sat( L_shl( Lacc, exp ) );
     834           0 :         exp = sub( sub( 30, exp ), 22 );
     835             : 
     836             :         /* tmp may potentially become negative, when Lacc is a very large value */
     837           0 :         IF( tmp > 0 )
     838             :         {
     839           0 :             tmp = div_s( 16384, tmp ); /* 15+exp1 */
     840             :         }
     841             :         ELSE
     842             :         {
     843           0 :             tmp = 0;
     844           0 :             move16();
     845             :         }
     846           0 :         Ltemp = L_deposit_h( tmp );
     847           0 :         out[k] = round_fx_o( L_shl_o( Ltemp, negate( add( exp, 8 ) ), &Overflow ), &Overflow );
     848           0 :         move16();
     849             : 
     850             :         /* out[k] = shl(tmp,-exp-8); in Q7 */
     851             :     }
     852           0 :     return;
     853             : }
     854             : 
     855             : /*===================================================================*/
     856             : /* FUNCTION      :  erb_diff_fx ()                                   */
     857             : /*-------------------------------------------------------------------*/
     858             : /* PURPOSE       :  Quantize erb amplitude for QPPP                  */
     859             : /*-------------------------------------------------------------------*/
     860             : /* INPUT ARGUMENTS  :                                                */
     861             : /*   _ (Word16) pl :  previous pitch lag, Q0                         */
     862             : /*   _ (Word16) l :   current pitch lag, Q0                          */
     863             : /*   _ (Word16 []) prev_erb : Previous erb amplitude, Q13            */
     864             : /*   _ (Word16 []) curr_erb : Current erb amplitude, Q13             */
     865             : /*   _ (Word16 []) curr_lsp : LSP coefficients, Q12                  */
     866             : /*   _ (Word16 [])  num_erb : Number of ERBs  , Q0                   */
     867             : /*-------------------------------------------------------------------*/
     868             : /* OUTPUT ARGUMENTS :                                                */
     869             : /*   _ (Word16 []) index: quantized differential erb index           */
     870             : /*-------------------------------------------------------------------*/
     871             : /* INPUT/OUTPUT ARGUMENTS :                                          */
     872             : /*                    _ None                                         */
     873             : /*-------------------------------------------------------------------*/
     874             : /* RETURN ARGUMENTS : _ None.                                        */
     875             : /*-------------------------------------------------------------------*/
     876             : /* CALLED FROM : TX                                                  */
     877             : /*===================================================================*/
     878           0 : static void erb_diff_fx(
     879             :     const Word16 *prev_erb, /* i  : previous ERB              */
     880             :     Word16 pl,              /* i  : previous lag              */
     881             :     const Word16 *curr_erb, /* i  : current ERB               */
     882             :     Word16 l,               /* i  : current lag               */
     883             :     const Word16 *curr_lsp, /* i  : current LSP coefficients  */
     884             :     Word16 *index,          /* 0  : ERB index                 */
     885             :     Word16 num_erb          /* i  : Number of ERBs            */
     886             : )
     887             : {
     888             :     Word16 i;
     889             :     Word16 pslot[NUM_ERB_WB], cslot[NUM_ERB_WB];
     890             :     Word16 tmp, t_prev_erb[NUM_ERB_WB], LPC[M + 1], mfreq[NUM_ERB_WB], PowSpect[NUM_ERB_WB], dif_erb[NUM_ERB_WB];
     891           0 :     const Word16 *AmpCB1_fx = NULL;
     892             : 
     893           0 :     IF( EQ_16( num_erb, NUM_ERB_NB ) )
     894             :     {
     895           0 :         AmpCB1_fx = AmpCB1_NB_fx;
     896           0 :         move16();
     897             :     }
     898           0 :     ELSE IF( EQ_16( num_erb, NUM_ERB_WB ) )
     899             :     {
     900           0 :         AmpCB1_fx = AmpCB1_WB_fx;
     901           0 :         move16();
     902             :     }
     903           0 :     erb_slot_fx( l, cslot, mfreq, num_erb ); /* cslot in Qo and mfreq in Q15 */
     904           0 :     erb_slot_fx( pl, pslot, t_prev_erb, num_erb );
     905             : 
     906           0 :     FOR( i = 0; i < M + 1; i++ )
     907             :     {
     908           0 :         LPC[i] = mult_r( curr_lsp[i], pwf78_fx[i] );
     909           0 :         move16();
     910             :     }
     911             : 
     912           0 :     LPCPowSpect_fx( mfreq, num_erb, LPC, M + 1, PowSpect ); /* Powspect in Q7 */
     913             : 
     914           0 :     FOR( i = 0; i < num_erb; i++ )
     915             :     {
     916           0 :         if ( cslot[i] == 0 )
     917             :         {
     918           0 :             PowSpect[i] = 0;
     919           0 :             move16();
     920             :         }
     921             :     }
     922           0 :     FOR( i = 0; i < num_erb; i++ )
     923             :     {
     924           0 :         t_prev_erb[i] = prev_erb[i];
     925           0 :         move16();
     926             :     }
     927           0 :     IF( GT_16( pl, l ) )
     928             :     {
     929           0 :         tmp = t_prev_erb[0];
     930           0 :         move16();
     931           0 :         FOR( i = 0; i < num_erb; i++ )
     932             :         {
     933           0 :             IF( pslot[i] != 0 )
     934             :             {
     935           0 :                 tmp = t_prev_erb[i];
     936           0 :                 move16();
     937             :             }
     938             :             ELSE
     939             :             {
     940           0 :                 t_prev_erb[i] = tmp;
     941           0 :                 move16();
     942             :             }
     943             :         }
     944             :     }
     945           0 :     ELSE IF( GT_16( l, pl ) )
     946             :     {
     947           0 :         tmp = t_prev_erb[num_erb - 1];
     948           0 :         move16();
     949             : 
     950           0 :         FOR( i = num_erb - 1; i >= 0; i-- )
     951             :         {
     952           0 :             IF( pslot[i] != 0 )
     953             :             {
     954           0 :                 tmp = t_prev_erb[i];
     955           0 :                 move16();
     956             :             }
     957             :             ELSE
     958             :             {
     959           0 :                 t_prev_erb[i] = tmp;
     960           0 :                 move16();
     961             :             }
     962             :         }
     963             :     }
     964           0 :     FOR( i = 0; i < num_erb; i++ )
     965             :     {
     966           0 :         dif_erb[i] = sub( curr_erb[i], t_prev_erb[i] );
     967           0 :         move16();
     968             :     }
     969             : 
     970             :     /* First Band Amplitude Search */
     971           0 :     index[0] = erb_diff_search_fx( t_prev_erb, curr_erb, dif_erb,
     972             :                                    PowSpect, AmpCB1_fx,
     973             :                                    ERB_CBSIZE1, 10, 1 );
     974           0 :     move16();
     975           0 :     IF( EQ_16( num_erb, NUM_ERB_NB ) )
     976             :     {
     977             :         /* Second Band Amplitude Search */
     978           0 :         index[1] = erb_diff_search_fx( t_prev_erb, curr_erb, dif_erb,
     979             :                                        PowSpect, AmpCB2_NB_fx,
     980             :                                        ERB_CBSIZE2, 9, 11 );
     981           0 :         move16();
     982             :     }
     983           0 :     ELSE IF( EQ_16( num_erb, NUM_ERB_WB ) )
     984             :     {
     985             :         /* Second Band Amplitude Search */
     986           0 :         index[1] = erb_diff_search_fx( t_prev_erb, curr_erb, dif_erb,
     987             :                                        PowSpect, AmpCB2_WB_fx,
     988             :                                        ERB_CBSIZE2, 11, 11 );
     989           0 :         move16();
     990             :     }
     991           0 : }

Generated by: LCOV version 1.14