LCOV - code coverage report
Current view: top level - lib_enc - ivas_qspherical_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 199 223 89.2 %
Date: 2025-05-23 08:37:30 Functions: 6 6 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_prot.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "ivas_stat_enc.h"
      41             : #include "wmc_auto.h"
      42             : #include "prot.h"
      43             : 
      44             : 
      45             : /*-----------------------------------------------------------------------*
      46             :  * Local function prototypes
      47             :  *-----------------------------------------------------------------------*/
      48             : 
      49             : static float quantize_theta_phi( float *theta_cb, const int16_t no_th, const int16_t *no_phi_loc, const float abs_theta, int16_t *id_phi, int16_t *id_phi_remap, float *phi_hat, const float phi, const int16_t no_bits, int16_t *id_theta, float *phi_q, const int16_t remap, const MC_LS_SETUP mc_format );
      50             : 
      51             : static float direction_distance_cp( float theta, float theta_hat, float theta_hat1, const float phi, const float phi_hat, const float phi_hat1, float *d1 );
      52             : 
      53             : /*-------------------------------------------------------------------*
      54             :  * quantize_direction_frame()
      55             :  *
      56             :  *
      57             :  *----------------------------------------------------------------------*/
      58             : 
      59      217725 : void quantize_direction_frame(
      60             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure   */
      61             :     float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
      62             :     float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
      63             :     const int16_t hrmasa_flag /* i  : flag indicating high-rate MASA MD coding*/
      64             : )
      65             : {
      66             :     int16_t i, j;
      67             :     uint16_t idx;
      68             : 
      69             :     /* Quantize directions */
      70      217725 :     q_direction->not_in_2D = 0;
      71     1301131 :     for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
      72             :     {
      73     1083406 :         idx = q_direction->band_data[i].energy_ratio_index_mod[0];
      74     4916402 :         for ( j = 0; j < q_direction->cfg.nblocks; j++ )
      75             :         {
      76     3832996 :             if ( azimuth_orig != NULL )
      77             :             {
      78     3832996 :                 azimuth_orig[i][j] = q_direction->band_data[i].azimuth[j];
      79             :             }
      80             : 
      81     3832996 :             if ( elevation_orig != NULL )
      82             :             {
      83     3832996 :                 elevation_orig[i][j] = q_direction->band_data[i].elevation[j];
      84             :             }
      85             : 
      86             :             /* requantize the direction */
      87     7665992 :             q_direction->band_data[i].spherical_index[j] = quantize_direction( q_direction->band_data[i].elevation[j],
      88     3832996 :                                                                                q_direction->band_data[i].azimuth[j],
      89     3832996 :                                                                                q_direction->band_data[i].bits_sph_idx[j],
      90     3832996 :                                                                                &q_direction->band_data[i].elevation[j],
      91     3832996 :                                                                                &q_direction->band_data[i].azimuth[j], &q_direction->band_data[i].elevation_index[j],
      92     3832996 :                                                                                &q_direction->band_data[i].azimuth_index[j],
      93             :                                                                                q_direction->cfg.mc_ls_setup );
      94             : 
      95     3832996 :             q_direction->not_in_2D += q_direction->band_data[i].elevation_index[j];
      96             : 
      97     3832996 :             if ( hrmasa_flag )
      98             :             {
      99      158082 :                 if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
     100             :                 {
     101           0 :                     q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[0] - 3];
     102           0 :                     q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[0] - 1][q_direction->band_data[i].elevation_index[j]];
     103             :                 }
     104             :                 else
     105             :                 {
     106      158082 :                     q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[0] - 3] * 2 - 1;
     107      158082 :                     q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[0] - 1][( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1];
     108             :                 }
     109             :             }
     110             :             else
     111             :             {
     112     3674914 :                 if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
     113             :                 {
     114       25889 :                     q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[idx] - 3];
     115       25889 :                     q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][q_direction->band_data[i].elevation_index[j]];
     116             :                 }
     117             :                 else
     118             :                 {
     119     3649025 :                     q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[idx] - 3] * 2 - 1;
     120     3649025 :                     q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1];
     121             :                 }
     122             :             }
     123             : 
     124     3832996 :             if ( q_direction->band_data[i].azimuth_index[j] == MASA_NO_INDEX )
     125             :             {
     126        3067 :                 q_direction->band_data[i].azimuth_index[j] = 0;
     127             :             }
     128             : 
     129     3832996 :             if ( q_direction->band_data[i].bits_sph_idx[j] <= 2 )
     130             :             {
     131           0 :                 q_direction->band_data[i].elevation_index[j] = 0;
     132             :             }
     133             :             else
     134             :             {
     135     3832996 :                 if ( q_direction->cfg.mc_ls_setup == MC_LS_SETUP_INVALID )
     136             :                 {
     137             :                     /*deorder elevation indexing*/
     138     3807107 :                     if ( ( q_direction->band_data[i].elevation_index[j] & 1 ) != 0 )
     139             :                     {
     140      722999 :                         q_direction->band_data[i].elevation_index[j] = ( ( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1 ) + ( q_direction->band_data[i].elevation_m_alphabet[j] >> 1 );
     141             :                     }
     142             :                     else
     143             :                     {
     144     3084108 :                         q_direction->band_data[i].elevation_index[j] = -( ( q_direction->band_data[i].elevation_index[j] ) >> 1 ) + ( q_direction->band_data[i].elevation_m_alphabet[j] >> 1 );
     145             :                     }
     146             :                 }
     147             :             }
     148             :         }
     149             :     }
     150             : 
     151      217725 :     if ( q_direction->not_in_2D > 0 )
     152             :     {
     153      191512 :         q_direction->not_in_2D = 1 + MASA_LIMIT_2D;
     154             :     }
     155             : 
     156      217725 :     return;
     157             : }
     158             : 
     159             : 
     160             : /*-------------------------------------------------------------------*
     161             :  * quantize_direction_frame2D()
     162             :  *
     163             :  *
     164             :  *----------------------------------------------------------------------*/
     165             : 
     166       10150 : void quantize_direction_frame2D(
     167             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure   */
     168             :     float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
     169             :     float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] )
     170             : {
     171             :     int16_t i, j;
     172             :     uint16_t idx;
     173             :     /* Quantize directions */
     174       10150 :     q_direction->not_in_2D = 0;
     175       54544 :     for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
     176             :     {
     177       44394 :         idx = q_direction->band_data[i].energy_ratio_index[0];
     178      128055 :         for ( j = 0; j < q_direction->cfg.nblocks; j++ )
     179             :         {
     180       83661 :             if ( azimuth_orig != NULL )
     181             :             {
     182       83661 :                 azimuth_orig[i][j] = q_direction->band_data[i].azimuth[j];
     183             :             }
     184       83661 :             if ( elevation_orig != NULL )
     185             :             {
     186       83661 :                 elevation_orig[i][j] = q_direction->band_data[i].elevation[j];
     187             :             }
     188       83661 :             q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][0];
     189             : 
     190             :             /* requantize the direction */
     191      167322 :             q_direction->band_data[i].spherical_index[j] = quantize_direction2D( q_direction->band_data[i].azimuth[j],
     192       83661 :                                                                                  q_direction->band_data[i].azimuth_m_alphabet[j],
     193       83661 :                                                                                  &q_direction->band_data[i].azimuth[j],
     194       83661 :                                                                                  &q_direction->band_data[i].azimuth_index[j],
     195             :                                                                                  q_direction->cfg.mc_ls_setup );
     196             : 
     197       83661 :             q_direction->band_data[i].elevation_m_alphabet[j] = 1;
     198             :         }
     199             :     }
     200             : 
     201       10150 :     return;
     202             : }
     203             : 
     204             : 
     205             : /*-------------------------------------------------------------------*
     206             :  * small_requantize_direction_frame()
     207             :  *
     208             :  *
     209             :  *----------------------------------------------------------------------*/
     210             : 
     211        7640 : void small_requantize_direction_frame(
     212             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure   */
     213             :     float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
     214             :     float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
     215             :     const int16_t raw_flag[MASA_MAXIMUM_CODING_SUBBANDS],
     216             :     int16_t bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS],
     217             :     int16_t *diff )
     218             : {
     219             :     int16_t i, j;
     220             :     uint16_t bits_dir[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
     221             : 
     222        7640 :     if ( ( *diff > 0 ) && ( q_direction->not_in_2D > 0 ) )
     223             :     {
     224       34881 :         for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
     225             :         {
     226      141445 :             for ( j = 0; j < q_direction->cfg.nblocks; j++ )
     227             :             {
     228      113156 :                 bits_dir[i][j] = q_direction->band_data[i].bits_sph_idx[j];
     229             :             }
     230             :         }
     231             : 
     232        6592 :         small_reduction_direction( q_direction, bits_dir, raw_flag, diff );
     233             : 
     234        6592 :         if ( *diff <= 0 )
     235             :         {
     236        6330 :             for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
     237             :             {
     238        5056 :                 if ( raw_flag[i] == 1 )
     239             :                 {
     240        4348 :                     bits_dir_bands[i] = 0;
     241       21740 :                     for ( j = 0; j < q_direction->cfg.nblocks; j++ )
     242             :                     {
     243       17392 :                         bits_dir_bands[i] += bits_dir[i][j];
     244       17392 :                         q_direction->band_data[i].bits_sph_idx[j] = bits_dir[i][j];
     245             : 
     246             :                         /* requantize the direction */
     247       34784 :                         q_direction->band_data[i].spherical_index[j] = quantize_direction(
     248       17392 :                             elevation_orig[i][j], azimuth_orig[i][j],
     249       17392 :                             q_direction->band_data[i].bits_sph_idx[j],
     250       17392 :                             &q_direction->band_data[i].elevation[j], &q_direction->band_data[i].azimuth[j],
     251       17392 :                             &q_direction->band_data[i].elevation_index[j], &q_direction->band_data[i].azimuth_index[j],
     252             :                             q_direction->cfg.mc_ls_setup );
     253             : 
     254       17392 :                         if ( q_direction->band_data[i].azimuth_index[j] == MASA_NO_INDEX )
     255             :                         {
     256          19 :                             q_direction->band_data[i].azimuth_index[j] = 0;
     257             :                         }
     258             :                     }
     259             :                 }
     260             :             }
     261             :         }
     262             :     }
     263             : 
     264        7640 :     return;
     265             : }
     266             : 
     267             : 
     268             : /*-------------------------------------------------------------------*
     269             :  * quantize_direction()
     270             :  *
     271             :  *
     272             :  *----------------------------------------------------------------------*/
     273             : 
     274             : /*! r: quantized spherical index */
     275     3994616 : uint16_t quantize_direction(
     276             :     const float theta,          /* i  : input elevation value        */
     277             :     float phi,                  /* i  : input azimuth value          */
     278             :     const int16_t no_bits,      /* i  : number of bits               */
     279             :     float *theta_q,             /* o  : quantized elevation          */
     280             :     float *phi_q,               /* o  : quantized azimuth            */
     281             :     uint16_t *index_theta,      /* o  : quantized elevation index    */
     282             :     uint16_t *index_phi,        /* o  : quantized azimuth index      */
     283             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode */
     284             : )
     285             : {
     286             :     float abs_theta, theta_hat, phi_hat;
     287             :     int16_t i, sign_th;
     288             :     int16_t cum_n[500];
     289             :     int16_t id_th, id_phi;
     290             :     float theta_cb[MAX_NO_THETA];
     291             :     int16_t no_th;
     292             :     uint16_t idx_sph;
     293             :     int16_t id_phi_remap;
     294             : 
     295     3994616 :     if ( no_bits == 0 )
     296             :     {
     297           0 :         *theta_q = 0;
     298           0 :         *phi_q = 0;
     299           0 :         *index_theta = MASA_NO_INDEX;
     300           0 :         *index_phi = MASA_NO_INDEX;
     301           0 :         return 0;
     302             :     }
     303             : 
     304     3994616 :     if ( no_bits == 1 )
     305             :     {
     306           0 :         *theta_q = 0;
     307           0 :         *index_theta = MASA_NO_INDEX;
     308           0 :         if ( ( phi < -90 ) || ( phi > 90 ) )
     309             :         {
     310           0 :             *phi_q = -180;
     311           0 :             *index_phi = 1;
     312             : 
     313           0 :             return 1;
     314             :         }
     315             :         else
     316             :         {
     317           0 :             *phi_q = 0;
     318           0 :             *index_phi = 0;
     319             : 
     320           0 :             return 0;
     321             :         }
     322             :     }
     323             : 
     324     3994616 :     if ( no_bits == 2 )
     325             :     {
     326         678 :         *theta_q = 0;
     327         678 :         *index_theta = MASA_NO_INDEX;
     328         678 :         if ( mc_format != MC_LS_SETUP_INVALID )
     329             :         {
     330          11 :             id_phi = quantize_phi_chan_lbr( phi, &phi_hat, no_phi_masa[no_bits - 1][0] );
     331          11 :             phi_hat += 180;
     332          11 :             idx_sph = id_phi;
     333          11 :             *phi_q = phi_hat - 180;
     334          11 :             id_phi_remap = id_phi;
     335          11 :             *index_phi = id_phi_remap;
     336             :         }
     337             :         else
     338             :         {
     339         667 :             id_phi = quantize_phi( phi + 180, 0, &phi_hat, no_phi_masa[no_bits - 1][0] );
     340         667 :             idx_sph = id_phi;
     341         667 :             *phi_q = phi_hat - 180;
     342         667 :             id_phi_remap = ivas_qmetadata_reorder_generic( id_phi - ( no_phi_masa[no_bits - 1][0] >> 1 ) );
     343         667 :             *index_phi = id_phi_remap;
     344             :         }
     345             : 
     346         678 :         return idx_sph;
     347             :     }
     348             : 
     349     3993938 :     no_th = no_theta_masa[no_bits - 3];
     350             : 
     351    31955114 :     for ( i = 0; i < no_th; i++ )
     352             :     {
     353    27961176 :         theta_cb[i] = i * delta_theta_masa[no_bits - 3];
     354             :     }
     355             : 
     356     3993938 :     if ( theta_cb[i - 1] > 90 )
     357             :     {
     358     1726395 :         theta_cb[i - 1] = 90;
     359             :     }
     360             : 
     361     3993938 :     phi = phi + 180;
     362             : 
     363     3993938 :     if ( theta < 0 )
     364             :     {
     365     2021317 :         abs_theta = -theta;
     366     2021317 :         sign_th = -1;
     367             :     }
     368             :     else
     369             :     {
     370     1972621 :         abs_theta = theta;
     371     1972621 :         sign_th = 1;
     372             :     }
     373             : 
     374     3993938 :     theta_hat = quantize_theta_phi( theta_cb, no_th, no_phi_masa[no_bits - 1], abs_theta, &id_phi,
     375             :                                     &id_phi_remap, &phi_hat, phi, no_bits, &id_th, phi_q, 1, mc_format );
     376             : 
     377     3993938 :     if ( mc_format != MC_LS_SETUP_INVALID )
     378             :     {
     379             :         /* indexing only for upper hemisphere */
     380       33278 :         cum_n[0] = no_phi_masa[no_bits - 1][0];
     381      166665 :         for ( i = 1; i < no_th; i++ )
     382             :         {
     383      133387 :             cum_n[i] = cum_n[i - 1] + no_phi_masa[no_bits - 1][i];
     384             :         }
     385             : 
     386       33278 :         if ( id_phi < MASA_NO_INDEX )
     387             :         {
     388       33160 :             if ( id_th == 0 )
     389             :             {
     390        4253 :                 idx_sph = id_phi;
     391             :             }
     392             :             else
     393             :             {
     394       28907 :                 idx_sph = cum_n[id_th - 1] + id_phi;
     395             :             }
     396             :         }
     397             :         else
     398             :         {
     399         118 :             if ( id_th == 0 )
     400             :             {
     401           0 :                 idx_sph = 0;
     402             :             }
     403             :             else
     404             :             {
     405         118 :                 idx_sph = cum_n[id_th - 1];
     406             :             }
     407             :         }
     408       33278 :         *theta_q = theta_hat;
     409       33278 :         if ( theta_hat == 90 )
     410             :         {
     411         118 :             *phi_q = 0;
     412         118 :             id_phi = MASA_NO_INDEX;
     413             :         }
     414             :         else
     415             :         {
     416       33160 :             *phi_q = phi_hat - 180;
     417             :         }
     418       33278 :         *index_theta = id_th;
     419       33278 :         *index_phi = id_phi_remap;
     420             :     }
     421             :     else
     422             :     {
     423             :         /* Starting from Equator, alternating positive and negative */
     424     3960660 :         cum_n[0] = no_phi_masa[no_bits - 1][0];
     425    27794511 :         for ( i = 1; i < no_th; i++ )
     426             :         {
     427    23833851 :             cum_n[2 * i - 1] = cum_n[2 * i - 2] + no_phi_masa[no_bits - 1][i];
     428    23833851 :             cum_n[2 * i] = cum_n[2 * i - 1] + no_phi_masa[no_bits - 1][i];
     429             :         }
     430             : 
     431     3960660 :         if ( no_th > 0 )
     432             :         {
     433     3960660 :             assert( abs( cum_n[2 * ( no_th - 1 )] ) < 32768 );
     434             :         }
     435             : 
     436     3960660 :         if ( id_th == 0 )
     437             :         {
     438     2097369 :             if ( id_phi < MASA_NO_INDEX )
     439             :             {
     440     2097369 :                 idx_sph = id_phi;
     441             :             }
     442             :             else
     443             :             {
     444           0 :                 idx_sph = 0;
     445             :             }
     446             :         }
     447             :         else
     448             :         {
     449     1863291 :             if ( sign_th > 0 )
     450             :             {
     451      740603 :                 if ( id_phi < MASA_NO_INDEX )
     452             :                 {
     453      739477 :                     idx_sph = cum_n[2 * id_th - 2] + id_phi;
     454             :                 }
     455             :                 else
     456             :                 {
     457        1126 :                     idx_sph = cum_n[2 * id_th - 2];
     458             :                 }
     459             : 
     460      740603 :                 id_th = 2 * id_th - 1;
     461             :             }
     462             :             else
     463             :             {
     464     1122688 :                 if ( id_phi < MASA_NO_INDEX )
     465             :                 {
     466     1120584 :                     idx_sph = cum_n[2 * id_th - 1] + id_phi;
     467             :                 }
     468             :                 else
     469             :                 {
     470        2104 :                     idx_sph = cum_n[2 * id_th - 1];
     471             :                 }
     472     1122688 :                 id_th = 2 * id_th;
     473             :             }
     474             :         }
     475             : 
     476     3960660 :         *theta_q = sign_th * theta_hat;
     477     3960660 :         if ( theta_hat == 90 )
     478             :         {
     479        3164 :             *phi_q = 0;
     480        3164 :             id_phi = MASA_NO_INDEX;
     481             :         }
     482             :         else
     483             :         {
     484     3957496 :             *phi_q = phi_hat - 180;
     485             :         }
     486             : 
     487     3960660 :         *index_theta = id_th;
     488     3960660 :         *index_phi = id_phi_remap;
     489             :     }
     490             : 
     491     3993938 :     return idx_sph;
     492             : }
     493             : 
     494             : 
     495             : /*-------------------------------------------------------------------*
     496             :  * direction_distance_cp()
     497             :  *
     498             :  * quantization distortion calculated on the sphere
     499             :  *----------------------------------------------------------------------*/
     500             : 
     501             : /*! r: distortion value */
     502     2306016 : static float direction_distance_cp(
     503             :     float theta,          /* i  : elevation absolute value                      */
     504             :     float theta_hat,      /* i  : quantized elevation value in absolute value   */
     505             :     float theta_hat1,     /* i  : quantized elevation value in absolute value   */
     506             :     const float phi,      /* i  : azimuth value                                 */
     507             :     const float phi_hat,  /* i  : quantized azimuth value                       */
     508             :     const float phi_hat1, /* i  : quantized azimuth value                       */
     509             :     float *d1 )
     510             : {
     511             :     float d, ct, st, st1, st2;
     512             : 
     513     2306016 :     theta *= PI_OVER_180;
     514     2306016 :     theta_hat *= PI_OVER_180;
     515     2306016 :     theta_hat1 *= PI_OVER_180;
     516     2306016 :     st = sinf( theta );
     517     2306016 :     ct = cosf( theta );
     518     2306016 :     st1 = sinf( theta_hat );
     519     2306016 :     st2 = sinf( theta_hat1 );
     520             : 
     521     2306016 :     d = st * st1 + ct * ( sqrtf( 1 - st1 * st1 ) ) * cosf( ( phi - phi_hat ) * PI_OVER_180 );
     522     2306016 :     *d1 = st * st2 + ct * ( sqrtf( 1 - st2 * st2 ) ) * cosf( ( phi - phi_hat1 ) * PI_OVER_180 );
     523             : 
     524     2306016 :     return d;
     525             : }
     526             : 
     527             : 
     528             : /*-------------------------------------------------------------------*
     529             :  * quantize_theta_phi()
     530             :  *
     531             :  * joint quantization of elevation and azimuth
     532             :  *----------------------------------------------------------------------*/
     533             : 
     534             : /*! r: quantized elevation value */
     535     3993938 : static float quantize_theta_phi(
     536             :     float *theta_cb,            /* i  : elevation codebook                                  */
     537             :     const int16_t no_th,        /* i  : elevation codebook size                             */
     538             :     const int16_t *no_phi_loc,  /* i  : number of azimuth values for each elevation codeword*/
     539             :     const float abs_theta,      /* i  : absolute value of elevation to be quantized         */
     540             :     int16_t *id_phi,            /* o  : azimuth index                                       */
     541             :     int16_t *id_phi_remap,      /* o  : remapped azimuth index                              */
     542             :     float *phi_hat,             /* o  : quantized azimuth value                             */
     543             :     const float phi,            /* i  : input azimuth value; to be quantized                */
     544             :     const int16_t no_bits,      /* i  : number of bits used for quantization                */
     545             :     int16_t *id_theta,          /* o  : elevation index                                     */
     546             :     float *phi_q,               /* o  : rotated quantized azimuth                           */
     547             :     const int16_t remap,        /* i  : flag for remapping                                  */
     548             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode                        */
     549             : )
     550             : {
     551             :     float theta_hat, theta_hat1, phi_hat1;
     552             :     int16_t id_th, id_th1, id_th2, id_ph, id_ph1;
     553             :     float d, d1;
     554             : 
     555     3993938 :     id_th = (int16_t) ( abs_theta / delta_theta_masa[no_bits - 3] );
     556     3993938 :     if ( id_th >= no_th )
     557             :     {
     558           6 :         id_th = no_th - 1;
     559             :     }
     560     3993938 :     theta_hat = theta_cb[id_th];
     561     3993938 :     if ( id_th < no_th - 1 )
     562             :     {
     563     3763876 :         id_th += squant( abs_theta, &theta_hat, &theta_cb[id_th], 2 );
     564             :     }
     565             : 
     566     3993938 :     if ( no_th > 1 )
     567             :     {
     568     3993938 :         if ( ( no_th < 6 ) && mc_format == MC_LS_SETUP_INVALID )
     569             :         {
     570     2336237 :             if ( id_th == 0 )
     571             :             {
     572     1294002 :                 id_th1 = 1;
     573             :             }
     574     1042235 :             else if ( id_th == no_th - 1 )
     575             :             {
     576      570314 :                 id_th1 = no_th - 2;
     577             :             }
     578             :             else
     579             :             {
     580      471921 :                 id_th1 = id_th - 1;
     581      471921 :                 id_th2 = id_th + 1;
     582             : 
     583      471921 :                 if ( fabsf( abs_theta - theta_cb[id_th1] ) > fabsf( abs_theta - theta_cb[id_th2] ) )
     584             :                 {
     585      167424 :                     id_th1 = id_th2;
     586             :                 }
     587             :             }
     588             :         }
     589             :         else
     590             :         {
     591     1657701 :             id_th1 = id_th;
     592             :         }
     593             : 
     594     3993938 :         if ( no_phi_loc[id_th] > 1 )
     595             :         {
     596             :             /* Note: (id_th % 2 == 1) must be equal to id_th % 2 */
     597     3990590 :             if ( mc_format != MC_LS_SETUP_INVALID )
     598             :             {
     599       33160 :                 id_ph = quantize_phi_chan_compand( phi, phi_hat, no_phi_loc[id_th], ( theta_cb[id_th] > MC_MASA_THR_ELEVATION ), mc_format );
     600       33160 :                 *id_phi_remap = id_ph;
     601             :             }
     602             :             else
     603             :             {
     604     3957430 :                 id_ph = quantize_phi( phi, ( id_th % 2 == 1 ), phi_hat, no_phi_loc[id_th] );
     605             :             }
     606             :         }
     607             :         else
     608             :         {
     609        3348 :             id_ph = MASA_NO_INDEX;
     610        3348 :             *id_phi_remap = MASA_NO_INDEX;
     611        3348 :             *phi_hat = 180;
     612        3348 :             *phi_q = 0;
     613             :         }
     614             : 
     615     3993938 :         if ( ( no_phi_loc[id_th1] > 1 ) && ( id_ph < MASA_NO_INDEX ) && ( no_th < 6 ) && ( mc_format == MC_LS_SETUP_INVALID ) )
     616             :         {
     617     2306016 :             theta_hat1 = theta_cb[id_th1];
     618             : 
     619     2306016 :             id_ph1 = quantize_phi( phi, ( id_th1 % 2 == 1 ), &phi_hat1, no_phi_loc[id_th1] );
     620             : 
     621     2306016 :             d = direction_distance_cp( abs_theta, theta_hat, theta_hat1, phi, *phi_hat, phi_hat1, &d1 );
     622             : 
     623     2306016 :             if ( d1 > d )
     624             :             {
     625      238130 :                 *phi_hat = phi_hat1;
     626      238130 :                 id_ph = id_ph1;
     627      238130 :                 theta_hat = theta_cb[id_th1];
     628      238130 :                 id_th = id_th1;
     629             :             }
     630             :         }
     631             :     }
     632             :     else
     633             :     {
     634           0 :         if ( mc_format != MC_LS_SETUP_INVALID )
     635             :         {
     636           0 :             id_ph = quantize_phi_chan_compand( phi, phi_hat, no_phi_loc[id_th], 0, mc_format );
     637           0 :             *id_phi_remap = id_ph;
     638             :         }
     639             :         else
     640             :         {
     641           0 :             id_ph = quantize_phi( phi, ( id_th % 2 == 1 ), phi_hat, no_phi_loc[id_th] );
     642             :         }
     643             :     }
     644             : 
     645     3993938 :     if ( remap )
     646             :     {
     647     3993938 :         if ( id_ph < MASA_NO_INDEX )
     648             :         {
     649     3990590 :             *id_phi_remap = ivas_qmetadata_reorder_generic( id_ph - ( no_phi_loc[id_th] >> 1 ) );
     650             :         }
     651             :     }
     652             :     else
     653             :     {
     654           0 :         *id_phi_remap = id_ph;
     655             :     }
     656             : 
     657     3993938 :     *id_phi = id_ph;
     658     3993938 :     *id_theta = id_th;
     659             : 
     660     3993938 :     return theta_hat;
     661             : }

Generated by: LCOV version 1.14