LCOV - code coverage report
Current view: top level - lib_com - ivas_dirac_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 469 904 51.9 %
Date: 2025-08-23 01:22:27 Functions: 10 12 83.3 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_rom_com.h"
      39             : #include "prot_fx.h"
      40             : #include "cnst.h"
      41             : #include "wmc_auto.h"
      42             : #include "ivas_prot_fx.h"
      43             : #include "ivas_rom_com_fx.h"
      44             : 
      45             : /*-----------------------------------------------------------------------*
      46             :  * Local function prototypes
      47             :  *-----------------------------------------------------------------------*/
      48             : 
      49             : 
      50             : static UWord16 deindex_sph_idx_general_fx( const Word16 idx_sph, const Word16 no_bits, Word32 *theta_dec_fx, Word32 *phi_dec_fx, UWord16 *p_id_phi, const MC_LS_SETUP mc_format );
      51             : 
      52             : /*-------------------------------------------------------------------------
      53             :  * ivas_get_hodirac_flag()
      54             :  *
      55             :  * Return flag for HO-DirAC method at high bitrates
      56             :  *------------------------------------------------------------------------*/
      57             : 
      58             : /*! r: HO-DirAC flag */
      59      872869 : Word16 ivas_get_hodirac_flag_fx(
      60             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate      */
      61             :     const Word16 sba_order         /* i  : Ambisonic (SBA) order   */
      62             : )
      63             : {
      64      872869 :     test();
      65      872869 :     IF( GT_16( sba_order, 1 ) && GT_32( ivas_total_brate, IVAS_256k ) )
      66             :     {
      67      127231 :         return 1;
      68             :     }
      69             :     ELSE
      70             :     {
      71      745638 :         return 0;
      72             :     }
      73             : }
      74             : /*-------------------------------------------------------------------------
      75             :  * ivas_dirac_sba_config()
      76             :  *
      77             :  * DirAC Configuration function; used also in MASA decoder
      78             :  *------------------------------------------------------------------------*/
      79        4466 : ivas_error ivas_dirac_config_fx(
      80             :     void *st_ivas,       /* i/o: IVAS encoder/decoder state structure  */
      81             :     const Word16 enc_dec /* i  : encoder or decoder flag               */
      82             : )
      83             : {
      84             :     IVAS_FORMAT ivas_format;
      85             :     Word16 sba_order;
      86             :     Word16 *element_mode;
      87             :     Word32 ivas_total_brate;
      88             :     DIRAC_CONFIG_DATA_HANDLE hConfig;
      89             :     IVAS_QMETADATA_HANDLE hQMetaData;
      90             :     Word32 Fs;
      91             :     Word16 *band_grouping;
      92             :     ivas_error error;
      93             :     Word16 spar_dirac_split_band;
      94             :     IVAS_FB_MIXER_HANDLE hFbMdft;
      95             :     Word16 *dirac_to_spar_md_bands;
      96             : 
      97        4466 :     error = IVAS_ERR_OK;
      98        4466 :     move32();
      99             : 
     100        4466 :     IF( enc_dec == ENC )
     101             :     {
     102           0 :         ivas_format = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_format;
     103           0 :         move32();
     104           0 :         element_mode = &( (Encoder_Struct *) st_ivas )->hEncoderConfig->element_mode_init;
     105           0 :         sba_order = ( (Encoder_Struct *) st_ivas )->sba_analysis_order;
     106           0 :         move16();
     107           0 :         ivas_total_brate = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_total_brate;
     108           0 :         move32();
     109           0 :         Fs = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->input_Fs;
     110           0 :         move32();
     111           0 :         band_grouping = ( (Encoder_Struct *) st_ivas )->hDirAC->band_grouping;
     112           0 :         hConfig = ( (Encoder_Struct *) st_ivas )->hDirAC->hConfig;
     113           0 :         hQMetaData = ( (Encoder_Struct *) st_ivas )->hQMetaData;
     114           0 :         IF( ( (Encoder_Struct *) st_ivas )->hSpar != NULL )
     115             :         {
     116           0 :             hFbMdft = ( (Encoder_Struct *) st_ivas )->hSpar->hFbMixer;
     117           0 :             dirac_to_spar_md_bands = ( (Encoder_Struct *) st_ivas )->hSpar->dirac_to_spar_md_bands;
     118             :         }
     119             :         ELSE
     120             :         {
     121           0 :             hFbMdft = NULL;
     122           0 :             dirac_to_spar_md_bands = NULL;
     123             :         }
     124             :     }
     125             :     ELSE
     126             :     {
     127        4466 :         ivas_format = ( (Decoder_Struct *) st_ivas )->ivas_format;
     128        4466 :         element_mode = &( (Decoder_Struct *) st_ivas )->element_mode_init;
     129        4466 :         sba_order = ( (Decoder_Struct *) st_ivas )->sba_analysis_order;
     130        4466 :         move16();
     131        4466 :         ivas_total_brate = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->ivas_total_brate;
     132        4466 :         move32();
     133        4466 :         Fs = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->output_Fs;
     134        4466 :         move32();
     135        4466 :         band_grouping = ( (Decoder_Struct *) st_ivas )->hDirAC->band_grouping;
     136        4466 :         hConfig = ( (Decoder_Struct *) st_ivas )->hDirAC->hConfig;
     137        4466 :         hQMetaData = ( (Decoder_Struct *) st_ivas )->hQMetaData;
     138        4466 :         IF( ( (Decoder_Struct *) st_ivas )->hSpar != NULL )
     139             :         {
     140        1252 :             hFbMdft = ( (Decoder_Struct *) st_ivas )->hSpar->hFbMixer;
     141        1252 :             dirac_to_spar_md_bands = ( (Decoder_Struct *) st_ivas )->hSpar->dirac_to_spar_md_bands;
     142             :         }
     143             :         ELSE
     144             :         {
     145        3214 :             hFbMdft = NULL;
     146        3214 :             dirac_to_spar_md_bands = NULL;
     147             :         }
     148        4466 :         ( (Decoder_Struct *) st_ivas )->hDirAC->hFbMdft = hFbMdft;
     149             :     }
     150             : 
     151        4466 :     test();
     152        4466 :     IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
     153             :     {
     154        1252 :         hConfig->nbands = IVAS_MAX_NUM_BANDS;
     155        1252 :         move16();
     156             : 
     157        1252 :         spar_dirac_split_band = s_min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
     158             : 
     159        1252 :         IF( ivas_get_hodirac_flag_fx( ivas_total_brate, sba_order ) ) // add call after merge of 100861_dirac_dec
     160             :         {
     161         126 :             spar_dirac_split_band = 0;
     162         126 :             move16();
     163             :         }
     164             :     }
     165             :     ELSE
     166             :     {
     167        3214 :         hConfig->nbands = 5;
     168        3214 :         spar_dirac_split_band = 0;
     169             : 
     170        3214 :         move16();
     171        3214 :         move16();
     172             :     }
     173        4466 :     hConfig->enc_param_start_band = 0;
     174        4466 :     hConfig->dec_param_estim = FALSE;
     175             : 
     176        4466 :     move16();
     177        4466 :     move16();
     178             : 
     179        4466 :     test();
     180        4466 :     IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) /* skip for MASA decoder */
     181             :     {
     182        1252 :         IF( NE_32( ( error = ivas_dirac_sba_config_fx( hQMetaData, element_mode, ivas_total_brate, sba_order, sub( hConfig->nbands, spar_dirac_split_band ), ivas_format ) ), IVAS_ERR_OK ) )
     183             :         {
     184           0 :             return error;
     185             :         }
     186             : 
     187        1252 :         IF( hQMetaData != NULL )
     188             :         {
     189        1252 :             if ( enc_dec == ENC )
     190             :             {
     191           0 :                 hConfig->nbands = hQMetaData->q_direction[0].cfg.nbands;
     192           0 :                 move16();
     193             :             }
     194        1252 :             hConfig->enc_param_start_band = add( hQMetaData->q_direction[0].cfg.start_band, spar_dirac_split_band );
     195        1252 :             move16();
     196             :         }
     197             : 
     198        1252 :         hConfig->dec_param_estim = TRUE;
     199        1252 :         move16();
     200        1252 :         if ( EQ_16( hConfig->dec_param_estim, TRUE ) )
     201             :         {
     202        1252 :             hConfig->enc_param_start_band = spar_dirac_split_band;
     203        1252 :             move16();
     204             :         }
     205             : 
     206        1252 :         IF( ivas_get_hodirac_flag_fx( ivas_total_brate, sba_order ) )
     207             :         {
     208         126 :             hConfig->dec_param_estim = FALSE;
     209         126 :             hConfig->enc_param_start_band = 0;
     210             : 
     211         126 :             move16();
     212         126 :             move16();
     213             : 
     214         126 :             set8_fx( (Word8 *) hQMetaData->twoDirBands, (Word8) 1, hQMetaData->q_direction[0].cfg.nbands );
     215         126 :             hQMetaData->numTwoDirBands = (UWord8) hQMetaData->q_direction[0].cfg.nbands;
     216         126 :             move16();
     217             :         }
     218             :     }
     219             : 
     220        4466 :     test();
     221        4466 :     IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
     222             :     {
     223             :         // 100861_dirac_dec
     224        1252 :         ivas_dirac_config_bands_fx( band_grouping, IVAS_MAX_NUM_BANDS, (Word16) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hConfig->enc_param_start_band, hFbMdft, 1 );
     225             :     }
     226             :     ELSE
     227             :     {
     228        3214 :         ivas_dirac_config_bands_fx( band_grouping, hConfig->nbands, (Word16) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), NULL, 0, 0, hFbMdft, 1 );
     229             :     }
     230             : 
     231        4466 :     return error;
     232             : }
     233             : 
     234             : 
     235             : /*-------------------------------------------------------------------------
     236             :  * ivas_dirac_config_bands_fx()
     237             :  *
     238             :  * DirAC Configuration freq. band function; used also in MASA decoder
     239             :  *------------------------------------------------------------------------*/
     240             : 
     241      105318 : void ivas_dirac_config_bands_fx(
     242             :     Word16 *band_grouping,             /* o  : band grouping                                                */
     243             :     const Word16 nbands,               /* i  : number of bands                                              */
     244             :     const Word16 max_band,             /* i  : maximal band index +1                                        */
     245             :     Word16 *dirac_to_spar_md_bands,    /* o  : mapping of DirAC parameter band index to SPAR FB band index  */
     246             :     const Word8 useLowerBandRes,       /* i  : flag indicating lower band resolution for DirAC              */
     247             :     const Word16 enc_param_start_band, /* i  : band index of first DirAC parameter band                     */
     248             :     IVAS_FB_MIXER_HANDLE hFbMdft,
     249             :     const Word8 BandGroupLowRes )
     250             : {
     251             :     Word16 i;
     252             :     {
     253      105318 :         IF( EQ_16( nbands, 5 ) )
     254             :         {
     255        4356 :             Copy( DirAC_band_grouping_5, band_grouping, 5 + 1 );
     256             :         }
     257      100962 :         ELSE IF( EQ_16( nbands, 6 ) )
     258             :         {
     259           0 :             Copy( DirAC_band_grouping_6, band_grouping, 6 + 1 );
     260             :         }
     261      100962 :         ELSE IF( EQ_16( nbands, 12 ) )
     262             :         {
     263             :             Word16 band;
     264     1312506 :             FOR( band = 0; band < DIRAC_MAX_NBANDS; band++ )
     265             :             {
     266     1211544 :                 dirac_to_spar_md_bands[band] = band;
     267     1211544 :                 move16();
     268             :             }
     269      100962 :             IF( hFbMdft != NULL )
     270             :             {
     271             :                 Word16 sb, idx1, idx2, b;
     272             : 
     273      100354 :                 idx1 = -1;
     274      100354 :                 move16();
     275      100354 :                 sb = 0;
     276      100354 :                 move16();
     277     5047674 :                 FOR( b = 0; b < max_band; b++ )
     278             :                 {
     279     4947320 :                     idx2 = hFbMdft->pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[b];
     280     4947320 :                     move16();
     281     4947320 :                     IF( GT_16( idx2, idx1 ) )
     282             :                     {
     283     1150552 :                         band_grouping[sb++] = b;
     284     1150552 :                         move16();
     285     1150552 :                         idx1 = idx2;
     286     1150552 :                         move16();
     287             :                     }
     288             :                 }
     289      100354 :                 band_grouping[sb] = max_band;
     290      100354 :                 move16();
     291             : 
     292             :                 /* set the remaining bands to max_band to avoid problems for the DirAC parameter estimation with bw < FB */
     293      254404 :                 FOR( b = sb; b <= nbands; b++ )
     294             :                 {
     295      154050 :                     band_grouping[b] = max_band;
     296      154050 :                     move16();
     297             :                 }
     298             :             }
     299             :             ELSE
     300             :             {
     301         608 :                 Copy( DirAC_band_grouping_12, band_grouping, 12 + 1 );
     302             :             }
     303             : 
     304      100962 :             IF( useLowerBandRes )
     305             :             {
     306        8952 :                 Word16 step = DIRAC_LOW_BANDRES_STEP;
     307        8952 :                 move16();
     308             :                 Word16 reduced_band;
     309             : 
     310        8952 :                 IF( BandGroupLowRes )
     311             :                 {
     312        1122 :                     FOR( ( band = enc_param_start_band + 2, reduced_band = enc_param_start_band + 1 ); band <= DIRAC_MAX_NBANDS; ( band += step, reduced_band++ ) )
     313             :                     {
     314         748 :                         band_grouping[reduced_band] = band_grouping[band];
     315         748 :                         move16();
     316             :                     }
     317        1122 :                     FOR( ; reduced_band <= DIRAC_MAX_NBANDS; reduced_band++ )
     318             :                     {
     319         748 :                         band_grouping[reduced_band] = max_band;
     320         748 :                         move16();
     321             :                     }
     322             :                 }
     323       26856 :                 FOR( ( band = enc_param_start_band + ( DIRAC_MAX_NBANDS - enc_param_start_band ) / 2 - 1, reduced_band = DIRAC_MAX_NBANDS - 1 ); band >= enc_param_start_band; ( band--, reduced_band -= step ) )
     324             :                 {
     325       17904 :                     dirac_to_spar_md_bands[reduced_band] = dirac_to_spar_md_bands[band];
     326       17904 :                     move16();
     327       17904 :                     dirac_to_spar_md_bands[reduced_band - 1] = dirac_to_spar_md_bands[band];
     328       17904 :                     move16();
     329             :                 }
     330             :             }
     331             :             ELSE
     332             :             {
     333             :                 /* always code the last two fb bands together */
     334       92010 :                 band_grouping[DIRAC_MAX_NBANDS - 1] = max_band;
     335       92010 :                 move16();
     336       92010 :                 dirac_to_spar_md_bands[DIRAC_MAX_NBANDS - 1] = sub( DIRAC_MAX_NBANDS, 2 );
     337       92010 :                 move16();
     338             :             }
     339             :         }
     340             :         ELSE
     341             :         {
     342           0 :             assert( 0 && "nbands must be 5 or 6!" );
     343             :         }
     344             :     }
     345             : 
     346             :     /* Limit the band range to band max */
     347     1443960 :     FOR( i = 0; i < nbands + 1; i++ )
     348             :     {
     349     1338642 :         IF( GT_16( band_grouping[i], max_band ) )
     350             :         {
     351        1016 :             band_grouping[i] = max_band;
     352        1016 :             move16();
     353             :         }
     354             :     }
     355             : 
     356      105318 :     return;
     357             : }
     358             : 
     359             : 
     360             : /*-------------------------------------------------------------------*
     361             :  * ivas_get_dirac_sba_max_md_bits()
     362             :  *
     363             :  * Return maximum SBA DirAC metadata bit-budget and nominal bit-budget
     364             :  *-------------------------------------------------------------------*/
     365             : 
     366        3112 : void ivas_get_dirac_sba_max_md_bits_fx(
     367             :     const Word32 sba_total_brate,
     368             :     Word16 *bits_frame_nominal,
     369             :     Word16 *metadata_max_bits,
     370             :     Word16 *qmetadata_max_bit_req,
     371             :     const Word16 nbands,
     372             :     IVAS_FORMAT ivas_format )
     373             : {
     374        3112 :     IF( LE_32( sba_total_brate, IVAS_13k2 ) )
     375             :     {
     376         284 :         *bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
     377         284 :         *metadata_max_bits = 70;
     378             : 
     379         284 :         move16();
     380         284 :         move16();
     381             :     }
     382        2828 :     ELSE IF( LE_32( sba_total_brate, IVAS_16k4 ) )
     383             :     {
     384         333 :         *bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
     385         333 :         *metadata_max_bits = 80;
     386             : 
     387         333 :         move16();
     388         333 :         move16();
     389             :     }
     390        2495 :     ELSE IF( LE_32( sba_total_brate, IVAS_24k4 ) )
     391             :     {
     392         244 :         *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
     393         244 :         *metadata_max_bits = 103;
     394             : 
     395         244 :         move16();
     396         244 :         move16();
     397             :         /* OSBA needs an additional 2-bits safety margin to avoid acelp crashes */
     398         244 :         IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) )
     399             :         {
     400          86 :             ( *metadata_max_bits ) = sub( ( *metadata_max_bits ), 7 );
     401          86 :             move16();
     402             :         }
     403             :     }
     404        2251 :     ELSE IF( LE_32( sba_total_brate, IVAS_32k ) )
     405             :     {
     406         242 :         *bits_frame_nominal = ACELP_32k / FRAMES_PER_SEC;
     407         242 :         *metadata_max_bits = 214;
     408             : 
     409         242 :         move16();
     410         242 :         move16();
     411             :     }
     412        2009 :     ELSE IF( LE_32( sba_total_brate, IVAS_48k ) )
     413             :     {
     414         144 :         *bits_frame_nominal = IVAS_48k / FRAMES_PER_SEC;
     415         144 :         *metadata_max_bits = 240;
     416             : 
     417         144 :         move16();
     418         144 :         move16();
     419             :     }
     420        1865 :     ELSE IF( LE_32( sba_total_brate, IVAS_64k ) )
     421             :     {
     422         212 :         *bits_frame_nominal = IVAS_64k / FRAMES_PER_SEC;
     423         212 :         *metadata_max_bits = 200;
     424             : 
     425         212 :         move16();
     426         212 :         move16();
     427             :     }
     428        1653 :     ELSE IF( LE_32( sba_total_brate, IVAS_80k ) )
     429             :     {
     430         265 :         *bits_frame_nominal = IVAS_80k / FRAMES_PER_SEC;
     431         265 :         *metadata_max_bits = 200;
     432             : 
     433         265 :         move16();
     434         265 :         move16();
     435             :     }
     436        1388 :     ELSE IF( LE_32( sba_total_brate, IVAS_96k ) )
     437             :     {
     438         227 :         *bits_frame_nominal = IVAS_96k / FRAMES_PER_SEC;
     439         227 :         *metadata_max_bits = 200;
     440             : 
     441         227 :         move16();
     442         227 :         move16();
     443             :     }
     444        1161 :     ELSE IF( LE_32( sba_total_brate, IVAS_128k ) )
     445             :     {
     446         197 :         *bits_frame_nominal = IVAS_128k / FRAMES_PER_SEC;
     447         197 :         *metadata_max_bits = 250;
     448             : 
     449         197 :         move16();
     450         197 :         move16();
     451             :     }
     452             :     ELSE
     453             :     {
     454             :         /* *bits_frame_nominal = (int16_t) ( sba_total_brate / FRAMES_PER_SEC ); */
     455         964 :         *bits_frame_nominal = extract_l( Mpy_32_32( sba_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     456         964 :         move16();
     457         964 :         *metadata_max_bits = MAX16B; /* no limit */
     458         964 :         move16();
     459             :     }
     460        3112 :     Word32 var1 = L_mult0( *metadata_max_bits, nbands );
     461        3112 :     Word16 exp = 0;
     462        3112 :     Word16 var2 = BASOP_Util_Divide3232_Scale( var1, 5, &exp );
     463        3112 :     Word32 var2_32 = L_deposit_h( var2 );
     464        3112 :     Word32 var4 = var2_32;
     465             : 
     466        3112 :     move16();
     467        3112 :     move32();
     468             : 
     469        3112 :     Word16 exp_res = 0;
     470        3112 :     move16();
     471        3112 :     IF( var1 % 5 != 0 )
     472             :     {
     473        1450 :         var4 = BASOP_Util_Add_Mant32Exp( var2_32, exp, ONE_IN_Q30, 1, &exp_res );
     474        1450 :         exp = exp_res;
     475        1450 :         move16();
     476             :     }
     477        3112 :     Word16 flag = BASOP_Util_Cmp_Mant32Exp( MAX16B, 31, var4, exp );
     478             :     Word32 tmp;
     479        3112 :     IF( EQ_16( flag, 1 ) )
     480             :     {
     481        2814 :         tmp = var4;
     482        2814 :         move32();
     483             :     }
     484             :     ELSE
     485             :     {
     486         298 :         tmp = MAX16B;
     487         298 :         exp = 31;
     488             : 
     489         298 :         move32();
     490         298 :         move16();
     491             :     }
     492        3112 :     *metadata_max_bits = (Word16) L_shr( tmp, 31 - exp );
     493        3112 :     *qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_SBA >> 1;
     494             : 
     495        3112 :     move16();
     496        3112 :     move16();
     497             : 
     498        3112 :     return;
     499             : }
     500             : 
     501             : /*-------------------------------------------------------------------------
     502             :  * ivas_dirac_sba_config()
     503             :  *
     504             :  * DirAC Configuration function for SBA
     505             :  *------------------------------------------------------------------------*/
     506        3112 : ivas_error ivas_dirac_sba_config_fx(
     507             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle                                    */
     508             :     Word16 *element_mode,             /* i/o: element mode of the core coder                       */
     509             :     Word32 sba_total_brate,           /* i  : SBA total bitrate                                    */
     510             :     const Word16 sba_order,           /* i  : Ambisonic (SBA) order                                */
     511             :     const Word16 nbands               /* i  : number of frequency bands                            */
     512             :     ,
     513             :     IVAS_FORMAT ivas_format )
     514             : {
     515             :     Word16 nbands_coded;
     516             :     Word16 hodirac_flag;
     517             :     ivas_error error;
     518             : 
     519        3112 :     Word32 tmp1 = IVAS_192k;
     520        3112 :     Word32 tmp2 = SPAR_DIRAC_SPLIT_START_BAND;
     521        3112 :     Word16 exp = 0;
     522             : 
     523        3112 :     move32();
     524        3112 :     move32();
     525        3112 :     move16();
     526        3112 :     Word16 tmp3 = BASOP_Util_Divide3232_Scale( tmp1, tmp2, &exp );
     527        3112 :     Word32 res = L_shr( L_deposit_h( tmp3 ), sub( 31, exp ) );
     528             : 
     529        3112 :     error = IVAS_ERR_OK;
     530        3112 :     hQMetaData->is_masa_ivas_format = 0;
     531        3112 :     move32();
     532        3112 :     move16();
     533             : 
     534        3112 :     hodirac_flag = ivas_get_hodirac_flag_fx( sba_total_brate, sba_order );
     535             : 
     536             :     /* map the bitrate for SID frame */
     537        3112 :     IF( EQ_32( sba_total_brate, IVAS_SID_5k2 ) )
     538             :     {
     539           0 :         IF( EQ_16( *element_mode, IVAS_SCE ) )
     540             :         {
     541           0 :             sba_total_brate = ACELP_24k40;
     542           0 :             move32();
     543             :         }
     544             :         ELSE
     545             :         {
     546           0 :             sba_total_brate = ACELP_48k;
     547           0 :             move32();
     548             :         }
     549             :     }
     550             : 
     551        3112 :     ivas_set_qmetadata_maxbit_req_fx( hQMetaData, SBA_FORMAT );
     552             : 
     553        3112 :     IF( LE_32( sba_total_brate, IVAS_16k4 ) )
     554             :     {
     555         617 :         hQMetaData->useLowerRes = 1;
     556         617 :         move16();
     557             :     }
     558             :     ELSE
     559             :     {
     560        2495 :         hQMetaData->useLowerRes = 0;
     561        2495 :         move16();
     562             :     }
     563             : 
     564        3112 :     nbands_coded = nbands;
     565        3112 :     move16();
     566             : 
     567        3112 :     IF( LE_32( sba_total_brate, res ) )
     568             :     {
     569         617 :         hQMetaData->useLowerBandRes = 1;
     570         617 :         Word16 tmp = s_and( nbands, 1 );
     571             : 
     572         617 :         move16();
     573         617 :         nbands_coded = add( shr( nbands, 1 ), tmp );
     574             :     }
     575             :     ELSE
     576             :     {
     577        2495 :         hQMetaData->useLowerBandRes = 0;
     578        2495 :         move16();
     579        2495 :         nbands_coded = sub( nbands, 1 ); /* always combine the last two bands */
     580             :     }
     581             : 
     582             :     {
     583        3112 :         Word16 no_dirs = 1;
     584        3112 :         move16();
     585        3112 :         IF( hodirac_flag )
     586             :         {
     587         298 :             no_dirs = 2;
     588         298 :             move16();
     589             :         }
     590             : 
     591        3112 :         IF( NE_32( ( error = ivas_qmetadata_allocate_memory_fx( hQMetaData, nbands_coded, no_dirs, 0 ) ), IVAS_ERR_OK ) ) // WIP
     592             :         {
     593           0 :             return error;
     594             :         }
     595             :     }
     596             : 
     597        3112 :     ivas_get_dirac_sba_max_md_bits_fx( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands,
     598             :                                        ivas_format );
     599             : 
     600        3112 :     return error;
     601             : }
     602             : 
     603             : 
     604        7200 : void computeDirectionVectors_fixed(
     605             :     Word32 *intensity_real_x, /* i: exp = i_e */
     606             :     Word32 *intensity_real_y, /* i: exp = i_e */
     607             :     Word32 *intensity_real_z, /* i: exp = i_e */
     608             :     const Word16 enc_param_start_band,
     609             :     const Word16 num_frequency_bands,
     610             :     Word32 *direction_vector_x, /* o: Q30*/
     611             :     Word32 *direction_vector_y, /* o: Q30*/
     612             :     Word32 *direction_vector_z, /* o: Q30*/
     613             :     Word16 i_e,                 /*Exponent of all the intensity buffers*/
     614             :     Word16 *i_e_band )
     615             : {
     616             :     Word16 i;
     617             :     Word32 intensityNorm;
     618             :     Word16 intensityNorm_e;
     619             :     Word32 temp1;
     620             :     Word16 exp1;
     621             :     Word16 norm_x, norm_y, norm_z;
     622             :     Word32 scaled_x, scaled_y, scaled_z;
     623             :     Word16 e_x, e_y, e_z;
     624      180000 :     FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i )
     625             :     {
     626      172800 :         norm_x = norm_l( *intensity_real_x );
     627      172800 :         norm_y = norm_l( *intensity_real_y );
     628      172800 :         norm_z = norm_l( *intensity_real_z );
     629      172800 :         scaled_x = L_shl( *intensity_real_x, norm_x );
     630      172800 :         scaled_y = L_shl( *intensity_real_y, norm_y );
     631      172800 :         scaled_z = L_shl( *intensity_real_z, norm_z );
     632      172800 :         IF( i_e_band != NULL )
     633             :         {
     634      172800 :             e_x = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_x ) );
     635      172800 :             e_y = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_y ) );
     636      172800 :             e_z = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_z ) );
     637             :         }
     638             :         ELSE
     639             :         {
     640           0 :             e_x = sub( i_e, norm_x );
     641           0 :             e_y = sub( i_e, norm_y );
     642           0 :             e_z = sub( i_e, norm_z );
     643             :         }
     644      172800 :         temp1 = BASOP_Util_Add_Mant32Exp( Mult_32_32( scaled_x, scaled_x ), shl( e_x, 1 ), Mult_32_32( scaled_y, scaled_y ), shl( e_y, 1 ), &exp1 );
     645      172800 :         intensityNorm = BASOP_Util_Add_Mant32Exp( temp1, exp1, Mult_32_32( scaled_z, scaled_z ), shl( e_z, 1 ), &intensityNorm_e );
     646             : 
     647      172800 :         IF( LE_32( intensityNorm, EPSILON_FX ) )
     648             :         {
     649           0 :             intensityNorm = L_shl( 1, intensityNorm_e );
     650           0 :             *( direction_vector_x++ ) = ONE_IN_Q30;
     651           0 :             *( direction_vector_y++ ) = 0;
     652           0 :             *( direction_vector_z++ ) = 0;
     653             : 
     654           0 :             move32();
     655           0 :             move32();
     656           0 :             move32();
     657           0 :             intensity_real_x++;
     658           0 :             intensity_real_y++;
     659           0 :             intensity_real_z++;
     660             :         }
     661             :         ELSE
     662             :         {
     663      172800 :             intensityNorm = ISqrt32( intensityNorm, &intensityNorm_e );                                                        /*Q31-intensityNorm_e*/
     664      172800 :             *( direction_vector_x++ ) = L_shl( Mult_32_32( scaled_x, intensityNorm ), sub( add( e_x, intensityNorm_e ), 1 ) ); /*Q30*/
     665      172800 :             intensity_real_x++;
     666      172800 :             *( direction_vector_y++ ) = L_shl( Mult_32_32( scaled_y, intensityNorm ), sub( add( e_y, intensityNorm_e ), 1 ) ); /*Q30*/
     667      172800 :             intensity_real_y++;
     668      172800 :             *( direction_vector_z++ ) = L_shl( Mult_32_32( scaled_z, intensityNorm ), sub( add( e_z, intensityNorm_e ), 1 ) ); /*Q30*/
     669      172800 :             intensity_real_z++;
     670             : 
     671      172800 :             move32();
     672      172800 :             move32();
     673      172800 :             move32();
     674             :         }
     675             :     }
     676             : 
     677        7200 :     return;
     678             : }
     679             : /*-------------------------------------------------------------------------
     680             :  * computeDirectionVectors()
     681             :  *
     682             :  *
     683             :  *------------------------------------------------------------------------*/
     684             : 
     685           0 : void computeDirectionVectors_fx(
     686             :     Word32 *intensity_real_x, // i: Q( i_q )
     687             :     Word32 *intensity_real_y, // i: Q( i_q )
     688             :     Word32 *intensity_real_z, // i: Q( i_q )
     689             :     const Word16 enc_param_start_band,
     690             :     const Word16 num_frequency_bands,
     691             :     Word32 *direction_vector_x, // o: Q( i_q )
     692             :     Word32 *direction_vector_y, // o: Q( i_q )
     693             :     Word32 *direction_vector_z, // o: Q( i_q )
     694             :     Word16 *i_q                 /*input/output Q*/
     695             : )
     696             : {
     697             :     Word16 i;
     698             :     Word32 intensityNorm;
     699             : 
     700           0 :     Word16 sq = sub( 31, sub( shl( *i_q, 1 ), 31 ) );
     701           0 :     Word16 sq1 = sub( shl( *i_q, 1 ), 31 );
     702           0 :     Word16 exp = sq;
     703           0 :     Word16 local_i_q = sq1;
     704           0 :     Word16 min_factor = 30;
     705             : 
     706           0 :     move16();
     707           0 :     move16();
     708           0 :     move16();
     709             : 
     710           0 :     Word32 *init_x = intensity_real_x;
     711           0 :     Word32 *init_y = intensity_real_y;
     712           0 :     Word32 *init_z = intensity_real_z;
     713             :     // First loop to determine the Q for the direction vector
     714           0 :     FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i )
     715             :     {
     716           0 :         intensityNorm = L_add( L_add( Mpy_32_32_r( *( intensity_real_x ), *( intensity_real_x ) ),
     717             :                                       Mpy_32_32_r( *( intensity_real_y ), *( intensity_real_y ) ) ),
     718             :                                Mpy_32_32_r( *( intensity_real_z ), *( intensity_real_z ) ) ); /*Q (2*i_q - 31) */
     719           0 :         exp = sq;
     720           0 :         move16();
     721           0 :         IF( LE_32( intensityNorm, EPSILON_FX ) )
     722             :         {
     723           0 :             intensity_real_x++;
     724           0 :             intensity_real_y++;
     725           0 :             intensity_real_z++;
     726             :         }
     727             :         ELSE
     728             :         {
     729           0 :             intensityNorm = ISqrt32( intensityNorm, &exp ); // Q31-exp
     730           0 :             intensity_real_x++;                             // i_q + Q31-exp -31 = i_q -exp
     731           0 :             intensity_real_y++;                             // i_q + Q31-exp -31 = i_q -exp
     732           0 :             intensity_real_z++;                             // i_q + Q31-exp-31 = i_q -exo
     733           0 :             local_i_q = sub( *i_q, exp );
     734           0 :             min_factor = s_min( min_factor, local_i_q );
     735             :         }
     736             :     }
     737           0 :     intensity_real_x = init_x;
     738           0 :     intensity_real_y = init_y;
     739           0 :     intensity_real_z = init_z;
     740             :     // Actual processing loop for the direction vector
     741           0 :     FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i )
     742             :     {
     743           0 :         intensityNorm = L_add( L_add( Mpy_32_32_r( *( intensity_real_x ), *( intensity_real_x ) ),
     744             :                                       Mpy_32_32_r( *( intensity_real_y ), *( intensity_real_y ) ) ),
     745             :                                Mpy_32_32_r( *( intensity_real_z ), *( intensity_real_z ) ) ); /*Q (2*i_q - 31) */
     746           0 :         exp = sq;
     747           0 :         move16();
     748           0 :         IF( LE_32( intensityNorm, EPSILON_FX ) )
     749             :         {
     750           0 :             intensityNorm = L_shl( 1, min_factor );
     751           0 :             *( direction_vector_x++ ) = L_shl( 1, min_factor ); // Q is min_factor
     752           0 :             *( direction_vector_y++ ) = 0;
     753           0 :             *( direction_vector_z++ ) = 0;
     754           0 :             intensity_real_x++;
     755           0 :             intensity_real_y++;
     756           0 :             intensity_real_z++;
     757             : 
     758           0 :             move32();
     759           0 :             move32();
     760           0 :             move32();
     761             :         }
     762             :         ELSE
     763             :         {
     764           0 :             intensityNorm = ISqrt32( intensityNorm, &exp );                                                          // Q31-exp
     765           0 :             Word32 temp = L_shr( Mpy_32_32( *( intensity_real_x++ ), intensityNorm ), ( *i_q - exp - min_factor ) ); // Q is min_factor
     766           0 :             *( direction_vector_x++ ) = temp;                                                                        // i_q + Q31-exp -31 = i_q -exp
     767           0 :             temp = L_shr( Mpy_32_32( *( intensity_real_y++ ), intensityNorm ), ( *i_q - exp - min_factor ) );        // Q is min_factor
     768           0 :             *( direction_vector_y++ ) = temp;                                                                        // i_q + Q31-exp -31 = i_q -exp
     769           0 :             temp = L_shr( Mpy_32_32( *( intensity_real_z++ ), intensityNorm ), ( *i_q - exp - min_factor ) );        // Q is min_factor
     770           0 :             *( direction_vector_z++ ) = temp;                                                                        // i_q + Q31-exp-31 = i_q -exp
     771             : 
     772           0 :             move32();
     773           0 :             move32();
     774           0 :             move32();
     775             :         }
     776             :     }
     777           0 :     *i_q = min_factor;
     778           0 :     move16();
     779           0 :     return;
     780             : }
     781             : 
     782             : /*-------------------------------------------------------------------------
     783             :  * computeDiffuseness()
     784             :  *
     785             :  *
     786             :  *------------------------------------------------------------------------*/
     787      737503 : void computeDiffuseness_fixed(
     788             :     Word32 *buffer_intensity[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF], // i: Q(q_factor_intensity)
     789             :     const Word32 *buffer_energy,                                     // i: Q(q_factor_energy)
     790             :     const Word16 num_freq_bands,
     791             :     Word32 *diffuseness, // o: exp(out_exp)
     792             :     Word16 *q_factor_intensity,
     793             :     Word16 *q_factor_energy,
     794             :     Word16 *q_diffuseness /*Ouput Q*/
     795             : )
     796             : {
     797             :     Word32 intensity_slow[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX];
     798             :     Word32 intensity_slow_abs[CLDFB_NO_CHANNELS_MAX];
     799             :     Word64 intensity_slow_abs_64[CLDFB_NO_CHANNELS_MAX];
     800             :     Word16 intensity_slow_abs_q[CLDFB_NO_CHANNELS_MAX];
     801             :     Word32 energy_slow[CLDFB_NO_CHANNELS_MAX];
     802             :     Word16 i, j, k;
     803      737503 :     Word32 tmp = 0;
     804      737503 :     move32();
     805             :     Word32 *p_tmp;
     806             :     const Word32 *p_tmp_c;
     807             :     Word16 min_q_shift1, min_q_shift2, exp1, exp2, q_tmp;
     808             :     Word16 q_ene, q_intensity;
     809             : 
     810             :     /* Compute Intensity slow and energy slow buffer_intensity and buffer_energy */
     811             : 
     812      737503 :     set_zero_fx( intensity_slow, i_mult( DIRAC_NUM_DIMS, CLDFB_NO_CHANNELS_MAX ) );
     813      737503 :     set_zero_fx( intensity_slow_abs, CLDFB_NO_CHANNELS_MAX );
     814      737503 :     set_zero_fx( energy_slow, CLDFB_NO_CHANNELS_MAX );
     815             : 
     816             :     /* Calculate max possible shift for the buffer buffer_energy and buffer_intensity */
     817      737503 :     min_q_shift1 = Q31;
     818      737503 :     move16();
     819      737503 :     min_q_shift1 = s_min( min_q_shift1, getScaleFactor32( buffer_energy, i_mult( DIRAC_NO_COL_AVG_DIFF, num_freq_bands ) ) );
     820      737503 :     min_q_shift1 = sub( min_q_shift1, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) );
     821             : 
     822      737503 :     min_q_shift2 = Q31;
     823      737503 :     move16();
     824     2950012 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     825             :     {
     826    73012797 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     827             :         {
     828    70800288 :             min_q_shift2 = s_min( min_q_shift2, getScaleFactor32( buffer_intensity[i][j], num_freq_bands ) );
     829             :         }
     830             :     }
     831      737503 :     min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) );
     832             : 
     833      737503 :     q_ene = add( q_factor_energy[0], min_q_shift1 );
     834      737503 :     move16();
     835      737503 :     q_intensity = add( q_factor_intensity[0], min_q_shift2 );
     836      737503 :     move16();
     837             : 
     838    24337599 :     FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i )
     839             :     {
     840             :         /* Energy slow */
     841    23600096 :         p_tmp_c = buffer_energy + i * num_freq_bands;
     842             : 
     843    23600096 :         q_tmp = add( q_factor_energy[i], min_q_shift1 );
     844             : 
     845             : 
     846    23600096 :         Word16 shift_q = sub( q_tmp, q_ene );
     847    23600096 :         Word32 shiftEquiv = L_add( 0, 0 );
     848             :         Word16 shift_qtotal;
     849    23600096 :         if ( shift_q < 0 )
     850             :         {
     851      756959 :             shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q );
     852             :         }
     853    23600096 :         if ( shift_q >= 0 )
     854             :         {
     855    22843137 :             shiftEquiv = L_add( 0x7FFFFFFF, 0 );
     856             :         }
     857    23600096 :         shift_qtotal = sub( min_q_shift1, s_max( shift_q, 0 ) );
     858             : 
     859   286196352 :         FOR( k = 0; k < num_freq_bands; k++ )
     860             :         {
     861   262596256 :             tmp = L_shl( p_tmp_c[k], shift_qtotal );
     862   262596256 :             energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv );
     863   262596256 :             move32();
     864             :         }
     865             : 
     866             : 
     867    23600096 :         q_ene = s_min( q_ene, q_tmp );
     868             : 
     869             :         /* Intensity slow */
     870    23600096 :         q_tmp = add( q_factor_intensity[i], min_q_shift2 );
     871             : 
     872    23600096 :         shift_q = sub( q_tmp, q_intensity );
     873    23600096 :         if ( shift_q < 0 )
     874             :         {
     875      753319 :             shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q );
     876             :         }
     877    23600096 :         if ( shift_q >= 0 )
     878             :         {
     879    22846777 :             shiftEquiv = L_lshl( 0x7FFFFFFF, 0 );
     880             :         }
     881    23600096 :         shift_qtotal = sub( min_q_shift2, s_max( shift_q, 0 ) );
     882             : 
     883    94400384 :         FOR( j = 0; j < DIRAC_NUM_DIMS; ++j )
     884             :         {
     885    70800288 :             p_tmp = buffer_intensity[j][i];
     886   858589056 :             FOR( k = 0; k < num_freq_bands; k++ )
     887             :             {
     888   787788768 :                 tmp = L_shl( p_tmp[k], shift_qtotal );
     889   787788768 :                 intensity_slow[j * num_freq_bands + k] = Madd_32_32_r( tmp, intensity_slow[j * num_freq_bands + k], shiftEquiv );
     890   787788768 :                 move32();
     891             :             }
     892             :         }
     893             : 
     894    23600096 :         q_intensity = s_min( q_intensity, q_tmp );
     895             :     }
     896             : 
     897      737503 :     min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) );
     898      737503 :     min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) );
     899      737503 :     scale_sig32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ), min_q_shift1 );
     900      737503 :     q_intensity = add( q_intensity, min_q_shift1 );
     901     8943636 :     FOR( k = 0; k < num_freq_bands; k++ )
     902             :     {
     903     8206133 :         intensity_slow_abs_64[k] = 0;
     904     8206133 :         move64();
     905             :     }
     906             : 
     907             :     /* intensity_slow.^2 + intensity_slow_abs*/
     908     2950012 :     FOR( j = 0; j < DIRAC_NUM_DIMS; ++j )
     909             :     {
     910     2212509 :         p_tmp = intensity_slow + j * num_freq_bands;
     911    26830908 :         FOR( k = 0; k < num_freq_bands; k++ )
     912             :         {
     913    24618399 :             intensity_slow_abs_64[k] = W_add( intensity_slow_abs_64[k], W_mult_32_32( p_tmp[k], p_tmp[k] ) ); // 2*q_intensity+1
     914             :         }
     915             :     }
     916     8943636 :     FOR( k = 0; k < num_freq_bands; k++ )
     917             :     {
     918     8206133 :         Word16 shift = W_norm( intensity_slow_abs_64[k] );
     919     8206133 :         intensity_slow_abs[k] = W_extract_h( W_shl( intensity_slow_abs_64[k], shift ) );
     920     8206133 :         move32();
     921     8206133 :         intensity_slow_abs_q[k] = sub( add( add( q_intensity, q_intensity ), shift ), 31 );
     922     8206133 :         move16();
     923             :     }
     924             : 
     925             :     /* Compute Diffuseness */
     926      737503 :     p_tmp = intensity_slow_abs;
     927      737503 :     exp2 = 0;
     928      737503 :     move16();
     929     8943636 :     FOR( i = 0; i < num_freq_bands; ++i )
     930             :     {
     931     8206133 :         exp1 = sub( 31, intensity_slow_abs_q[i] );
     932     8206133 :         tmp = Sqrt32( p_tmp[i], &exp1 );
     933             : 
     934     8206133 :         tmp = BASOP_Util_Divide3232_Scale_newton( tmp, L_add( energy_slow[i], EPSILLON_FX ), &exp2 );
     935     8206133 :         q_tmp = add( sub( 31, exp2 ), sub( sub( 31, exp1 ), q_ene ) );
     936             : 
     937     8206133 :         IF( LT_16( q_tmp, Q30 ) )
     938             :         {
     939      103705 :             tmp = L_sub( L_shr( ONE_IN_Q30, sub( Q30, q_tmp ) ), tmp );
     940             :         }
     941             :         ELSE
     942             :         {
     943     8102428 :             tmp = L_sub( ONE_IN_Q30, L_shr( tmp, sub( q_tmp, Q30 ) ) );
     944     8102428 :             q_tmp = Q30;
     945     8102428 :             move16();
     946             :         }
     947             : 
     948     8206133 :         IF( GE_32( tmp, L_shl( 1, q_tmp ) ) )
     949             :         {
     950       12774 :             diffuseness[i] = ONE_IN_Q30;
     951       12774 :             move32();
     952             :         }
     953     8193359 :         ELSE IF( tmp <= 0 )
     954             :         {
     955      478616 :             diffuseness[i] = 0;
     956      478616 :             move32();
     957             :         }
     958             :         ELSE
     959             :         {
     960     7714743 :             diffuseness[i] = L_shl( tmp, sub( Q30, q_tmp ) );
     961     7714743 :             move32();
     962             :         }
     963             :     }
     964      737503 :     *q_diffuseness = Q30;
     965      737503 :     move16();
     966             : 
     967      737503 :     return;
     968             : }
     969             : 
     970     3746091 : Word32 deindex_azimuth_fx(                             /* o  : output Q22                              */
     971             :                            Word16 id_phi,              /* i  : index                                   */
     972             :                            const Word16 no_bits,       /* i  : number of bits for the spherical grid   */
     973             :                            const Word16 id_th,         /* i  : elevation index                         */
     974             :                            const Word16 remap,         /* i  : remapping flag                          */
     975             :                            const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode            */
     976             : )
     977             : {
     978             :     Word16 flag_delta;
     979             :     Word32 dd_fx, delta_phi_fx;
     980             :     Word32 phi_hat_fx;
     981     3746091 :     test();
     982     3746091 :     IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) && EQ_16( no_bits, 2 ) )
     983             :     {
     984          10 :         IF( s_and( id_phi, 1 ) == 0 )
     985             :         {
     986           8 :             phi_hat_fx = cb_azi_chan_fx[id_phi / 2]; // Q22
     987           8 :             move32();
     988             :         }
     989             :         ELSE
     990             :         {
     991           2 :             phi_hat_fx = L_negate( cb_azi_chan_fx[( id_phi + 1 ) / 2] ); // Q22
     992             :         }
     993          10 :         return phi_hat_fx;
     994             :     }
     995     3746081 :     flag_delta = extract_l( EQ_16( s_and( id_th, 1 ), 1 ) );
     996             : 
     997     3746081 :     IF( remap )
     998             :     {
     999      229031 :         id_phi = add( ivas_qmetadata_dereorder_generic_fx( id_phi ), shr( no_phi_masa[no_bits - 1][id_th], 1 ) );
    1000             :     }
    1001             : 
    1002     3746081 :     delta_phi_fx = Mpy_32_32( 1509949440, no_phi_masa_inv_fx[no_bits - 1][id_th] ); // q = 22
    1003     3746081 :     test();
    1004     3746081 :     test();
    1005     3746081 :     IF( EQ_16( flag_delta, 1 ) && GT_16( no_phi_masa[no_bits - 1][id_th], 2 ) && EQ_32( mc_format, MC_LS_SETUP_INVALID ) )
    1006             :     {
    1007      907727 :         dd_fx = Mpy_32_32( delta_phi_fx, 1073741824 ); // q = 22
    1008             :     }
    1009             :     ELSE
    1010             :     {
    1011     2838354 :         dd_fx = 0;
    1012     2838354 :         move32();
    1013             :     }
    1014             : 
    1015     3746081 :     id_phi = sub( id_phi, shr( no_phi_masa[no_bits - 1][id_th], 1 ) );
    1016     3746081 :     phi_hat_fx = L_add( imult3216( delta_phi_fx, id_phi ), dd_fx );
    1017     3746081 :     IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) )
    1018             :     {
    1019      103073 :         Word32 a = L_shr( imult3216( delta_theta_masa_fx[no_bits - 3], id_th ), 22 ); // Q22 -> Q0
    1020      103073 :         move32();
    1021      103073 :         Word16 flag = 0;
    1022      103073 :         move16();
    1023      103073 :         if ( GT_32( a, MC_MASA_THR_ELEVATION ) )
    1024             :         {
    1025        7917 :             flag = 1;
    1026        7917 :             move16();
    1027             :         }
    1028      103073 :         phi_hat_fx = companding_azimuth_fx( phi_hat_fx, mc_format, flag, -1 );
    1029             :     }
    1030     3746081 :     return phi_hat_fx;
    1031             : }
    1032             : 
    1033             : 
    1034             : /*----------------------------------------------------------------
    1035             :  * deindex_spherical_component()
    1036             :  *
    1037             :  * decoding the spherical index for one tile
    1038             :  *-----------------------------------------------------------------*/
    1039             : 
    1040     1765287 : void deindex_spherical_component_fx(
    1041             :     const UWord16 sph_idx,      /* i  : spherical index                         */
    1042             :     Word32 *az_fx,              /* o  : decoded azimuth value               Q22 */
    1043             :     Word32 *el_fx,              /* o  : decoded elevation value             Q22 */
    1044             :     UWord16 *az_idx,            /* o  : azimuth index                           */
    1045             :     UWord16 *el_idx,            /* o  : elevation index                         */
    1046             :     const UWord16 no_bits,      /* i  : number of bits for the spherical grid   */
    1047             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode            */
    1048             : )
    1049             : {
    1050     1765287 :     assert( sph_idx < ( 1 << no_bits ) );
    1051     1765287 :     SWITCH( no_bits )
    1052             :     {
    1053           0 :         case 0:
    1054           0 :             *az_fx = 0;
    1055           0 :             move32();
    1056           0 :             *el_fx = 0;
    1057           0 :             move32();
    1058           0 :             *az_idx = 0;
    1059           0 :             move16();
    1060           0 :             *el_idx = 0;
    1061           0 :             move16();
    1062           0 :             BREAK;
    1063           0 :         case 1:
    1064           0 :             *az_idx = sph_idx;
    1065           0 :             move16();
    1066           0 :             *az_fx = L_shl( ( *az_idx ) * ( -180 ), 22 );
    1067           0 :             *el_fx = 0;
    1068           0 :             move32();
    1069           0 :             *el_idx = 0;
    1070           0 :             move16();
    1071           0 :             BREAK;
    1072         657 :         case 2:
    1073         657 :             *el_fx = 0;
    1074         657 :             move32();
    1075         657 :             *el_idx = 0;
    1076         657 :             move16();
    1077         657 :             *az_idx = sph_idx;
    1078         657 :             move16();
    1079         657 :             *az_fx = deindex_azimuth_fx( *az_idx, no_bits, 0, 0, mc_format );
    1080         657 :             move16();
    1081         657 :             BREAK;
    1082     1764630 :         default:
    1083     1764630 :             *el_idx = deindex_sph_idx_general_fx( sph_idx, no_bits, el_fx, az_fx, az_idx, mc_format );
    1084     1764630 :             move16();
    1085     1764630 :             BREAK;
    1086             :     }
    1087             : 
    1088     1765287 :     return;
    1089             : }
    1090             : 
    1091             : /*----------------------------------------------------------------
    1092             :  * calculate_hodirac_sector_parameters()
    1093             :  *
    1094             :  *
    1095             :  *-----------------------------------------------------------------*/
    1096             : 
    1097           0 : void calculate_hodirac_sector_parameters_fx(
    1098             :     DIRAC_ENC_HANDLE hDirAC,                                          /* i  : DirAC handle                                  */
    1099             :     Word32 RealBuffer_fx[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : signal vector (L+1)^2 x N_bins, real part     */
    1100             :     Word32 ImagBuffer_fx[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : signal vector, imaginary part                 */
    1101             :     Word16 Qfac,                                                      /* i  : Q-factor of signal vector                     */
    1102             :     const Word32 beta_fx,                                             /* i  : forgetting factor for average filtering, Q30  */
    1103             :     const Word16 *band_grouping,                                      /* i  : indices of band groups                        */
    1104             :     const Word16 N_bands,                                             /* i  : number of bands (groups)                      */
    1105             :     const Word16 enc_param_start_band,                                /* i  : first band to process                         */
    1106             :     Word32 *azi_fx,                                                   /* o  : array of sector azimuth angles, flat,    Q23  */
    1107             :     Word32 *ele_fx,                                                   /* o  : array of sector elevation angles, flat,  Q23  */
    1108             :     Word32 *diff_fx,                                                  /* o  : array of sector diffuseness values, flat      */
    1109             :     Word16 *diff_exp,                                                 /* o  : array of sector diffuseness exponents, flat   */
    1110             :     Word32 *ene_fx,                                                   /* o  : array of sector energy values, flat           */
    1111             :     Word16 *ene_exp                                                   /* o  : array of sector energy exponents, flat        */
    1112             : )
    1113             : {
    1114             :     Word16 i_sec, i_bin, i_band;
    1115             :     Word32 p_real_fx, p_imag_fx, normI_fx, energy_fx, tmp_diff_fx;
    1116             :     Word16 energy_exp, normI_exp, tmp_diff_exp;
    1117           0 :     Word16 tmp_exp_1 = sub( 33, shl( Qfac, 1 ) ); // 31 - (2 *Qfac - 2 )
    1118           0 :     Word16 tmp_exp_2 = sub( 35, shl( Qfac, 1 ) ); // 31 - (2 *Qfac - 4 )
    1119             :     Word32 tmp32_1, tmp32_2;
    1120           0 :     Word64 temp_x64 = 0, temp_y64 = 0, temp_z64 = 0;
    1121           0 :     Word16 tmp_scale = 0;
    1122           0 :     move64();
    1123           0 :     move64();
    1124           0 :     move64();
    1125           0 :     move16();
    1126             : 
    1127             :     Word32 sec_I_vec_x_fx[NUM_ANA_SECTORS];
    1128             :     Word32 sec_I_vec_y_fx[NUM_ANA_SECTORS];
    1129             :     Word32 sec_I_vec_z_fx[NUM_ANA_SECTORS];
    1130             :     Word16 sec_I_vec_x_exp[NUM_ANA_SECTORS];
    1131             :     Word16 sec_I_vec_y_exp[NUM_ANA_SECTORS];
    1132             :     Word16 sec_I_vec_z_exp[NUM_ANA_SECTORS];
    1133             : 
    1134           0 :     FOR( i_sec = 0; i_sec < NUM_ANA_SECTORS; i_sec++ )
    1135             :     {
    1136           0 :         Word32 *p_sec_I_vec_x_fx = &sec_I_vec_x_fx[i_sec];
    1137           0 :         Word32 *p_sec_I_vec_y_fx = &sec_I_vec_y_fx[i_sec];
    1138           0 :         Word32 *p_sec_I_vec_z_fx = &sec_I_vec_z_fx[i_sec];
    1139           0 :         Word16 *p_sec_I_vec_x_exp = &sec_I_vec_x_exp[i_sec];
    1140           0 :         Word16 *p_sec_I_vec_y_exp = &sec_I_vec_y_exp[i_sec];
    1141           0 :         Word16 *p_sec_I_vec_z_exp = &sec_I_vec_z_exp[i_sec];
    1142             : 
    1143           0 :         const Word32 *p_c_weights_fx = c_weights_fx; // Q30
    1144             : 
    1145           0 :         Word32 *p_ImagBuffer_0_fx = ImagBuffer_fx[0];
    1146           0 :         Word32 *p_ImagBuffer_1_fx = ImagBuffer_fx[1];
    1147           0 :         Word32 *p_ImagBuffer_2_fx = ImagBuffer_fx[2];
    1148           0 :         Word32 *p_ImagBuffer_3_fx = ImagBuffer_fx[3];
    1149           0 :         Word32 *p_ImagBuffer_4_fx = ImagBuffer_fx[4];
    1150           0 :         Word32 *p_ImagBuffer_5_fx = ImagBuffer_fx[5];
    1151           0 :         Word32 *p_ImagBuffer_6_fx = ImagBuffer_fx[6];
    1152           0 :         Word32 *p_ImagBuffer_8_fx = ImagBuffer_fx[8];
    1153             : 
    1154           0 :         Word32 *p_RealBuffer_0_fx = RealBuffer_fx[0];
    1155           0 :         Word32 *p_RealBuffer_1_fx = RealBuffer_fx[1];
    1156           0 :         Word32 *p_RealBuffer_2_fx = RealBuffer_fx[2];
    1157           0 :         Word32 *p_RealBuffer_3_fx = RealBuffer_fx[3];
    1158           0 :         Word32 *p_RealBuffer_4_fx = RealBuffer_fx[4];
    1159           0 :         Word32 *p_RealBuffer_5_fx = RealBuffer_fx[5];
    1160           0 :         Word32 *p_RealBuffer_6_fx = RealBuffer_fx[6];
    1161           0 :         Word32 *p_RealBuffer_8_fx = RealBuffer_fx[8];
    1162             : 
    1163           0 :         FOR( i_band = enc_param_start_band; i_band < N_bands; i_band++ )
    1164             :         {
    1165           0 :             Word32 *p_azi_fx = &azi_fx[i_sec * N_bands + i_band];
    1166           0 :             Word32 *p_ele_fx = &ele_fx[i_sec * N_bands + i_band];
    1167           0 :             Word32 *p_ene_fx = &ene_fx[i_sec * N_bands + i_band];
    1168           0 :             Word16 *p_ene_exp = &ene_exp[i_sec * N_bands + i_band];
    1169             : 
    1170           0 :             Word32 *p_diff_fx = &diff_fx[i_sec * N_bands + i_band];
    1171           0 :             Word16 *p_diff_exp = &diff_exp[i_sec * N_bands + i_band];
    1172           0 :             Word32 *p_azi_prev_fx = &hDirAC->azi_prev_fx[i_sec * N_bands + i_band];
    1173           0 :             Word32 *p_ele_prev_fx = &hDirAC->ele_prev_fx[i_sec * N_bands + i_band];
    1174             : 
    1175           0 :             Word32 *p_energy_smth_fx = &hDirAC->energy_smth_fx[i_sec][i_band];
    1176           0 :             Word16 *p_energy_smth_exp = &hDirAC->energy_smth_exp[i_sec][i_band];
    1177           0 :             Word32 *p_sec_I_vec_smth_x_fx = &hDirAC->sec_I_vec_smth_x_fx[i_sec][i_band];
    1178           0 :             Word32 *p_sec_I_vec_smth_y_fx = &hDirAC->sec_I_vec_smth_y_fx[i_sec][i_band];
    1179           0 :             Word32 *p_sec_I_vec_smth_z_fx = &hDirAC->sec_I_vec_smth_z_fx[i_sec][i_band];
    1180           0 :             Word16 *p_sec_I_vec_smth_x_exp = &hDirAC->sec_I_vec_smth_x_exp[i_sec][i_band];
    1181           0 :             Word16 *p_sec_I_vec_smth_y_exp = &hDirAC->sec_I_vec_smth_y_exp[i_sec][i_band];
    1182           0 :             Word16 *p_sec_I_vec_smth_z_exp = &hDirAC->sec_I_vec_smth_z_exp[i_sec][i_band];
    1183           0 :             *p_sec_I_vec_x_fx = 0;
    1184           0 :             move32();
    1185           0 :             *p_sec_I_vec_x_exp = 0;
    1186           0 :             move16();
    1187           0 :             *p_sec_I_vec_y_fx = 0;
    1188           0 :             move32();
    1189           0 :             *p_sec_I_vec_y_exp = 0;
    1190           0 :             move16();
    1191           0 :             *p_sec_I_vec_z_fx = 0;
    1192           0 :             move32();
    1193           0 :             *p_sec_I_vec_z_exp = 0;
    1194           0 :             move16();
    1195           0 :             energy_fx = 0;
    1196           0 :             move32();
    1197           0 :             energy_exp = 0;
    1198           0 :             move16();
    1199           0 :             Word64 sec_I_vec_x_64_fx = 0;
    1200           0 :             Word64 sec_I_vec_y_64_fx = 0;
    1201           0 :             Word64 sec_I_vec_z_64_fx = 0;
    1202           0 :             Word64 energy_64_fx = 0;
    1203           0 :             move64();
    1204           0 :             move64();
    1205           0 :             move64();
    1206           0 :             move64();
    1207           0 :             IF( i_sec == 0 )
    1208             :             {
    1209           0 :                 FOR( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
    1210             :                 {
    1211           0 :                     Word32 w_fx = *( p_c_weights_fx++ ); // Q30
    1212           0 :                     move32();
    1213             :                     Word32 sec_w_imag_fx, sec_x_imag_fx, sec_y_imag_fx, sec_z_imag_fx;
    1214             :                     Word32 sec_w_real_fx, sec_x_real_fx, sec_y_real_fx, sec_z_real_fx;
    1215           0 :                     sec_w_imag_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_0_fx ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx ) );                                                                                                                         // Qfac - 2
    1216           0 :                     sec_x_imag_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_4_fx++ ) );                                                                                                                     // Qfac - 2
    1217           0 :                     sec_y_imag_fx = Msub_32_32( ( Msub_32_32( ( Madd_32_32( Mpy_32_32( HODIRAC_FAC3, *( p_ImagBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx++ ) ) ), HODIRAC_FAC3, *( p_ImagBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_ImagBuffer_8_fx++ ) ); // Qfac - 2
    1218           0 :                     sec_z_imag_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_5_fx++ ) );                                                                                                                     // Qfac - 2
    1219             : 
    1220           0 :                     sec_w_real_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_0_fx ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx ) );                                                                                                                     // Qfac - 2
    1221           0 :                     sec_x_real_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_4_fx++ ) );                                                                                                                 // Qfac - 2
    1222           0 :                     sec_y_real_fx = Msub_32_32( ( Msub_32_32( Madd_32_32( Mpy_32_32( HODIRAC_FAC3, *( p_RealBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx++ ) ), HODIRAC_FAC3, *( p_RealBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_RealBuffer_8_fx++ ) ); // Qfac - 2
    1223           0 :                     sec_z_real_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_5_fx++ ) );                                                                                                                 // Qfac - 2
    1224             : 
    1225             : 
    1226           0 :                     p_real_fx = Mpy_32_32( sec_w_real_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
    1227           0 :                     p_imag_fx = Mpy_32_32( sec_w_imag_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
    1228             : 
    1229           0 :                     temp_x64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_x_real_fx ), p_imag_fx, sec_x_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1  =  2 * Qfac - 4
    1230           0 :                     temp_y64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_y_real_fx ), p_imag_fx, sec_y_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 =  2 * Qfac - 4
    1231           0 :                     temp_z64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_z_real_fx ), p_imag_fx, sec_z_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 =  2 * Qfac - 4
    1232           0 :                     sec_I_vec_x_64_fx = W_add( sec_I_vec_x_64_fx, temp_x64 );
    1233           0 :                     sec_I_vec_y_64_fx = W_add( sec_I_vec_y_64_fx, temp_y64 );
    1234           0 :                     sec_I_vec_z_64_fx = W_add( sec_I_vec_z_64_fx, temp_z64 );
    1235             : 
    1236             :                     Word64 tmp1;
    1237             :                     Word64 tmp2, tmp3, tmp4, sec_sum64;
    1238           0 :                     tmp1 = W_mac_32_32( W_mult_32_32( p_real_fx, p_real_fx ), p_imag_fx, p_imag_fx );                 // 2 * (Qfac - 3) + 1
    1239           0 :                     tmp1 = W_shl( tmp1, 2 );                                                                          // 2 * (Qfac - 2) + 1
    1240           0 :                     tmp2 = W_mac_32_32( W_mult_32_32( sec_x_real_fx, sec_x_real_fx ), sec_x_imag_fx, sec_x_imag_fx ); // 2 * (Qfac - 2) + 1
    1241           0 :                     tmp3 = W_mac_32_32( W_mult_32_32( sec_y_real_fx, sec_y_real_fx ), sec_y_imag_fx, sec_y_imag_fx ); // 2 * (Qfac - 2) + 1
    1242           0 :                     tmp4 = W_mac_32_32( W_mult_32_32( sec_z_real_fx, sec_z_real_fx ), sec_z_imag_fx, sec_z_imag_fx ); // 2 * (Qfac - 2) + 1
    1243           0 :                     sec_sum64 = W_add( tmp1, W_add( W_add( tmp2, tmp3 ), tmp4 ) );                                    // 2 * (Qfac - 2) + 1
    1244             : 
    1245             :                     // instead dividing changed Q//
    1246           0 :                     energy_64_fx = W_add( energy_64_fx, sec_sum64 ); // 2 * (Qfac - 2) + 1 + 1
    1247             :                 }
    1248           0 :                 tmp_scale = sub( W_norm( energy_64_fx ), 32 );
    1249           0 :                 energy_fx = W_shl_sat_l( energy_64_fx, tmp_scale );
    1250           0 :                 energy_exp = sub( tmp_exp_1, tmp_scale );
    1251           0 :                 if ( energy_fx == 0 )
    1252             :                 {
    1253           0 :                     energy_exp = 0;
    1254           0 :                     move16();
    1255             :                 }
    1256             : 
    1257           0 :                 tmp_scale = sub( W_norm( sec_I_vec_x_64_fx ), 32 );
    1258           0 :                 *p_sec_I_vec_x_fx = W_shl_sat_l( sec_I_vec_x_64_fx, tmp_scale );
    1259           0 :                 move32();
    1260           0 :                 *p_sec_I_vec_x_exp = sub( tmp_exp_2, tmp_scale );
    1261           0 :                 move16();
    1262           0 :                 if ( *p_sec_I_vec_x_fx == 0 )
    1263             :                 {
    1264           0 :                     *p_sec_I_vec_x_exp = 0;
    1265           0 :                     move16();
    1266             :                 }
    1267             : 
    1268           0 :                 tmp_scale = sub( W_norm( sec_I_vec_y_64_fx ), 32 );
    1269           0 :                 *p_sec_I_vec_y_fx = W_shl_sat_l( sec_I_vec_y_64_fx, tmp_scale );
    1270           0 :                 move32();
    1271           0 :                 *p_sec_I_vec_y_exp = sub( tmp_exp_2, tmp_scale );
    1272           0 :                 move16();
    1273           0 :                 if ( *p_sec_I_vec_y_fx == 0 )
    1274             :                 {
    1275           0 :                     *p_sec_I_vec_y_exp = 0;
    1276           0 :                     move16();
    1277             :                 }
    1278             : 
    1279           0 :                 tmp_scale = sub( W_norm( sec_I_vec_z_64_fx ), 32 );
    1280           0 :                 *p_sec_I_vec_z_fx = W_shl_sat_l( sec_I_vec_z_64_fx, tmp_scale );
    1281           0 :                 move32();
    1282           0 :                 *p_sec_I_vec_z_exp = sub( tmp_exp_2, tmp_scale );
    1283           0 :                 move16();
    1284           0 :                 if ( *p_sec_I_vec_z_fx == 0 )
    1285             :                 {
    1286           0 :                     *p_sec_I_vec_z_exp = 0;
    1287           0 :                     move16();
    1288             :                 }
    1289             :             }
    1290             :             ELSE
    1291             :             {
    1292           0 :                 FOR( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
    1293             :                 {
    1294           0 :                     Word32 w_fx = *( p_c_weights_fx++ ); // Q30
    1295           0 :                     move32();
    1296             :                     Word32 sec_w_imag_fx, sec_x_imag_fx, sec_y_imag_fx, sec_z_imag_fx;
    1297             :                     Word32 sec_w_real_fx, sec_x_real_fx, sec_y_real_fx, sec_z_real_fx;
    1298             : 
    1299           0 :                     sec_w_imag_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_0_fx ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx ) );                                                                                                                          // Qfac - 2
    1300           0 :                     sec_x_imag_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_4_fx++ ) );                                                                                                                      // Qfac - 2
    1301           0 :                     sec_y_imag_fx = Madd_32_32( ( Madd_32_32( ( Madd_32_32( Mpy_32_32( -HODIRAC_FAC3, *( p_ImagBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx++ ) ) ), HODIRAC_FAC3, *( p_ImagBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_ImagBuffer_8_fx++ ) ); // Qfac - 2
    1302           0 :                     sec_z_imag_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_5_fx++ ) );                                                                                                                      // Qfac - 2
    1303             : 
    1304           0 :                     sec_w_real_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_0_fx ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx ) );                                                                                                                          // Qfac - 2
    1305           0 :                     sec_x_real_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_4_fx++ ) );                                                                                                                      // Qfac - 2
    1306           0 :                     sec_y_real_fx = Madd_32_32( ( Madd_32_32( ( Madd_32_32( Mpy_32_32( -HODIRAC_FAC3, *( p_RealBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx++ ) ) ), HODIRAC_FAC3, *( p_RealBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_RealBuffer_8_fx++ ) ); // Qfac - 2
    1307           0 :                     sec_z_real_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_5_fx++ ) );                                                                                                                      // Qfac - 2
    1308             : 
    1309             : 
    1310           0 :                     p_real_fx = Mpy_32_32( sec_w_real_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
    1311           0 :                     p_imag_fx = Mpy_32_32( sec_w_imag_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
    1312             : 
    1313           0 :                     temp_x64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_x_real_fx ), p_imag_fx, sec_x_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 =  2 * Qfac - 4
    1314           0 :                     temp_y64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_y_real_fx ), p_imag_fx, sec_y_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 =  2 * Qfac - 4
    1315           0 :                     temp_z64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_z_real_fx ), p_imag_fx, sec_z_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 =  2 * Qfac - 4
    1316           0 :                     sec_I_vec_x_64_fx = W_add( sec_I_vec_x_64_fx, temp_x64 );
    1317           0 :                     sec_I_vec_y_64_fx = W_add( sec_I_vec_y_64_fx, temp_y64 );
    1318           0 :                     sec_I_vec_z_64_fx = W_add( sec_I_vec_z_64_fx, temp_z64 );
    1319             : 
    1320             :                     Word64 tmp1;
    1321             :                     Word64 tmp2, tmp3, tmp4, sec_sum64;
    1322           0 :                     tmp1 = W_mac_32_32( W_mult_32_32( p_real_fx, p_real_fx ), p_imag_fx, p_imag_fx );                 // 2 * (Qfac - 3) + 1
    1323           0 :                     tmp1 = W_shl( tmp1, 2 );                                                                          // 2 * (Qfac - 2) + 1
    1324           0 :                     tmp2 = W_mac_32_32( W_mult_32_32( sec_x_real_fx, sec_x_real_fx ), sec_x_imag_fx, sec_x_imag_fx ); // 2 * (Qfac - 2) + 1
    1325           0 :                     tmp3 = W_mac_32_32( W_mult_32_32( sec_y_real_fx, sec_y_real_fx ), sec_y_imag_fx, sec_y_imag_fx ); // 2 * (Qfac - 2) + 1
    1326           0 :                     tmp4 = W_mac_32_32( W_mult_32_32( sec_z_real_fx, sec_z_real_fx ), sec_z_imag_fx, sec_z_imag_fx ); // 2 * (Qfac - 2) + 1
    1327           0 :                     sec_sum64 = W_add( tmp1, W_add( W_add( tmp2, tmp3 ), tmp4 ) );                                    // 2 * (Qfac - 2) + 1
    1328             : 
    1329             :                     // instead dividing changed Q//
    1330           0 :                     energy_64_fx = W_add( energy_64_fx, sec_sum64 ); // 2 * (Qfac - 2) + 1 + 1
    1331             :                 }
    1332           0 :                 tmp_scale = sub( W_norm( energy_64_fx ), 32 );
    1333           0 :                 energy_fx = W_shl_sat_l( energy_64_fx, tmp_scale );
    1334           0 :                 energy_exp = sub( tmp_exp_1, tmp_scale );
    1335           0 :                 if ( energy_fx == 0 )
    1336             :                 {
    1337           0 :                     energy_exp = 0;
    1338           0 :                     move16();
    1339             :                 }
    1340             : 
    1341           0 :                 tmp_scale = sub( W_norm( sec_I_vec_x_64_fx ), 32 );
    1342           0 :                 *p_sec_I_vec_x_fx = W_shl_sat_l( sec_I_vec_x_64_fx, tmp_scale );
    1343           0 :                 move32();
    1344           0 :                 *p_sec_I_vec_x_exp = sub( tmp_exp_2, tmp_scale );
    1345           0 :                 move16();
    1346           0 :                 if ( *p_sec_I_vec_x_fx == 0 )
    1347             :                 {
    1348           0 :                     *p_sec_I_vec_x_exp = 0;
    1349           0 :                     move16();
    1350             :                 }
    1351             : 
    1352           0 :                 tmp_scale = sub( W_norm( sec_I_vec_y_64_fx ), 32 );
    1353           0 :                 *p_sec_I_vec_y_fx = W_shl_sat_l( sec_I_vec_y_64_fx, tmp_scale );
    1354           0 :                 move32();
    1355           0 :                 *p_sec_I_vec_y_exp = sub( tmp_exp_2, tmp_scale );
    1356           0 :                 move16();
    1357           0 :                 if ( *p_sec_I_vec_y_fx == 0 )
    1358             :                 {
    1359           0 :                     *p_sec_I_vec_y_exp = 0;
    1360           0 :                     move16();
    1361             :                 }
    1362             : 
    1363           0 :                 tmp_scale = sub( W_norm( sec_I_vec_z_64_fx ), 32 );
    1364           0 :                 *p_sec_I_vec_z_fx = W_shl_sat_l( sec_I_vec_z_64_fx, tmp_scale );
    1365           0 :                 move32();
    1366           0 :                 *p_sec_I_vec_z_exp = sub( tmp_exp_2, tmp_scale );
    1367           0 :                 move16();
    1368           0 :                 if ( *p_sec_I_vec_z_fx == 0 )
    1369             :                 {
    1370           0 :                     *p_sec_I_vec_z_exp = 0;
    1371           0 :                     move16();
    1372             :                 }
    1373             :             }
    1374             : 
    1375           0 :             IF( hDirAC->firstrun_sector_params )
    1376             :             {
    1377           0 :                 *p_sec_I_vec_smth_x_fx = *p_sec_I_vec_x_fx;
    1378           0 :                 move32();
    1379           0 :                 *p_sec_I_vec_smth_y_fx = *p_sec_I_vec_y_fx;
    1380           0 :                 move32();
    1381           0 :                 *p_sec_I_vec_smth_z_fx = *p_sec_I_vec_z_fx;
    1382           0 :                 move32();
    1383           0 :                 *p_energy_smth_fx = energy_fx;
    1384           0 :                 move32();
    1385           0 :                 *p_sec_I_vec_smth_x_exp = *p_sec_I_vec_x_exp;
    1386           0 :                 move16();
    1387           0 :                 *p_sec_I_vec_smth_y_exp = *p_sec_I_vec_y_exp;
    1388           0 :                 move16();
    1389           0 :                 *p_sec_I_vec_smth_z_exp = *p_sec_I_vec_z_exp;
    1390           0 :                 move16();
    1391           0 :                 *p_energy_smth_exp = energy_exp;
    1392           0 :                 move16();
    1393             :             }
    1394             :             ELSE
    1395             :             {
    1396           0 :                 Word32 w_fx = L_sub( ONE_IN_Q30, beta_fx ); // Q30
    1397             :                 Word32 tmp_1, tmp_2, tmp_3, tmp_sec_1, tmp_sec_2, tmp_sec_3;
    1398             :                 Word16 e_x, e_y, e_z;
    1399           0 :                 move16();
    1400             : 
    1401           0 :                 e_x = s_max( *p_sec_I_vec_x_exp, *p_sec_I_vec_smth_x_exp );
    1402           0 :                 e_y = s_max( *p_sec_I_vec_y_exp, *p_sec_I_vec_smth_y_exp );
    1403           0 :                 e_z = s_max( *p_sec_I_vec_z_exp, *p_sec_I_vec_smth_z_exp );
    1404             : 
    1405           0 :                 tmp_1 = L_shr( *p_sec_I_vec_x_fx, sub( e_x, *p_sec_I_vec_x_exp ) );               // e_x
    1406           0 :                 tmp_2 = L_shr( *p_sec_I_vec_y_fx, sub( e_y, *p_sec_I_vec_y_exp ) );               // e_y
    1407           0 :                 tmp_3 = L_shr( *p_sec_I_vec_z_fx, sub( e_z, *p_sec_I_vec_z_exp ) );               // e_z
    1408           0 :                 tmp_sec_1 = L_shr( *p_sec_I_vec_smth_x_fx, sub( e_x, *p_sec_I_vec_smth_x_exp ) ); // e_x
    1409           0 :                 tmp_sec_2 = L_shr( *p_sec_I_vec_smth_y_fx, sub( e_y, *p_sec_I_vec_smth_y_exp ) ); // e_y
    1410           0 :                 tmp_sec_3 = L_shr( *p_sec_I_vec_smth_z_fx, sub( e_z, *p_sec_I_vec_smth_z_exp ) ); // e_z
    1411             : 
    1412             : 
    1413           0 :                 temp_x64 = W_mac_32_32( W_mult_32_32( w_fx, tmp_1 ), beta_fx, tmp_sec_1 ); // 31-e_x+30+1=62-e_x
    1414           0 :                 temp_y64 = W_mac_32_32( W_mult_32_32( w_fx, tmp_2 ), beta_fx, tmp_sec_2 ); // 31-e_y+30+1=62-e_y
    1415           0 :                 temp_z64 = W_mac_32_32( W_mult_32_32( w_fx, tmp_3 ), beta_fx, tmp_sec_3 ); // 31-e_z+30+1=62-e_z
    1416             : 
    1417           0 :                 tmp_scale = sub( W_norm( temp_x64 ), 32 );
    1418           0 :                 *p_sec_I_vec_smth_x_fx = W_shl_sat_l( temp_x64, tmp_scale );
    1419           0 :                 move32();
    1420           0 :                 *p_sec_I_vec_smth_x_exp = sub( sub( e_x, 31 ), tmp_scale ); // 31-(62-e_x+tmp_scale)=e_x-tmp_scale-31
    1421           0 :                 move16();
    1422           0 :                 if ( *p_sec_I_vec_smth_x_fx == 0 )
    1423             :                 {
    1424           0 :                     *p_sec_I_vec_smth_x_exp = 0;
    1425           0 :                     move16();
    1426             :                 }
    1427             : 
    1428           0 :                 tmp_scale = sub( W_norm( temp_y64 ), 32 );
    1429           0 :                 *p_sec_I_vec_smth_y_fx = W_shl_sat_l( temp_y64, tmp_scale );
    1430           0 :                 move32();
    1431           0 :                 *p_sec_I_vec_smth_y_exp = sub( sub( e_y, 31 ), tmp_scale ); // 31-(62-e_z+tmp_scale)=e_x-tmp_scale-31
    1432           0 :                 move16();
    1433           0 :                 if ( *p_sec_I_vec_smth_y_fx == 0 )
    1434             :                 {
    1435           0 :                     *p_sec_I_vec_smth_y_exp = 0;
    1436           0 :                     move16();
    1437             :                 }
    1438             : 
    1439           0 :                 tmp_scale = sub( W_norm( temp_z64 ), 32 );
    1440           0 :                 *p_sec_I_vec_smth_z_fx = W_shl_sat_l( temp_z64, tmp_scale );
    1441           0 :                 move32();
    1442           0 :                 *p_sec_I_vec_smth_z_exp = sub( sub( e_z, 31 ), tmp_scale ); // 31-(62-e_z+tmp_scale)=e_x-tmp_scale-31
    1443           0 :                 move16();
    1444           0 :                 if ( *p_sec_I_vec_smth_z_fx == 0 )
    1445             :                 {
    1446           0 :                     *p_sec_I_vec_smth_z_exp = 0;
    1447           0 :                     move16();
    1448             :                 }
    1449             : 
    1450           0 :                 *p_energy_smth_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( w_fx, energy_fx ), add( energy_exp, 1 ), Mpy_32_32( beta_fx, *p_energy_smth_fx ), add( *p_energy_smth_exp, 1 ), p_energy_smth_exp );
    1451           0 :                 move32();
    1452             :             }
    1453             : 
    1454           0 :             IF( LT_32( energy_fx, EPSILON_FX_SMALL ) )
    1455             :             {
    1456           0 :                 *p_azi_fx = 0;
    1457           0 :                 move32();
    1458           0 :                 *p_ele_fx = 0;
    1459           0 :                 move32();
    1460           0 :                 *p_ene_fx = 0;
    1461           0 :                 move32();
    1462           0 :                 *p_ene_exp = 0;
    1463           0 :                 move16();
    1464           0 :                 *p_diff_fx = ONE_IN_Q30;
    1465           0 :                 move32();
    1466           0 :                 *p_diff_exp = 1;
    1467           0 :                 move16();
    1468             :             }
    1469             :             ELSE
    1470             :             {
    1471             :                 Word32 tmp_x, tmp_y, tmp_z, tmp_xy_hypo, tmp32;
    1472             :                 Word16 tmp16, tmp_e;
    1473           0 :                 tmp_x = Mpy_32_32( *p_sec_I_vec_smth_x_fx, *p_sec_I_vec_smth_x_fx );
    1474           0 :                 tmp_y = Mpy_32_32( *p_sec_I_vec_smth_y_fx, *p_sec_I_vec_smth_y_fx );
    1475           0 :                 tmp_z = Mpy_32_32( *p_sec_I_vec_smth_z_fx, *p_sec_I_vec_smth_z_fx );
    1476           0 :                 tmp32 = BASOP_Util_Add_Mant32Exp( tmp_x, shl( *p_sec_I_vec_smth_x_exp, 1 ), tmp_y, shl( *p_sec_I_vec_smth_y_exp, 1 ), &tmp_e );
    1477           0 :                 normI_fx = BASOP_Util_Add_Mant32Exp( tmp32, tmp_e, tmp_z, shl( *p_sec_I_vec_smth_z_exp, 1 ), &normI_exp );
    1478           0 :                 normI_fx = Sqrt32( normI_fx, &normI_exp );
    1479             : 
    1480           0 :                 tmp32 = BASOP_Util_Add_Mant32Exp( tmp32, tmp_e, 0, 0, &tmp_e ); // normalising value of tmp32
    1481           0 :                 tmp_xy_hypo = Sqrt32( tmp32, &tmp_e );                          // sqrt(x^2 + y^2)
    1482             : 
    1483           0 :                 tmp16 = BASOP_util_atan2( *p_sec_I_vec_smth_y_fx, *p_sec_I_vec_smth_x_fx, sub( *p_sec_I_vec_smth_y_exp, *p_sec_I_vec_smth_x_exp ) ); // Q13
    1484           0 :                 *p_azi_fx = Mpy_32_32( L_deposit_h( tmp16 ), _180_OVER_PI_Q25 );                                                                     // (Q13 + 16) + Q25 - 31 = 54 - 31 = Q23
    1485           0 :                 move32();
    1486           0 :                 tmp16 = BASOP_util_atan2( *p_sec_I_vec_smth_z_fx, L_add( tmp_xy_hypo, EPSILON_FX_SMALL ), sub( *p_sec_I_vec_smth_z_exp, tmp_e ) ); // Q13
    1487           0 :                 *p_ele_fx = Mpy_32_32( L_deposit_h( tmp16 ), _180_OVER_PI_Q25 );                                                                   // (Q13 + 16) + Q25 - 31 = 54 - 31 = Q23
    1488           0 :                 move32();
    1489           0 :                 *p_ene_fx = *p_energy_smth_fx;
    1490           0 :                 move32();
    1491           0 :                 *p_ene_exp = *p_energy_smth_exp;
    1492           0 :                 move16();
    1493             : 
    1494           0 :                 tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( normI_fx, L_add_sat( *p_energy_smth_fx, EPSILON_FX_SMALL ), &tmp_e ) );
    1495           0 :                 tmp_e = add( tmp_e, sub( normI_exp, *p_energy_smth_exp ) );
    1496           0 :                 tmp32 = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, L_negate( tmp32 ), tmp_e, &tmp_e );
    1497           0 :                 *p_diff_fx = tmp32;
    1498           0 :                 move32();
    1499           0 :                 *p_diff_exp = tmp_e;
    1500           0 :                 move16();
    1501             :             }
    1502             : 
    1503           0 :             tmp_diff_fx = *p_diff_fx;
    1504           0 :             move32();
    1505           0 :             tmp_diff_exp = *p_diff_exp;
    1506           0 :             move16();
    1507           0 :             if ( tmp_diff_fx < 0 )
    1508             :             {
    1509           0 :                 tmp_diff_fx = 0;
    1510           0 :                 move32();
    1511             :             }
    1512             : 
    1513           0 :             tmp_diff_fx = L_shr( tmp_diff_fx, sub( 2, tmp_diff_exp ) ); // Q29
    1514           0 :             tmp_diff_exp = 2;
    1515           0 :             move16();
    1516             : 
    1517           0 :             IF( GT_32( tmp_diff_fx, ONE_IN_Q28 ) )
    1518             :             {
    1519           0 :                 IF( hDirAC->firstrun_sector_params )
    1520             :                 {
    1521           0 :                     *p_azi_fx = 0;
    1522           0 :                     move32();
    1523           0 :                     *p_ele_fx = 0;
    1524           0 :                     move32();
    1525             :                 }
    1526             :                 ELSE
    1527             :                 {
    1528           0 :                     tmp32_1 = L_sub( ONE_IN_Q29, tmp_diff_fx );
    1529           0 :                     tmp32_2 = L_sub( tmp_diff_fx, ONE_IN_Q29 / 2 );
    1530             : 
    1531             :                     // *p_azi = 2.f * (1.f - tmp_diff) * *p_azi + (2.f * tmp_diff - 1.f) * *p_azi_prev
    1532           0 :                     *p_azi_fx = L_shl( Madd_32_32( Mpy_32_32( tmp32_1, *p_azi_fx ), tmp32_2, *p_azi_prev_fx ), 3 ); // Q29 + Q23 - 31 + 2 = Q23
    1533           0 :                     move32();
    1534             : 
    1535             :                     // *p_ele = 2.f * (1.f - tmp_diff) * *p_ele + (2.f * tmp_diff - 1.f) * *p_ele_prev
    1536           0 :                     *p_ele_fx = L_shl( Madd_32_32( Mpy_32_32( tmp32_1, *p_ele_fx ), tmp32_2, *p_ele_prev_fx ), 3 ); // Q29 + Q23 - 31 + 2 = Q23
    1537           0 :                     move32();
    1538             :                 }
    1539             :             }
    1540             :             ELSE
    1541             :             {
    1542           0 :                 *p_azi_prev_fx = *p_azi_fx;
    1543           0 :                 move32();
    1544           0 :                 *p_ele_prev_fx = *p_ele_fx;
    1545           0 :                 move32();
    1546             :             }
    1547             :         }
    1548             :     }
    1549             : 
    1550           0 :     hDirAC->firstrun_sector_params = 0;
    1551           0 :     move16();
    1552             : 
    1553           0 :     return;
    1554             : }
    1555             : 
    1556             : 
    1557             : /*-----------------------------------------------------------------------*
    1558             :  * Local functions
    1559             :  *-----------------------------------------------------------------------*/
    1560             : 
    1561             : 
    1562             : /*-------------------------------------------------------------------*
    1563             :  * deindex_sph_idx_general()
    1564             :  *
    1565             :  * deindex the spherical index for more than 2 bits for the spherical grid
    1566             :  *----------------------------------------------------------------------*/
    1567             : 
    1568     1764630 : static UWord16 deindex_sph_idx_general_fx(
    1569             :     const Word16 idx_sph,       /* i  : spherical index                           */
    1570             :     const Word16 no_bits,       /* i  : number of bits in the spherical grid      */
    1571             :     Word32 *theta_dec_fx,       /* o  : decoded elevation value               Q22 */
    1572             :     Word32 *phi_dec_fx,         /* o  : decoded azimuth value                 Q22 */
    1573             :     UWord16 *p_id_phi,          /* o  : decoded azimuth index                     */
    1574             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode              */
    1575             : )
    1576             : {
    1577             :     Word16 i;
    1578             :     UWord16 id_th;
    1579             :     Word16 q_id_th;
    1580             :     Word32 id_th_fx;
    1581             :     Word16 sign_theta;
    1582             :     Word16 id_phi;
    1583             :     Word16 cum_n[250];
    1584             :     Word16 no_th;
    1585             :     const Word16 *n;
    1586             : 
    1587     1764630 :     id_th = 0;
    1588     1764630 :     move16();
    1589     1764630 :     id_phi = 0;
    1590     1764630 :     move16();
    1591     1764630 :     sign_theta = 1;
    1592     1764630 :     move16();
    1593             : 
    1594     1764630 :     no_th = no_theta_masa[no_bits - 3];
    1595     1764630 :     move16();
    1596     1764630 :     n = no_phi_masa[no_bits - 1];
    1597     1764630 :     IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) )
    1598             :     {
    1599             :         /* indexing */
    1600             : 
    1601        9710 :         cum_n[0] = n[0];
    1602        9710 :         move16();
    1603        9710 :         IF( GE_16( idx_sph, cum_n[0] ) )
    1604             :         {
    1605       11928 :             FOR( i = 1; i < no_th; i++ )
    1606             :             {
    1607       11928 :                 cum_n[i] = add( cum_n[i - 1], n[i] );
    1608       11928 :                 move16();
    1609       11928 :                 IF( LT_16( idx_sph, cum_n[i] ) )
    1610             :                 {
    1611        8170 :                     id_th = i;
    1612        8170 :                     move16();
    1613        8170 :                     id_phi = sub( idx_sph, cum_n[i - 1] );
    1614        8170 :                     BREAK;
    1615             :                 }
    1616             :             }
    1617             :         }
    1618             :     }
    1619             :     ELSE
    1620             :     {
    1621             :         /* Starting from Equator, alternating positive and negative */
    1622     1754920 :         cum_n[0] = n[0];
    1623     1754920 :         move16();
    1624     1754920 :         IF( GE_16( idx_sph, cum_n[0] ) )
    1625             :         {
    1626     1394008 :             FOR( i = 1; i < no_th; i++ )
    1627             :             {
    1628     1394008 :                 cum_n[2 * i - 1] = add( cum_n[2 * i - 2], n[i] );
    1629     1394008 :                 move16();
    1630             : 
    1631     1394008 :                 IF( LT_16( idx_sph, cum_n[2 * i - 1] ) )
    1632             :                 {
    1633      408123 :                     id_th = i;
    1634      408123 :                     move16();
    1635      408123 :                     sign_theta = 1;
    1636      408123 :                     move16();
    1637      408123 :                     id_phi = sub( idx_sph, cum_n[2 * i - 2] );
    1638      408123 :                     BREAK;
    1639             :                 }
    1640             : 
    1641      985885 :                 cum_n[2 * i] = add( cum_n[2 * i - 1], n[i] );
    1642      985885 :                 move16();
    1643             : 
    1644      985885 :                 IF( LT_16( idx_sph, cum_n[2 * i] ) )
    1645             :                 {
    1646      430173 :                     id_th = i;
    1647      430173 :                     move16();
    1648      430173 :                     sign_theta = -1;
    1649      430173 :                     move16();
    1650      430173 :                     id_phi = sub( idx_sph, cum_n[2 * i - 1] );
    1651      430173 :                     BREAK;
    1652             :                 }
    1653             : 
    1654      555712 :                 IF( EQ_16( i, sub( no_th, 1 ) ) )
    1655             :                 {
    1656           0 :                     id_th = i;
    1657           0 :                     move16();
    1658           0 :                     sign_theta = -1;
    1659           0 :                     move16();
    1660           0 :                     id_phi = 0; /* idx_sph - cum_n[2*i-1]; */
    1661           0 :                     move16();
    1662           0 :                     BREAK;
    1663             :                 }
    1664             :             }
    1665             :         }
    1666             :     }
    1667             : 
    1668     1764630 :     IF( id_th == 0 )
    1669             :     {
    1670      918164 :         id_phi = idx_sph;
    1671      918164 :         move16();
    1672             :     }
    1673             :     ELSE
    1674             :     {
    1675      846466 :         test();
    1676      846466 :         if ( EQ_32( id_th, sub( no_th, 1 ) ) && GT_16( no_bits, 4 ) )
    1677             :         {
    1678        2568 :             id_phi = 0;
    1679        2568 :             move16();
    1680             :         }
    1681             :     }
    1682             : 
    1683     1764630 :     q_id_th = norm_l( id_th );
    1684     1764630 :     id_th_fx = L_shl( id_th, q_id_th );
    1685     1764630 :     *theta_dec_fx = L_shl( Mpy_32_32( id_th_fx, delta_theta_masa_fx[no_bits - 3] ), sub( 31, q_id_th ) ); // Q22
    1686     1764630 :     move32();
    1687             : 
    1688     1764630 :     IF( GE_32( *theta_dec_fx, 90 << Q22 ) )
    1689             :     {
    1690        2538 :         *theta_dec_fx = ( 90 << 22 ) * sign_theta;
    1691        2538 :         move32();
    1692        2538 :         *phi_dec_fx = 0;
    1693        2538 :         move32();
    1694        2538 :         *p_id_phi = 0;
    1695        2538 :         move16();
    1696             :     }
    1697             :     ELSE
    1698             :     {
    1699     1762092 :         *theta_dec_fx *= sign_theta;
    1700             : 
    1701     1762092 :         *phi_dec_fx = deindex_azimuth_fx( id_phi, no_bits, id_th, 0, mc_format ); // Q22
    1702     1762092 :         move32();
    1703     1762092 :         *p_id_phi = id_phi;
    1704     1762092 :         move16();
    1705             :     }
    1706             : 
    1707     1764630 :     return id_th;
    1708             : }

Generated by: LCOV version 1.14