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

Generated by: LCOV version 1.14