LCOV - code coverage report
Current view: top level - lib_dec - ivas_ism_metadata_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 542 558 97.1 %
Date: 2025-05-03 01:55:50 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 <stdint.h>
      34             : #include "options.h"
      35             : #include "ivas_cnst.h"
      36             : #include "ivas_prot_fx.h"
      37             : #include "ivas_rom_com.h"
      38             : #include "ivas_rom_com_fx.h"
      39             : #include "prot_fx.h"
      40             : #include "ivas_stat_enc.h"
      41             : #include <math.h>
      42             : #include "wmc_auto.h"
      43             : #include "ivas_prot_fx.h"
      44             : 
      45             : 
      46             : /*-----------------------------------------------------------------------*
      47             :  * Local functions
      48             :  *-----------------------------------------------------------------------*/
      49             : static void decode_angle_indices_fx( DEC_CORE_HANDLE st0, ISM_METADATA_ANGLE_HANDLE angle, const Word16 non_diegetic_flag, Word16 *flag_abs_azimuth );
      50             : static Word16 decode_radius_fx( DEC_CORE_HANDLE st0, Word16 *last_radius_idx, Word16 *flag_abs_radius );
      51             : 
      52             : 
      53             : /*-------------------------------------------------------------------------*
      54             :  * Local constants
      55             :  *-------------------------------------------------------------------------*/
      56             : 
      57             : #define IVAS_ISM_DTX_HO_MAX 5
      58             : 
      59             : #define CNG_MD_MAX_DIFF_AZIMUTH   5
      60             : #define CNG_MD_MAX_DIFF_ELEVATION 5
      61             : 
      62             : #define MAX_BITS_ISM_METADATA ( 2 * ISM_EXTENDED_METADATA_BITS + MAX_NUM_OBJECTS * ( 1 /*number of objects*/ + ISM_METADATA_MD_FLAG_BITS + 2 * ISM_METADATA_FLAG_BITS + ISM_METADATA_IS_NDP_BITS + 1 /*abs.flag*/ + ISM_AZIMUTH_NBITS + ISM_ELEVATION_NBITS + 1 /*abs.flag*/ + ISM_RADIUS_NBITS + 1 /*abs.flag*/ + ISM_AZIMUTH_NBITS + ISM_ELEVATION_NBITS ) + 10 /* margin */ ) /* max. bit-budget of ISM metadata */
      63             : 
      64             : 
      65             : /*-------------------------------------------------------------------*
      66             :  * ism_metadata_smooth()
      67             :  *
      68             :  * Smooth the metadata evolution
      69             :  *-------------------------------------------------------------------*/
      70             : 
      71        8381 : static void ism_metadata_smooth_fx(
      72             :     ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles      */
      73             :     const Word32 ism_total_brate,   /* i  : ISms total bitrate        */
      74             :     const Word16 nchan_ism          /* i  : number of objects         */
      75             : )
      76             : {
      77             :     ISM_METADATA_HANDLE hIsmMetaData;
      78             :     Word16 ch;
      79             :     Word32 diff_fx;
      80             : 
      81       34899 :     FOR( ch = 0; ch < nchan_ism; ch++ )
      82             :     {
      83       26518 :         hIsmMetaData = hIsmMeta[ch];
      84             : 
      85             :         /* smooth azimuth */
      86       26518 :         diff_fx = L_sub( hIsmMetaData->last_true_azimuth_fx, hIsmMetaData->last_azimuth_fx );
      87             : 
      88       26518 :         IF( GT_32( diff_fx, ISM_AZIMUTH_MAX_FX ) )
      89             :         {
      90        1190 :             diff_fx = L_sub( diff_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX ) );
      91        1190 :             hIsmMetaData->last_azimuth_fx = L_add( hIsmMetaData->last_azimuth_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX ) ); // Q22
      92        1190 :             move32();
      93             :         }
      94       25328 :         ELSE IF( LT_32( diff_fx, ISM_AZIMUTH_MIN_FX ) )
      95             :         {
      96         358 :             diff_fx = L_add( diff_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX ) );
      97             :         }
      98             : 
      99       26518 :         test();
     100       26518 :         IF( GT_32( ism_total_brate, IVAS_SID_5k2 ) && GT_32( L_abs( diff_fx ), L_shl( IVAS_ISM_DTX_HO_MAX * CNG_MD_MAX_DIFF_AZIMUTH, Q22 ) ) )
     101             :         {
     102             :             /* skip the smoothing */
     103             :         }
     104       24216 :         ELSE IF( GT_32( L_abs( diff_fx ), L_shl( CNG_MD_MAX_DIFF_AZIMUTH, Q22 ) ) )
     105             :         {
     106             :             Word32 temp;
     107        8674 :             IF( ( diff_fx > 0 ) )
     108             :             {
     109        6028 :                 temp = L_shl( CNG_MD_MAX_DIFF_AZIMUTH, Q22 );
     110             :             }
     111             :             ELSE
     112             :             {
     113        2646 :                 temp = L_negate( L_shl( CNG_MD_MAX_DIFF_AZIMUTH, Q22 ) );
     114             :             }
     115        8674 :             hIsmMetaData->azimuth_fx = L_add( hIsmMetaData->last_azimuth_fx, temp );
     116        8674 :             move32();
     117             :         }
     118       15542 :         ELSE IF( diff_fx != 0 )
     119             :         {
     120        4808 :             hIsmMetaData->azimuth_fx = hIsmMetaData->last_true_azimuth_fx;
     121        4808 :             move32();
     122             :         }
     123             : 
     124       26518 :         IF( GT_32( hIsmMetaData->azimuth_fx, ISM_AZIMUTH_MAX_FX ) )
     125             :         {
     126         254 :             hIsmMetaData->azimuth_fx = L_sub( hIsmMetaData->azimuth_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX ) );
     127         254 :             move32();
     128             :         }
     129             : 
     130             :         /* smooth elevation */
     131       26518 :         diff_fx = L_sub( hIsmMetaData->last_true_elevation_fx, hIsmMetaData->last_elevation_fx );
     132             : 
     133       26518 :         test();
     134       26518 :         IF( GT_32( ism_total_brate, IVAS_SID_5k2 ) && GT_32( diff_fx, L_shl( IVAS_ISM_DTX_HO_MAX * CNG_MD_MAX_DIFF_ELEVATION, Q22 ) ) )
     135             :         {
     136             :             /* skip the smoothing */
     137             :         }
     138       26487 :         ELSE IF( GT_32( L_abs( diff_fx ), L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 ) ) )
     139             :         {
     140             :             Word32 temp;
     141        3438 :             IF( ( diff_fx > 0 ) )
     142             :             {
     143        1619 :                 temp = L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 );
     144             :             }
     145             :             ELSE
     146             :             {
     147        1819 :                 temp = L_negate( L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 ) );
     148             :             }
     149        3438 :             hIsmMetaData->elevation_fx = L_add( hIsmMetaData->last_elevation_fx, temp );
     150        3438 :             move32();
     151             :         }
     152             :     }
     153             : 
     154        8381 :     return;
     155             : }
     156             : 
     157             : 
     158             : /*-------------------------------------------------------------------------*
     159             :  * ivas_ism_metadata_dec()
     160             :  *
     161             :  * decode and dequantize ISM metadata
     162             :  *-------------------------------------------------------------------------*/
     163             : 
     164      109581 : ivas_error ivas_ism_metadata_dec_fx(
     165             :     const Word32 ism_total_brate,            /* i  : ISM  total bitrate                     */
     166             :     const Word16 nchan_ism,                  /* i  : number of ISM channels                 */
     167             :     Word16 *nchan_transport,                 /* o  : number of transport channels           */
     168             :     ISM_METADATA_HANDLE hIsmMeta[],          /* i/o: ISM metadata handles                   */
     169             :     SCE_DEC_HANDLE hSCE[],                   /* i/o: SCE decoder handles                    */
     170             :     const Word16 bfi,                        /* i  : bfi flag                               */
     171             :     Word16 nb_bits_metadata[],               /* o  : number of metadata bits                */
     172             :     ISM_MODE ism_mode,                       /* i  : ISM mode                               */
     173             :     ISM_DTX_DATA_DEC hISMDTX,                /* i/o: ISM DTX structure                      */
     174             :     const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i  : Param ISM Config Handle                */
     175             :     Word16 *ism_extmeta_active,              /* i/o: Extended metadata active in renderer   */
     176             :     Word16 *ism_extmeta_cnt,                 /* i/o: Number of change frames observed       */
     177             :     DEC_CORE_HANDLE st0 )                    /* i  : core-coder handle                      */
     178             : {
     179      109581 :     Word16 ch, nb_bits_start = 0, last_bit_pos;
     180             :     Word16 idx_radius;
     181             :     Word32 element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS];
     182             :     Word16 ism_extmeta_bitstream;
     183             :     Word16 non_diegetic_flag_global;
     184             :     Word32 yaw_fx, pitch_fx; // Q22
     185             :     Word16 radius_fx;        // Q9
     186             :     Word16 flag_abs_radius;
     187             :     Word16 flag_abs_orientation;
     188             :     Word16 flag_abs_position;
     189             :     Word16 idx_angle1;
     190             :     Word16 idx_angle2;
     191             :     Word16 next_bit_pos_orig;
     192             :     UWord16 i, bstr_meta[MAX_BITS_ISM_METADATA], *bstr_orig;
     193             :     ISM_METADATA_HANDLE hIsmMetaData;
     194             :     Word16 nchan_transport_prev, ism_metadata_flag_global;
     195             :     Word16 null_metadata_flag[MAX_NUM_OBJECTS];
     196             :     Word16 lowrate_metadata_flag[MAX_NUM_OBJECTS];
     197             :     Word16 ism_imp[MAX_NUM_OBJECTS];
     198             :     Word16 nbands, nblocks;
     199             :     Word16 md_diff_flag[MAX_NUM_OBJECTS];
     200             :     ivas_error error;
     201             :     Word32 res_dec, res_frac;
     202      109581 :     move16();
     203             : 
     204      109581 :     push_wmops( "ism_meta_dec" );
     205             : 
     206             :     /* initialization */
     207      109581 :     ism_metadata_flag_global = 0;
     208      109581 :     move16();
     209      109581 :     nchan_transport_prev = *nchan_transport;
     210      109581 :     move16();
     211      109581 :     iDiv_and_mod_32( ism_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
     212      109581 :     last_bit_pos = extract_l( L_sub( res_dec, 1 ) );
     213      109581 :     bstr_orig = st0->bit_stream;
     214      109581 :     next_bit_pos_orig = st0->next_bit_pos;
     215      109581 :     move16();
     216      109581 :     st0->next_bit_pos = 0;
     217      109581 :     move16();
     218      109581 :     ism_extmeta_bitstream = 0;
     219      109581 :     move16();
     220      109581 :     non_diegetic_flag_global = 0;
     221      109581 :     move16();
     222      109581 :     set16_fx( null_metadata_flag, 0, nchan_ism );
     223      109581 :     set16_fx( lowrate_metadata_flag, 0, nchan_ism );
     224             : 
     225             :     /* reverse the bitstream for easier reading of indices */
     226    19834161 :     FOR( i = 0; i < s_min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ )
     227             :     {
     228    19724580 :         bstr_meta[i] = st0->bit_stream[last_bit_pos - i];
     229    19724580 :         move16();
     230             :     }
     231      109581 :     st0->bit_stream = bstr_meta;
     232      109581 :     st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */
     233      109581 :     move32();
     234             : 
     235      109581 :     IF( !bfi )
     236             :     {
     237             :         /*----------------------------------------------------------------*
     238             :          * Read ISM common signaling
     239             :          *----------------------------------------------------------------*/
     240      108757 :         test();
     241      108757 :         IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     242             :         {
     243             :             /* number of objects was read in ivas_dec_setup() */
     244       13092 :             st0->next_bit_pos = add( st0->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ );
     245       13092 :             move32();
     246             :         }
     247       95665 :         ELSE IF( NE_32( ism_mode, ISM_MASA_MODE_DISC ) && NE_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     248             :         {
     249             :             /* number of objects was read in ivas_dec_setup() */
     250       90951 :             st0->next_bit_pos = add( st0->next_bit_pos, nchan_ism );
     251       90951 :             move16();
     252             : 
     253       90951 :             ism_mode = ivas_ism_mode_select( nchan_ism, ism_total_brate );
     254             :         }
     255             : 
     256      108757 :         IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     257             :         {
     258       15649 :             *nchan_transport = MAX_PARAM_ISM_WAVE;
     259       15649 :             move16();
     260             :         }
     261       93108 :         ELSE IF( EQ_32( ism_mode, ISM_MODE_DISC ) )
     262             :         {
     263       75302 :             *nchan_transport = nchan_ism;
     264       75302 :             move16();
     265             :         }
     266             : 
     267      108757 :         IF( NE_32( *nchan_transport, nchan_transport_prev ) )
     268             :         {
     269           0 :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" );
     270             :         }
     271             : 
     272             :         /* read extended metadata presence flag */
     273      108757 :         test();
     274      108757 :         test();
     275      108757 :         IF( ( EQ_32( ism_mode, ISM_MODE_DISC ) || EQ_32( ism_mode, ISM_SBA_MODE_DISC ) ) && GE_32( ism_total_brate, ISM_EXTENDED_METADATA_BRATE ) )
     276             :         {
     277       66739 :             ism_extmeta_bitstream = get_next_indice_fx( st0, ISM_EXTENDED_METADATA_BITS );
     278             : 
     279             :             /* read global non-diegetic object flag */
     280       66739 :             IF( ism_extmeta_bitstream )
     281             :             {
     282        7080 :                 non_diegetic_flag_global = get_next_indice_fx( st0, ISM_METADATA_IS_NDP_BITS );
     283             :             }
     284             :         }
     285             : 
     286             :         /* Apply hysteresis in case rate switching causes fluctuation in presence of extended metadata */
     287      108757 :         test();
     288      108757 :         IF( EQ_16( *ism_extmeta_active, -1 ) || EQ_16( *ism_extmeta_active, ism_extmeta_bitstream ) ) /* If first frame or bitstream matches internal state */
     289             :         {
     290      108560 :             *ism_extmeta_active = ism_extmeta_bitstream;
     291      108560 :             move16();
     292      108560 :             *ism_extmeta_cnt = 0;
     293      108560 :             move16();
     294             :         }
     295             :         ELSE
     296             :         {
     297         197 :             ( *ism_extmeta_cnt )++;
     298         197 :             IF( EQ_16( *ism_extmeta_cnt, ISM_METADATA_RS_MAX_FRAMES ) ) /* ISM_METADATA_RS_MAX_FRAMES change frames observed - update state */
     299             :             {
     300          39 :                 *ism_extmeta_active = ism_extmeta_bitstream;
     301          39 :                 move16();
     302          39 :                 *ism_extmeta_cnt = 0;
     303          39 :                 move16();
     304             :             }
     305             :         }
     306             : 
     307             :         /* Read ISM metadata flags (one per object) */
     308      394328 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     309             :         {
     310      285571 :             test();
     311      285571 :             IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     312             :             {
     313       43740 :                 ism_imp[ch] = get_next_indice_fx( st0, 1 );
     314       43740 :                 move16();
     315             :             }
     316      241831 :             ELSE IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     317             :             {
     318             :                 /* ISM importance flag is already read in ivas_masa_decode() */
     319        9221 :                 ism_imp[ch] = hIsmMeta[ch]->ism_imp;
     320        9221 :                 move16();
     321             :             }
     322             :             ELSE
     323             :             {
     324      232610 :                 ism_imp[ch] = get_next_indice_fx( st0, ISM_METADATA_FLAG_BITS );
     325      232610 :                 move16();
     326             :             }
     327             : 
     328      285571 :             IF( GT_16( ism_imp[ch], ISM_NO_META ) )
     329             :             {
     330      275280 :                 hIsmMeta[ch]->ism_metadata_flag = 1;
     331      275280 :                 move16();
     332             :             }
     333             :             ELSE
     334             :             {
     335       10291 :                 hIsmMeta[ch]->ism_metadata_flag = 0;
     336       10291 :                 move16();
     337             :             }
     338             : 
     339      285571 :             ism_metadata_flag_global = s_or( ism_metadata_flag_global, hIsmMeta[ch]->ism_metadata_flag );
     340             :         }
     341             : 
     342      134904 :         FOR( ; ch < nchan_ism; ch++ )
     343             :         {
     344       26147 :             hIsmMeta[ch]->ism_metadata_flag = 1;
     345       26147 :             move16();
     346       26147 :             ism_metadata_flag_global = s_or( ism_metadata_flag_global, hIsmMeta[ch]->ism_metadata_flag );
     347             :         }
     348             : 
     349             :         /* read ISM_NO_META class signalling */
     350      108757 :         test();
     351      108757 :         IF( EQ_32( ism_mode, ISM_MODE_DISC ) || EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     352             :         {
     353      333446 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     354             :             {
     355      245052 :                 IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
     356             :                 {
     357             :                     /* low-rate ISM_NO_META frame */
     358       10291 :                     test();
     359       10291 :                     IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     360             :                     {
     361           0 :                         null_metadata_flag[ch] = hIsmMeta[ch]->ism_md_null_flag;
     362           0 :                         move16();
     363             :                     }
     364             :                     ELSE
     365             :                     {
     366       10291 :                         null_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
     367       10291 :                         move16();
     368             :                     }
     369             :                 }
     370             :             }
     371             : 
     372      333446 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     373             :             {
     374      245052 :                 IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
     375             :                 {
     376       10291 :                     test();
     377       10291 :                     IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     378             :                     {
     379           0 :                         lowrate_metadata_flag[ch] = hIsmMeta[ch]->ism_md_lowrate_flag;
     380           0 :                         move16();
     381             : 
     382           0 :                         if ( null_metadata_flag[ch] == 0 )
     383             :                         {
     384           0 :                             ism_metadata_flag_global = s_or( ism_metadata_flag_global, lowrate_metadata_flag[ch] );
     385             :                         }
     386             :                     }
     387       10291 :                     ELSE IF( NE_32( ism_mode, ISM_SBA_MODE_DISC ) )
     388             :                     {
     389       10291 :                         IF( null_metadata_flag[ch] )
     390             :                         {
     391             :                             /* read the true ISM class */
     392        4670 :                             ism_imp[ch] = get_next_indice_fx( st0, ISM_METADATA_FLAG_BITS );
     393        4670 :                             move16();
     394             :                         }
     395             :                         ELSE
     396             :                         {
     397             :                             /* read presence of MD in low-rate ISM_NO_META frame flag */
     398        5621 :                             lowrate_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
     399        5621 :                             move16();
     400             : 
     401        5621 :                             ism_metadata_flag_global = s_or( ism_metadata_flag_global, lowrate_metadata_flag[ch] );
     402             :                         }
     403             :                     }
     404             :                 }
     405             :             }
     406             :         }
     407             : 
     408      108757 :         IF( ism_metadata_flag_global )
     409             :         {
     410             :             /*----------------------------------------------------------------*
     411             :              * Metadata decoding and dequantization, loop over all objects
     412             :              *----------------------------------------------------------------*/
     413             : 
     414      108740 :             Word16 total_bits_metadata = 0, bits_metadata_ism = 0;
     415      108740 :             move16();
     416      108740 :             move16();
     417             :             Word16 nb_bits_objcod_read;
     418             : 
     419      108740 :             IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     420             :             {
     421       15649 :                 nb_bits_start = st0->next_bit_pos;
     422       15649 :                 move16();
     423             :             }
     424             : 
     425      420423 :             FOR( ch = 0; ch < nchan_ism; ch++ )
     426             :             {
     427      311683 :                 hIsmMetaData = hIsmMeta[ch];
     428      311683 :                 test();
     429      311683 :                 test();
     430      311683 :                 test();
     431      311683 :                 if ( EQ_32( ism_mode, ISM_MODE_DISC ) || EQ_32( ism_mode, ISM_SBA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     432             :                 {
     433      254238 :                     nb_bits_start = st0->next_bit_pos;
     434      254238 :                     move16();
     435             :                 }
     436      311683 :                 flag_abs_position = 0;
     437      311683 :                 move16();
     438      311683 :                 flag_abs_orientation = 0;
     439      311683 :                 move16();
     440      311683 :                 flag_abs_radius = 0;
     441      311683 :                 move16();
     442             : 
     443      311683 :                 test();
     444      311683 :                 IF( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
     445             :                 {
     446      306819 :                     IF( non_diegetic_flag_global )
     447             :                     {
     448             :                         /* read non-diegetic flag for each object */
     449        2415 :                         hIsmMetaData->non_diegetic_flag = get_next_indice_fx( st0, ISM_METADATA_IS_NDP_BITS );
     450        2415 :                         move16();
     451             :                     }
     452             :                     ELSE
     453             :                     {
     454      304404 :                         hIsmMetaData->non_diegetic_flag = 0;
     455      304404 :                         move16();
     456             :                     }
     457             : 
     458      306819 :                     IF( hIsmMetaData->non_diegetic_flag )
     459             :                     {
     460             :                         /* Panning gain decoding */
     461         805 :                         decode_angle_indices_fx( st0, &( hIsmMetaData->position_angle ), hIsmMetaData->non_diegetic_flag, &flag_abs_position );
     462         805 :                         idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx;
     463         805 :                         move16();
     464         805 :                         idx_angle2 = shl( 1, ( ISM_ELEVATION_NBITS - 1 ) );
     465             : 
     466             :                         /* Panning gain dequantization */
     467         805 :                         hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_angle1, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, ( 1 << ISM_AZIMUTH_NBITS ) );
     468         805 :                         hIsmMetaData->elevation_fx = 0;
     469         805 :                         move32();
     470         805 :                         move32();
     471             : 
     472             :                         /* save for smoothing metadata evolution */
     473         805 :                         hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
     474         805 :                         move32();
     475         805 :                         hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
     476         805 :                         move32();
     477             :                     }
     478             :                     ELSE
     479             :                     {
     480      306014 :                         decode_angle_indices_fx( st0, &( hIsmMetaData->position_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_position );
     481      306014 :                         idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx;
     482      306014 :                         move16();
     483      306014 :                         idx_angle2 = hIsmMetaData->position_angle.last_angle2_idx;
     484      306014 :                         move16();
     485             : 
     486             :                         /* Azimuth/Elevation dequantization */
     487      306014 :                         IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     488             :                         {
     489       57445 :                             hParamIsm->azi_index[ch] = idx_angle1;
     490       57445 :                             move16();
     491       57445 :                             hParamIsm->ele_index[ch] = idx_angle2;
     492       57445 :                             move16();
     493             :                         }
     494             :                         ELSE /* ISM_MODE_DISC */
     495             :                         {
     496      248569 :                             hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_angle1, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, ( 1 << ISM_AZIMUTH_NBITS ) );
     497      248569 :                             hIsmMetaData->elevation_fx = ism_dequant_meta_fx( idx_angle2, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, ( 1 << ISM_ELEVATION_NBITS ) );
     498      248569 :                             move32();
     499      248569 :                             move32();
     500             : 
     501             :                             /* radius/raw/pitch dequantization */
     502      248569 :                             IF( ism_extmeta_bitstream )
     503             :                             {
     504       21311 :                                 decode_angle_indices_fx( st0, &( hIsmMetaData->orientation_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_orientation );
     505       21311 :                                 idx_angle1 = hIsmMetaData->orientation_angle.last_angle1_idx;
     506       21311 :                                 move16();
     507       21311 :                                 idx_angle2 = hIsmMetaData->orientation_angle.last_angle2_idx;
     508       21311 :                                 move16();
     509       21311 :                                 yaw_fx = ism_dequant_meta_fx( idx_angle1, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, ( 1 << ISM_AZIMUTH_NBITS ) );
     510       21311 :                                 pitch_fx = ism_dequant_meta_fx( idx_angle2, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, ( 1 << ISM_ELEVATION_NBITS ) );
     511             : 
     512       21311 :                                 idx_radius = decode_radius_fx( st0, &hIsmMetaData->last_radius_idx, &flag_abs_radius );
     513       21311 :                                 radius_fx = usdequant_fx( idx_radius, ISM_RADIUS_MIN_Q9, ISM_RADIUS_DELTA_Q8 );
     514       21311 :                                 IF( EQ_16( *ism_extmeta_active, 1 ) )
     515             :                                 {
     516       21071 :                                     hIsmMetaData->yaw_fx = yaw_fx;
     517       21071 :                                     move32();
     518       21071 :                                     hIsmMetaData->pitch_fx = pitch_fx;
     519       21071 :                                     move32();
     520       21071 :                                     hIsmMetaData->radius_fx = radius_fx;
     521       21071 :                                     move16();
     522             :                                 }
     523             :                             }
     524             :                             ELSE
     525             :                             {
     526      227258 :                                 IF( *ism_extmeta_active == 0 )
     527             :                                 {
     528      227186 :                                     hIsmMetaData->yaw_fx = 0;
     529      227186 :                                     move32();
     530      227186 :                                     hIsmMetaData->pitch_fx = 0;
     531      227186 :                                     move32();
     532      227186 :                                     hIsmMetaData->radius_fx = 512; /* 1.0f in Q9 */
     533      227186 :                                     move16();
     534             :                                 }
     535             :                             }
     536             :                         }
     537             :                         /* save for smoothing metadata evolution */
     538      306014 :                         hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
     539      306014 :                         move32();
     540      306014 :                         hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
     541      306014 :                         move32();
     542             :                     }
     543             :                 }
     544             :                 /* save number of metadata bits read */
     545      311683 :                 test();
     546      311683 :                 test();
     547      311683 :                 test();
     548      311683 :                 IF( EQ_32( ism_mode, ISM_MODE_DISC ) || EQ_32( ism_mode, ISM_SBA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     549             :                 {
     550      254238 :                     nb_bits_metadata[ch] = sub( st0->next_bit_pos, nb_bits_start );
     551      254238 :                     move16();
     552             :                 }
     553             :             }
     554             : 
     555      108740 :             IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     556             :             {
     557       15649 :                 hParamIsm->flag_noisy_speech = get_next_indice_fx( st0, 1 );
     558       15649 :                 move16();
     559             : 
     560             :                 /* Loop over multiwave to read the object indices from bitstream */
     561       46947 :                 FOR( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ )
     562             :                 {
     563      375576 :                     FOR( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
     564             :                     {
     565      688556 :                         FOR( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
     566             :                         {
     567      344278 :                             hParamIsm->obj_indices[nbands][nblocks][ch] = get_next_indice_fx( st0, PARAM_ISM_OBJ_IND_NBITS );
     568      344278 :                             move16();
     569             :                         }
     570             :                     }
     571             :                 }
     572             : 
     573             :                 /* Loop over all bands to read power ratio's from bitstream */
     574      187788 :                 FOR( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
     575             :                 {
     576      344278 :                     FOR( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
     577             :                     {
     578      172139 :                         hParamIsm->power_ratios_idx[nbands][nblocks] = get_next_indice_fx( st0, PARAM_ISM_POW_RATIO_NBITS );
     579      172139 :                         move16();
     580             :                     }
     581             :                 }
     582             : 
     583             :                 /* save number of metadata bits read */
     584       15649 :                 total_bits_metadata = sub( st0->next_bit_pos, nb_bits_start );
     585             : 
     586             :                 /* bits per ISM*/
     587             : 
     588             :                 // total_bits_metadata / *nchan_transport
     589             :                 Word16 tmp, tmp_e;
     590       15649 :                 tmp = BASOP_Util_Divide1616_Scale( total_bits_metadata, *nchan_transport, &tmp_e );
     591       15649 :                 bits_metadata_ism = shr( tmp, sub( 15, tmp_e ) ); // Q0
     592             : 
     593       15649 :                 nb_bits_objcod_read = 0;
     594       15649 :                 move16();
     595       46947 :                 FOR( ch = 0; ch < *nchan_transport; ch++ )
     596             :                 {
     597       31298 :                     IF( EQ_16( ch, sub( *nchan_transport, 1 ) ) )
     598             :                     {
     599       15649 :                         nb_bits_metadata[ch] = sub( total_bits_metadata, nb_bits_objcod_read );
     600       15649 :                         move16();
     601             :                     }
     602             :                     ELSE
     603             :                     {
     604       15649 :                         nb_bits_metadata[ch] = bits_metadata_ism;
     605       15649 :                         move16();
     606       15649 :                         nb_bits_objcod_read = add( nb_bits_objcod_read, bits_metadata_ism );
     607             :                     }
     608             :                 }
     609             :             }
     610             :         }
     611             :         ELSE
     612             :         {
     613          17 :             set16_fx( nb_bits_metadata, 0, *nchan_transport );
     614             :         }
     615             :     }
     616             :     ELSE /* BFI */
     617             :     {
     618        2933 :         FOR( ch = 0; ch < nchan_ism; ch++ )
     619             :         {
     620        2109 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     621        2109 :             move16();
     622             :         }
     623             : 
     624         824 :         set16_fx( nb_bits_metadata, 0, *nchan_transport );
     625             : 
     626         824 :         IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     627             :         {
     628        1075 :             FOR( ch = 0; ch < nchan_ism; ch++ )
     629             :             {
     630         840 :                 hParamIsm->azi_index[ch] = add( hParamIsm->azi_index[ch], i_mult2( hParamIsm->last_az_sgn[ch], hParamIsm->last_az_diff[ch] ) ); // Q0
     631         840 :                 move16();
     632         840 :                 hParamIsm->ele_index[ch] = add( hParamIsm->ele_index[ch], i_mult2( hParamIsm->last_el_sgn[ch], hParamIsm->last_el_diff[ch] ) ); // Q0
     633         840 :                 move16();
     634         840 :                 hIsmMeta[ch]->position_angle.last_angle1_idx = hParamIsm->azi_index[ch];
     635         840 :                 move16();
     636         840 :                 hIsmMeta[ch]->position_angle.last_angle2_idx = hParamIsm->ele_index[ch];
     637         840 :                 move16();
     638             :             }
     639             :         }
     640             :     }
     641             : 
     642      109581 :     IF( LT_16( hISMDTX.ism_dtx_hangover_cnt, IVAS_ISM_DTX_HO_MAX ) )
     643             :     {
     644        6230 :         ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
     645        6230 :         hISMDTX.ism_dtx_hangover_cnt = add( hISMDTX.ism_dtx_hangover_cnt, 1 );
     646        6230 :         move16();
     647             :     }
     648             : 
     649      109581 :     IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     650             :     {
     651             :         /* set the bitstream pointer to its original position */
     652       13100 :         nb_bits_metadata[0] = st0->next_bit_pos;
     653       13100 :         move16();
     654       13100 :         st0->bit_stream = bstr_orig;
     655       13100 :         st0->next_bit_pos = next_bit_pos_orig;
     656       13100 :         move16();
     657             : 
     658             :         /* updates*/
     659       13100 :         set16_fx( md_diff_flag, 1, nchan_ism );
     660             : 
     661       13100 :         update_last_metadata_fx( nchan_ism, hIsmMeta, md_diff_flag );
     662       13100 :         pop_wmops();
     663       13100 :         return IVAS_ERR_OK;
     664             :     }
     665             : 
     666       96481 :     test();
     667       96481 :     if ( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     668             :     {
     669        4795 :         ism_metadata_flag_global = 1;
     670        4795 :         move16();
     671             :     }
     672             : 
     673             :     /*----------------------------------------------------------------*
     674             :      * Configuration and decision about bitrates per channel
     675             :      *----------------------------------------------------------------*/
     676             : 
     677       96481 :     IF( !bfi )
     678             :     {
     679       95665 :         Word16 masa_ism_flag = 0;
     680       95665 :         move16();
     681       95665 :         test();
     682       95665 :         IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     683             :         {
     684        4714 :             masa_ism_flag = 1;
     685        4714 :             move16();
     686             : 
     687       13935 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     688             :             {
     689        9221 :                 element_brate[ch] = hSCE[ch]->element_brate;
     690        9221 :                 move32();
     691             :             }
     692             :         }
     693             : 
     694       95665 :         IF( NE_32( ( error = ivas_ism_config_fx( ism_total_brate, *nchan_transport, nchan_ism, hIsmMeta, ism_extmeta_bitstream, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, masa_ism_flag ) ), IVAS_ERR_OK ) )
     695             :         {
     696           0 :             return error;
     697             :         }
     698             : 
     699      337496 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     700             :         {
     701      241831 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     702      241831 :             move16();
     703             : 
     704      241831 :             hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
     705      241831 :             move16();
     706      241831 :             test();
     707      241831 :             test();
     708      241831 :             IF( EQ_32( ism_mode, ISM_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     709             :             {
     710      210533 :                 test();
     711      210533 :                 test();
     712      210533 :                 test();
     713      210533 :                 test();
     714      216467 :                 if ( ism_imp[ch] == ISM_NO_META && ( ( LT_32( total_brate[ch], ACELP_8k00 ) && LT_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) ||
     715       11311 :                                                      ( LE_32( total_brate[ch], ACELP_16k_LOW_LIMIT ) && GE_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) ) )
     716             :                 {
     717        6736 :                     hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
     718        6736 :                     move16();
     719             :                 }
     720             :             }
     721             : 
     722      241831 :             test();
     723      241831 :             if ( NE_32( ism_mode, ISM_MASA_MODE_DISC ) && NE_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     724             :             {
     725      232610 :                 hSCE[ch]->element_brate = element_brate[ch];
     726      232610 :                 move32();
     727             :             }
     728      241831 :             hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
     729      241831 :             move32();
     730             :         }
     731             : 
     732      121812 :         FOR( ; ch < nchan_ism; ch++ )
     733             :         {
     734       26147 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     735       26147 :             move16();
     736             :         }
     737             :     }
     738             :     ELSE
     739             :     {
     740        2535 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     741             :         {
     742        1719 :             hSCE[ch]->element_brate = hSCE[ch]->last_element_brate;
     743        1719 :             move32();
     744        1719 :             hSCE[ch]->hCoreCoder[0]->total_brate = hSCE[ch]->hCoreCoder[0]->last_total_brate;
     745        1719 :             move32();
     746             :         }
     747             :     }
     748             : 
     749             :     /*----------------------------------------------------------------*
     750             :      * Set bitsream pointers
     751             :      *----------------------------------------------------------------*/
     752             : 
     753             :     /* set the bitstream pointer to its original position */
     754       96481 :     st0->bit_stream = bstr_orig;
     755       96481 :     st0->next_bit_pos = next_bit_pos_orig;
     756       96481 :     move16();
     757             : 
     758             :     /* set bitstream pointers for each ISM */
     759      243550 :     FOR( ch = 1; ch < *nchan_transport; ch++ )
     760             :     {
     761      147069 :         hSCE[ch]->hCoreCoder[0]->bit_stream = ( hSCE[ch - 1]->hCoreCoder[0]->bit_stream + extract_l( Mpy_32_32( hSCE[ch - 1]->hCoreCoder[0]->total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ) );
     762             :     }
     763             : 
     764             :     /*----------------------------------------------------------------*
     765             :      * Updates
     766             :      *----------------------------------------------------------------*/
     767             : 
     768       96481 :     set16_fx( md_diff_flag, 1, nchan_ism );
     769             : 
     770       96481 :     update_last_metadata_fx( nchan_ism, hIsmMeta, md_diff_flag );
     771             : 
     772      340031 :     FOR( ch = 0; ch < *nchan_transport; ch++ )
     773             :     {
     774      243550 :         hSCE[ch]->hCoreCoder[0]->cng_ism_flag = 0;
     775      243550 :         move16();
     776             :     }
     777             : 
     778       96481 :     pop_wmops();
     779             : 
     780       96481 :     return IVAS_ERR_OK;
     781             : }
     782             : 
     783             : 
     784             : /*-------------------------------------------------------------------------
     785             :  * ivas_ism_metadata_dec_create()
     786             :  *
     787             :  * Create, allocate, initialize and configure IVAS decoder ISM metadata handles
     788             :  *-------------------------------------------------------------------------*/
     789             : 
     790         810 : ivas_error ivas_ism_metadata_dec_create_fx(
     791             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder structure      */
     792             :     const Word16 n_ISms,       /* i  : number of objects           */
     793             :     Word32 element_brate_tmp[] /* o  : element bitrate per object  */
     794             : )
     795             : {
     796             :     Word16 ch;
     797             :     ivas_error error;
     798             : 
     799             :     /* allocate ISM metadata handles */
     800        4050 :     FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
     801             :     {
     802        3240 :         IF( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL )
     803             :         {
     804           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) );
     805             :         }
     806             : 
     807        3240 :         st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0;
     808        3240 :         move16();
     809        3240 :         st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0;
     810        3240 :         move16();
     811        3240 :         st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 );
     812        3240 :         move16();
     813        3240 :         st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0;
     814        3240 :         move16();
     815        3240 :         st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 );
     816        3240 :         move16();
     817        3240 :         st_ivas->hIsmMetaData[ch]->last_radius_idx = 8; /* Init to radius 1.0 */
     818        3240 :         move16();
     819             : 
     820        3240 :         st_ivas->hIsmMetaData[ch]->last_true_azimuth_fx = 0;
     821        3240 :         move32();
     822        3240 :         st_ivas->hIsmMetaData[ch]->last_true_elevation_fx = 0;
     823        3240 :         move32();
     824        3240 :         st_ivas->hIsmMetaData[ch]->last_azimuth_fx = 0;
     825        3240 :         move32();
     826        3240 :         st_ivas->hIsmMetaData[ch]->last_elevation_fx = 0;
     827        3240 :         move32();
     828             : 
     829        3240 :         st_ivas->hIsmMetaData[ch]->ism_imp = -1;
     830        3240 :         move16();
     831        3240 :         st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
     832        3240 :         move16();
     833        3240 :         st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
     834        3240 :         move16();
     835             : 
     836        3240 :         ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] );
     837             :     }
     838             : 
     839         810 :     IF( element_brate_tmp != NULL )
     840             :     {
     841         169 :         IF( NE_32( ( error = ivas_ism_config_fx( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ), IVAS_ERR_OK ) )
     842             :         {
     843           0 :             return error;
     844             :         }
     845             :     }
     846             : 
     847         810 :     st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX;
     848         810 :     move16();
     849             : 
     850         810 :     return IVAS_ERR_OK;
     851             : }
     852             : 
     853             : 
     854             : /*-------------------------------------------------------------------------
     855             :  * decode_angle_indices()
     856             :  *
     857             :  * Decoding of a position/orientation angle
     858             :  *-------------------------------------------------------------------------*/
     859             : 
     860      328130 : static void decode_angle_indices_fx(
     861             :     DEC_CORE_HANDLE st0,             /* i/o: bitstream handle                */
     862             :     ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle                    */
     863             :     const Word16 non_diegetic_flag,  /* i  : Non diegetic flag               */
     864             :     Word16 *flag_abs_angle1          /* o  : Azimuth/yaw encoding mode       */
     865             : )
     866             : {
     867             :     Word16 idx_angle1, nbits_diff_angle1, diff, sgn;
     868             :     Word16 idx_angle2, nbits_diff_angle2;
     869             : 
     870             :     /*----------------------------------------------------------------*
     871             :      * Azimuth/yaw decoding and dequantization
     872             :      *----------------------------------------------------------------*/
     873             : 
     874             :     /* Decode azimuth/yaw index */
     875      328130 :     IF( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* azimuth_abs_flag */
     876             :     {
     877      101691 :         idx_angle1 = get_next_indice_fx( st0, ISM_AZIMUTH_NBITS );
     878      101691 :         *flag_abs_angle1 = 1;
     879      101691 :         move16();
     880             :     }
     881             :     ELSE
     882             :     {
     883      226439 :         diff = 0;
     884      226439 :         move16();
     885      226439 :         sgn = 1;
     886      226439 :         move16();
     887             : 
     888      226439 :         IF( get_next_indice_fx( st0, 1 ) == 0 )
     889             :         {
     890       52162 :             nbits_diff_angle1 = 1;
     891       52162 :             move16();
     892             :         }
     893             :         ELSE
     894             :         {
     895      174277 :             nbits_diff_angle1 = 1;
     896      174277 :             move16();
     897             : 
     898      174277 :             if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
     899             :             {
     900       56111 :                 sgn = -1;
     901       56111 :                 move16();
     902             :             }
     903             : 
     904      174277 :             nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     905             : 
     906             :             /* read until the stop bit */
     907      499387 :             WHILE( nbits_diff_angle1 < ( ISM_AZIMUTH_NBITS - 1 ) && get_next_indice_fx( st0, 1 ) == 1 )
     908             :             {
     909      325110 :                 diff = add( diff, 1 );
     910      325110 :                 nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     911             :             }
     912             : 
     913      174277 :             if ( LT_16( nbits_diff_angle1, ( ISM_AZIMUTH_NBITS - 1 ) ) )
     914             :             {
     915             :                 /* count stop bit */
     916      159598 :                 nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     917             :             }
     918             :         }
     919      226439 :         idx_angle1 = add( angle->last_angle1_idx, i_mult2( sgn, diff ) );
     920             :     }
     921             : 
     922             :     /* azimuth/yaw is on a circle - check for diff coding for -180° -> 180° and vice versa changes */
     923      328130 :     IF( GT_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     924             :     {
     925          11 :         idx_angle1 = sub( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ); /* +180° -> -180° */
     926             :     }
     927      328119 :     ELSE IF( idx_angle1 < 0 )
     928             :     {
     929        1136 :         idx_angle1 = add( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ); /* -180° -> +180° */
     930             :     }
     931             : 
     932             :     /* +180° == -180° */
     933      328130 :     if ( EQ_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     934             :     {
     935        2855 :         idx_angle1 = 0;
     936        2855 :         move16();
     937             :     }
     938             : 
     939             :     /* sanity check in case of FER or BER */
     940      328130 :     test();
     941      328130 :     if ( ( idx_angle1 < 0 ) || GT_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     942             :     {
     943           0 :         idx_angle1 = angle->last_angle1_idx;
     944           0 :         move16();
     945             :     }
     946             : 
     947             :     /*----------------------------------------------------------------*
     948             :      * Elevation/pitch decoding and dequantization
     949             :      *----------------------------------------------------------------*/
     950             : 
     951      328130 :     IF( non_diegetic_flag == 0 )
     952             :     {
     953             :         /* Decode elevation/pitch index */
     954      327325 :         test();
     955      327325 :         IF( ( *flag_abs_angle1 == 0 ) && EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* elevation_abs_flag */
     956             :         {
     957       27986 :             idx_angle2 = get_next_indice_fx( st0, ISM_ELEVATION_NBITS );
     958             :         }
     959             :         ELSE
     960             :         {
     961      299339 :             diff = 0;
     962      299339 :             move16();
     963      299339 :             sgn = 1;
     964      299339 :             move16();
     965             : 
     966      299339 :             IF( get_next_indice_fx( st0, 1 ) == 0 )
     967             :             {
     968      123881 :                 nbits_diff_angle2 = 1;
     969      123881 :                 move16();
     970             :             }
     971             :             ELSE
     972             :             {
     973      175458 :                 nbits_diff_angle2 = 1;
     974      175458 :                 move16();
     975             : 
     976      175458 :                 if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
     977             :                 {
     978       88013 :                     sgn = -1;
     979       88013 :                     move16();
     980             :                 }
     981             : 
     982      175458 :                 nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
     983             : 
     984             :                 /* read until the stop bit */
     985      624061 :                 WHILE( ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) && ( get_next_indice_fx( st0, 1 ) == 1 ) )
     986             :                 {
     987      448603 :                     diff = add( diff, 1 );
     988      448603 :                     nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
     989             :                 }
     990             : 
     991      175458 :                 if ( LT_16( nbits_diff_angle2, ISM_ELEVATION_NBITS ) )
     992             :                 {
     993             :                     /* count stop bit */
     994      117678 :                     nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
     995             :                 }
     996             :             }
     997             : 
     998      299339 :             idx_angle2 = add( angle->last_angle2_idx, i_mult( sgn, diff ) );
     999             :         }
    1000             : 
    1001             :         /* sanity check in case of FER or BER */
    1002      327325 :         test();
    1003      327325 :         if ( ( idx_angle2 < 0 ) || GT_16( idx_angle2, ( ( 1 << ISM_ELEVATION_NBITS ) - 1 ) ) )
    1004             :         {
    1005           0 :             idx_angle2 = angle->last_angle2_idx;
    1006           0 :             move16();
    1007             :         }
    1008             :     }
    1009             :     ELSE
    1010             :     {
    1011         805 :         idx_angle2 = angle->last_angle2_idx; /* second MD parameter is not transmitted for non-diegetic object */
    1012         805 :         move16();
    1013             :     }
    1014             : 
    1015             :     /*----------------------------------------------------------------*
    1016             :      * Final updates
    1017             :      *----------------------------------------------------------------*/
    1018             : 
    1019      328130 :     angle->last_angle2_idx = idx_angle2;
    1020      328130 :     move16();
    1021      328130 :     angle->last_angle1_idx = idx_angle1;
    1022      328130 :     move16();
    1023             : 
    1024      328130 :     return;
    1025             : }
    1026             : 
    1027             : 
    1028             : /*-------------------------------------------------------------------------
    1029             :  * decode_radius()
    1030             :  *
    1031             :  * Radius decoding and dequantization
    1032             :  *-------------------------------------------------------------------------*/
    1033             : 
    1034       21311 : static Word16 decode_radius_fx(
    1035             :     DEC_CORE_HANDLE st0,     /* i/o: bitstream handle           */
    1036             :     Word16 *last_radius_idx, /* i/o: last radius index          */
    1037             :     Word16 *flag_abs_radius  /* o  : Radius encoding mode       */
    1038             : )
    1039             : {
    1040             :     Word16 idx_radius, nbits_diff_radius, diff, sgn;
    1041             : 
    1042             :     /* Decode radius index */
    1043       21311 :     IF( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* elevation_abs_flag */
    1044             :     {
    1045        5843 :         *flag_abs_radius = 1;
    1046        5843 :         move16();
    1047        5843 :         idx_radius = get_next_indice_fx( st0, ISM_RADIUS_NBITS );
    1048             :     }
    1049             :     ELSE
    1050             :     {
    1051       15468 :         diff = 0;
    1052       15468 :         move16();
    1053       15468 :         sgn = 1;
    1054       15468 :         move16();
    1055             : 
    1056       15468 :         IF( get_next_indice_fx( st0, 1 ) == 0 )
    1057             :         {
    1058       12900 :             nbits_diff_radius = 1;
    1059       12900 :             move16();
    1060             :         }
    1061             :         ELSE
    1062             :         {
    1063        2568 :             nbits_diff_radius = 1;
    1064        2568 :             move16();
    1065             : 
    1066        2568 :             if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
    1067             :             {
    1068        1187 :                 sgn = -1;
    1069        1187 :                 move16();
    1070             :             }
    1071             : 
    1072        2568 :             nbits_diff_radius = add( nbits_diff_radius, 1 );
    1073             : 
    1074             :             /* read until the stop bit */
    1075        5762 :             WHILE( ( nbits_diff_radius < ISM_RADIUS_NBITS ) && ( get_next_indice_fx( st0, 1 ) == 1 ) )
    1076             :             {
    1077        3194 :                 diff = add( diff, 1 );
    1078        3194 :                 nbits_diff_radius = add( nbits_diff_radius, 1 );
    1079             :             }
    1080             : 
    1081        2568 :             IF( LT_16( nbits_diff_radius, ISM_RADIUS_NBITS ) )
    1082             :             {
    1083             :                 /* count stop bit */
    1084        2425 :                 nbits_diff_radius = add( nbits_diff_radius, 1 );
    1085             :             }
    1086             :         }
    1087       15468 :         idx_radius = add( *last_radius_idx, i_mult2( sgn, diff ) );
    1088             :     }
    1089             : 
    1090             :     /* sanity check in case of FER or BER */
    1091       21311 :     test();
    1092       21311 :     if ( ( idx_radius < 0 ) || GT_16( idx_radius, ( 1 << ISM_RADIUS_NBITS ) - 1 ) )
    1093             :     {
    1094           0 :         idx_radius = *last_radius_idx;
    1095           0 :         move16();
    1096             :     }
    1097             : 
    1098             :     /* Final updates */
    1099       21311 :     *last_radius_idx = idx_radius;
    1100       21311 :     move16();
    1101             : 
    1102       21311 :     return idx_radius;
    1103             : }
    1104             : 
    1105             : 
    1106             : /*-------------------------------------------------------------------*
    1107             :  * ivas_ism_metadata_sid_dec()
    1108             :  *
    1109             :  * Decode ISM metadata in SID frame
    1110             :  *-------------------------------------------------------------------*/
    1111             : 
    1112        2151 : void ivas_ism_metadata_sid_dec_fx(
    1113             :     SCE_DEC_HANDLE hSCE[MAX_SCE],   /* i/o: SCE decoder structure       */
    1114             :     const Word32 ism_total_brate,   /* i  : ISM total bitrate           */
    1115             :     const Word16 bfi,               /* i  : bfi flag                    */
    1116             :     const Word16 nchan_ism,         /* i  : number of objects           */
    1117             :     const Word16 nchan_transport,   /* i  : number of transport channels*/
    1118             :     const ISM_MODE ism_mode,        /* i  : ISM mode                    */
    1119             :     Word16 *flag_noisy_speech,      /* o  : noisy speech flag           */
    1120             :     Word16 *sce_id_dtx,             /* o  : SCE DTX ID                  */
    1121             :     ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles        */
    1122             :     Word16 nb_bits_metadata[]       /* o  : number of metadata bits     */
    1123             : )
    1124             : {
    1125             :     Word16 i, ch, last_bit_pos;
    1126             :     Word32 q_step_fx, q_step_border_fx;
    1127             :     Word16 idx, idx_azimuth, idx_elevation;
    1128             :     Word16 nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
    1129             :     Word16 md_diff_flag[MAX_NUM_OBJECTS];
    1130             :     ISM_MODE ism_mode_bstr;
    1131             :     DEC_CORE_HANDLE st0;
    1132             :     ISM_METADATA_HANDLE hIsmMetaData;
    1133             :     Word16 next_bit_pos_orig;
    1134             :     UWord16 bstr_meta[IVAS_SID_5k2 / FRAMES_PER_SEC], *bstr_orig;
    1135             : 
    1136        2151 :     IF( ism_total_brate == FRAME_NO_DATA )
    1137             :     {
    1138        1601 :         ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
    1139             : 
    1140        1601 :         return;
    1141             :     }
    1142             : 
    1143             :     /* initialization */
    1144         550 :     st0 = hSCE[0]->hCoreCoder[0];
    1145             : 
    1146         550 :     last_bit_pos = extract_l( L_sub( Mpy_32_32( ism_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ), L_add( 1, SID_FORMAT_NBITS ) ) );
    1147         550 :     bstr_orig = st0->bit_stream;
    1148         550 :     next_bit_pos_orig = st0->next_bit_pos;
    1149         550 :     move16();
    1150         550 :     st0->next_bit_pos = 0;
    1151         550 :     move16();
    1152             : 
    1153             :     /* reverse the bitstream for easier reading of indices */
    1154       55550 :     FOR( i = 0; i < s_min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ )
    1155             :     {
    1156       55000 :         bstr_meta[i] = st0->bit_stream[last_bit_pos - i];
    1157       55000 :         move16();
    1158             :     }
    1159         550 :     st0->bit_stream = bstr_meta;
    1160         550 :     st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */
    1161         550 :     move32();
    1162             : 
    1163         550 :     IF( !bfi )
    1164             :     {
    1165             :         /*----------------------------------------------------------------*
    1166             :          * ISm common signaling
    1167             :          *----------------------------------------------------------------*/
    1168             : 
    1169             :         /* number of objects was already read in ivas_ism_get_dtx_dec() */
    1170             :         /* update the position in the bitstream */
    1171         550 :         st0->next_bit_pos = add( st0->next_bit_pos, nchan_ism );
    1172         550 :         move16();
    1173             :         /* read SID metadata flag( one per object ) */
    1174        2366 :         FOR( ch = 0; ch < nchan_ism; ch++ )
    1175             :         {
    1176        1816 :             md_diff_flag[ch] = get_next_indice_fx( st0, 1 );
    1177        1816 :             move16();
    1178             :         }
    1179             : 
    1180             :         /*----------------------------------------------------------------*
    1181             :          * Set quantization bits based on the number of coded objects
    1182             :          *----------------------------------------------------------------*/
    1183             : 
    1184         550 :         ivas_get_ism_sid_quan_bitbudget_fx( nchan_ism, &nBits_azimuth, &nBits_elevation, &q_step_fx, &q_step_border_fx, &nBits_coh, &nBits_sce_id );
    1185             : 
    1186             :         /*----------------------------------------------------------------*
    1187             :          * Spatial parameters, loop over TCs - 1
    1188             :          *----------------------------------------------------------------*/
    1189             : 
    1190         550 :         *flag_noisy_speech = 0;
    1191         550 :         move16();
    1192         550 :         *sce_id_dtx = 0;
    1193         550 :         move16();
    1194             : 
    1195             :         /* read ISM mode flag to explicitly signal number of spatial parameters */
    1196         550 :         IF( GT_16( nchan_ism, 2 ) )
    1197             :         {
    1198         385 :             idx = get_next_indice_fx( st0, 1 );
    1199         385 :             ism_mode_bstr = (ISM_MODE) add( idx, 1 );
    1200             :             /* note: ISM mode was already read and used for configuration in in ivas_ism_dtx_dec() */
    1201             : 
    1202         385 :             IF( EQ_32( ism_mode_bstr, ISM_MODE_PARAM ) )
    1203             :             {
    1204             :                 /* read noisy speech flag */
    1205         107 :                 *flag_noisy_speech = get_next_indice_fx( st0, 1 );
    1206         107 :                 move16();
    1207         107 :                 nBits_sce_id = 1;
    1208         107 :                 move16();
    1209             :             }
    1210             :         }
    1211             : 
    1212         550 :         IF( GT_16( nchan_transport, 1 ) )
    1213             :         {
    1214             :             /* read sce id */
    1215         496 :             *sce_id_dtx = get_next_indice_fx( st0, nBits_sce_id );
    1216         496 :             move16();
    1217             :             /* decode the coherence */
    1218        2044 :             FOR( ch = 0; ch < nchan_transport; ch++ )
    1219             :             {
    1220        1548 :                 IF( EQ_16( ch, *sce_id_dtx ) )
    1221             :                 {
    1222         496 :                     hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = 32767; // 1.0f in Q15
    1223         496 :                     move16();
    1224         496 :                     CONTINUE;
    1225             :                 }
    1226             : 
    1227        1052 :                 idx = get_next_indice_fx( st0, nBits_coh );
    1228        1052 :                 hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = div_s( idx, sub( ( shl( 1, nBits_coh ) ), 1 ) ); // Q15
    1229        1052 :                 move16();
    1230             :             }
    1231             :         }
    1232             : 
    1233         550 :         if ( EQ_32( ism_mode, ISM_MODE_PARAM ) )
    1234             :         {
    1235         107 :             hSCE[*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = hSCE[!*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx;
    1236         107 :             move16();
    1237             :         }
    1238             : 
    1239             :         /*----------------------------------------------------------------*
    1240             :          * Metadata decoding and dequantization, loop over all objects
    1241             :          *----------------------------------------------------------------*/
    1242             : 
    1243        2366 :         FOR( ch = 0; ch < nchan_ism; ch++ )
    1244             :         {
    1245        1816 :             hIsmMetaData = hIsmMeta[ch];
    1246        1816 :             IF( EQ_16( md_diff_flag[ch], 1 ) )
    1247             :             {
    1248             :                 /* Azimuth decoding */
    1249         642 :                 idx_azimuth = get_next_indice_fx( st0, nBits_azimuth );
    1250         642 :                 hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_azimuth, ism_azimuth_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_azimuth );
    1251         642 :                 move32();
    1252             :                 /* Elevation decoding */
    1253         642 :                 idx_elevation = get_next_indice_fx( st0, nBits_elevation );
    1254         642 :                 hIsmMetaData->elevation_fx = ism_dequant_meta_fx( idx_elevation, ism_elevation_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_elevation );
    1255         642 :                 move32();
    1256             :                 /* update last indexes to correspond to active frames coding */
    1257         642 :                 IF( GT_16( nBits_azimuth, ISM_AZIMUTH_NBITS ) )
    1258             :                 {
    1259         209 :                     hIsmMetaData->position_angle.last_angle1_idx = shr( idx_azimuth, sub( nBits_azimuth, ISM_AZIMUTH_NBITS ) );
    1260         209 :                     move16();
    1261         209 :                     hIsmMetaData->position_angle.last_angle2_idx = shr( idx_elevation, sub( nBits_elevation, ISM_ELEVATION_NBITS ) );
    1262         209 :                     move16();
    1263             :                 }
    1264             :                 ELSE
    1265             :                 {
    1266         433 :                     hIsmMetaData->position_angle.last_angle1_idx = shl( idx_azimuth, sub( ISM_AZIMUTH_NBITS, nBits_azimuth ) );
    1267         433 :                     move16();
    1268         433 :                     hIsmMetaData->position_angle.last_angle2_idx = shl( idx_elevation, sub( ISM_ELEVATION_NBITS, nBits_elevation ) );
    1269         433 :                     move16();
    1270             :                 }
    1271             : 
    1272             :                 /* save for smoothing metadata evolution */
    1273         642 :                 hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
    1274         642 :                 move32();
    1275         642 :                 hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
    1276         642 :                 move32();
    1277             :             }
    1278             :         }
    1279             : 
    1280             :         /* take into account padding bits as metadata bits to keep later bitrate checks valid */
    1281             :         Word32 res_dec, res_frac;
    1282         550 :         iDiv_and_mod_32( IVAS_SID_5k2 - SID_2k40, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
    1283         550 :         nb_bits_metadata[*sce_id_dtx] = (Word16) res_dec;
    1284         550 :         move16();
    1285             : 
    1286             :         /* set the bitstream pointer to its original position */
    1287         550 :         st0->bit_stream = bstr_orig;
    1288         550 :         st0->next_bit_pos = next_bit_pos_orig;
    1289         550 :         move16();
    1290             :     }
    1291             : 
    1292             :     /* smooth the metadata evolution */
    1293         550 :     ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
    1294             : 
    1295         550 :     return;
    1296             : }

Generated by: LCOV version 1.14