LCOV - code coverage report
Current view: top level - lib_com - ivas_qspherical_com_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 253 283 89.4 %
Date: 2025-05-03 01:55:50 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 "prot_fx.h"
      40             : #include "cnst.h"
      41             : #include "wmc_auto.h"
      42             : #include "ivas_prot_fx.h"
      43             : #include "ivas_rom_com_fx.h"
      44             : 
      45             : 
      46             : /*-------------------------------------------------------------------------
      47             :  * ivas_qmetadata_reorder_generic()
      48             :  *
      49             :  *------------------------------------------------------------------------*/
      50    22273839 : UWord16 ivas_qmetadata_reorder_generic_fx(
      51             :     const Word16 signed_value )
      52             : {
      53             :     UWord16 unsigned_value;
      54             : 
      55    22273839 :     IF( signed_value < 0 )
      56             :     {
      57             :         // unsigned_value = ( ( UWord16 ) - ( signed_value + 1 ) << 1 ) + 1;
      58     9215387 :         unsigned_value = (UWord16) L_add( L_shl( negate( add( signed_value, 1 ) ), 1 ), 1 );
      59             :     }
      60             :     ELSE
      61             :     {
      62    13058452 :         unsigned_value = (UWord16) L_shl( signed_value, 1 );
      63             :     }
      64             : 
      65    22273839 :     return unsigned_value;
      66             : }
      67             : 
      68             : 
      69             : /*-------------------------------------------------------------------------
      70             :  * ivas_qmetadata_dereorder_generic()
      71             :  *
      72             :  * Returns the original value of the array "folded" by ReorderGeneric
      73             :  *------------------------------------------------------------------------*/
      74             : 
      75             : /*! r: "Unfolded" value, positive or negative depending on the value of the input */
      76    13479400 : Word16 ivas_qmetadata_dereorder_generic_fx(
      77             :     const UWord16 uns_value /* i  : unsigned value result of ReorderGeneric                                     */
      78             : )
      79             : {
      80    13479400 :     IF( L_and( uns_value, 1 ) != 0 )
      81             :     {
      82     5832127 :         return sub( negate( extract_l( L_shr( uns_value, 1 ) ) ), 1 );
      83             :     }
      84             :     ELSE
      85             :     {
      86     7647273 :         return extract_l( L_shr( uns_value, 1 ) );
      87             :     }
      88             : }
      89             : 
      90             : 
      91             : /*-------------------------------------------------------------------------
      92             :  * ivas_dirac_project_elevation_index()
      93             :  *
      94             :  *
      95             :  *------------------------------------------------------------------------*/
      96             : 
      97             : /*! r: projected elevation index */
      98     8958124 : Word16 ivas_dirac_project_elevation_index_fx(
      99             :     const Word16 el_idx,      /* i  : elevation index                         */
     100             :     const Word16 el_alph,     /* i  : number of elevation symbols             */
     101             :     const Word16 el_alph_proj /* i  : size of projected alphabet              */
     102             : )
     103             : {
     104             :     Word16 el_idx_proj;
     105             : 
     106             :     /* evaluate floor((el_idx / (el_alph - 1)) * (el_alph_proj - 1) + 0.5) using only integer */
     107     8958124 :     el_idx_proj = idiv1616( add( imult1616( imult1616( 2, el_idx ), sub( el_alph_proj, 1 ) ), sub( el_alph, 1 ) ), imult1616( 2, sub( el_alph, 1 ) ) );
     108             : 
     109     8958124 :     return el_idx_proj;
     110             : }
     111             : 
     112             : 
     113             : /*-------------------------------------------------------------------------
     114             :  * ivas_chan_project_elevation_index()
     115             :  *
     116             :  *
     117             :  *------------------------------------------------------------------------*/
     118             : 
     119             : /*! r: projected index in channel mode */
     120       84795 : Word16 ivas_chan_project_elevation_index_fx(
     121             :     const Word16 el_idx,      /* i  : elevation index                 */
     122             :     const Word16 el_alph,     /* i  : number of elevation symbols     */
     123             :     const Word16 el_alph_proj /* i  : size of projected alphabet      */
     124             : )
     125             : {
     126             :     Word16 el_idx_proj;
     127             : 
     128             :     /* evaluate floor((el_idx / (el_alph - 1)) * (el_alph_proj - 1) + 0.5) using only integer */
     129       84795 :     IF( EQ_16( el_idx, sub( el_alph, 1 ) ) )
     130             :     {
     131        9106 :         el_idx_proj = sub( el_alph_proj, 1 );
     132             :     }
     133             :     ELSE
     134             :     {
     135       75689 :         el_idx_proj = idiv1616( add( imult1616( imult1616( 2, el_idx ), el_alph_proj ), el_alph ), imult1616( 2, el_alph ) );
     136             :     }
     137             : 
     138       84795 :     return el_idx_proj;
     139             : }
     140             : 
     141             : 
     142             : /*-------------------------------------------------------------------------
     143             :  * ivas_dirac_project_azimuth_index()
     144             :  *
     145             :  *
     146             :  *------------------------------------------------------------------------*/
     147             : 
     148             : /*! r: projected azimuth index */
     149    10386410 : Word16 ivas_dirac_project_azimuth_index_fx(
     150             :     const Word16 az_idx,      /* i  : azimuth index                           */
     151             :     const Word16 az_alph,     /* i  : number of azimuth symbols               */
     152             :     const Word16 az_alph_proj /* i  : size of projected alphabet              */
     153             : )
     154             : {
     155             :     Word16 az_idx_proj;
     156             : 
     157    10386410 :     IF( EQ_16( az_alph_proj, 1 ) )
     158             :     {
     159        5125 :         return 0;
     160             :     }
     161             : 
     162             :     /* evaluate floor((az_idx / az_alph) * az_alph_proj + 0.5) using only integer */
     163    10381285 :     az_idx_proj = idiv1616( add( imult1616( imult1616( 2, az_idx ), az_alph_proj ), az_alph ), imult1616( 2, az_alph ) );
     164             : 
     165    10381285 :     if ( EQ_16( az_idx_proj, az_alph_proj ) )
     166             :     {
     167      242243 :         az_idx_proj = 0;
     168      242243 :         move16();
     169             :     }
     170             : 
     171    10381285 :     return az_idx_proj;
     172             : }
     173             : 
     174             : 
     175             : /*-------------------------------------------------------------------------
     176             :  * small_reduction_direction()
     177             :  *
     178             :  * Compute the allocated bit reduction in spherical indexing for bit budget
     179             :  * is exceeded by diff. bits
     180             :  *------------------------------------------------------------------------*/
     181             : 
     182        8368 : void small_reduction_direction_fx(
     183             :     IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure   */
     184             :     UWord16 bits_dir[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
     185             :     const Word16 raw_flag[MASA_MAXIMUM_CODING_SUBBANDS],
     186             :     Word16 *diff )
     187             : {
     188             :     Word16 i, j, k;
     189             : 
     190        8368 :     test();
     191       22512 :     FOR( k = 0; ( k < 2 ) && ( *diff > 0 ); k++ )
     192             :     {
     193       14144 :         test();
     194       14144 :         test();
     195       70132 :         FOR( i = q_direction->cfg.start_band; ( i < q_direction->cfg.nbands ) && ( *diff > 0 ); i++ )
     196             :         {
     197       55988 :             test();
     198       55988 :             IF( EQ_16( raw_flag[i], 1 ) )
     199             :             {
     200       26650 :                 test();
     201      130063 :                 FOR( j = 0; ( j < q_direction->cfg.nblocks ) && ( *diff > 0 ); j++ )
     202             :                 {
     203      103413 :                     test();
     204      103413 :                     IF( GT_32( bits_dir[i][j], MASA_MIN_BITS_TF ) )
     205             :                     {
     206       65797 :                         bits_dir[i][j] = (UWord16) L_sub( bits_dir[i][j], 1 );
     207       65797 :                         move16();
     208       65797 :                         ( *diff )--;
     209             :                     }
     210             :                 }
     211             :             }
     212             :         }
     213             :     }
     214             : 
     215        8368 :     return;
     216             : }
     217             : 
     218             : 
     219             : /*-----------------------------------------------------------------------*
     220             :  * quantize_phi()
     221             :  *
     222             :  * Quantize azimuth.
     223             :  * Input phi expected to be an angle in degree between 0 and 360.
     224             :  *-----------------------------------------------------------------------*/
     225             : /*! r: index azimuth */
     226             : 
     227        8376 : Word16 quantize_phi_fx(
     228             :     Word32 phi,              /* i  : azimuth value, Q22                                            */
     229             :     const Word16 flag_delta, /* i  : flag indicating if the azimuth codebook is translated or not  */
     230             :     Word32 *phi_hat,         /* o  : quantized azimuth, Q22                                        */
     231             :     const Word16 n           /* i  : azimuth codebook size                                         */
     232             : )
     233             : {
     234             :     Word16 id_phi;
     235             :     Word32 dd_fx;
     236             :     Word32 delta_phi_fx;
     237             :     Word32 inv_delta_phi_fx;
     238             :     Word32 temp_res;
     239             : 
     240        8376 :     delta_phi_fx = delta_phi_val[n]; // Q22
     241        8376 :     move32();
     242        8376 :     inv_delta_phi_fx = inv_delta_phi_val[n]; // Q31
     243        8376 :     move32();
     244        8376 :     IF( EQ_16( n, 1 ) )
     245             :     {
     246           0 :         *phi_hat = 0;
     247           0 :         move32();
     248             : 
     249           0 :         return 0;
     250             :     }
     251             : 
     252        8376 :     test();
     253        8376 :     IF( EQ_16( flag_delta, 1 ) && GT_16( n, 2 ) )
     254             :     {
     255           0 :         dd_fx = dd_val[n];
     256           0 :         move32();
     257             :     }
     258             :     ELSE
     259             :     {
     260        8376 :         dd_fx = 0;
     261        8376 :         move32();
     262             :     }
     263             : 
     264        8376 :     temp_res = Mpy_32_32( L_sub( L_sub( phi, DEGREE_180_Q_22 ), dd_fx ), inv_delta_phi_fx ); // Q22 + Q31 - Q31 -> Q22
     265        8376 :     id_phi = round_fx( L_shr( temp_res, Q22 - Q16 ) );                                       // Q0
     266             : 
     267        8376 :     assert( L_sub( L_abs( temp_res ), abs( id_phi ) * ONE_IN_Q22 ) <= ONE_IN_Q21 );
     268             : 
     269             : 
     270        8376 :     IF( add( id_phi, shr( n, 1 ) ) < 0 )
     271             :     {
     272           0 :         id_phi = add( id_phi, 1 );
     273             :     }
     274             : 
     275        8376 :     IF( sub( id_phi, shr( n, 1 ) ) >= 0 )
     276             :     {
     277           4 :         id_phi = negate( shr( n, 1 ) );
     278             :     }
     279             : 
     280        8376 :     IF( EQ_16( id_phi, negate( add( shr( n, 1 ), ( n % 2 ) ) ) ) )
     281             :     {
     282           7 :         id_phi = add( id_phi, ( n % 2 ) );
     283             :     }
     284             :     ELSE{
     285        8369 :         IF( EQ_16( id_phi, add( shr( n, 1 ), ( n % 2 ) ) ) ){
     286           0 :             IF( n % 2 ){
     287           0 :                 id_phi = sub( id_phi, 1 );
     288             : }
     289             : ELSE
     290             : {
     291           0 :     id_phi = negate( id_phi );
     292             : }
     293             : }
     294             : }
     295             : 
     296        8376 : *phi_hat = L_add_sat( L_add_sat( imult3216( delta_phi_fx, id_phi ), dd_fx ), DEGREE_180_Q_22 ); // Q22
     297        8376 : move32();
     298        8376 : id_phi = add( id_phi, shr( n, 1 ) );
     299             : 
     300        8376 : return id_phi;
     301             : }
     302             : 
     303     6591116 : Word16 quantize_phi_enc_fx(
     304             :     Word32 phi,              /* i  : azimuth value, Q22                                            */
     305             :     const Word16 flag_delta, /* i  : flag indicating if the azimuth codebook is translated or not  */
     306             :     Word32 *phi_hat,         /* o  : quantized azimuth, Q22                                        */
     307             :     const Word16 n           /* i  : azimuth codebook size                                         */
     308             : )
     309             : {
     310             :     Word16 id_phi;
     311             :     Word32 dd_fx;
     312             :     Word32 delta_phi_fx;
     313             :     Word32 inv_delta_phi_fx;
     314             :     Word32 temp_res;
     315             :     Word16 temp_e;
     316             : 
     317     6591116 :     delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( 360, n, &temp_e );
     318     6591116 :     delta_phi_fx = L_shl( delta_phi_fx, sub( temp_e, 9 ) );
     319     6591116 :     inv_delta_phi_fx = BASOP_Util_Divide3232_Scale_newton( n, 360, &temp_e );
     320             : 
     321     6591116 :     IF( EQ_16( n, 1 ) )
     322             :     {
     323           0 :         *phi_hat = 0;
     324           0 :         move32();
     325             : 
     326           0 :         return 0;
     327             :     }
     328             : 
     329     6591116 :     test();
     330     6591116 :     IF( EQ_16( flag_delta, 1 ) && GT_16( n, 2 ) )
     331             :     {
     332     1598880 :         dd_fx = dd_val[n];
     333     1598880 :         move32();
     334             :     }
     335             :     ELSE
     336             :     {
     337     4992236 :         dd_fx = 0;
     338     4992236 :         move32();
     339             :     }
     340             : 
     341     6591116 :     temp_res = Mpy_32_32( L_sub( L_sub( phi, DEGREE_180_Q_22 ), dd_fx ), inv_delta_phi_fx );
     342     6591116 :     temp_res = L_shl( temp_res, temp_e );
     343     6591116 :     id_phi = round_fx( L_shr( temp_res, Q22 - Q16 ) );
     344             : 
     345     6591116 :     assert( L_sub( L_abs( temp_res ), abs( id_phi ) * ONE_IN_Q22 ) <= ONE_IN_Q21 );
     346             : 
     347             : 
     348     6591116 :     IF( add( id_phi, shr( n, 1 ) ) < 0 )
     349             :     {
     350       25217 :         id_phi = add( id_phi, 1 );
     351             :     }
     352             : 
     353     6591116 :     IF( sub( id_phi, shr( n, 1 ) ) >= 0 )
     354             :     {
     355      473579 :         id_phi = negate( shr( n, 1 ) );
     356             :     }
     357             : 
     358     6591116 :     IF( EQ_16( id_phi, negate( add( shr( n, 1 ), ( n % 2 ) ) ) ) )
     359             :     {
     360      809096 :         id_phi = add( id_phi, ( n % 2 ) );
     361             :     }
     362             :     ELSE{
     363     5782020 :         IF( EQ_16( id_phi, add( shr( n, 1 ), ( n % 2 ) ) ) ){
     364           0 :             IF( n % 2 ){
     365           0 :                 id_phi = sub( id_phi, 1 );
     366             : }
     367             : ELSE
     368             : {
     369           0 :     id_phi = negate( id_phi );
     370             : }
     371             : }
     372             : }
     373             : 
     374     6591116 : *phi_hat = L_add_sat( L_add_sat( ( imult3216( delta_phi_fx, id_phi ) ), dd_fx ), DEGREE_180_Q_22 );
     375     6591116 : move32();
     376     6591116 : id_phi = add( id_phi, shr( n, 1 ) );
     377             : 
     378     6591116 : return id_phi;
     379             : }
     380             : /*-----------------------------------------------------------------------*
     381             :  * companding_azimuth()
     382             :  *
     383             :  * Compand azimuth based on the format
     384             :  *-----------------------------------------------------------------------*/
     385             : 
     386      314031 : Word32 companding_azimuth_fx(
     387             :     const Word32 azi_fx,         /* i  : input azimuth value, Q22                   */
     388             :     const MC_LS_SETUP mc_format, /* i  : input channel format                       */
     389             :     const Word16 theta_flag,     /* i  : zero/non zero elevation flag               */
     390             :     const Word16 direction       /* i  : direction of companding (direct or inverse)*/
     391             : )
     392             : {
     393      314031 :     const Word16 pointsA[] = { 0, 60, 110, 150, 180, 0, 50, 90, 150, 180, 0, 30, 80, 150, 180 };   // Q0
     394      314031 :     const Word16 pointsB[] = { 0, 90, 110, 170, 180, 0, 90, 110, 170, 180, 0, 10, 100, 170, 180 }; // Q0
     395             :     const Word16 *pA;
     396      314031 :     const Word32 pointsA_fx[] = { 0, 251658240, 461373440, 629145600, 754974720, 0, 209715200, 377487360, 629145600, 754974720, 0, 125829120, 335544320, 629145600, 754974720 }; // q=22
     397      314031 :     const Word32 pointsB_fx[] = { 0, 377487360, 461373440, 713031680, 754974720, 0, 377487360, 461373440, 713031680, 754974720, 0, 41943040, 419430400, 713031680, 754974720 };  // q=22
     398             :     const Word32 *pA_fx, *pB_fx;
     399             :     Word16 no_points;
     400             :     Word32 comp_azi_fx;
     401             :     Word16 i, not_done, start;
     402             :     Word32 abs_azi_fx;
     403      314031 :     move16();
     404      314031 :     move16();
     405      314031 :     move16();
     406      314031 :     move16();
     407      314031 :     move16();
     408      314031 :     move16();
     409      314031 :     move16();
     410      314031 :     move16();
     411      314031 :     move16();
     412      314031 :     move16();
     413      314031 :     move16();
     414      314031 :     move16();
     415      314031 :     move16();
     416      314031 :     move16();
     417      314031 :     move16();
     418      314031 :     move16();
     419      314031 :     move16();
     420      314031 :     move16();
     421      314031 :     move16();
     422      314031 :     move16();
     423      314031 :     move16();
     424      314031 :     move16();
     425      314031 :     move16();
     426      314031 :     move16();
     427      314031 :     move16();
     428      314031 :     move16();
     429      314031 :     move16();
     430      314031 :     move16();
     431      314031 :     move16();
     432      314031 :     move16();
     433      314031 :     move32();
     434      314031 :     move32();
     435      314031 :     move32();
     436      314031 :     move32();
     437      314031 :     move32();
     438      314031 :     move32();
     439      314031 :     move32();
     440      314031 :     move32();
     441      314031 :     move32();
     442      314031 :     move32();
     443      314031 :     move32();
     444      314031 :     move32();
     445      314031 :     move32();
     446      314031 :     move32();
     447      314031 :     move32();
     448      314031 :     move32();
     449      314031 :     move32();
     450      314031 :     move32();
     451      314031 :     move32();
     452      314031 :     move32();
     453      314031 :     move32();
     454      314031 :     move32();
     455      314031 :     move32();
     456      314031 :     move32();
     457      314031 :     move32();
     458      314031 :     move32();
     459      314031 :     move32();
     460      314031 :     move32();
     461      314031 :     move32();
     462      314031 :     move32();
     463             : 
     464      314031 :     test();
     465      314031 :     test();
     466      314031 :     IF( EQ_32( mc_format, MC_LS_SETUP_5_1 ) || EQ_32( mc_format, MC_LS_SETUP_5_1_2 ) || EQ_32( mc_format, MC_LS_SETUP_5_1_4 ) ) /* 5.1, 5.1+2 or 5.1+4*/
     467             :     {
     468      250833 :         start = 5;
     469      250833 :         move16();
     470             :     }
     471             :     ELSE
     472             :     {
     473       63198 :         start = 0;
     474       63198 :         move16();
     475             :     }
     476             : 
     477             :     /* theta flag 1 is for non zero, larger than a threshold elevation */
     478      314031 :     test();
     479      314031 :     test();
     480      314031 :     test();
     481      314031 :     IF( ( EQ_16( theta_flag, 1 ) ) && ( ( EQ_32( mc_format, MC_LS_SETUP_5_1_2 ) ) || ( EQ_32( mc_format, MC_LS_SETUP_5_1_4 ) ) || ( EQ_32( mc_format, MC_LS_SETUP_7_1_4 ) ) ) ) /* 5.1+2, 5.1+4 or 7.1+4*/
     482             :     {
     483       28186 :         start = 10;
     484       28186 :         move16();
     485             :     }
     486      314031 :     no_points = 5;
     487      314031 :     move16();
     488             : 
     489      314031 :     pA_fx = &pointsA_fx[start];
     490      314031 :     pB_fx = &pointsB_fx[start];
     491      314031 :     pA = &pointsA[start];
     492             : 
     493      314031 :     IF( EQ_16( direction, -1 ) ) /* inverse companding */
     494             :     {
     495      196953 :         pA_fx = &pointsB_fx[start];
     496      196953 :         pB_fx = &pointsA_fx[start];
     497      196953 :         pA = &pointsB[start];
     498             :     }
     499             :     ELSE
     500             :     {
     501      117078 :         IF( NE_16( direction, 1 ) )
     502             :         {
     503           0 :             printf( "Wrong direction in companding" );
     504             :         }
     505             :     }
     506             : 
     507      314031 :     not_done = 1;
     508      314031 :     move16();
     509      314031 :     abs_azi_fx = L_abs( azi_fx );
     510             : 
     511      314031 :     comp_azi_fx = azi_fx;
     512      314031 :     move32();
     513      314031 :     i = 0;
     514      314031 :     move16();
     515      695083 :     WHILE( not_done && ( LT_16( i, sub( no_points, 1 ) ) ) )
     516             :     {
     517      381052 :         test();
     518      381052 :         IF( LE_32( abs_azi_fx, pA_fx[i + 1] ) )
     519             :         {
     520      314031 :             not_done = 0;
     521      314031 :             move16();
     522             :             /* calculate companding */
     523      314031 :             comp_azi_fx = Mpy_32_32( L_sub( pB_fx[i + 1], pB_fx[i] ), L_sub( abs_azi_fx, pA_fx[i] ) ); // ( Q22 + Q22 - Q31 ) -> Q13
     524      314031 :             SWITCH( sub( pA[i + 1], pA[i] ) )
     525             :             {
     526        9604 :                 case 10:
     527             :                     // Q13 + Q31 - Q31 -> Q13
     528        9604 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 214748364 ); // 1 / 10 in 2 ^ 31
     529        9604 :                     BREAK;
     530       11668 :                 case 20:
     531             :                     // Q13 + Q31 - Q31 -> Q13
     532       11668 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 107374182 ); // 1 / 20 in 2 ^ 31
     533       11668 :                     BREAK;
     534        3447 :                 case 30:
     535             :                     // Q13 + Q31 - Q31 -> Q13
     536        3447 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 71582788 ); // 1 / 30 in 2 ^ 31
     537        3447 :                     BREAK;
     538        8661 :                 case 40:
     539             :                     // Q13 + Q31 - Q31 -> Q13
     540        8661 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 53687091 ); // 1 / 40 in 2 ^ 31
     541        8661 :                     BREAK;
     542       88822 :                 case 50:
     543             :                     // Q13 + Q31 - Q31 -> Q13
     544       88822 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 42949672 ); // 1 / 50 in 2 ^ 31
     545       88822 :                     BREAK;
     546       18710 :                 case 60:
     547             :                     // Q13 + Q31 - Q31 -> Q13
     548       18710 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 35791394 ); // 1 / 60 in 2 ^ 31
     549       18710 :                     BREAK;
     550        7111 :                 case 70:
     551             :                     // Q13 + Q31 - Q31 -> Q13
     552        7111 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 30678337 ); // 1 / 70 in 2 ^ 31
     553        7111 :                     BREAK;
     554      166008 :                 case 90:
     555             :                     // Q13 + Q31 - Q31 -> Q13
     556      166008 :                     comp_azi_fx = Mpy_32_32( comp_azi_fx, 23860929 ); // 1 / 90 in 2 ^ 31
     557      166008 :                     BREAK;
     558           0 :                 default:
     559           0 :                     assert( 0 );
     560             :                     BREAK;
     561             :             }
     562      314031 :             comp_azi_fx = L_add( pB_fx[i], L_shl( comp_azi_fx, Q22 - Q13 ) ); // Q22
     563             :             // comp_azi = pB[i] + ( pB[i + 1] - pB[i] ) / ( pA[i + 1] - pA[i] ) * ( abs_azi - pA[i] );
     564             :         }
     565             :         ELSE
     566             :         {
     567       67021 :             i = add( i, 1 );
     568             :         }
     569             :     }
     570             : 
     571      314031 :     IF( azi_fx < 0 )
     572             :     {
     573      150249 :         comp_azi_fx = L_negate( comp_azi_fx ); // Q22
     574             :     }
     575             : 
     576      314031 :     IF( EQ_16( not_done, 1 ) )
     577             :     {
     578           0 :         comp_azi_fx = azi_fx; // Q22
     579           0 :         move32();
     580             :     }
     581             : 
     582      314031 :     return comp_azi_fx; // Q22
     583             : }
     584             : 
     585             : /*-----------------------------------------------------------------------*
     586             :  * quantize_phi_chan_lbr()
     587             :  *
     588             :  * Quantize azimuth in low-bitrate channel mode.
     589             :  * Input phi expected to be an angle in degree between 0 and 360.
     590             :  *-----------------------------------------------------------------------*/
     591             : 
     592             : /*! r: index azimuth */
     593        2325 : Word16 quantize_phi_chan_lbr_fx(
     594             :     const Word32 phi, /* i  : azimuth value, Q22               */
     595             :     Word32 *phi_hat,  /* o  : quantized azimuth, Q22           */
     596             :     const Word16 n    /* i  : azimuth codebook size            */
     597             : )
     598             : {
     599             :     Word16 id_phi, phi_hat_16;
     600             : 
     601             : 
     602        2325 :     IF( LE_16( n, 1 ) )
     603             :     {
     604           0 :         *phi_hat = 0;
     605           0 :         move32();
     606             : 
     607           0 :         return 0;
     608             :     }
     609             : 
     610        2325 :     id_phi = squant_fx( round_fx( L_abs( phi ) ) /* Q6 */, &phi_hat_16 /* Q6 */, cb_azi_chan_16fx, shr( n, 1 ) );
     611        2325 :     *phi_hat = L_deposit_h( phi_hat_16 ); // Q6 -> Q22
     612        2325 :     move32();
     613             : 
     614        2325 :     test();
     615        2325 :     IF( phi < 0 && id_phi > 0 )
     616             :     {
     617         920 :         id_phi = sub( shl( id_phi, 1 ), 1 );
     618         920 :         *phi_hat = L_negate( *phi_hat ); // Q22
     619         920 :         move32();
     620             :     }
     621             :     ELSE
     622             :     {
     623             :         // id_phi *= 2;
     624        1405 :         id_phi = shl( id_phi, 1 );
     625             :     }
     626             : 
     627        2325 :     return id_phi;
     628             : }
     629             : 
     630             : 
     631             : /*-----------------------------------------------------------------------*
     632             :  * quantize_phi_chan_compand()
     633             :  *
     634             :  * Quantize azimuth.
     635             :  * Input phi expected to be an angle in degree between 0 and 360.
     636             :  *-----------------------------------------------------------------------*/
     637             : 
     638             : 
     639             : /*! r: index azimuth */
     640      117078 : Word16 quantize_phi_chan_compand_fx(
     641             :     Word32 phi,                 /* i  : azimuth value                Q22 */
     642             :     Word32 *phi_hat,            /* o  : quantized azimuth            Q22 */
     643             :     const Word16 n,             /* i  : azimuth codebook size            */
     644             :     const Word16 theta_flag,    /* i  : flag signaling high elevation    */
     645             :     const MC_LS_SETUP mc_format /* i  : channel format if in MC-mode     */
     646             : )
     647             : {
     648             :     Word16 id_phi;
     649             :     Word32 delta_phi; // Q22
     650             :     Word16 tmp_e;
     651             : 
     652      117078 :     IF( LE_16( n, 1 ) )
     653             :     {
     654           0 :         *phi_hat = 0;
     655           0 :         move32();
     656             : 
     657           0 :         return 0;
     658             :     }
     659             : 
     660      117078 :     phi = companding_azimuth_fx( L_sub( phi, 180 << Q22 ), mc_format, theta_flag, 1 );
     661             : 
     662             :     /* quantize companded value */
     663             :     // delta_phi = 360.0f / (float) n;
     664      117078 :     delta_phi = BASOP_Util_Divide3232_Scale_newton( 360, n, &tmp_e );
     665      117078 :     delta_phi = L_shr( delta_phi, sub( 9, tmp_e ) ); // Q22
     666             :     // id_phi = (int16_t) round_f( ( phi / (float) delta_phi ) );
     667      117078 :     id_phi = BASOP_Util_Divide3232_Scale( phi, delta_phi, &tmp_e ); // Q15
     668      117078 :     id_phi = round_fx( L_shl( id_phi, add( tmp_e, 1 ) ) );          // Q0
     669             : 
     670      117078 :     IF( add( id_phi, shr( n, 1 ) ) < 0 )
     671             :     {
     672           0 :         id_phi = add( id_phi, 1 );
     673             :     }
     674      117078 :     IF( sub( id_phi, shr( n, 1 ) ) >= 0 )
     675             :     {
     676         811 :         id_phi = negate( shr( n, 1 ) );
     677             :     }
     678             : 
     679      117078 :     IF( EQ_16( id_phi, negate( add( shr( n, 1 ), ( n % 2 ) ) ) ) )
     680             :     {
     681         933 :         id_phi = add( id_phi, ( n % 2 ) );
     682             :     }
     683             :     ELSE{
     684      116145 :         IF( EQ_16( id_phi, add( shr( n, 1 ), ( n % 2 ) ) ) ){
     685           0 :             IF( n % 2 ){
     686           0 :                 id_phi = sub( id_phi, 1 );
     687             : }
     688             : ELSE
     689             : {
     690           0 :     id_phi = negate( id_phi );
     691             : }
     692             : }
     693             : }
     694             : //*phi_hat = id_phi * delta_phi;
     695      117078 : *phi_hat = imult3216( delta_phi, id_phi ); // Q22
     696      117078 : move32();
     697             : 
     698             : // id_phi += ( n >> 1 );
     699      117078 : id_phi = add( id_phi, shr( n, 1 ) );
     700             : 
     701             : 
     702      117078 : *phi_hat = L_add( companding_azimuth_fx( *phi_hat, mc_format, theta_flag, -1 ), DEGREE_180_Q_22 ); // Q22
     703      117078 : move32();
     704             : 
     705      117078 : return id_phi;
     706             : }

Generated by: LCOV version 1.14