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 -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 548 566 96.8 %
Date: 2025-08-23 01:22:27 Functions: 7 7 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         362 :             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        8678 :             IF( ( diff_fx > 0 ) )
     108             :             {
     109        6032 :                 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        8678 :             hIsmMetaData->azimuth_fx = L_add( hIsmMetaData->last_azimuth_fx, temp );
     116        8678 :             move32();
     117             :         }
     118       15538 :         ELSE IF( diff_fx != 0 )
     119             :         {
     120        4804 :             hIsmMetaData->azimuth_fx = hIsmMetaData->last_true_azimuth_fx;
     121        4804 :             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        3440 :             IF( ( diff_fx > 0 ) )
     142             :             {
     143        1619 :                 temp = L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 );
     144             :             }
     145             :             ELSE
     146             :             {
     147        1821 :                 temp = L_negate( L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 ) );
     148             :             }
     149        3440 :             hIsmMetaData->elevation_fx = L_add( hIsmMetaData->last_elevation_fx, temp );
     150        3440 :             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      117233 : 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      117233 :     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      117233 :     move16();
     203             : 
     204      117233 :     push_wmops( "ism_meta_dec" );
     205             : 
     206             :     /* initialization */
     207      117233 :     ism_metadata_flag_global = 0;
     208      117233 :     move16();
     209      117233 :     nchan_transport_prev = *nchan_transport;
     210      117233 :     move16();
     211      117233 :     iDiv_and_mod_32( ism_total_brate, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
     212      117233 :     last_bit_pos = extract_l( L_sub( res_dec, 1 ) );
     213      117233 :     bstr_orig = st0->bit_stream;
     214      117233 :     next_bit_pos_orig = st0->next_bit_pos;
     215      117233 :     move16();
     216      117233 :     st0->next_bit_pos = 0;
     217      117233 :     move16();
     218      117233 :     ism_extmeta_bitstream = 0;
     219      117233 :     move16();
     220      117233 :     non_diegetic_flag_global = 0;
     221      117233 :     move16();
     222      117233 :     set16_fx( null_metadata_flag, 0, nchan_ism );
     223      117233 :     set16_fx( lowrate_metadata_flag, 0, nchan_ism );
     224             : 
     225             :     /* reverse the bitstream for easier reading of indices */
     226    21219173 :     FOR( i = 0; i < s_min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ )
     227             :     {
     228    21101940 :         bstr_meta[i] = st0->bit_stream[last_bit_pos - i];
     229    21101940 :         move16();
     230             :     }
     231      117233 :     st0->bit_stream = bstr_meta;
     232      117233 :     st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */
     233      117233 :     move32();
     234             : 
     235      117233 :     IF( !bfi )
     236             :     {
     237             :         /*----------------------------------------------------------------*
     238             :          * Read ISM common signaling
     239             :          *----------------------------------------------------------------*/
     240      116370 :         test();
     241      116370 :         IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     242             :         {
     243             :             /* number of objects was read in ivas_dec_setup() */
     244       19633 :             st0->next_bit_pos = add( st0->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ );
     245       19633 :             move32();
     246             :         }
     247       96737 :         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       91951 :             st0->next_bit_pos = add( st0->next_bit_pos, nchan_ism );
     251       91951 :             move16();
     252             : 
     253       91951 :             ism_mode = ivas_ism_mode_select( nchan_ism, ism_total_brate );
     254             :         }
     255             : 
     256      116370 :         IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     257             :         {
     258       15649 :             *nchan_transport = MAX_PARAM_ISM_WAVE;
     259       15649 :             move16();
     260             :         }
     261      100721 :         ELSE IF( EQ_32( ism_mode, ISM_MODE_DISC ) )
     262             :         {
     263       76302 :             *nchan_transport = nchan_ism;
     264       76302 :             move16();
     265             :         }
     266             : 
     267      116370 :         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      116370 :         test();
     274      116370 :         test();
     275      116370 :         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       74280 :             ism_extmeta_bitstream = get_next_indice_fx( st0, ISM_EXTENDED_METADATA_BITS );
     278             : 
     279             :             /* read global non-diegetic object flag */
     280       74280 :             IF( ism_extmeta_bitstream )
     281             :             {
     282        8080 :                 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      116370 :         test();
     288      116370 :         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      116173 :             *ism_extmeta_active = ism_extmeta_bitstream;
     291      116173 :             move16();
     292      116173 :             *ism_extmeta_cnt = 0;
     293      116173 :             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      423412 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     309             :         {
     310      307042 :             test();
     311      307042 :             IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     312             :             {
     313       61031 :                 ism_imp[ch] = get_next_indice_fx( st0, 1 );
     314       61031 :                 move16();
     315             :             }
     316      246011 :             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        9401 :                 ism_imp[ch] = hIsmMeta[ch]->ism_imp;
     320        9401 :                 move16();
     321             :             }
     322             :             ELSE
     323             :             {
     324      236610 :                 ism_imp[ch] = get_next_indice_fx( st0, ISM_METADATA_FLAG_BITS );
     325      236610 :                 move16();
     326             :             }
     327             : 
     328      307042 :             IF( GT_16( ism_imp[ch], ISM_NO_META ) )
     329             :             {
     330      296602 :                 hIsmMeta[ch]->ism_metadata_flag = 1;
     331      296602 :                 move16();
     332             :             }
     333             :             ELSE
     334             :             {
     335       10440 :                 hIsmMeta[ch]->ism_metadata_flag = 0;
     336       10440 :                 move16();
     337             :             }
     338             : 
     339      307042 :             ism_metadata_flag_global = s_or( ism_metadata_flag_global, hIsmMeta[ch]->ism_metadata_flag );
     340             :         }
     341             : 
     342      142517 :         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      116370 :         test();
     351      116370 :         IF( EQ_32( ism_mode, ISM_MODE_DISC ) || EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     352             :         {
     353      362278 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     354             :             {
     355      266343 :                 IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
     356             :                 {
     357             :                     /* low-rate ISM_NO_META frame */
     358       10440 :                     test();
     359       10440 :                     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       10440 :                         null_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
     367       10440 :                         move16();
     368             :                     }
     369             :                 }
     370             :             }
     371             : 
     372      362278 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     373             :             {
     374      266343 :                 IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
     375             :                 {
     376       10440 :                     test();
     377       10440 :                     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       10440 :                     ELSE IF( NE_32( ism_mode, ISM_SBA_MODE_DISC ) )
     388             :                     {
     389       10440 :                         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        5770 :                             lowrate_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
     399        5770 :                             move16();
     400             : 
     401        5770 :                             ism_metadata_flag_global = s_or( ism_metadata_flag_global, lowrate_metadata_flag[ch] );
     402             :                         }
     403             :                     }
     404             :                 }
     405             :             }
     406             :         }
     407             : 
     408      116370 :         IF( ism_metadata_flag_global )
     409             :         {
     410             :             /*----------------------------------------------------------------*
     411             :              * Metadata decoding and dequantization, loop over all objects
     412             :              *----------------------------------------------------------------*/
     413             : 
     414      116353 :             Word16 total_bits_metadata = 0, bits_metadata_ism = 0;
     415      116353 :             move16();
     416      116353 :             move16();
     417             :             Word16 nb_bits_objcod_read;
     418             : 
     419      116353 :             IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     420             :             {
     421       15649 :                 nb_bits_start = st0->next_bit_pos;
     422       15649 :                 move16();
     423             :             }
     424             : 
     425      449507 :             FOR( ch = 0; ch < nchan_ism; ch++ )
     426             :             {
     427      333154 :                 hIsmMetaData = hIsmMeta[ch];
     428      333154 :                 test();
     429      333154 :                 test();
     430      333154 :                 test();
     431      333154 :                 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      275709 :                     nb_bits_start = st0->next_bit_pos;
     434      275709 :                     move16();
     435             :                 }
     436      333154 :                 flag_abs_position = 0;
     437      333154 :                 move16();
     438      333154 :                 flag_abs_orientation = 0;
     439      333154 :                 move16();
     440      333154 :                 flag_abs_radius = 0;
     441      333154 :                 move16();
     442             : 
     443      333154 :                 test();
     444      333154 :                 IF( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
     445             :                 {
     446      328258 :                     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      325843 :                         hIsmMetaData->non_diegetic_flag = 0;
     455      325843 :                         move16();
     456             :                     }
     457             : 
     458      328258 :                     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      327453 :                         decode_angle_indices_fx( st0, &( hIsmMetaData->position_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_position );
     481      327453 :                         idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx;
     482      327453 :                         move16();
     483      327453 :                         idx_angle2 = hIsmMetaData->position_angle.last_angle2_idx;
     484      327453 :                         move16();
     485             : 
     486             :                         /* Azimuth/Elevation dequantization */
     487      327453 :                         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      270008 :                             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      270008 :                             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      270008 :                             move32();
     499      270008 :                             move32();
     500             : 
     501             :                             /* radius/raw/pitch dequantization */
     502      270008 :                             IF( ism_extmeta_bitstream )
     503             :                             {
     504       25281 :                                 decode_angle_indices_fx( st0, &( hIsmMetaData->orientation_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_orientation );
     505       25281 :                                 idx_angle1 = hIsmMetaData->orientation_angle.last_angle1_idx;
     506       25281 :                                 move16();
     507       25281 :                                 idx_angle2 = hIsmMetaData->orientation_angle.last_angle2_idx;
     508       25281 :                                 move16();
     509       25281 :                                 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       25281 :                                 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       25281 :                                 idx_radius = decode_radius_fx( st0, &hIsmMetaData->last_radius_idx, &flag_abs_radius );
     513       25281 :                                 radius_fx = usdequant_fx( idx_radius, ISM_RADIUS_MIN_Q9, ISM_RADIUS_DELTA_Q8 );
     514       25281 :                                 IF( EQ_16( *ism_extmeta_active, 1 ) )
     515             :                                 {
     516       25041 :                                     hIsmMetaData->yaw_fx = yaw_fx;
     517       25041 :                                     move32();
     518       25041 :                                     hIsmMetaData->pitch_fx = pitch_fx;
     519       25041 :                                     move32();
     520       25041 :                                     hIsmMetaData->radius_fx = radius_fx;
     521       25041 :                                     move16();
     522             :                                 }
     523             :                             }
     524             :                             ELSE
     525             :                             {
     526      244727 :                                 IF( *ism_extmeta_active == 0 )
     527             :                                 {
     528      244655 :                                     hIsmMetaData->yaw_fx = 0;
     529      244655 :                                     move32();
     530      244655 :                                     hIsmMetaData->pitch_fx = 0;
     531      244655 :                                     move32();
     532      244655 :                                     hIsmMetaData->radius_fx = 512; /* 1.0f in Q9 */
     533      244655 :                                     move16();
     534             :                                 }
     535             :                             }
     536             :                         }
     537             :                         /* save for smoothing metadata evolution */
     538      327453 :                         hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
     539      327453 :                         move32();
     540      327453 :                         hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
     541      327453 :                         move32();
     542             :                     }
     543             :                 }
     544             :                 /* save number of metadata bits read */
     545      333154 :                 test();
     546      333154 :                 test();
     547      333154 :                 test();
     548      333154 :                 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      275709 :                     nb_bits_metadata[ch] = sub( st0->next_bit_pos, nb_bits_start );
     551      275709 :                     move16();
     552             :                 }
     553             :             }
     554             : 
     555      116353 :             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        3081 :         FOR( ch = 0; ch < nchan_ism; ch++ )
     619             :         {
     620        2218 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     621        2218 :             move16();
     622             :         }
     623             : 
     624         863 :         set16_fx( nb_bits_metadata, 0, *nchan_transport );
     625             : 
     626         863 :         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      117233 :     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      117233 :     IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     650             :     {
     651             :         /* set the bitstream pointer to its original position */
     652       19680 :         nb_bits_metadata[0] = st0->next_bit_pos;
     653       19680 :         move16();
     654       19680 :         st0->bit_stream = bstr_orig;
     655       19680 :         st0->next_bit_pos = next_bit_pos_orig;
     656       19680 :         move16();
     657             : 
     658             :         /* updates*/
     659       19680 :         set16_fx( md_diff_flag, 1, nchan_ism );
     660             : 
     661       19680 :         update_last_metadata_fx( nchan_ism, hIsmMeta, md_diff_flag );
     662       19680 :         pop_wmops();
     663       19680 :         return IVAS_ERR_OK;
     664             :     }
     665             : 
     666       97553 :     test();
     667       97553 :     if ( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     668             :     {
     669        4867 :         ism_metadata_flag_global = 1;
     670        4867 :         move16();
     671             :     }
     672             : 
     673             :     /*----------------------------------------------------------------*
     674             :      * Configuration and decision about bitrates per channel
     675             :      *----------------------------------------------------------------*/
     676             : 
     677       97553 :     IF( !bfi )
     678             :     {
     679       96737 :         Word16 masa_ism_flag = 0;
     680       96737 :         move16();
     681       96737 :         test();
     682       96737 :         IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     683             :         {
     684        4786 :             masa_ism_flag = 1;
     685        4786 :             move16();
     686             : 
     687       14187 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     688             :             {
     689        9401 :                 element_brate[ch] = hSCE[ch]->element_brate;
     690        9401 :                 move32();
     691             :             }
     692             :         }
     693             : 
     694       96737 :         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      342748 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     700             :         {
     701      246011 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     702      246011 :             move16();
     703             : 
     704      246011 :             hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
     705      246011 :             move16();
     706      246011 :             test();
     707      246011 :             test();
     708      246011 :             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      214713 :                 test();
     711      214713 :                 test();
     712      214713 :                 test();
     713      214713 :                 test();
     714      220809 :                 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       11473 :                                                      ( LE_32( total_brate[ch], ACELP_16k_LOW_LIMIT ) && GE_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) ) )
     716             :                 {
     717        6725 :                     hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
     718        6725 :                     move16();
     719             :                 }
     720             :             }
     721             : 
     722      246011 :             test();
     723      246011 :             if ( NE_32( ism_mode, ISM_MASA_MODE_DISC ) && NE_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     724             :             {
     725      236610 :                 hSCE[ch]->element_brate = element_brate[ch];
     726      236610 :                 move32();
     727             :             }
     728      246011 :             hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
     729      246011 :             move32();
     730             :         }
     731             : 
     732      122884 :         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       97553 :     st0->bit_stream = bstr_orig;
     755       97553 :     st0->next_bit_pos = next_bit_pos_orig;
     756       97553 :     move16();
     757             : 
     758             :     /* set bitstream pointers for each ISM */
     759      247730 :     FOR( ch = 1; ch < *nchan_transport; ch++ )
     760             :     {
     761      150177 :         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       97553 :     set16_fx( md_diff_flag, 1, nchan_ism );
     769             : 
     770       97553 :     update_last_metadata_fx( nchan_ism, hIsmMeta, md_diff_flag );
     771             : 
     772      345283 :     FOR( ch = 0; ch < *nchan_transport; ch++ )
     773             :     {
     774      247730 :         hSCE[ch]->hCoreCoder[0]->cng_ism_flag = 0;
     775      247730 :         move16();
     776             :     }
     777             : 
     778       97553 :     pop_wmops();
     779             : 
     780       97553 :     return IVAS_ERR_OK;
     781             : }
     782             : 
     783             : 
     784             : /*-------------------------------------------------------------------*
     785             :  * ivas_ism_reset_metadata_handle_dec()
     786             :  *
     787             :  * Reset ISM decoder metadata handle
     788             :  *-------------------------------------------------------------------*/
     789             : 
     790        3038 : void ivas_ism_reset_metadata_handle_dec_fx(
     791             :     ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle     */
     792             : )
     793             : {
     794        3038 :     hIsmMeta->last_ism_metadata_flag = 0;
     795        3038 :     move16();
     796        3038 :     hIsmMeta->position_angle.last_angle1_idx = 0;
     797        3038 :     move16();
     798        3038 :     hIsmMeta->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 );
     799        3038 :     move16();
     800        3038 :     hIsmMeta->orientation_angle.last_angle1_idx = 0;
     801        3038 :     move16();
     802        3038 :     hIsmMeta->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 );
     803        3038 :     move16();
     804        3038 :     hIsmMeta->last_radius_idx = 8; /* Init to radius 1.0 */
     805        3038 :     move16();
     806             : 
     807        3038 :     hIsmMeta->last_true_azimuth_fx = 0;
     808        3038 :     move32();
     809        3038 :     hIsmMeta->last_true_elevation_fx = 0;
     810        3038 :     move32();
     811        3038 :     hIsmMeta->last_azimuth_fx = 0;
     812        3038 :     move32();
     813        3038 :     hIsmMeta->last_elevation_fx = 0;
     814        3038 :     move32();
     815             : 
     816        3038 :     hIsmMeta->ism_imp = -1;
     817        3038 :     move16();
     818        3038 :     hIsmMeta->ism_md_null_flag = 0;
     819        3038 :     move16();
     820        3038 :     hIsmMeta->ism_md_lowrate_flag = 0;
     821        3038 :     move16();
     822             : 
     823        3038 :     ivas_ism_reset_metadata( hIsmMeta );
     824             : 
     825        3038 :     return;
     826             : }
     827             : 
     828             : 
     829             : /*-------------------------------------------------------------------------
     830             :  * ivas_ism_metadata_dec_create()
     831             :  *
     832             :  * Create, allocate, initialize and configure IVAS decoder ISM metadata handles
     833             :  *-------------------------------------------------------------------------*/
     834             : 
     835         901 : ivas_error ivas_ism_metadata_dec_create_fx(
     836             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder structure               */
     837             :     const Word16 n_ISms,       /* i  : number of separately coded objects   */
     838             :     Word32 element_brate_tmp[] /* o  : element bitrate per object           */
     839             : )
     840             : {
     841             :     Word16 ch;
     842             :     ivas_error error;
     843             : 
     844             :     /* allocate ISM metadata handles */
     845        3201 :     FOR( ch = 0; ch < n_ISms; ch++ )
     846             :     {
     847        2300 :         IF( st_ivas->hIsmMetaData[ch] == NULL ) /* note: the handle can be allocated in OMASA bitrate switching from ISM_MASA_MODE_xxx_ONE_OBJ to ISM_MASA_MODE_DISC mode for 'ch==0' */
     848             :         {
     849        2073 :             IF( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL )
     850             :             {
     851           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) );
     852             :             }
     853             :         }
     854             : 
     855        2300 :         ivas_ism_reset_metadata_handle_dec_fx( st_ivas->hIsmMetaData[ch] );
     856             :     }
     857             : 
     858             :     /* sanity freeing - it can happen only in reconfiguration when a smaller number of handles than before is requested */
     859        2205 :     FOR( ; ch < MAX_NUM_OBJECTS; ch++ )
     860             :     {
     861        1304 :         IF( st_ivas->hIsmMetaData[ch] != NULL )
     862             :         {
     863           0 :             free( st_ivas->hIsmMetaData[ch] );
     864           0 :             st_ivas->hIsmMetaData[ch] = NULL;
     865             :         }
     866             :     }
     867             : 
     868         901 :     IF( element_brate_tmp != NULL )
     869             :     {
     870         259 :         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 ) )
     871             :         {
     872           0 :             return error;
     873             :         }
     874             :     }
     875             : 
     876         901 :     st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX;
     877         901 :     move16();
     878             : 
     879         901 :     return IVAS_ERR_OK;
     880             : }
     881             : 
     882             : 
     883             : /*-------------------------------------------------------------------------
     884             :  * decode_angle_indices()
     885             :  *
     886             :  * Decoding of a position/orientation angle
     887             :  *-------------------------------------------------------------------------*/
     888             : 
     889      353539 : static void decode_angle_indices_fx(
     890             :     DEC_CORE_HANDLE st0,             /* i/o: bitstream handle                */
     891             :     ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle                    */
     892             :     const Word16 non_diegetic_flag,  /* i  : Non diegetic flag               */
     893             :     Word16 *flag_abs_angle1          /* o  : Azimuth/yaw encoding mode       */
     894             : )
     895             : {
     896             :     Word16 idx_angle1, nbits_diff_angle1, diff, sgn;
     897             :     Word16 idx_angle2, nbits_diff_angle2;
     898             : 
     899             :     /*----------------------------------------------------------------*
     900             :      * Azimuth/yaw decoding and dequantization
     901             :      *----------------------------------------------------------------*/
     902             : 
     903             :     /* Decode azimuth/yaw index */
     904      353539 :     IF( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* azimuth_abs_flag */
     905             :     {
     906      110720 :         idx_angle1 = get_next_indice_fx( st0, ISM_AZIMUTH_NBITS );
     907      110720 :         *flag_abs_angle1 = 1;
     908      110720 :         move16();
     909             :     }
     910             :     ELSE
     911             :     {
     912      242819 :         diff = 0;
     913      242819 :         move16();
     914      242819 :         sgn = 1;
     915      242819 :         move16();
     916             : 
     917      242819 :         IF( get_next_indice_fx( st0, 1 ) == 0 )
     918             :         {
     919       55566 :             nbits_diff_angle1 = 1;
     920       55566 :             move16();
     921             :         }
     922             :         ELSE
     923             :         {
     924      187253 :             nbits_diff_angle1 = 1;
     925      187253 :             move16();
     926             : 
     927      187253 :             if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
     928             :             {
     929       60425 :                 sgn = -1;
     930       60425 :                 move16();
     931             :             }
     932             : 
     933      187253 :             nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     934             : 
     935             :             /* read until the stop bit */
     936      536975 :             WHILE( nbits_diff_angle1 < ( ISM_AZIMUTH_NBITS - 1 ) && get_next_indice_fx( st0, 1 ) == 1 )
     937             :             {
     938      349722 :                 diff = add( diff, 1 );
     939      349722 :                 nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     940             :             }
     941             : 
     942      187253 :             if ( LT_16( nbits_diff_angle1, ( ISM_AZIMUTH_NBITS - 1 ) ) )
     943             :             {
     944             :                 /* count stop bit */
     945      171297 :                 nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     946             :             }
     947             :         }
     948      242819 :         idx_angle1 = add( angle->last_angle1_idx, i_mult2( sgn, diff ) );
     949             :     }
     950             : 
     951             :     /* azimuth/yaw is on a circle - check for diff coding for -180° -> 180° and vice versa changes */
     952      353539 :     IF( GT_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     953             :     {
     954          11 :         idx_angle1 = sub( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ); /* +180° -> -180° */
     955             :     }
     956      353528 :     ELSE IF( idx_angle1 < 0 )
     957             :     {
     958        1210 :         idx_angle1 = add( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ); /* -180° -> +180° */
     959             :     }
     960             : 
     961             :     /* +180° == -180° */
     962      353539 :     if ( EQ_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     963             :     {
     964        3051 :         idx_angle1 = 0;
     965        3051 :         move16();
     966             :     }
     967             : 
     968             :     /* sanity check in case of FER or BER */
     969      353539 :     test();
     970      353539 :     if ( ( idx_angle1 < 0 ) || GT_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     971             :     {
     972           0 :         idx_angle1 = angle->last_angle1_idx;
     973           0 :         move16();
     974             :     }
     975             : 
     976             :     /*----------------------------------------------------------------*
     977             :      * Elevation/pitch decoding and dequantization
     978             :      *----------------------------------------------------------------*/
     979             : 
     980      353539 :     IF( non_diegetic_flag == 0 )
     981             :     {
     982             :         /* Decode elevation/pitch index */
     983      352734 :         test();
     984      352734 :         IF( ( *flag_abs_angle1 == 0 ) && EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* elevation_abs_flag */
     985             :         {
     986       30145 :             idx_angle2 = get_next_indice_fx( st0, ISM_ELEVATION_NBITS );
     987             :         }
     988             :         ELSE
     989             :         {
     990      322589 :             diff = 0;
     991      322589 :             move16();
     992      322589 :             sgn = 1;
     993      322589 :             move16();
     994             : 
     995      322589 :             IF( get_next_indice_fx( st0, 1 ) == 0 )
     996             :             {
     997      133447 :                 nbits_diff_angle2 = 1;
     998      133447 :                 move16();
     999             :             }
    1000             :             ELSE
    1001             :             {
    1002      189142 :                 nbits_diff_angle2 = 1;
    1003      189142 :                 move16();
    1004             : 
    1005      189142 :                 if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
    1006             :                 {
    1007       94856 :                     sgn = -1;
    1008       94856 :                     move16();
    1009             :                 }
    1010             : 
    1011      189142 :                 nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
    1012             : 
    1013             :                 /* read until the stop bit */
    1014      672883 :                 WHILE( ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) && ( get_next_indice_fx( st0, 1 ) == 1 ) )
    1015             :                 {
    1016      483741 :                     diff = add( diff, 1 );
    1017      483741 :                     nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
    1018             :                 }
    1019             : 
    1020      189142 :                 if ( LT_16( nbits_diff_angle2, ISM_ELEVATION_NBITS ) )
    1021             :                 {
    1022             :                     /* count stop bit */
    1023      126844 :                     nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
    1024             :                 }
    1025             :             }
    1026             : 
    1027      322589 :             idx_angle2 = add( angle->last_angle2_idx, i_mult( sgn, diff ) );
    1028             :         }
    1029             : 
    1030             :         /* sanity check in case of FER or BER */
    1031      352734 :         test();
    1032      352734 :         if ( ( idx_angle2 < 0 ) || GT_16( idx_angle2, ( ( 1 << ISM_ELEVATION_NBITS ) - 1 ) ) )
    1033             :         {
    1034           0 :             idx_angle2 = angle->last_angle2_idx;
    1035           0 :             move16();
    1036             :         }
    1037             :     }
    1038             :     ELSE
    1039             :     {
    1040         805 :         idx_angle2 = angle->last_angle2_idx; /* second MD parameter is not transmitted for non-diegetic object */
    1041         805 :         move16();
    1042             :     }
    1043             : 
    1044             :     /*----------------------------------------------------------------*
    1045             :      * Final updates
    1046             :      *----------------------------------------------------------------*/
    1047             : 
    1048      353539 :     angle->last_angle2_idx = idx_angle2;
    1049      353539 :     move16();
    1050      353539 :     angle->last_angle1_idx = idx_angle1;
    1051      353539 :     move16();
    1052             : 
    1053      353539 :     return;
    1054             : }
    1055             : 
    1056             : 
    1057             : /*-------------------------------------------------------------------------
    1058             :  * decode_radius()
    1059             :  *
    1060             :  * Radius decoding and dequantization
    1061             :  *-------------------------------------------------------------------------*/
    1062             : 
    1063       25281 : static Word16 decode_radius_fx(
    1064             :     DEC_CORE_HANDLE st0,     /* i/o: bitstream handle           */
    1065             :     Word16 *last_radius_idx, /* i/o: last radius index          */
    1066             :     Word16 *flag_abs_radius  /* o  : Radius encoding mode       */
    1067             : )
    1068             : {
    1069             :     Word16 idx_radius, nbits_diff_radius, diff, sgn;
    1070             : 
    1071             :     /* Decode radius index */
    1072       25281 :     IF( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* elevation_abs_flag */
    1073             :     {
    1074        7094 :         *flag_abs_radius = 1;
    1075        7094 :         move16();
    1076        7094 :         idx_radius = get_next_indice_fx( st0, ISM_RADIUS_NBITS );
    1077             :     }
    1078             :     ELSE
    1079             :     {
    1080       18187 :         diff = 0;
    1081       18187 :         move16();
    1082       18187 :         sgn = 1;
    1083       18187 :         move16();
    1084             : 
    1085       18187 :         IF( get_next_indice_fx( st0, 1 ) == 0 )
    1086             :         {
    1087       15121 :             nbits_diff_radius = 1;
    1088       15121 :             move16();
    1089             :         }
    1090             :         ELSE
    1091             :         {
    1092        3066 :             nbits_diff_radius = 1;
    1093        3066 :             move16();
    1094             : 
    1095        3066 :             if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
    1096             :             {
    1097        1416 :                 sgn = -1;
    1098        1416 :                 move16();
    1099             :             }
    1100             : 
    1101        3066 :             nbits_diff_radius = add( nbits_diff_radius, 1 );
    1102             : 
    1103             :             /* read until the stop bit */
    1104        6922 :             WHILE( ( nbits_diff_radius < ISM_RADIUS_NBITS ) && ( get_next_indice_fx( st0, 1 ) == 1 ) )
    1105             :             {
    1106        3856 :                 diff = add( diff, 1 );
    1107        3856 :                 nbits_diff_radius = add( nbits_diff_radius, 1 );
    1108             :             }
    1109             : 
    1110        3066 :             IF( LT_16( nbits_diff_radius, ISM_RADIUS_NBITS ) )
    1111             :             {
    1112             :                 /* count stop bit */
    1113        2883 :                 nbits_diff_radius = add( nbits_diff_radius, 1 );
    1114             :             }
    1115             :         }
    1116       18187 :         idx_radius = add( *last_radius_idx, i_mult2( sgn, diff ) );
    1117             :     }
    1118             : 
    1119             :     /* sanity check in case of FER or BER */
    1120       25281 :     test();
    1121       25281 :     if ( ( idx_radius < 0 ) || GT_16( idx_radius, ( 1 << ISM_RADIUS_NBITS ) - 1 ) )
    1122             :     {
    1123           0 :         idx_radius = *last_radius_idx;
    1124           0 :         move16();
    1125             :     }
    1126             : 
    1127             :     /* Final updates */
    1128       25281 :     *last_radius_idx = idx_radius;
    1129       25281 :     move16();
    1130             : 
    1131       25281 :     return idx_radius;
    1132             : }
    1133             : 
    1134             : 
    1135             : /*-------------------------------------------------------------------*
    1136             :  * ivas_ism_metadata_sid_dec()
    1137             :  *
    1138             :  * Decode ISM metadata in SID frame
    1139             :  *-------------------------------------------------------------------*/
    1140             : 
    1141        2151 : void ivas_ism_metadata_sid_dec_fx(
    1142             :     SCE_DEC_HANDLE hSCE[MAX_SCE],   /* i/o: SCE decoder structure       */
    1143             :     const Word32 ism_total_brate,   /* i  : ISM total bitrate           */
    1144             :     const Word16 bfi,               /* i  : bfi flag                    */
    1145             :     const Word16 nchan_ism,         /* i  : number of objects           */
    1146             :     const Word16 nchan_transport,   /* i  : number of transport channels*/
    1147             :     const ISM_MODE ism_mode,        /* i  : ISM mode                    */
    1148             :     Word16 *flag_noisy_speech,      /* o  : noisy speech flag           */
    1149             :     Word16 *sce_id_dtx,             /* o  : SCE DTX ID                  */
    1150             :     ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles        */
    1151             :     Word16 nb_bits_metadata[]       /* o  : number of metadata bits     */
    1152             : )
    1153             : {
    1154             :     Word16 i, ch, last_bit_pos;
    1155             :     Word32 q_step_fx, q_step_border_fx;
    1156             :     Word16 idx, idx_azimuth, idx_elevation;
    1157             :     Word16 nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
    1158             :     Word16 md_diff_flag[MAX_NUM_OBJECTS];
    1159             :     ISM_MODE ism_mode_bstr;
    1160             :     DEC_CORE_HANDLE st0;
    1161             :     ISM_METADATA_HANDLE hIsmMetaData;
    1162             :     Word16 next_bit_pos_orig;
    1163             :     UWord16 bstr_meta[IVAS_SID_5k2 / FRAMES_PER_SEC], *bstr_orig;
    1164             : 
    1165        2151 :     IF( ism_total_brate == FRAME_NO_DATA )
    1166             :     {
    1167        1601 :         ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
    1168             : 
    1169        1601 :         return;
    1170             :     }
    1171             : 
    1172             :     /* initialization */
    1173         550 :     st0 = hSCE[0]->hCoreCoder[0];
    1174             : 
    1175         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 ) ) );
    1176         550 :     bstr_orig = st0->bit_stream;
    1177         550 :     next_bit_pos_orig = st0->next_bit_pos;
    1178         550 :     move16();
    1179         550 :     st0->next_bit_pos = 0;
    1180         550 :     move16();
    1181             : 
    1182             :     /* reverse the bitstream for easier reading of indices */
    1183       55550 :     FOR( i = 0; i < s_min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ )
    1184             :     {
    1185       55000 :         bstr_meta[i] = st0->bit_stream[last_bit_pos - i];
    1186       55000 :         move16();
    1187             :     }
    1188         550 :     st0->bit_stream = bstr_meta;
    1189         550 :     st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */
    1190         550 :     move32();
    1191             : 
    1192         550 :     IF( !bfi )
    1193             :     {
    1194             :         /*----------------------------------------------------------------*
    1195             :          * ISm common signaling
    1196             :          *----------------------------------------------------------------*/
    1197             : 
    1198             :         /* number of objects was already read in ivas_ism_get_dtx_dec() */
    1199             :         /* update the position in the bitstream */
    1200         550 :         st0->next_bit_pos = add( st0->next_bit_pos, nchan_ism );
    1201         550 :         move16();
    1202             :         /* read SID metadata flag( one per object ) */
    1203        2366 :         FOR( ch = 0; ch < nchan_ism; ch++ )
    1204             :         {
    1205        1816 :             md_diff_flag[ch] = get_next_indice_fx( st0, 1 );
    1206        1816 :             move16();
    1207             :         }
    1208             : 
    1209             :         /*----------------------------------------------------------------*
    1210             :          * Set quantization bits based on the number of coded objects
    1211             :          *----------------------------------------------------------------*/
    1212             : 
    1213         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 );
    1214             : 
    1215             :         /*----------------------------------------------------------------*
    1216             :          * Spatial parameters, loop over TCs - 1
    1217             :          *----------------------------------------------------------------*/
    1218             : 
    1219         550 :         *flag_noisy_speech = 0;
    1220         550 :         move16();
    1221         550 :         *sce_id_dtx = 0;
    1222         550 :         move16();
    1223             : 
    1224             :         /* read ISM mode flag to explicitly signal number of spatial parameters */
    1225         550 :         IF( GT_16( nchan_ism, 2 ) )
    1226             :         {
    1227         385 :             idx = get_next_indice_fx( st0, 1 );
    1228         385 :             ism_mode_bstr = (ISM_MODE) add( idx, 1 );
    1229             :             /* note: ISM mode was already read and used for configuration in in ivas_ism_dtx_dec() */
    1230             : 
    1231         385 :             IF( EQ_32( ism_mode_bstr, ISM_MODE_PARAM ) )
    1232             :             {
    1233             :                 /* read noisy speech flag */
    1234         107 :                 *flag_noisy_speech = get_next_indice_fx( st0, 1 );
    1235         107 :                 move16();
    1236         107 :                 nBits_sce_id = 1;
    1237         107 :                 move16();
    1238             :             }
    1239             :         }
    1240             : 
    1241         550 :         IF( GT_16( nchan_transport, 1 ) )
    1242             :         {
    1243             :             /* read sce id */
    1244         496 :             *sce_id_dtx = get_next_indice_fx( st0, nBits_sce_id );
    1245         496 :             move16();
    1246             :             /* decode the coherence */
    1247        2044 :             FOR( ch = 0; ch < nchan_transport; ch++ )
    1248             :             {
    1249        1548 :                 IF( EQ_16( ch, *sce_id_dtx ) )
    1250             :                 {
    1251         496 :                     hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = 32767; // 1.0f in Q15
    1252         496 :                     move16();
    1253         496 :                     CONTINUE;
    1254             :                 }
    1255             : 
    1256        1052 :                 idx = get_next_indice_fx( st0, nBits_coh );
    1257        1052 :                 hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = div_s( idx, sub( ( shl( 1, nBits_coh ) ), 1 ) ); // Q15
    1258        1052 :                 move16();
    1259             :             }
    1260             :         }
    1261             : 
    1262         550 :         if ( EQ_32( ism_mode, ISM_MODE_PARAM ) )
    1263             :         {
    1264         107 :             hSCE[*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = hSCE[!*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx;
    1265         107 :             move16();
    1266             :         }
    1267             : 
    1268             :         /*----------------------------------------------------------------*
    1269             :          * Metadata decoding and dequantization, loop over all objects
    1270             :          *----------------------------------------------------------------*/
    1271             : 
    1272        2366 :         FOR( ch = 0; ch < nchan_ism; ch++ )
    1273             :         {
    1274        1816 :             hIsmMetaData = hIsmMeta[ch];
    1275        1816 :             IF( EQ_16( md_diff_flag[ch], 1 ) )
    1276             :             {
    1277             :                 /* Azimuth decoding */
    1278         642 :                 idx_azimuth = get_next_indice_fx( st0, nBits_azimuth );
    1279         642 :                 hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_azimuth, ism_azimuth_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_azimuth );
    1280         642 :                 move32();
    1281             :                 /* Elevation decoding */
    1282         642 :                 idx_elevation = get_next_indice_fx( st0, nBits_elevation );
    1283         642 :                 hIsmMetaData->elevation_fx = ism_dequant_meta_fx( idx_elevation, ism_elevation_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_elevation );
    1284         642 :                 move32();
    1285             :                 /* update last indexes to correspond to active frames coding */
    1286         642 :                 IF( GT_16( nBits_azimuth, ISM_AZIMUTH_NBITS ) )
    1287             :                 {
    1288         209 :                     hIsmMetaData->position_angle.last_angle1_idx = shr( idx_azimuth, sub( nBits_azimuth, ISM_AZIMUTH_NBITS ) );
    1289         209 :                     move16();
    1290         209 :                     hIsmMetaData->position_angle.last_angle2_idx = shr( idx_elevation, sub( nBits_elevation, ISM_ELEVATION_NBITS ) );
    1291         209 :                     move16();
    1292             :                 }
    1293             :                 ELSE
    1294             :                 {
    1295         433 :                     hIsmMetaData->position_angle.last_angle1_idx = shl( idx_azimuth, sub( ISM_AZIMUTH_NBITS, nBits_azimuth ) );
    1296         433 :                     move16();
    1297         433 :                     hIsmMetaData->position_angle.last_angle2_idx = shl( idx_elevation, sub( ISM_ELEVATION_NBITS, nBits_elevation ) );
    1298         433 :                     move16();
    1299             :                 }
    1300             : 
    1301             :                 /* save for smoothing metadata evolution */
    1302         642 :                 hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
    1303         642 :                 move32();
    1304         642 :                 hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
    1305         642 :                 move32();
    1306             :             }
    1307             :         }
    1308             : 
    1309             :         /* take into account padding bits as metadata bits to keep later bitrate checks valid */
    1310             :         Word32 res_dec, res_frac;
    1311         550 :         iDiv_and_mod_32( IVAS_SID_5k2 - SID_2k40, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
    1312         550 :         nb_bits_metadata[*sce_id_dtx] = (Word16) res_dec;
    1313         550 :         move16();
    1314             : 
    1315             :         /* set the bitstream pointer to its original position */
    1316         550 :         st0->bit_stream = bstr_orig;
    1317         550 :         st0->next_bit_pos = next_bit_pos_orig;
    1318         550 :         move16();
    1319             :     }
    1320             : 
    1321             :     /* smooth the metadata evolution */
    1322         550 :     ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
    1323             : 
    1324         550 :     return;
    1325             : }

Generated by: LCOV version 1.14