LCOV - code coverage report
Current view: top level - lib_com - ivas_dirac_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 375 401 93.5 %
Date: 2025-05-23 08:37:30 Functions: 11 11 100.0 %

          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 "ivas_prot.h"
      40             : #include "prot.h"
      41             : #include "cnst.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : 
      45             : /*-----------------------------------------------------------------------*
      46             :  * Local function prototypes
      47             :  *-----------------------------------------------------------------------*/
      48             : 
      49             : static uint16_t deindex_sph_idx_general( const int16_t idx_sph, const int16_t no_bits, float *theta_dec, float *phi_dec, uint16_t *p_id_phi, const MC_LS_SETUP mc_format );
      50             : 
      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     1895891 : int16_t ivas_get_hodirac_flag(
      60             :     const int32_t ivas_total_brate, /* i  : IVAS total bitrate      */
      61             :     const int16_t sba_order         /* i  : Ambisonic (SBA) order   */
      62             : )
      63             : {
      64     1895891 :     if ( sba_order > 1 && ivas_total_brate > IVAS_256k )
      65             :     {
      66      242158 :         return 1;
      67             :     }
      68             :     else
      69             :     {
      70     1653733 :         return 0;
      71             :     }
      72             : }
      73             : 
      74             : 
      75             : /*-------------------------------------------------------------------------
      76             :  * ivas_dirac_sba_config()
      77             :  *
      78             :  * DirAC Configuration function; used also in MASA decoder
      79             :  *------------------------------------------------------------------------*/
      80             : 
      81       16006 : ivas_error ivas_dirac_config(
      82             :     void *st_ivas,        /* i/o: IVAS encoder/decoder state structure  */
      83             :     const int16_t enc_dec /* i  : encoder or decoder flag               */
      84             : )
      85             : {
      86             :     IVAS_FORMAT ivas_format;
      87             :     int16_t sba_order;
      88             :     int16_t *element_mode;
      89             :     int32_t ivas_total_brate;
      90             :     DIRAC_CONFIG_DATA_HANDLE hConfig;
      91             :     IVAS_QMETADATA_HANDLE hQMetaData;
      92             :     int32_t Fs;
      93             :     int16_t *band_grouping;
      94             :     ivas_error error;
      95             :     int16_t spar_dirac_split_band;
      96             :     IVAS_FB_MIXER_HANDLE hFbMdft;
      97             :     int16_t *dirac_to_spar_md_bands;
      98             : 
      99       16006 :     error = IVAS_ERR_OK;
     100             : 
     101       16006 :     if ( enc_dec == ENC )
     102             :     {
     103        1954 :         ivas_format = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_format;
     104        1954 :         element_mode = &( (Encoder_Struct *) st_ivas )->hEncoderConfig->element_mode_init;
     105        1954 :         sba_order = ( (Encoder_Struct *) st_ivas )->sba_analysis_order;
     106        1954 :         ivas_total_brate = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_total_brate;
     107        1954 :         Fs = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->input_Fs;
     108        1954 :         band_grouping = ( (Encoder_Struct *) st_ivas )->hDirAC->band_grouping;
     109        1954 :         hConfig = ( (Encoder_Struct *) st_ivas )->hDirAC->hConfig;
     110        1954 :         hQMetaData = ( (Encoder_Struct *) st_ivas )->hQMetaData;
     111        1954 :         if ( ( (Encoder_Struct *) st_ivas )->hSpar != NULL )
     112             :         {
     113        1954 :             hFbMdft = ( (Encoder_Struct *) st_ivas )->hSpar->hFbMixer;
     114        1954 :             dirac_to_spar_md_bands = ( (Encoder_Struct *) st_ivas )->hSpar->dirac_to_spar_md_bands;
     115             :         }
     116             :         else
     117             :         {
     118           0 :             hFbMdft = NULL;
     119           0 :             dirac_to_spar_md_bands = NULL;
     120             :         }
     121             :     }
     122             :     else
     123             :     {
     124       14052 :         ivas_format = ( (Decoder_Struct *) st_ivas )->ivas_format;
     125       14052 :         element_mode = &( (Decoder_Struct *) st_ivas )->element_mode_init;
     126       14052 :         sba_order = ( (Decoder_Struct *) st_ivas )->sba_analysis_order;
     127       14052 :         ivas_total_brate = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->ivas_total_brate;
     128       14052 :         Fs = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->output_Fs;
     129       14052 :         band_grouping = ( (Decoder_Struct *) st_ivas )->hDirAC->band_grouping;
     130       14052 :         hConfig = ( (Decoder_Struct *) st_ivas )->hDirAC->hConfig;
     131       14052 :         hQMetaData = ( (Decoder_Struct *) st_ivas )->hQMetaData;
     132       14052 :         if ( ( (Decoder_Struct *) st_ivas )->hSpar != NULL )
     133             :         {
     134        4035 :             hFbMdft = ( (Decoder_Struct *) st_ivas )->hSpar->hFbMixer;
     135        4035 :             dirac_to_spar_md_bands = ( (Decoder_Struct *) st_ivas )->hSpar->dirac_to_spar_md_bands;
     136             :         }
     137             :         else
     138             :         {
     139       10017 :             hFbMdft = NULL;
     140       10017 :             dirac_to_spar_md_bands = NULL;
     141             :         }
     142       14052 :         ( (Decoder_Struct *) st_ivas )->hDirAC->hFbMdft = hFbMdft;
     143             :     }
     144             : 
     145       16006 :     if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT )
     146             :     {
     147        5989 :         hConfig->nbands = IVAS_MAX_NUM_BANDS;
     148             : 
     149        5989 :         spar_dirac_split_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
     150             : 
     151        5989 :         if ( ivas_get_hodirac_flag( ivas_total_brate, sba_order ) )
     152             :         {
     153         606 :             spar_dirac_split_band = 0;
     154             :         }
     155             :     }
     156             :     else
     157             :     {
     158       10017 :         hConfig->nbands = 5;
     159       10017 :         spar_dirac_split_band = 0;
     160             :     }
     161       16006 :     hConfig->enc_param_start_band = 0;
     162       16006 :     hConfig->dec_param_estim = FALSE;
     163       16006 :     if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) /* skip for MASA decoder */
     164             :     {
     165        5989 :         if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band, ivas_format ) ) != IVAS_ERR_OK )
     166             :         {
     167           0 :             return error;
     168             :         }
     169             : 
     170        5989 :         if ( hQMetaData != NULL )
     171             :         {
     172        5989 :             if ( enc_dec == ENC )
     173             :             {
     174        1954 :                 hConfig->nbands = hQMetaData->q_direction[0].cfg.nbands;
     175             :             }
     176        5989 :             hConfig->enc_param_start_band = hQMetaData->q_direction[0].cfg.start_band + spar_dirac_split_band;
     177             :         }
     178             : 
     179        5989 :         hConfig->dec_param_estim = TRUE;
     180        5989 :         if ( hConfig->dec_param_estim == TRUE )
     181             :         {
     182        5989 :             hConfig->enc_param_start_band = spar_dirac_split_band;
     183             :         }
     184             : 
     185        5989 :         if ( ivas_get_hodirac_flag( ivas_total_brate, sba_order ) )
     186             :         {
     187         606 :             hConfig->dec_param_estim = FALSE;
     188         606 :             hConfig->enc_param_start_band = 0;
     189             : 
     190         606 :             set_c( (int8_t *) hQMetaData->twoDirBands, (int8_t) 1, hQMetaData->q_direction[0].cfg.nbands );
     191         606 :             hQMetaData->numTwoDirBands = (uint8_t) hQMetaData->q_direction[0].cfg.nbands;
     192             :         }
     193             :     }
     194             : 
     195       16006 :     if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT )
     196             :     {
     197        5989 :         ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hConfig->enc_param_start_band, hFbMdft, 1 );
     198             :     }
     199             :     else
     200             :     {
     201       10017 :         ivas_dirac_config_bands( band_grouping, hConfig->nbands, (int16_t) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), NULL, 0, 0, hFbMdft, 1 );
     202             :     }
     203             : 
     204       16006 :     return error;
     205             : }
     206             : 
     207             : 
     208             : /*-------------------------------------------------------------------------
     209             :  * ivas_dirac_config_bands()
     210             :  *
     211             :  * DirAC Configuration freq. band function; used also in MASA decoder
     212             :  *------------------------------------------------------------------------*/
     213             : 
     214      324532 : void ivas_dirac_config_bands(
     215             :     int16_t *band_grouping, /* o  : band grouping                          */
     216             :     const int16_t nbands,   /* i  : number of bands                        */
     217             :     const int16_t max_band, /* i  : maximal band index +1                  */
     218             :     int16_t *dirac_to_spar_md_bands,
     219             :     const int8_t useLowerBandRes,
     220             :     const int16_t enc_param_start_band,
     221             :     IVAS_FB_MIXER_HANDLE hFbMdft,
     222             :     const int8_t BandGroupLowRes )
     223             : {
     224             :     int16_t i;
     225             :     {
     226      324532 :         if ( nbands == 5 )
     227             :         {
     228       13443 :             mvs2s( DirAC_band_grouping_5, band_grouping, 5 + 1 );
     229             :         }
     230      311089 :         else if ( nbands == 6 )
     231             :         {
     232           0 :             mvs2s( DirAC_band_grouping_6, band_grouping, 6 + 1 );
     233             :         }
     234      311089 :         else if ( nbands == 12 )
     235             :         {
     236             :             int16_t band;
     237     4044157 :             for ( band = 0; band < DIRAC_MAX_NBANDS; band++ )
     238             :             {
     239     3733068 :                 dirac_to_spar_md_bands[band] = band;
     240             :             }
     241      311089 :             if ( hFbMdft != NULL )
     242             :             {
     243             :                 int16_t sb, idx1, idx2, b;
     244             : 
     245      309262 :                 idx1 = -1;
     246      309262 :                 sb = 0;
     247    15631482 :                 for ( b = 0; b < max_band; b++ )
     248             :                 {
     249    15322220 :                     idx2 = hFbMdft->pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[b];
     250    15322220 :                     if ( idx2 > idx1 )
     251             :                     {
     252     3549469 :                         band_grouping[sb++] = b;
     253     3549469 :                         idx1 = idx2;
     254             :                     }
     255             :                 }
     256      309262 :                 band_grouping[sb] = max_band;
     257             : 
     258             :                 /* set the remaining bands to max_band to avoid problems for the DirAC parameter estimation with bw < FB */
     259      780199 :                 for ( b = sb; b <= nbands; b++ )
     260             :                 {
     261      470937 :                     band_grouping[b] = max_band;
     262             :                 }
     263             :             }
     264             :             else
     265             :             {
     266        1827 :                 mvs2s( DirAC_band_grouping_12, band_grouping, 12 + 1 );
     267             :             }
     268             : 
     269      311089 :             if ( useLowerBandRes )
     270             :             {
     271       27996 :                 int16_t step = DIRAC_LOW_BANDRES_STEP;
     272             :                 int16_t reduced_band;
     273             : 
     274       27996 :                 if ( BandGroupLowRes )
     275             :                 {
     276        4752 :                     for ( band = enc_param_start_band + 2, reduced_band = enc_param_start_band + 1; band <= DIRAC_MAX_NBANDS; band += step, reduced_band++ )
     277             :                     {
     278        3168 :                         band_grouping[reduced_band] = band_grouping[band];
     279             :                     }
     280        4752 :                     for ( ; reduced_band <= DIRAC_MAX_NBANDS; reduced_band++ )
     281             :                     {
     282        3168 :                         band_grouping[reduced_band] = max_band;
     283             :                     }
     284             :                 }
     285             : 
     286       83988 :                 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 )
     287             :                 {
     288       55992 :                     dirac_to_spar_md_bands[reduced_band] = dirac_to_spar_md_bands[band];
     289       55992 :                     dirac_to_spar_md_bands[reduced_band - 1] = dirac_to_spar_md_bands[band];
     290             :                 }
     291             :             }
     292             :             else
     293             :             {
     294             :                 /* always code the last two fb bands together */
     295      283093 :                 band_grouping[DIRAC_MAX_NBANDS - 1] = max_band;
     296      283093 :                 dirac_to_spar_md_bands[DIRAC_MAX_NBANDS - 1] = DIRAC_MAX_NBANDS - 2;
     297             :             }
     298             :         }
     299             :         else
     300             :         {
     301           0 :             assert( 0 && "nbands must be 5 or 6!" );
     302             :         }
     303             :     }
     304             : 
     305             :     /* Limit the band range to band max */
     306     4449347 :     for ( i = 0; i < nbands + 1; i++ )
     307             :     {
     308     4124815 :         if ( band_grouping[i] > max_band )
     309             :         {
     310        3036 :             band_grouping[i] = max_band;
     311             :         }
     312             :     }
     313             : 
     314      324532 :     return;
     315             : }
     316             : 
     317             : /*-------------------------------------------------------------------*
     318             :  * ivas_get_dirac_sba_max_md_bits()
     319             :  *
     320             :  * Return maximum SBA DirAC metadata bit-budget and nominal bit-budget
     321             :  *-------------------------------------------------------------------*/
     322             : 
     323       11851 : void ivas_get_dirac_sba_max_md_bits(
     324             :     const int32_t sba_total_brate,
     325             :     int16_t *bits_frame_nominal,
     326             :     int16_t *metadata_max_bits,
     327             :     int16_t *qmetadata_max_bit_req,
     328             :     const int16_t nbands,
     329             :     IVAS_FORMAT ivas_format )
     330             : {
     331       11851 :     if ( sba_total_brate <= IVAS_13k2 )
     332             :     {
     333        1092 :         *bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
     334        1092 :         *metadata_max_bits = 70;
     335             :     }
     336       10759 :     else if ( sba_total_brate <= IVAS_16k4 )
     337             :     {
     338        1287 :         *bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
     339        1287 :         *metadata_max_bits = 80;
     340             :     }
     341        9472 :     else if ( sba_total_brate <= IVAS_24k4 )
     342             :     {
     343         922 :         *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
     344         922 :         *metadata_max_bits = 103;
     345             :         /* OSBA needs an additional 5-bits safety margin to avoid acelp crashes */
     346         922 :         if ( ivas_format == SBA_ISM_FORMAT )
     347             :         {
     348         354 :             ( *metadata_max_bits ) -= 7;
     349             :         }
     350             :     }
     351        8550 :     else if ( sba_total_brate <= IVAS_32k )
     352             :     {
     353         923 :         *bits_frame_nominal = ACELP_32k / FRAMES_PER_SEC;
     354         923 :         *metadata_max_bits = 214;
     355             :     }
     356        7627 :     else if ( sba_total_brate <= IVAS_48k )
     357             :     {
     358         534 :         *bits_frame_nominal = IVAS_48k / FRAMES_PER_SEC;
     359         534 :         *metadata_max_bits = 240;
     360             :     }
     361        7093 :     else if ( sba_total_brate <= IVAS_64k )
     362             :     {
     363         806 :         *bits_frame_nominal = IVAS_64k / FRAMES_PER_SEC;
     364         806 :         *metadata_max_bits = 200;
     365             :     }
     366        6287 :     else if ( sba_total_brate <= IVAS_80k )
     367             :     {
     368        1004 :         *bits_frame_nominal = IVAS_80k / FRAMES_PER_SEC;
     369        1004 :         *metadata_max_bits = 200;
     370             :     }
     371        5283 :     else if ( sba_total_brate <= IVAS_96k )
     372             :     {
     373         861 :         *bits_frame_nominal = IVAS_96k / FRAMES_PER_SEC;
     374         861 :         *metadata_max_bits = 200;
     375             :     }
     376        4422 :     else if ( sba_total_brate <= IVAS_128k )
     377             :     {
     378         739 :         *bits_frame_nominal = IVAS_128k / FRAMES_PER_SEC;
     379         739 :         *metadata_max_bits = 250;
     380             :     }
     381             :     else
     382             :     {
     383        3683 :         *bits_frame_nominal = (int16_t) ( sba_total_brate / FRAMES_PER_SEC );
     384        3683 :         *metadata_max_bits = MAX16B; /* no limit */
     385             :     }
     386       11851 :     *metadata_max_bits = (int16_t) min( (float) MAX16B, ceilf( (float) *metadata_max_bits * nbands / 5 ) );
     387       11851 :     *qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_SBA >> 1;
     388             : 
     389       11851 :     return;
     390             : }
     391             : 
     392             : 
     393             : /*-------------------------------------------------------------------------
     394             :  * ivas_dirac_sba_config()
     395             :  *
     396             :  * DirAC Configuration function for SBA
     397             :  *------------------------------------------------------------------------*/
     398             : 
     399       11851 : ivas_error ivas_dirac_sba_config(
     400             :     IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle                                    */
     401             :     int16_t *element_mode,            /* i/o: element mode of the core coder                       */
     402             :     int32_t sba_total_brate,          /* i  : SBA total bitrate                                    */
     403             :     const int16_t sba_order,          /* i  : Ambisonic (SBA) order                                */
     404             :     const int16_t nbands,             /* i  : number of frequency bands                            */
     405             :     IVAS_FORMAT ivas_format )
     406             : {
     407             :     int16_t nbands_coded;
     408             :     int16_t hodirac_flag;
     409             :     ivas_error error;
     410             : 
     411       11851 :     error = IVAS_ERR_OK;
     412       11851 :     hQMetaData->is_masa_ivas_format = 0;
     413       11851 :     hodirac_flag = ivas_get_hodirac_flag( sba_total_brate, sba_order );
     414             : 
     415             :     /* map the bitrate for SID frame */
     416       11851 :     if ( sba_total_brate == IVAS_SID_5k2 )
     417             :     {
     418           0 :         if ( *element_mode == IVAS_SCE )
     419             :         {
     420           0 :             sba_total_brate = ACELP_24k40;
     421             :         }
     422             :         else
     423             :         {
     424           0 :             sba_total_brate = ACELP_48k;
     425             :         }
     426             :     }
     427             : 
     428       11851 :     ivas_set_qmetadata_maxbit_req( hQMetaData, SBA_FORMAT );
     429             : 
     430       11851 :     if ( sba_total_brate <= IVAS_16k4 )
     431             :     {
     432        2379 :         hQMetaData->useLowerRes = 1;
     433             :     }
     434             :     else
     435             :     {
     436        9472 :         hQMetaData->useLowerRes = 0;
     437             :     }
     438             : 
     439       11851 :     nbands_coded = nbands;
     440       11851 :     if ( sba_total_brate <= (int32_t) ( (float) IVAS_192k / (float) SPAR_DIRAC_SPLIT_START_BAND ) )
     441             :     {
     442        2379 :         hQMetaData->useLowerBandRes = 1;
     443        2379 :         nbands_coded = nbands / 2 + nbands % 2;
     444             :     }
     445             :     else
     446             :     {
     447        9472 :         hQMetaData->useLowerBandRes = 0;
     448        9472 :         nbands_coded = nbands - 1; /* always combine the last two bands */
     449             :     }
     450             : 
     451             :     {
     452       11851 :         int16_t no_dirs = 1;
     453       11851 :         if ( hodirac_flag )
     454             :         {
     455        1164 :             no_dirs = 2;
     456             :         }
     457             : 
     458       11851 :         if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, nbands_coded, no_dirs, 0 ) ) != IVAS_ERR_OK )
     459             :         {
     460           0 :             return error;
     461             :         }
     462             :     }
     463             : 
     464       11851 :     ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands, ivas_format );
     465             : 
     466       11851 :     return error;
     467             : }
     468             : 
     469             : 
     470             : /*-------------------------------------------------------------------------
     471             :  * computeDirectionVectors()
     472             :  *
     473             :  *
     474             :  *------------------------------------------------------------------------*/
     475             : 
     476      706480 : void computeDirectionVectors(
     477             :     float *intensity_real_x,
     478             :     float *intensity_real_y,
     479             :     float *intensity_real_z,
     480             :     const int16_t enc_param_start_band,
     481             :     const int16_t num_frequency_bands,
     482             :     float *direction_vector_x,
     483             :     float *direction_vector_y,
     484             :     float *direction_vector_z )
     485             : {
     486             :     int16_t i;
     487             :     float intensityNorm;
     488             : 
     489     4670684 :     for ( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i )
     490             :     {
     491     3964204 :         intensityNorm = *( intensity_real_x ) * *( intensity_real_x ) +
     492     3964204 :                         *( intensity_real_y ) * *( intensity_real_y ) +
     493     3964204 :                         *( intensity_real_z ) * *( intensity_real_z );
     494             : 
     495     3964204 :         if ( intensityNorm <= EPSILON )
     496             :         {
     497       51790 :             intensityNorm = 1.0f;
     498       51790 :             *( direction_vector_x++ ) = 1.0f;
     499       51790 :             *( direction_vector_y++ ) = 0.0f;
     500       51790 :             *( direction_vector_z++ ) = 0.0f;
     501       51790 :             intensity_real_x++;
     502       51790 :             intensity_real_y++;
     503       51790 :             intensity_real_z++;
     504             :         }
     505             :         else
     506             :         {
     507     3912414 :             intensityNorm = sqrtf( 1.f / intensityNorm );
     508     3912414 :             *( direction_vector_x++ ) = *( intensity_real_x++ ) * intensityNorm;
     509     3912414 :             *( direction_vector_y++ ) = *( intensity_real_y++ ) * intensityNorm;
     510     3912414 :             *( direction_vector_z++ ) = *( intensity_real_z++ ) * intensityNorm;
     511             :         }
     512             :     }
     513             : 
     514      706480 :     return;
     515             : }
     516             : 
     517             : 
     518             : /*-------------------------------------------------------------------------
     519             :  * computeDiffuseness()
     520             :  *
     521             :  *
     522             :  *------------------------------------------------------------------------*/
     523             : 
     524     2339969 : void computeDiffuseness(
     525             :     float *buffer_intensity[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF],
     526             :     const float *buffer_energy,
     527             :     const int16_t num_freq_bands,
     528             :     float *diffuseness )
     529             : {
     530             :     float intensity_slow[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX];
     531             :     float intensity_slow_abs[CLDFB_NO_CHANNELS_MAX];
     532             :     float energy_slow[CLDFB_NO_CHANNELS_MAX];
     533             :     int16_t i, j, k;
     534     2339969 :     float tmp = 0;
     535             :     float *p_tmp;
     536             :     const float *p_tmp_c;
     537             : 
     538             :     /* Compute Intensity slow and energy slow */
     539             : 
     540     2339969 :     set_f( intensity_slow, 0.0f, DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX );
     541     2339969 :     set_f( intensity_slow_abs, 0.0f, CLDFB_NO_CHANNELS_MAX );
     542     2339969 :     set_f( energy_slow, 0.0f, CLDFB_NO_CHANNELS_MAX );
     543             : 
     544    77218977 :     for ( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i )
     545             :     {
     546             :         /* Energy slow */
     547    74879008 :         p_tmp_c = buffer_energy + i * num_freq_bands;
     548   934124928 :         for ( k = 0; k < num_freq_bands; k++ )
     549             :         {
     550   859245920 :             energy_slow[k] += *( p_tmp_c++ );
     551             :         }
     552             : 
     553             :         /* Intensity slow */
     554   299516032 :         for ( j = 0; j < DIRAC_NUM_DIMS; ++j )
     555             :         {
     556   224637024 :             p_tmp = buffer_intensity[j][i];
     557             : 
     558  2802374784 :             for ( k = 0; k < num_freq_bands; k++ )
     559             :             {
     560  2577737760 :                 intensity_slow[j * num_freq_bands + k] += *( p_tmp++ );
     561             :             }
     562             :         }
     563             :     }
     564             : 
     565             :     /* intensity_slow.^2 + intensity_slow_abs*/
     566     9359876 :     for ( j = 0; j < DIRAC_NUM_DIMS; ++j )
     567             :     {
     568     7019907 :         p_tmp = intensity_slow + j * num_freq_bands;
     569             : 
     570    87574212 :         for ( k = 0; k < num_freq_bands; k++ )
     571             :         {
     572    80554305 :             *( p_tmp ) *= ( *p_tmp );
     573    80554305 :             intensity_slow_abs[k] += *( p_tmp++ );
     574             :         }
     575             :     }
     576             : 
     577             :     /* Compute Diffuseness */
     578     2339969 :     p_tmp = intensity_slow_abs;
     579    29191404 :     for ( i = 0; i < num_freq_bands; ++i )
     580             :     {
     581    26851435 :         tmp = sqrtf( *( p_tmp++ ) ) / ( energy_slow[i] + EPSILON );
     582    26851435 :         tmp = 1.0f - tmp;
     583    26851435 :         diffuseness[i] = ( ( tmp < 1.0f ) ? ( ( tmp < 0.0f ) ? 0.f : tmp ) : 1.0f );
     584             :     }
     585             : 
     586     2339969 :     return;
     587             : }
     588             : 
     589             : 
     590             : /*-------------------------------------------------------------------*
     591             :  * deindex_azimuth()
     592             :  *
     593             :  * Deindex one azimuth index
     594             :  *-------------------------------------------------------------------*/
     595             : 
     596             : /*! r: azimuth value */
     597    11405727 : float deindex_azimuth(
     598             :     int16_t id_phi,             /* i  : index                                   */
     599             :     const int16_t no_bits,      /* i  : number of bits for the spherical grid   */
     600             :     const int16_t id_th,        /* i  : elevation index                         */
     601             :     const int16_t remap,        /* i  : remapping flag                          */
     602             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode            */
     603             : )
     604             : {
     605             :     int16_t flag_delta;
     606             :     float dd, delta_phi;
     607             :     float phi_hat;
     608             : 
     609    11405727 :     if ( ( mc_format != MC_LS_SETUP_INVALID ) && ( no_bits == 2 ) )
     610             :     {
     611          33 :         if ( id_phi % 2 == 0 )
     612             :         {
     613          27 :             phi_hat = cb_azi_chan[id_phi / 2];
     614             :         }
     615             :         else
     616             :         {
     617           6 :             phi_hat = -cb_azi_chan[( id_phi + 1 ) / 2];
     618             :         }
     619          33 :         return phi_hat;
     620             :     }
     621    11405694 :     flag_delta = ( id_th % 2 == 1 );
     622             : 
     623    11405694 :     if ( remap )
     624             :     {
     625      697116 :         id_phi = ivas_qmetadata_dereorder_generic( id_phi ) + ( no_phi_masa[no_bits - 1][id_th] >> 1 );
     626             :     }
     627             : 
     628    11405694 :     delta_phi = 360 / (float) ( no_phi_masa[no_bits - 1][id_th] );
     629    11405694 :     if ( ( flag_delta == 1 ) && ( no_phi_masa[no_bits - 1][id_th] > 2 ) && mc_format == MC_LS_SETUP_INVALID )
     630             :     {
     631     2760669 :         dd = delta_phi / 2.0f;
     632             :     }
     633             :     else
     634             :     {
     635     8645025 :         dd = 0;
     636             :     }
     637             : 
     638    11405694 :     id_phi -= ( ( no_phi_masa[no_bits - 1][id_th] ) >> 1 );
     639    11405694 :     phi_hat = id_phi * delta_phi + dd + 180 - 180;
     640    11405694 :     if ( mc_format != MC_LS_SETUP_INVALID )
     641             :     {
     642      312246 :         phi_hat = companding_azimuth( phi_hat, mc_format, ( id_th * delta_theta_masa[no_bits - 3] > MC_MASA_THR_ELEVATION ), -1 );
     643             :     }
     644             : 
     645    11405694 :     return phi_hat;
     646             : }
     647             : 
     648             : 
     649             : /*----------------------------------------------------------------
     650             :  * deindex_spherical_component()
     651             :  *
     652             :  * decoding the spherical index for one tile
     653             :  *-----------------------------------------------------------------*/
     654             : 
     655     5375793 : void deindex_spherical_component(
     656             :     const uint16_t sph_idx,     /* i  : spherical index                         */
     657             :     float *az,                  /* o  : decoded azimuth value                   */
     658             :     float *el,                  /* o  : decoded elevation value                 */
     659             :     uint16_t *az_idx,           /* o  : azimuth index                           */
     660             :     uint16_t *el_idx,           /* o  : elevation index                         */
     661             :     const uint16_t no_bits,     /* i  : number of bits for the spherical grid   */
     662             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode            */
     663             : )
     664             : {
     665     5375793 :     assert( sph_idx < ( 1 << no_bits ) );
     666     5375793 :     switch ( no_bits )
     667             :     {
     668           0 :         case 0:
     669           0 :             *az = 0;
     670           0 :             *el = 0;
     671           0 :             *az_idx = 0;
     672           0 :             *el_idx = 0;
     673           0 :             break;
     674           0 :         case 1:
     675           0 :             *az_idx = sph_idx;
     676           0 :             *az = ( *az_idx ) * ( -180.f );
     677           0 :             *el = 0;
     678           0 :             *el_idx = 0;
     679           0 :             break;
     680        2007 :         case 2:
     681        2007 :             *el = 0;
     682        2007 :             *el_idx = 0;
     683        2007 :             *az_idx = sph_idx;
     684        2007 :             *az = deindex_azimuth( *az_idx, no_bits, 0, 0, mc_format );
     685        2007 :             break;
     686     5373786 :         default:
     687     5373786 :             *el_idx = deindex_sph_idx_general( sph_idx, no_bits, el, az, az_idx, mc_format );
     688     5373786 :             break;
     689             :     }
     690             : 
     691     5375793 :     return;
     692             : }
     693             : 
     694             : 
     695             : /*----------------------------------------------------------------
     696             :  * calculate_hodirac_sector_parameters()
     697             :  *
     698             :  *
     699             :  *-----------------------------------------------------------------*/
     700             : 
     701       64960 : void calculate_hodirac_sector_parameters(
     702             :     DIRAC_ENC_HANDLE hDirAC,                                      /* i  : DirAC handle                               */
     703             :     float RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : signal vector (L+1)^2 x N_bins, real part  */
     704             :     float ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i  : signal vector, imaginary part              */
     705             :     const float beta,                                             /* i  : forgetting factor for average filtering    */
     706             :     const int16_t *band_grouping,                                 /* i  : indices of band groups                     */
     707             :     const int16_t N_bands,                                        /* i  : number of bands (groups)                   */
     708             :     const int16_t enc_param_start_band,                           /* i  : first band to process                      */
     709             :     float *azi,                                                   /* o  : array of sector azimuth angles, flat       */
     710             :     float *ele,                                                   /* o  : array of sector elevation angles, flat     */
     711             :     float *diff,                                                  /* o  : array of sector diffuseness values, flat   */
     712             :     float *ene                                                    /* o  : array of sector energy values, flat        */
     713             : )
     714             : {
     715             :     int16_t i_sec, i_bin, i_band;
     716             :     float p_real, p_imag, normI, energy, tmp_diff;
     717             :     float sec_I_vec_x[NUM_ANA_SECTORS];
     718             :     float sec_I_vec_y[NUM_ANA_SECTORS];
     719             :     float sec_I_vec_z[NUM_ANA_SECTORS];
     720             : 
     721             : 
     722      194880 :     for ( i_sec = 0; i_sec < NUM_ANA_SECTORS; i_sec++ )
     723             :     {
     724             : 
     725      129920 :         float *p_sec_I_vec_x = &sec_I_vec_x[i_sec];
     726      129920 :         float *p_sec_I_vec_y = &sec_I_vec_y[i_sec];
     727      129920 :         float *p_sec_I_vec_z = &sec_I_vec_z[i_sec];
     728             : 
     729      129920 :         const float *p_c_weights = c_weights;
     730             : 
     731      129920 :         float *p_ImagBuffer_0 = ImagBuffer[0];
     732      129920 :         float *p_ImagBuffer_1 = ImagBuffer[1];
     733      129920 :         float *p_ImagBuffer_2 = ImagBuffer[2];
     734      129920 :         float *p_ImagBuffer_3 = ImagBuffer[3];
     735      129920 :         float *p_ImagBuffer_4 = ImagBuffer[4];
     736      129920 :         float *p_ImagBuffer_5 = ImagBuffer[5];
     737      129920 :         float *p_ImagBuffer_6 = ImagBuffer[6];
     738      129920 :         float *p_ImagBuffer_8 = ImagBuffer[8];
     739             : 
     740      129920 :         float *p_RealBuffer_0 = RealBuffer[0];
     741      129920 :         float *p_RealBuffer_1 = RealBuffer[1];
     742      129920 :         float *p_RealBuffer_2 = RealBuffer[2];
     743      129920 :         float *p_RealBuffer_3 = RealBuffer[3];
     744      129920 :         float *p_RealBuffer_4 = RealBuffer[4];
     745      129920 :         float *p_RealBuffer_5 = RealBuffer[5];
     746      129920 :         float *p_RealBuffer_6 = RealBuffer[6];
     747      129920 :         float *p_RealBuffer_8 = RealBuffer[8];
     748             : 
     749     1559040 :         for ( i_band = enc_param_start_band; i_band < N_bands; i_band++ )
     750             :         {
     751     1429120 :             float *p_azi = &azi[i_sec * N_bands + i_band];
     752     1429120 :             float *p_ele = &ele[i_sec * N_bands + i_band];
     753     1429120 :             float *p_ene = &ene[i_sec * N_bands + i_band];
     754             : 
     755     1429120 :             float *p_diff = &diff[i_sec * N_bands + i_band];
     756     1429120 :             float *p_azi_prev = &hDirAC->azi_prev[i_sec * N_bands + i_band];
     757     1429120 :             float *p_ele_prev = &hDirAC->ele_prev[i_sec * N_bands + i_band];
     758             : 
     759     1429120 :             float *p_energy_smth = &hDirAC->energy_smth[i_sec][i_band];
     760     1429120 :             float *p_sec_I_vec_smth_x = &hDirAC->sec_I_vec_smth_x[i_sec][i_band];
     761     1429120 :             float *p_sec_I_vec_smth_y = &hDirAC->sec_I_vec_smth_y[i_sec][i_band];
     762     1429120 :             float *p_sec_I_vec_smth_z = &hDirAC->sec_I_vec_smth_z[i_sec][i_band];
     763     1429120 :             *p_sec_I_vec_x = 0.f;
     764     1429120 :             *p_sec_I_vec_y = 0.f;
     765     1429120 :             *p_sec_I_vec_z = 0.f;
     766     1429120 :             energy = 0.f;
     767             : 
     768     1429120 :             if ( i_sec == 0 )
     769             :             {
     770    13704960 :                 for ( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
     771             :                 {
     772    12990400 :                     float w = *( p_c_weights++ );
     773             :                     float sec_w_imag, sec_x_imag, sec_y_imag, sec_z_imag;
     774             :                     float sec_w_real, sec_x_real, sec_y_real, sec_z_real;
     775             : 
     776    12990400 :                     sec_w_imag = 1.772454f * *( p_ImagBuffer_0 ) + 1.772454f * *( p_ImagBuffer_1 );
     777    12990400 :                     sec_x_imag = 1.772454f * *( p_ImagBuffer_3++ ) + 1.023326f * *( p_ImagBuffer_4++ );
     778    12990400 :                     sec_y_imag = 0.590818f * *( p_ImagBuffer_0++ ) + 1.772454f * *( p_ImagBuffer_1++ ) - 0.590817f * *( p_ImagBuffer_6++ ) - 1.023326f * *( p_ImagBuffer_8++ );
     779    12990400 :                     sec_z_imag = 1.772454f * *( p_ImagBuffer_2++ ) + 1.023326f * *( p_ImagBuffer_5++ );
     780             : 
     781    12990400 :                     sec_w_real = 1.772454f * *( p_RealBuffer_0 ) + 1.772454f * *( p_RealBuffer_1 );
     782    12990400 :                     sec_x_real = 1.772454f * *( p_RealBuffer_3++ ) + 1.023326f * *( p_RealBuffer_4++ );
     783    12990400 :                     sec_y_real = 0.590818f * *( p_RealBuffer_0++ ) + 1.772454f * *( p_RealBuffer_1++ ) - 0.590817f * *( p_RealBuffer_6++ ) - 1.023326f * *( p_RealBuffer_8++ );
     784    12990400 :                     sec_z_real = 1.772454f * *( p_RealBuffer_2++ ) + 1.023326f * *( p_RealBuffer_5++ );
     785             : 
     786    12990400 :                     p_real = sec_w_real * w;
     787    12990400 :                     p_imag = sec_w_imag * w;
     788             : 
     789    12990400 :                     *p_sec_I_vec_x += p_real * sec_x_real + p_imag * sec_x_imag;
     790    12990400 :                     *p_sec_I_vec_y += p_real * sec_y_real + p_imag * sec_y_imag;
     791    12990400 :                     *p_sec_I_vec_z += p_real * sec_z_real + p_imag * sec_z_imag;
     792             : 
     793    12990400 :                     energy += 0.5f * ( p_real * p_real + p_imag * p_imag + sec_x_real * sec_x_real + sec_x_imag * sec_x_imag +
     794    12990400 :                                        sec_y_real * sec_y_real + sec_y_imag * sec_y_imag +
     795    12990400 :                                        sec_z_real * sec_z_real + sec_z_imag * sec_z_imag );
     796             :                 }
     797             :             }
     798             :             else
     799             :             {
     800    13704960 :                 for ( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
     801             :                 {
     802    12990400 :                     float w = *( p_c_weights++ );
     803             :                     float sec_w_imag, sec_x_imag, sec_y_imag, sec_z_imag;
     804             :                     float sec_w_real, sec_x_real, sec_y_real, sec_z_real;
     805             : 
     806    12990400 :                     sec_w_imag = 1.772454f * *(p_ImagBuffer_0) -1.772454f * *( p_ImagBuffer_1 );
     807    12990400 :                     sec_x_imag = 1.772454f * *( p_ImagBuffer_3++ ) - 1.023326f * *( p_ImagBuffer_4++ );
     808    12990400 :                     sec_y_imag = -0.590818f * *( p_ImagBuffer_0++ ) + 1.772454f * *( p_ImagBuffer_1++ ) + 0.590817f * *( p_ImagBuffer_6++ ) + 1.023326f * *( p_ImagBuffer_8++ );
     809    12990400 :                     sec_z_imag = 1.772454f * *( p_ImagBuffer_2++ ) - 1.023326f * *( p_ImagBuffer_5++ );
     810             : 
     811    12990400 :                     sec_w_real = 1.772454f * *(p_RealBuffer_0) -1.772454f * *( p_RealBuffer_1 );
     812    12990400 :                     sec_x_real = 1.772454f * *( p_RealBuffer_3++ ) - 1.023326f * *( p_RealBuffer_4++ );
     813    12990400 :                     sec_y_real = -0.590818f * *( p_RealBuffer_0++ ) + 1.772454f * *( p_RealBuffer_1++ ) + 0.590817f * *( p_RealBuffer_6++ ) + 1.023326f * *( p_RealBuffer_8++ );
     814    12990400 :                     sec_z_real = 1.772454f * *( p_RealBuffer_2++ ) - 1.023326f * *( p_RealBuffer_5++ );
     815             : 
     816    12990400 :                     p_real = sec_w_real * w;
     817    12990400 :                     p_imag = sec_w_imag * w;
     818             : 
     819    12990400 :                     *p_sec_I_vec_x += p_real * sec_x_real + p_imag * sec_x_imag;
     820    12990400 :                     *p_sec_I_vec_y += p_real * sec_y_real + p_imag * sec_y_imag;
     821    12990400 :                     *p_sec_I_vec_z += p_real * sec_z_real + p_imag * sec_z_imag;
     822             : 
     823    12990400 :                     energy += 0.5f * ( p_real * p_real + p_imag * p_imag + sec_x_real * sec_x_real + sec_x_imag * sec_x_imag +
     824    12990400 :                                        sec_y_real * sec_y_real + sec_y_imag * sec_y_imag +
     825    12990400 :                                        sec_z_real * sec_z_real + sec_z_imag * sec_z_imag );
     826             :                 }
     827             :             }
     828     1429120 :             if ( hDirAC->firstrun_sector_params )
     829             :             {
     830         616 :                 *p_sec_I_vec_smth_x = *p_sec_I_vec_x;
     831         616 :                 *p_sec_I_vec_smth_y = *p_sec_I_vec_y;
     832         616 :                 *p_sec_I_vec_smth_z = *p_sec_I_vec_z;
     833         616 :                 *p_energy_smth = energy;
     834             :             }
     835             :             else
     836             :             {
     837     1428504 :                 float w = ( 1.0f - beta );
     838     1428504 :                 *p_sec_I_vec_smth_x = w * *p_sec_I_vec_x + beta * *p_sec_I_vec_smth_x;
     839     1428504 :                 *p_sec_I_vec_smth_y = w * *p_sec_I_vec_y + beta * *p_sec_I_vec_smth_y;
     840     1428504 :                 *p_sec_I_vec_smth_z = w * *p_sec_I_vec_z + beta * *p_sec_I_vec_smth_z;
     841     1428504 :                 *p_energy_smth = w * energy + beta * *p_energy_smth;
     842             :             }
     843             : 
     844     1429120 :             if ( energy < EPSILON )
     845             :             {
     846        8000 :                 *p_azi = 0.f;
     847        8000 :                 *p_ele = 0.f;
     848        8000 :                 *p_ene = 0.f;
     849        8000 :                 *p_diff = 1.f;
     850             :             }
     851             :             else
     852             :             {
     853     1421120 :                 normI = sqrtf( *p_sec_I_vec_smth_x * *p_sec_I_vec_smth_x +
     854     1421120 :                                *p_sec_I_vec_smth_y * *p_sec_I_vec_smth_y +
     855     1421120 :                                *p_sec_I_vec_smth_z * *p_sec_I_vec_smth_z );
     856     1421120 :                 *p_azi = atan2f( *p_sec_I_vec_smth_y, *p_sec_I_vec_smth_x ) * _180_OVER_PI;
     857     1421120 :                 *p_ele = asinf( *p_sec_I_vec_smth_z / ( normI + EPSILON ) ) * _180_OVER_PI;
     858     1421120 :                 *p_ene = *p_energy_smth;
     859     1421120 :                 *p_diff = 1.f - normI / ( *p_energy_smth + EPSILON );
     860             :             }
     861             : 
     862     1429120 :             tmp_diff = *p_diff;
     863             : 
     864     1429120 :             if ( tmp_diff < 0.0f )
     865             :             {
     866           0 :                 *p_diff = 0.f;
     867             :             }
     868     1429120 :             if ( tmp_diff > 0.5f )
     869             :             {
     870      489891 :                 if ( hDirAC->firstrun_sector_params )
     871             :                 {
     872         147 :                     *p_azi = 0.f;
     873         147 :                     *p_ele = 0.f;
     874             :                 }
     875             :                 else
     876             :                 {
     877      489744 :                     *p_azi = 2.f * ( 1.f - tmp_diff ) * *p_azi + ( 2.f * tmp_diff - 1.f ) * *p_azi_prev;
     878      489744 :                     *p_ele = 2.f * ( 1.f - tmp_diff ) * *p_ele + ( 2.f * tmp_diff - 1.f ) * *p_ele_prev;
     879             :                 }
     880             :             }
     881             :             else
     882             :             {
     883      939229 :                 *p_azi_prev = *p_azi;
     884      939229 :                 *p_ele_prev = *p_ele;
     885             :             }
     886             :         }
     887             :     }
     888             : 
     889       64960 :     hDirAC->firstrun_sector_params = 0;
     890             : 
     891       64960 :     return;
     892             : }
     893             : 
     894             : 
     895             : /*-----------------------------------------------------------------------*
     896             :  * Local functions
     897             :  *-----------------------------------------------------------------------*/
     898             : 
     899             : 
     900             : /*-------------------------------------------------------------------*
     901             :  * deindex_sph_idx_general()
     902             :  *
     903             :  * deindex the spherical index for more than 2 bits for the spherical grid
     904             :  *----------------------------------------------------------------------*/
     905             : 
     906             : /*! r: decoded elevation index */
     907     5373786 : static uint16_t deindex_sph_idx_general(
     908             :     const int16_t idx_sph,      /* i  : spherical index                     */
     909             :     const int16_t no_bits,      /* i  : number of bits in the spherical grid*/
     910             :     float *theta_dec,           /* o  : decoded elevation value             */
     911             :     float *phi_dec,             /* o  : decoded azimuth value               */
     912             :     uint16_t *p_id_phi,         /* o  : decoded azimuth index               */
     913             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode        */
     914             : )
     915             : {
     916             :     int16_t i;
     917             :     uint16_t id_th;
     918             :     int16_t sign_theta;
     919             :     int16_t id_phi;
     920             :     int16_t cum_n[250];
     921             :     int16_t no_th;
     922             :     const int16_t *n;
     923             : 
     924     5373786 :     id_th = 0;
     925     5373786 :     id_phi = 0;
     926     5373786 :     sign_theta = 1;
     927             : 
     928     5373786 :     no_th = no_theta_masa[no_bits - 3];
     929     5373786 :     n = no_phi_masa[no_bits - 1];
     930     5373786 :     if ( mc_format != MC_LS_SETUP_INVALID )
     931             :     {
     932             :         /* indexing */
     933             : 
     934       30705 :         cum_n[0] = n[0];
     935       30705 :         if ( idx_sph >= cum_n[0] )
     936             :         {
     937       38241 :             for ( i = 1; i < no_th; i++ )
     938             :             {
     939       38241 :                 cum_n[i] = cum_n[i - 1] + n[i];
     940       38241 :                 if ( idx_sph < cum_n[i] )
     941             :                 {
     942       26094 :                     id_th = i;
     943       26094 :                     id_phi = idx_sph - cum_n[i - 1];
     944       26094 :                     break;
     945             :                 }
     946             :             }
     947             :         }
     948             :     }
     949             :     else
     950             :     {
     951             :         /* Starting from Equator, alternating positive and negative */
     952     5343081 :         cum_n[0] = n[0];
     953     5343081 :         if ( idx_sph >= cum_n[0] )
     954             :         {
     955     4228887 :             for ( i = 1; i < no_th; i++ )
     956             :             {
     957     4228887 :                 cum_n[2 * i - 1] = cum_n[2 * i - 2] + n[i];
     958             : 
     959     4228887 :                 if ( idx_sph < cum_n[2 * i - 1] )
     960             :                 {
     961     1245219 :                     id_th = i;
     962     1245219 :                     sign_theta = 1;
     963     1245219 :                     id_phi = idx_sph - cum_n[2 * i - 2];
     964     1245219 :                     break;
     965             :                 }
     966             : 
     967     2983668 :                 cum_n[2 * i] = cum_n[2 * i - 1] + n[i];
     968             : 
     969     2983668 :                 if ( idx_sph < cum_n[2 * i] )
     970             :                 {
     971     1303815 :                     id_th = i;
     972     1303815 :                     sign_theta = -1;
     973     1303815 :                     id_phi = idx_sph - cum_n[2 * i - 1];
     974     1303815 :                     break;
     975             :                 }
     976             : 
     977     1679853 :                 if ( i == ( no_th - 1 ) )
     978             :                 {
     979           0 :                     id_th = i;
     980           0 :                     sign_theta = -1;
     981           0 :                     id_phi = 0; /* idx_sph - cum_n[2*i-1]; */
     982           0 :                     break;
     983             :                 }
     984             :             }
     985             :         }
     986             :     }
     987             : 
     988     5373786 :     if ( id_th == 0 )
     989             :     {
     990     2798658 :         id_phi = idx_sph;
     991             :     }
     992             :     else
     993             :     {
     994     2575128 :         if ( ( id_th == no_th - 1 ) && ( no_bits > 4 ) )
     995             :         {
     996        7869 :             id_phi = 0;
     997             :         }
     998             :     }
     999             : 
    1000     5373786 :     *theta_dec = id_th * delta_theta_masa[no_bits - 3];
    1001             : 
    1002     5373786 :     if ( *theta_dec >= 90 )
    1003             :     {
    1004        7779 :         *theta_dec = 90.f * sign_theta;
    1005        7779 :         *phi_dec = 0;
    1006        7779 :         *p_id_phi = 0;
    1007             :     }
    1008             :     else
    1009             :     {
    1010     5366007 :         *theta_dec *= sign_theta;
    1011             : 
    1012     5366007 :         *phi_dec = deindex_azimuth( id_phi, no_bits, id_th, 0, mc_format );
    1013     5366007 :         *p_id_phi = id_phi;
    1014             :     }
    1015             : 
    1016     5373786 :     return id_th;
    1017             : }

Generated by: LCOV version 1.14