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 @ da9cc8ead0679b4682d329fdff98cf1616159273 Lines: 547 565 96.8 %
Date: 2025-10-13 22:24:20 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 "prot_fx.h"
      39             : #include "ivas_stat_enc.h"
      40             : #include <math.h>
      41             : #include "wmc_auto.h"
      42             : #include "ivas_prot_fx.h"
      43             : 
      44             : 
      45             : /*-----------------------------------------------------------------------*
      46             :  * Local functions
      47             :  *-----------------------------------------------------------------------*/
      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        8367 : 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       34857 :     FOR( ch = 0; ch < nchan_ism; ch++ )
      82             :     {
      83       26490 :         hIsmMetaData = hIsmMeta[ch];
      84             : 
      85             :         /* smooth azimuth */
      86       26490 :         diff_fx = L_sub( hIsmMetaData->last_true_azimuth_fx, hIsmMetaData->last_azimuth_fx );
      87             : 
      88       26490 :         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       25300 :         ELSE IF( LT_32( diff_fx, ISM_AZIMUTH_MIN_FX ) )
      95             :         {
      96         352 :             diff_fx = L_add( diff_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX ) );
      97             :         }
      98             : 
      99       26490 :         test();
     100       26490 :         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       24188 :         ELSE IF( GT_32( L_abs( diff_fx ), L_shl( CNG_MD_MAX_DIFF_AZIMUTH, Q22 ) ) )
     105             :         {
     106             :             Word32 temp;
     107        8619 :             IF( ( diff_fx > 0 ) )
     108             :             {
     109        5995 :                 temp = L_shl( CNG_MD_MAX_DIFF_AZIMUTH, Q22 );
     110             :             }
     111             :             ELSE
     112             :             {
     113        2624 :                 temp = L_negate( L_shl( CNG_MD_MAX_DIFF_AZIMUTH, Q22 ) );
     114             :             }
     115        8619 :             hIsmMetaData->azimuth_fx = L_add( hIsmMetaData->last_azimuth_fx, temp );
     116        8619 :             move32();
     117             :         }
     118       15569 :         ELSE IF( diff_fx != 0 )
     119             :         {
     120        4791 :             hIsmMetaData->azimuth_fx = hIsmMetaData->last_true_azimuth_fx;
     121        4791 :             move32();
     122             :         }
     123             : 
     124       26490 :         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       26490 :         diff_fx = L_sub( hIsmMetaData->last_true_elevation_fx, hIsmMetaData->last_elevation_fx );
     132             : 
     133       26490 :         test();
     134       26490 :         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       26459 :         ELSE IF( GT_32( L_abs( diff_fx ), L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 ) ) )
     139             :         {
     140             :             Word32 temp;
     141        3413 :             IF( ( diff_fx > 0 ) )
     142             :             {
     143        1599 :                 temp = L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 );
     144             :             }
     145             :             ELSE
     146             :             {
     147        1814 :                 temp = L_negate( L_shl( CNG_MD_MAX_DIFF_ELEVATION, Q22 ) );
     148             :             }
     149        3413 :             hIsmMetaData->elevation_fx = L_add( hIsmMetaData->last_elevation_fx, temp );
     150        3413 :             move32();
     151             :         }
     152             :     }
     153             : 
     154        8367 :     return;
     155             : }
     156             : 
     157             : 
     158             : /*-------------------------------------------------------------------------*
     159             :  * ivas_ism_metadata_dec()
     160             :  *
     161             :  * decode and dequantize ISM metadata
     162             :  *-------------------------------------------------------------------------*/
     163             : 
     164      117272 : 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      117272 :     Word16 k, 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      117272 :     move16();
     202             : 
     203      117272 :     push_wmops( "ism_meta_dec" );
     204             : 
     205             :     /* initialization */
     206      117272 :     ism_metadata_flag_global = 0;
     207      117272 :     move16();
     208      117272 :     nchan_transport_prev = *nchan_transport;
     209      117272 :     move16();
     210      117272 :     k = extract_l( Mpy_32_32_r( ism_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     211      117272 :     last_bit_pos = sub( k, 1 );
     212      117272 :     bstr_orig = st0->bit_stream;
     213      117272 :     next_bit_pos_orig = st0->next_bit_pos;
     214      117272 :     move16();
     215      117272 :     st0->next_bit_pos = 0;
     216      117272 :     move16();
     217      117272 :     ism_extmeta_bitstream = 0;
     218      117272 :     move16();
     219      117272 :     non_diegetic_flag_global = 0;
     220      117272 :     move16();
     221      117272 :     set16_fx( null_metadata_flag, 0, nchan_ism );
     222      117272 :     set16_fx( lowrate_metadata_flag, 0, nchan_ism );
     223             : 
     224             :     /* reverse the bitstream for easier reading of indices */
     225    21226232 :     FOR( i = 0; i < s_min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ )
     226             :     {
     227    21108960 :         bstr_meta[i] = st0->bit_stream[last_bit_pos - i];
     228    21108960 :         move16();
     229             :     }
     230      117272 :     st0->bit_stream = bstr_meta;
     231      117272 :     st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */
     232      117272 :     move32();
     233             : 
     234      117272 :     IF( !bfi )
     235             :     {
     236             :         /*----------------------------------------------------------------*
     237             :          * Read ISM common signaling
     238             :          *----------------------------------------------------------------*/
     239      116408 :         test();
     240      116408 :         IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     241             :         {
     242             :             /* number of objects was read in ivas_dec_setup() */
     243       19633 :             st0->next_bit_pos = add( st0->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ );
     244       19633 :             move32();
     245             :         }
     246       96775 :         ELSE IF( NE_32( ism_mode, ISM_MASA_MODE_DISC ) && NE_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     247             :         {
     248             :             /* number of objects was read in ivas_dec_setup() */
     249       91989 :             st0->next_bit_pos = add( st0->next_bit_pos, nchan_ism );
     250       91989 :             move16();
     251             : 
     252       91989 :             ism_mode = ivas_ism_mode_select( nchan_ism, ism_total_brate );
     253             :         }
     254             : 
     255      116408 :         IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     256             :         {
     257       15685 :             *nchan_transport = MAX_PARAM_ISM_WAVE;
     258       15685 :             move16();
     259             :         }
     260      100723 :         ELSE IF( EQ_32( ism_mode, ISM_MODE_DISC ) )
     261             :         {
     262       76304 :             *nchan_transport = nchan_ism;
     263       76304 :             move16();
     264             :         }
     265             : 
     266      116408 :         IF( NE_32( *nchan_transport, nchan_transport_prev ) )
     267             :         {
     268           0 :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" );
     269             :         }
     270             : 
     271             :         /* read extended metadata presence flag */
     272      116408 :         test();
     273      116408 :         test();
     274      116408 :         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 ) )
     275             :         {
     276       74280 :             ism_extmeta_bitstream = get_next_indice_fx( st0, ISM_EXTENDED_METADATA_BITS );
     277             : 
     278             :             /* read global non-diegetic object flag */
     279       74280 :             IF( ism_extmeta_bitstream )
     280             :             {
     281        8080 :                 non_diegetic_flag_global = get_next_indice_fx( st0, ISM_METADATA_IS_NDP_BITS );
     282             :             }
     283             :         }
     284             : 
     285             :         /* Apply hysteresis in case rate switching causes fluctuation in presence of extended metadata */
     286      116408 :         test();
     287      116408 :         IF( EQ_16( *ism_extmeta_active, -1 ) || EQ_16( *ism_extmeta_active, ism_extmeta_bitstream ) ) /* If first frame or bitstream matches internal state */
     288             :         {
     289      116211 :             *ism_extmeta_active = ism_extmeta_bitstream;
     290      116211 :             move16();
     291      116211 :             *ism_extmeta_cnt = 0;
     292      116211 :             move16();
     293             :         }
     294             :         ELSE
     295             :         {
     296         197 :             ( *ism_extmeta_cnt )++;
     297         197 :             IF( EQ_16( *ism_extmeta_cnt, ISM_METADATA_RS_MAX_FRAMES ) ) /* ISM_METADATA_RS_MAX_FRAMES change frames observed - update state */
     298             :             {
     299          39 :                 *ism_extmeta_active = ism_extmeta_bitstream;
     300          39 :                 move16();
     301          39 :                 *ism_extmeta_cnt = 0;
     302          39 :                 move16();
     303             :             }
     304             :         }
     305             : 
     306             :         /* Read ISM metadata flags (one per object) */
     307      423526 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     308             :         {
     309      307118 :             test();
     310      307118 :             IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     311             :             {
     312       61031 :                 ism_imp[ch] = get_next_indice_fx( st0, 1 );
     313       61031 :                 move16();
     314             :             }
     315      246087 :             ELSE IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     316             :             {
     317             :                 /* ISM importance flag is already read in ivas_masa_decode() */
     318        9401 :                 ism_imp[ch] = hIsmMeta[ch]->ism_imp;
     319        9401 :                 move16();
     320             :             }
     321             :             ELSE
     322             :             {
     323      236686 :                 ism_imp[ch] = get_next_indice_fx( st0, ISM_METADATA_FLAG_BITS );
     324      236686 :                 move16();
     325             :             }
     326             : 
     327      307118 :             IF( GT_16( ism_imp[ch], ISM_NO_META ) )
     328             :             {
     329      296678 :                 hIsmMeta[ch]->ism_metadata_flag = 1;
     330      296678 :                 move16();
     331             :             }
     332             :             ELSE
     333             :             {
     334       10440 :                 hIsmMeta[ch]->ism_metadata_flag = 0;
     335       10440 :                 move16();
     336             :             }
     337             : 
     338      307118 :             ism_metadata_flag_global = s_or( ism_metadata_flag_global, hIsmMeta[ch]->ism_metadata_flag );
     339             :         }
     340             : 
     341      142627 :         FOR( ; ch < nchan_ism; ch++ )
     342             :         {
     343       26219 :             hIsmMeta[ch]->ism_metadata_flag = 1;
     344       26219 :             move16();
     345       26219 :             ism_metadata_flag_global = s_or( ism_metadata_flag_global, hIsmMeta[ch]->ism_metadata_flag );
     346             :         }
     347             : 
     348             :         /* read ISM_NO_META class signalling */
     349      116408 :         test();
     350      116408 :         IF( EQ_32( ism_mode, ISM_MODE_DISC ) || EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     351             :         {
     352      362284 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     353             :             {
     354      266347 :                 IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
     355             :                 {
     356             :                     /* low-rate ISM_NO_META frame */
     357       10440 :                     test();
     358       10440 :                     IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     359             :                     {
     360           0 :                         null_metadata_flag[ch] = hIsmMeta[ch]->ism_md_null_flag;
     361           0 :                         move16();
     362             :                     }
     363             :                     ELSE
     364             :                     {
     365       10440 :                         null_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
     366       10440 :                         move16();
     367             :                     }
     368             :                 }
     369             :             }
     370             : 
     371      362284 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     372             :             {
     373      266347 :                 IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
     374             :                 {
     375       10440 :                     test();
     376       10440 :                     IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     377             :                     {
     378           0 :                         lowrate_metadata_flag[ch] = hIsmMeta[ch]->ism_md_lowrate_flag;
     379           0 :                         move16();
     380             : 
     381           0 :                         if ( null_metadata_flag[ch] == 0 )
     382             :                         {
     383           0 :                             ism_metadata_flag_global = s_or( ism_metadata_flag_global, lowrate_metadata_flag[ch] );
     384             :                         }
     385             :                     }
     386       10440 :                     ELSE IF( NE_32( ism_mode, ISM_SBA_MODE_DISC ) )
     387             :                     {
     388       10440 :                         IF( null_metadata_flag[ch] )
     389             :                         {
     390             :                             /* read the true ISM class */
     391        4670 :                             ism_imp[ch] = get_next_indice_fx( st0, ISM_METADATA_FLAG_BITS );
     392        4670 :                             move16();
     393             :                         }
     394             :                         ELSE
     395             :                         {
     396             :                             /* read presence of MD in low-rate ISM_NO_META frame flag */
     397        5770 :                             lowrate_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
     398        5770 :                             move16();
     399             : 
     400        5770 :                             ism_metadata_flag_global = s_or( ism_metadata_flag_global, lowrate_metadata_flag[ch] );
     401             :                         }
     402             :                     }
     403             :                 }
     404             :             }
     405             :         }
     406             : 
     407      116408 :         IF( ism_metadata_flag_global )
     408             :         {
     409             :             /*----------------------------------------------------------------*
     410             :              * Metadata decoding and dequantization, loop over all objects
     411             :              *----------------------------------------------------------------*/
     412             : 
     413      116391 :             Word16 total_bits_metadata = 0, bits_metadata_ism = 0;
     414      116391 :             move16();
     415      116391 :             move16();
     416             :             Word16 nb_bits_objcod_read;
     417             : 
     418      116391 :             IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     419             :             {
     420       15685 :                 nb_bits_start = st0->next_bit_pos;
     421       15685 :                 move16();
     422             :             }
     423             : 
     424      449693 :             FOR( ch = 0; ch < nchan_ism; ch++ )
     425             :             {
     426      333302 :                 hIsmMetaData = hIsmMeta[ch];
     427      333302 :                 test();
     428      333302 :                 test();
     429      333302 :                 test();
     430      333302 :                 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 ) )
     431             :                 {
     432      275713 :                     nb_bits_start = st0->next_bit_pos;
     433      275713 :                     move16();
     434             :                 }
     435      333302 :                 flag_abs_position = 0;
     436      333302 :                 move16();
     437      333302 :                 flag_abs_orientation = 0;
     438      333302 :                 move16();
     439      333302 :                 flag_abs_radius = 0;
     440      333302 :                 move16();
     441             : 
     442      333302 :                 test();
     443      333302 :                 IF( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
     444             :                 {
     445      328406 :                     IF( non_diegetic_flag_global )
     446             :                     {
     447             :                         /* read non-diegetic flag for each object */
     448        2415 :                         hIsmMetaData->non_diegetic_flag = get_next_indice_fx( st0, ISM_METADATA_IS_NDP_BITS );
     449        2415 :                         move16();
     450             :                     }
     451             :                     ELSE
     452             :                     {
     453      325991 :                         hIsmMetaData->non_diegetic_flag = 0;
     454      325991 :                         move16();
     455             :                     }
     456             : 
     457      328406 :                     IF( hIsmMetaData->non_diegetic_flag )
     458             :                     {
     459             :                         /* Panning gain decoding */
     460         805 :                         decode_angle_indices_fx( st0, &( hIsmMetaData->position_angle ), hIsmMetaData->non_diegetic_flag, &flag_abs_position );
     461         805 :                         idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx;
     462         805 :                         move16();
     463         805 :                         idx_angle2 = shl( 1, ( ISM_ELEVATION_NBITS - 1 ) );
     464             : 
     465             :                         /* Panning gain dequantization */
     466         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 ) );
     467         805 :                         hIsmMetaData->elevation_fx = 0;
     468         805 :                         move32();
     469         805 :                         move32();
     470             : 
     471             :                         /* save for smoothing metadata evolution */
     472         805 :                         hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
     473         805 :                         move32();
     474         805 :                         hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
     475         805 :                         move32();
     476             :                     }
     477             :                     ELSE
     478             :                     {
     479      327601 :                         decode_angle_indices_fx( st0, &( hIsmMetaData->position_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_position );
     480      327601 :                         idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx;
     481      327601 :                         move16();
     482      327601 :                         idx_angle2 = hIsmMetaData->position_angle.last_angle2_idx;
     483      327601 :                         move16();
     484             : 
     485             :                         /* Azimuth/Elevation dequantization */
     486      327601 :                         IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     487             :                         {
     488       57589 :                             hParamIsm->azi_index[ch] = idx_angle1;
     489       57589 :                             move16();
     490       57589 :                             hParamIsm->ele_index[ch] = idx_angle2;
     491       57589 :                             move16();
     492             :                         }
     493             :                         ELSE /* ISM_MODE_DISC */
     494             :                         {
     495      270012 :                             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 ) );
     496      270012 :                             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 ) );
     497      270012 :                             move32();
     498      270012 :                             move32();
     499             : 
     500             :                             /* radius/raw/pitch dequantization */
     501      270012 :                             IF( ism_extmeta_bitstream )
     502             :                             {
     503       25281 :                                 decode_angle_indices_fx( st0, &( hIsmMetaData->orientation_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_orientation );
     504       25281 :                                 idx_angle1 = hIsmMetaData->orientation_angle.last_angle1_idx;
     505       25281 :                                 move16();
     506       25281 :                                 idx_angle2 = hIsmMetaData->orientation_angle.last_angle2_idx;
     507       25281 :                                 move16();
     508       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 ) );
     509       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 ) );
     510             : 
     511       25281 :                                 idx_radius = decode_radius_fx( st0, &hIsmMetaData->last_radius_idx, &flag_abs_radius );
     512       25281 :                                 radius_fx = usdequant_fx( idx_radius, ISM_RADIUS_MIN_Q9, ISM_RADIUS_DELTA_Q8 );
     513       25281 :                                 IF( EQ_16( *ism_extmeta_active, 1 ) )
     514             :                                 {
     515       25041 :                                     hIsmMetaData->yaw_fx = yaw_fx;
     516       25041 :                                     move32();
     517       25041 :                                     hIsmMetaData->pitch_fx = pitch_fx;
     518       25041 :                                     move32();
     519       25041 :                                     hIsmMetaData->radius_fx = radius_fx;
     520       25041 :                                     move16();
     521             :                                 }
     522             :                             }
     523             :                             ELSE
     524             :                             {
     525      244731 :                                 IF( *ism_extmeta_active == 0 )
     526             :                                 {
     527      244659 :                                     hIsmMetaData->yaw_fx = 0;
     528      244659 :                                     move32();
     529      244659 :                                     hIsmMetaData->pitch_fx = 0;
     530      244659 :                                     move32();
     531      244659 :                                     hIsmMetaData->radius_fx = 512; /* 1.0f in Q9 */
     532      244659 :                                     move16();
     533             :                                 }
     534             :                             }
     535             :                         }
     536             :                         /* save for smoothing metadata evolution */
     537      327601 :                         hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
     538      327601 :                         move32();
     539      327601 :                         hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
     540      327601 :                         move32();
     541             :                     }
     542             :                 }
     543             :                 /* save number of metadata bits read */
     544      333302 :                 test();
     545      333302 :                 test();
     546      333302 :                 test();
     547      333302 :                 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 ) )
     548             :                 {
     549      275713 :                     nb_bits_metadata[ch] = sub( st0->next_bit_pos, nb_bits_start );
     550      275713 :                     move16();
     551             :                 }
     552             :             }
     553             : 
     554      116391 :             IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     555             :             {
     556       15685 :                 hParamIsm->flag_noisy_speech = get_next_indice_fx( st0, 1 );
     557       15685 :                 move16();
     558             : 
     559             :                 /* Loop over multiwave to read the object indices from bitstream */
     560       47055 :                 FOR( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ )
     561             :                 {
     562      376440 :                     FOR( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
     563             :                     {
     564      690140 :                         FOR( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
     565             :                         {
     566      345070 :                             hParamIsm->obj_indices[nbands][nblocks][ch] = get_next_indice_fx( st0, PARAM_ISM_OBJ_IND_NBITS );
     567      345070 :                             move16();
     568             :                         }
     569             :                     }
     570             :                 }
     571             : 
     572             :                 /* Loop over all bands to read power ratio's from bitstream */
     573      188220 :                 FOR( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
     574             :                 {
     575      345070 :                     FOR( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
     576             :                     {
     577      172535 :                         hParamIsm->power_ratios_idx[nbands][nblocks] = get_next_indice_fx( st0, PARAM_ISM_POW_RATIO_NBITS );
     578      172535 :                         move16();
     579             :                     }
     580             :                 }
     581             : 
     582             :                 /* save number of metadata bits read */
     583       15685 :                 total_bits_metadata = sub( st0->next_bit_pos, nb_bits_start );
     584             : 
     585             :                 /* bits per ISM*/
     586             : 
     587             :                 // total_bits_metadata / *nchan_transport
     588             :                 Word16 tmp, tmp_e;
     589       15685 :                 tmp = BASOP_Util_Divide1616_Scale( total_bits_metadata, *nchan_transport, &tmp_e );
     590       15685 :                 bits_metadata_ism = shr( tmp, sub( 15, tmp_e ) ); // Q0
     591             : 
     592       15685 :                 nb_bits_objcod_read = 0;
     593       15685 :                 move16();
     594       47055 :                 FOR( ch = 0; ch < *nchan_transport; ch++ )
     595             :                 {
     596       31370 :                     IF( EQ_16( ch, sub( *nchan_transport, 1 ) ) )
     597             :                     {
     598       15685 :                         nb_bits_metadata[ch] = sub( total_bits_metadata, nb_bits_objcod_read );
     599       15685 :                         move16();
     600             :                     }
     601             :                     ELSE
     602             :                     {
     603       15685 :                         nb_bits_metadata[ch] = bits_metadata_ism;
     604       15685 :                         move16();
     605       15685 :                         nb_bits_objcod_read = add( nb_bits_objcod_read, bits_metadata_ism );
     606             :                     }
     607             :                 }
     608             :             }
     609             :         }
     610             :         ELSE
     611             :         {
     612          17 :             set16_fx( nb_bits_metadata, 0, *nchan_transport );
     613             :         }
     614             :     }
     615             :     ELSE /* BFI */
     616             :     {
     617        3085 :         FOR( ch = 0; ch < nchan_ism; ch++ )
     618             :         {
     619        2221 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     620        2221 :             move16();
     621             :         }
     622             : 
     623         864 :         set16_fx( nb_bits_metadata, 0, *nchan_transport );
     624             : 
     625         864 :         IF( EQ_32( ism_mode, ISM_MODE_PARAM ) )
     626             :         {
     627        1075 :             FOR( ch = 0; ch < nchan_ism; ch++ )
     628             :             {
     629         840 :                 hParamIsm->azi_index[ch] = add( hParamIsm->azi_index[ch], i_mult2( hParamIsm->last_az_sgn[ch], hParamIsm->last_az_diff[ch] ) ); // Q0
     630         840 :                 move16();
     631         840 :                 hParamIsm->ele_index[ch] = add( hParamIsm->ele_index[ch], i_mult2( hParamIsm->last_el_sgn[ch], hParamIsm->last_el_diff[ch] ) ); // Q0
     632         840 :                 move16();
     633         840 :                 hIsmMeta[ch]->position_angle.last_angle1_idx = hParamIsm->azi_index[ch];
     634         840 :                 move16();
     635         840 :                 hIsmMeta[ch]->position_angle.last_angle2_idx = hParamIsm->ele_index[ch];
     636         840 :                 move16();
     637             :             }
     638             :         }
     639             :     }
     640             : 
     641      117272 :     IF( LT_16( hISMDTX.ism_dtx_hangover_cnt, IVAS_ISM_DTX_HO_MAX ) )
     642             :     {
     643        6254 :         ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
     644        6254 :         hISMDTX.ism_dtx_hangover_cnt = add( hISMDTX.ism_dtx_hangover_cnt, 1 );
     645        6254 :         move16();
     646             :     }
     647             : 
     648      117272 :     IF( EQ_32( ism_mode, ISM_SBA_MODE_DISC ) )
     649             :     {
     650             :         /* set the bitstream pointer to its original position */
     651       19680 :         nb_bits_metadata[0] = st0->next_bit_pos;
     652       19680 :         move16();
     653       19680 :         st0->bit_stream = bstr_orig;
     654       19680 :         st0->next_bit_pos = next_bit_pos_orig;
     655       19680 :         move16();
     656             : 
     657             :         /* updates*/
     658       19680 :         set16_fx( md_diff_flag, 1, nchan_ism );
     659             : 
     660       19680 :         update_last_metadata_fx( nchan_ism, hIsmMeta, md_diff_flag );
     661       19680 :         pop_wmops();
     662       19680 :         return IVAS_ERR_OK;
     663             :     }
     664             : 
     665       97592 :     test();
     666       97592 :     if ( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     667             :     {
     668        4867 :         ism_metadata_flag_global = 1;
     669        4867 :         move16();
     670             :     }
     671             : 
     672             :     /*----------------------------------------------------------------*
     673             :      * Configuration and decision about bitrates per channel
     674             :      *----------------------------------------------------------------*/
     675             : 
     676       97592 :     IF( !bfi )
     677             :     {
     678       96775 :         Word16 masa_ism_flag = 0;
     679       96775 :         move16();
     680       96775 :         test();
     681       96775 :         IF( EQ_32( ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     682             :         {
     683        4786 :             masa_ism_flag = 1;
     684        4786 :             move16();
     685             : 
     686       14187 :             FOR( ch = 0; ch < *nchan_transport; ch++ )
     687             :             {
     688        9401 :                 element_brate[ch] = hSCE[ch]->element_brate;
     689        9401 :                 move32();
     690             :             }
     691             :         }
     692             : 
     693       96775 :         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 ) )
     694             :         {
     695           0 :             return error;
     696             :         }
     697             : 
     698      342862 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     699             :         {
     700      246087 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     701      246087 :             move16();
     702             : 
     703      246087 :             hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
     704      246087 :             move16();
     705      246087 :             test();
     706      246087 :             test();
     707      246087 :             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 ) )
     708             :             {
     709      214717 :                 test();
     710      214717 :                 test();
     711      214717 :                 test();
     712      214717 :                 test();
     713      220814 :                 if ( ism_imp[ch] == ISM_NO_META && ( ( LT_32( total_brate[ch], ACELP_8k00 ) && LT_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) ||
     714       11475 :                                                      ( LE_32( total_brate[ch], ACELP_16k_LOW_LIMIT ) && GE_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) ) )
     715             :                 {
     716        6728 :                     hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
     717        6728 :                     move16();
     718             :                 }
     719             :             }
     720             : 
     721      246087 :             test();
     722      246087 :             if ( NE_32( ism_mode, ISM_MASA_MODE_DISC ) && NE_32( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     723             :             {
     724      236686 :                 hSCE[ch]->element_brate = element_brate[ch];
     725      236686 :                 move32();
     726             :             }
     727      246087 :             hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
     728      246087 :             move32();
     729             :         }
     730             : 
     731      122994 :         FOR( ; ch < nchan_ism; ch++ )
     732             :         {
     733       26219 :             hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     734       26219 :             move16();
     735             :         }
     736             :     }
     737             :     ELSE
     738             :     {
     739        2539 :         FOR( ch = 0; ch < *nchan_transport; ch++ )
     740             :         {
     741        1722 :             hSCE[ch]->element_brate = hSCE[ch]->last_element_brate;
     742        1722 :             move32();
     743        1722 :             hSCE[ch]->hCoreCoder[0]->total_brate = hSCE[ch]->hCoreCoder[0]->last_total_brate;
     744        1722 :             move32();
     745             :         }
     746             :     }
     747             : 
     748             :     /*----------------------------------------------------------------*
     749             :      * Set bitsream pointers
     750             :      *----------------------------------------------------------------*/
     751             : 
     752             :     /* set the bitstream pointer to its original position */
     753       97592 :     st0->bit_stream = bstr_orig;
     754       97592 :     st0->next_bit_pos = next_bit_pos_orig;
     755       97592 :     move16();
     756             : 
     757             :     /* set bitstream pointers for each ISM */
     758      247809 :     FOR( ch = 1; ch < *nchan_transport; ch++ )
     759             :     {
     760      150217 :         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 ) ) );
     761             :     }
     762             : 
     763             :     /*----------------------------------------------------------------*
     764             :      * Updates
     765             :      *----------------------------------------------------------------*/
     766             : 
     767       97592 :     set16_fx( md_diff_flag, 1, nchan_ism );
     768             : 
     769       97592 :     update_last_metadata_fx( nchan_ism, hIsmMeta, md_diff_flag );
     770             : 
     771      345401 :     FOR( ch = 0; ch < *nchan_transport; ch++ )
     772             :     {
     773      247809 :         hSCE[ch]->hCoreCoder[0]->cng_ism_flag = 0;
     774      247809 :         move16();
     775             :     }
     776             : 
     777       97592 :     pop_wmops();
     778             : 
     779       97592 :     return IVAS_ERR_OK;
     780             : }
     781             : 
     782             : 
     783             : /*-------------------------------------------------------------------*
     784             :  * ivas_ism_reset_metadata_handle_dec()
     785             :  *
     786             :  * Reset ISM decoder metadata handle
     787             :  *-------------------------------------------------------------------*/
     788             : 
     789        3038 : void ivas_ism_reset_metadata_handle_dec_fx(
     790             :     ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle     */
     791             : )
     792             : {
     793        3038 :     hIsmMeta->last_ism_metadata_flag = 0;
     794        3038 :     move16();
     795        3038 :     hIsmMeta->position_angle.last_angle1_idx = 0;
     796        3038 :     move16();
     797        3038 :     hIsmMeta->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 );
     798        3038 :     move16();
     799        3038 :     hIsmMeta->orientation_angle.last_angle1_idx = 0;
     800        3038 :     move16();
     801        3038 :     hIsmMeta->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 );
     802        3038 :     move16();
     803        3038 :     hIsmMeta->last_radius_idx = 8; /* Init to radius 1.0 */
     804        3038 :     move16();
     805             : 
     806        3038 :     hIsmMeta->last_true_azimuth_fx = 0;
     807        3038 :     move32();
     808        3038 :     hIsmMeta->last_true_elevation_fx = 0;
     809        3038 :     move32();
     810        3038 :     hIsmMeta->last_azimuth_fx = 0;
     811        3038 :     move32();
     812        3038 :     hIsmMeta->last_elevation_fx = 0;
     813        3038 :     move32();
     814             : 
     815        3038 :     hIsmMeta->ism_imp = -1;
     816        3038 :     move16();
     817        3038 :     hIsmMeta->ism_md_null_flag = 0;
     818        3038 :     move16();
     819        3038 :     hIsmMeta->ism_md_lowrate_flag = 0;
     820        3038 :     move16();
     821             : 
     822        3038 :     ivas_ism_reset_metadata( hIsmMeta );
     823             : 
     824        3038 :     return;
     825             : }
     826             : 
     827             : 
     828             : /*-------------------------------------------------------------------------
     829             :  * ivas_ism_metadata_dec_create()
     830             :  *
     831             :  * Create, allocate, initialize and configure IVAS decoder ISM metadata handles
     832             :  *-------------------------------------------------------------------------*/
     833             : 
     834         901 : ivas_error ivas_ism_metadata_dec_create_fx(
     835             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder structure               */
     836             :     const Word16 n_ISms,       /* i  : number of separately coded objects   */
     837             :     Word32 element_brate_tmp[] /* o  : element bitrate per object           */
     838             : )
     839             : {
     840             :     Word16 ch;
     841             :     ivas_error error;
     842             : 
     843             :     /* allocate ISM metadata handles */
     844        3201 :     FOR( ch = 0; ch < n_ISms; ch++ )
     845             :     {
     846        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' */
     847             :         {
     848        2073 :             IF( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL )
     849             :             {
     850           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) );
     851             :             }
     852             :         }
     853             : 
     854        2300 :         ivas_ism_reset_metadata_handle_dec_fx( st_ivas->hIsmMetaData[ch] );
     855             :     }
     856             : 
     857             :     /* sanity freeing - it can happen only in reconfiguration when a smaller number of handles than before is requested */
     858        2205 :     FOR( ; ch < MAX_NUM_OBJECTS; ch++ )
     859             :     {
     860        1304 :         IF( st_ivas->hIsmMetaData[ch] != NULL )
     861             :         {
     862           0 :             free( st_ivas->hIsmMetaData[ch] );
     863           0 :             st_ivas->hIsmMetaData[ch] = NULL;
     864             :         }
     865             :     }
     866             : 
     867         901 :     IF( element_brate_tmp != NULL )
     868             :     {
     869         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 ) )
     870             :         {
     871           0 :             return error;
     872             :         }
     873             :     }
     874             : 
     875         901 :     st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX;
     876         901 :     move16();
     877             : 
     878         901 :     return IVAS_ERR_OK;
     879             : }
     880             : 
     881             : 
     882             : /*-------------------------------------------------------------------------
     883             :  * decode_angle_indices()
     884             :  *
     885             :  * Decoding of a position/orientation angle
     886             :  *-------------------------------------------------------------------------*/
     887             : 
     888      353687 : static void decode_angle_indices_fx(
     889             :     DEC_CORE_HANDLE st0,             /* i/o: bitstream handle                */
     890             :     ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle                    */
     891             :     const Word16 non_diegetic_flag,  /* i  : Non diegetic flag               */
     892             :     Word16 *flag_abs_angle1          /* o  : Azimuth/yaw encoding mode       */
     893             : )
     894             : {
     895             :     Word16 idx_angle1, nbits_diff_angle1, diff, sgn;
     896             :     Word16 idx_angle2, nbits_diff_angle2;
     897             : 
     898             :     /*----------------------------------------------------------------*
     899             :      * Azimuth/yaw decoding and dequantization
     900             :      *----------------------------------------------------------------*/
     901             : 
     902             :     /* Decode azimuth/yaw index */
     903      353687 :     IF( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* azimuth_abs_flag */
     904             :     {
     905      110750 :         idx_angle1 = get_next_indice_fx( st0, ISM_AZIMUTH_NBITS );
     906      110750 :         *flag_abs_angle1 = 1;
     907      110750 :         move16();
     908             :     }
     909             :     ELSE
     910             :     {
     911      242937 :         diff = 0;
     912      242937 :         move16();
     913      242937 :         sgn = 1;
     914      242937 :         move16();
     915             : 
     916      242937 :         IF( get_next_indice_fx( st0, 1 ) == 0 )
     917             :         {
     918       55586 :             nbits_diff_angle1 = 1;
     919       55586 :             move16();
     920             :         }
     921             :         ELSE
     922             :         {
     923      187351 :             nbits_diff_angle1 = 1;
     924      187351 :             move16();
     925             : 
     926      187351 :             if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
     927             :             {
     928       60454 :                 sgn = -1;
     929       60454 :                 move16();
     930             :             }
     931             : 
     932      187351 :             nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     933             : 
     934             :             /* read until the stop bit */
     935      537235 :             WHILE( nbits_diff_angle1 < ( ISM_AZIMUTH_NBITS - 1 ) && get_next_indice_fx( st0, 1 ) == 1 )
     936             :             {
     937      349884 :                 diff = add( diff, 1 );
     938      349884 :                 nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     939             :             }
     940             : 
     941      187351 :             if ( LT_16( nbits_diff_angle1, ( ISM_AZIMUTH_NBITS - 1 ) ) )
     942             :             {
     943             :                 /* count stop bit */
     944      171383 :                 nbits_diff_angle1 = add( nbits_diff_angle1, 1 );
     945             :             }
     946             :         }
     947      242937 :         idx_angle1 = add( angle->last_angle1_idx, i_mult2( sgn, diff ) );
     948             :     }
     949             : 
     950             :     /* azimuth/yaw is on a circle - check for diff coding for -180° -> 180° and vice versa changes */
     951      353687 :     IF( GT_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     952             :     {
     953          10 :         idx_angle1 = sub( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ); /* +180° -> -180° */
     954             :     }
     955      353677 :     ELSE IF( idx_angle1 < 0 )
     956             :     {
     957        1212 :         idx_angle1 = add( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ); /* -180° -> +180° */
     958             :     }
     959             : 
     960             :     /* +180° == -180° */
     961      353687 :     if ( EQ_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     962             :     {
     963        3054 :         idx_angle1 = 0;
     964        3054 :         move16();
     965             :     }
     966             : 
     967             :     /* sanity check in case of FER or BER */
     968      353687 :     test();
     969      353687 :     if ( ( idx_angle1 < 0 ) || GT_16( idx_angle1, ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) )
     970             :     {
     971           0 :         idx_angle1 = angle->last_angle1_idx;
     972           0 :         move16();
     973             :     }
     974             : 
     975             :     /*----------------------------------------------------------------*
     976             :      * Elevation/pitch decoding and dequantization
     977             :      *----------------------------------------------------------------*/
     978             : 
     979      353687 :     IF( non_diegetic_flag == 0 )
     980             :     {
     981             :         /* Decode elevation/pitch index */
     982      352882 :         test();
     983      352882 :         IF( ( *flag_abs_angle1 == 0 ) && EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* elevation_abs_flag */
     984             :         {
     985       30150 :             idx_angle2 = get_next_indice_fx( st0, ISM_ELEVATION_NBITS );
     986             :         }
     987             :         ELSE
     988             :         {
     989      322732 :             diff = 0;
     990      322732 :             move16();
     991      322732 :             sgn = 1;
     992      322732 :             move16();
     993             : 
     994      322732 :             IF( get_next_indice_fx( st0, 1 ) == 0 )
     995             :             {
     996      133515 :                 nbits_diff_angle2 = 1;
     997      133515 :                 move16();
     998             :             }
     999             :             ELSE
    1000             :             {
    1001      189217 :                 nbits_diff_angle2 = 1;
    1002      189217 :                 move16();
    1003             : 
    1004      189217 :                 if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
    1005             :                 {
    1006       94892 :                     sgn = -1;
    1007       94892 :                     move16();
    1008             :                 }
    1009             : 
    1010      189217 :                 nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
    1011             : 
    1012             :                 /* read until the stop bit */
    1013      673107 :                 WHILE( ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) && ( get_next_indice_fx( st0, 1 ) == 1 ) )
    1014             :                 {
    1015      483890 :                     diff = add( diff, 1 );
    1016      483890 :                     nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
    1017             :                 }
    1018             : 
    1019      189217 :                 if ( LT_16( nbits_diff_angle2, ISM_ELEVATION_NBITS ) )
    1020             :                 {
    1021             :                     /* count stop bit */
    1022      126916 :                     nbits_diff_angle2 = add( nbits_diff_angle2, 1 );
    1023             :                 }
    1024             :             }
    1025             : 
    1026      322732 :             idx_angle2 = add( angle->last_angle2_idx, i_mult( sgn, diff ) );
    1027             :         }
    1028             : 
    1029             :         /* sanity check in case of FER or BER */
    1030      352882 :         test();
    1031      352882 :         if ( ( idx_angle2 < 0 ) || GT_16( idx_angle2, ( ( 1 << ISM_ELEVATION_NBITS ) - 1 ) ) )
    1032             :         {
    1033           0 :             idx_angle2 = angle->last_angle2_idx;
    1034           0 :             move16();
    1035             :         }
    1036             :     }
    1037             :     ELSE
    1038             :     {
    1039         805 :         idx_angle2 = angle->last_angle2_idx; /* second MD parameter is not transmitted for non-diegetic object */
    1040         805 :         move16();
    1041             :     }
    1042             : 
    1043             :     /*----------------------------------------------------------------*
    1044             :      * Final updates
    1045             :      *----------------------------------------------------------------*/
    1046             : 
    1047      353687 :     angle->last_angle2_idx = idx_angle2;
    1048      353687 :     move16();
    1049      353687 :     angle->last_angle1_idx = idx_angle1;
    1050      353687 :     move16();
    1051             : 
    1052      353687 :     return;
    1053             : }
    1054             : 
    1055             : 
    1056             : /*-------------------------------------------------------------------------
    1057             :  * decode_radius()
    1058             :  *
    1059             :  * Radius decoding and dequantization
    1060             :  *-------------------------------------------------------------------------*/
    1061             : 
    1062       25281 : static Word16 decode_radius_fx(
    1063             :     DEC_CORE_HANDLE st0,     /* i/o: bitstream handle           */
    1064             :     Word16 *last_radius_idx, /* i/o: last radius index          */
    1065             :     Word16 *flag_abs_radius  /* o  : Radius encoding mode       */
    1066             : )
    1067             : {
    1068             :     Word16 idx_radius, nbits_diff_radius, diff, sgn;
    1069             : 
    1070             :     /* Decode radius index */
    1071       25281 :     IF( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* elevation_abs_flag */
    1072             :     {
    1073        7094 :         *flag_abs_radius = 1;
    1074        7094 :         move16();
    1075        7094 :         idx_radius = get_next_indice_fx( st0, ISM_RADIUS_NBITS );
    1076             :     }
    1077             :     ELSE
    1078             :     {
    1079       18187 :         diff = 0;
    1080       18187 :         move16();
    1081       18187 :         sgn = 1;
    1082       18187 :         move16();
    1083             : 
    1084       18187 :         IF( get_next_indice_fx( st0, 1 ) == 0 )
    1085             :         {
    1086       15121 :             nbits_diff_radius = 1;
    1087       15121 :             move16();
    1088             :         }
    1089             :         ELSE
    1090             :         {
    1091        3066 :             nbits_diff_radius = 1;
    1092        3066 :             move16();
    1093             : 
    1094        3066 :             if ( EQ_16( get_next_indice_fx( st0, 1 ), 1 ) ) /* negative sign */
    1095             :             {
    1096        1416 :                 sgn = -1;
    1097        1416 :                 move16();
    1098             :             }
    1099             : 
    1100        3066 :             nbits_diff_radius = add( nbits_diff_radius, 1 );
    1101             : 
    1102             :             /* read until the stop bit */
    1103        6922 :             WHILE( ( nbits_diff_radius < ISM_RADIUS_NBITS ) && ( get_next_indice_fx( st0, 1 ) == 1 ) )
    1104             :             {
    1105        3856 :                 diff = add( diff, 1 );
    1106        3856 :                 nbits_diff_radius = add( nbits_diff_radius, 1 );
    1107             :             }
    1108             : 
    1109        3066 :             IF( LT_16( nbits_diff_radius, ISM_RADIUS_NBITS ) )
    1110             :             {
    1111             :                 /* count stop bit */
    1112        2883 :                 nbits_diff_radius = add( nbits_diff_radius, 1 );
    1113             :             }
    1114             :         }
    1115       18187 :         idx_radius = add( *last_radius_idx, i_mult2( sgn, diff ) );
    1116             :     }
    1117             : 
    1118             :     /* sanity check in case of FER or BER */
    1119       25281 :     test();
    1120       25281 :     if ( ( idx_radius < 0 ) || GT_16( idx_radius, ( 1 << ISM_RADIUS_NBITS ) - 1 ) )
    1121             :     {
    1122           0 :         idx_radius = *last_radius_idx;
    1123           0 :         move16();
    1124             :     }
    1125             : 
    1126             :     /* Final updates */
    1127       25281 :     *last_radius_idx = idx_radius;
    1128       25281 :     move16();
    1129             : 
    1130       25281 :     return idx_radius;
    1131             : }
    1132             : 
    1133             : 
    1134             : /*-------------------------------------------------------------------*
    1135             :  * ivas_ism_metadata_sid_dec()
    1136             :  *
    1137             :  * Decode ISM metadata in SID frame
    1138             :  *-------------------------------------------------------------------*/
    1139             : 
    1140        2113 : void ivas_ism_metadata_sid_dec_fx(
    1141             :     SCE_DEC_HANDLE hSCE[MAX_SCE],   /* i/o: SCE decoder structure       */
    1142             :     const Word32 ism_total_brate,   /* i  : ISM total bitrate           */
    1143             :     const Word16 bfi,               /* i  : bfi flag                    */
    1144             :     const Word16 nchan_ism,         /* i  : number of objects           */
    1145             :     const Word16 nchan_transport,   /* i  : number of transport channels*/
    1146             :     const ISM_MODE ism_mode,        /* i  : ISM mode                    */
    1147             :     Word16 *flag_noisy_speech,      /* o  : noisy speech flag           */
    1148             :     Word16 *sce_id_dtx,             /* o  : SCE DTX ID                  */
    1149             :     ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles        */
    1150             :     Word16 nb_bits_metadata[]       /* o  : number of metadata bits     */
    1151             : )
    1152             : {
    1153             :     Word16 i, ch, last_bit_pos;
    1154             :     Word32 q_step_fx, q_step_border_fx;
    1155             :     Word16 idx, idx_azimuth, idx_elevation;
    1156             :     Word16 nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
    1157             :     Word16 md_diff_flag[MAX_NUM_OBJECTS];
    1158             :     ISM_MODE ism_mode_bstr;
    1159             :     DEC_CORE_HANDLE st0;
    1160             :     ISM_METADATA_HANDLE hIsmMetaData;
    1161             :     Word16 next_bit_pos_orig;
    1162             :     UWord16 bstr_meta[IVAS_SID_5k2 / FRAMES_PER_SEC], *bstr_orig;
    1163             : 
    1164        2113 :     IF( ism_total_brate == FRAME_NO_DATA )
    1165             :     {
    1166        1582 :         ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
    1167             : 
    1168        1582 :         return;
    1169             :     }
    1170             : 
    1171             :     /* initialization */
    1172         531 :     st0 = hSCE[0]->hCoreCoder[0];
    1173             : 
    1174         531 :     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 ) ) );
    1175         531 :     bstr_orig = st0->bit_stream;
    1176         531 :     next_bit_pos_orig = st0->next_bit_pos;
    1177         531 :     move16();
    1178         531 :     st0->next_bit_pos = 0;
    1179         531 :     move16();
    1180             : 
    1181             :     /* reverse the bitstream for easier reading of indices */
    1182       53631 :     FOR( i = 0; i < s_min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ )
    1183             :     {
    1184       53100 :         bstr_meta[i] = st0->bit_stream[last_bit_pos - i];
    1185       53100 :         move16();
    1186             :     }
    1187         531 :     st0->bit_stream = bstr_meta;
    1188         531 :     st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */
    1189         531 :     move32();
    1190             : 
    1191         531 :     IF( !bfi )
    1192             :     {
    1193             :         /*----------------------------------------------------------------*
    1194             :          * ISm common signaling
    1195             :          *----------------------------------------------------------------*/
    1196             : 
    1197             :         /* number of objects was already read in ivas_ism_get_dtx_dec() */
    1198             :         /* update the position in the bitstream */
    1199         531 :         st0->next_bit_pos = add( st0->next_bit_pos, nchan_ism );
    1200         531 :         move16();
    1201             :         /* read SID metadata flag( one per object ) */
    1202        2283 :         FOR( ch = 0; ch < nchan_ism; ch++ )
    1203             :         {
    1204        1752 :             md_diff_flag[ch] = get_next_indice_fx( st0, 1 );
    1205        1752 :             move16();
    1206             :         }
    1207             : 
    1208             :         /*----------------------------------------------------------------*
    1209             :          * Set quantization bits based on the number of coded objects
    1210             :          *----------------------------------------------------------------*/
    1211             : 
    1212         531 :         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 );
    1213             : 
    1214             :         /*----------------------------------------------------------------*
    1215             :          * Spatial parameters, loop over TCs - 1
    1216             :          *----------------------------------------------------------------*/
    1217             : 
    1218         531 :         *flag_noisy_speech = 0;
    1219         531 :         move16();
    1220         531 :         *sce_id_dtx = 0;
    1221         531 :         move16();
    1222             : 
    1223             :         /* read ISM mode flag to explicitly signal number of spatial parameters */
    1224         531 :         IF( GT_16( nchan_ism, 2 ) )
    1225             :         {
    1226         372 :             idx = get_next_indice_fx( st0, 1 );
    1227         372 :             ism_mode_bstr = (ISM_MODE) add( idx, 1 );
    1228             :             /* note: ISM mode was already read and used for configuration in in ivas_ism_dtx_dec() */
    1229             : 
    1230         372 :             IF( EQ_32( ism_mode_bstr, ISM_MODE_PARAM ) )
    1231             :             {
    1232             :                 /* read noisy speech flag */
    1233          94 :                 *flag_noisy_speech = get_next_indice_fx( st0, 1 );
    1234          94 :                 move16();
    1235          94 :                 nBits_sce_id = 1;
    1236          94 :                 move16();
    1237             :             }
    1238             :         }
    1239             : 
    1240         531 :         IF( GT_16( nchan_transport, 1 ) )
    1241             :         {
    1242             :             /* read sce id */
    1243         477 :             *sce_id_dtx = get_next_indice_fx( st0, nBits_sce_id );
    1244         477 :             move16();
    1245             :             /* decode the coherence */
    1246        1987 :             FOR( ch = 0; ch < nchan_transport; ch++ )
    1247             :             {
    1248        1510 :                 IF( EQ_16( ch, *sce_id_dtx ) )
    1249             :                 {
    1250         477 :                     hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = 32767; // 1.0f in Q15
    1251         477 :                     move16();
    1252         477 :                     CONTINUE;
    1253             :                 }
    1254             : 
    1255        1033 :                 idx = get_next_indice_fx( st0, nBits_coh );
    1256        1033 :                 hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = div_s( idx, sub( ( shl( 1, nBits_coh ) ), 1 ) ); // Q15
    1257        1033 :                 move16();
    1258             :             }
    1259             :         }
    1260             : 
    1261         531 :         if ( EQ_32( ism_mode, ISM_MODE_PARAM ) )
    1262             :         {
    1263          94 :             hSCE[*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = hSCE[!*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx;
    1264          94 :             move16();
    1265             :         }
    1266             : 
    1267             :         /*----------------------------------------------------------------*
    1268             :          * Metadata decoding and dequantization, loop over all objects
    1269             :          *----------------------------------------------------------------*/
    1270             : 
    1271        2283 :         FOR( ch = 0; ch < nchan_ism; ch++ )
    1272             :         {
    1273        1752 :             hIsmMetaData = hIsmMeta[ch];
    1274        1752 :             IF( EQ_16( md_diff_flag[ch], 1 ) )
    1275             :             {
    1276             :                 /* Azimuth decoding */
    1277         627 :                 idx_azimuth = get_next_indice_fx( st0, nBits_azimuth );
    1278         627 :                 hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_azimuth, ism_azimuth_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_azimuth );
    1279         627 :                 move32();
    1280             :                 /* Elevation decoding */
    1281         627 :                 idx_elevation = get_next_indice_fx( st0, nBits_elevation );
    1282         627 :                 hIsmMetaData->elevation_fx = ism_dequant_meta_fx( idx_elevation, ism_elevation_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_elevation );
    1283         627 :                 move32();
    1284             :                 /* update last indexes to correspond to active frames coding */
    1285         627 :                 IF( GT_16( nBits_azimuth, ISM_AZIMUTH_NBITS ) )
    1286             :                 {
    1287         209 :                     hIsmMetaData->position_angle.last_angle1_idx = shr( idx_azimuth, sub( nBits_azimuth, ISM_AZIMUTH_NBITS ) );
    1288         209 :                     move16();
    1289         209 :                     hIsmMetaData->position_angle.last_angle2_idx = shr( idx_elevation, sub( nBits_elevation, ISM_ELEVATION_NBITS ) );
    1290         209 :                     move16();
    1291             :                 }
    1292             :                 ELSE
    1293             :                 {
    1294         418 :                     hIsmMetaData->position_angle.last_angle1_idx = shl( idx_azimuth, sub( ISM_AZIMUTH_NBITS, nBits_azimuth ) );
    1295         418 :                     move16();
    1296         418 :                     hIsmMetaData->position_angle.last_angle2_idx = shl( idx_elevation, sub( ISM_ELEVATION_NBITS, nBits_elevation ) );
    1297         418 :                     move16();
    1298             :                 }
    1299             : 
    1300             :                 /* save for smoothing metadata evolution */
    1301         627 :                 hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx;
    1302         627 :                 move32();
    1303         627 :                 hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx;
    1304         627 :                 move32();
    1305             :             }
    1306             :         }
    1307             : 
    1308             :         /* take into account padding bits as metadata bits to keep later bitrate checks valid */
    1309         531 :         nb_bits_metadata[*sce_id_dtx] = extract_l( Mpy_32_32_r( IVAS_SID_5k2 - SID_2k40, ONE_BY_FRAMES_PER_SEC_Q31 ) );
    1310         531 :         move16();
    1311             : 
    1312             :         /* set the bitstream pointer to its original position */
    1313         531 :         st0->bit_stream = bstr_orig;
    1314         531 :         st0->next_bit_pos = next_bit_pos_orig;
    1315         531 :         move16();
    1316             :     }
    1317             : 
    1318             :     /* smooth the metadata evolution */
    1319         531 :     ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism );
    1320             : 
    1321         531 :     return;
    1322             : }

Generated by: LCOV version 1.14