LCOV - code coverage report
Current view: top level - lib_enc - ivas_ism_metadata_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 452 475 95.2 %
Date: 2025-05-23 08:37:30 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 <stdio.h>
      35             : #include <string.h>
      36             : #include "options.h"
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_prot.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "prot.h"
      41             : #include <math.h>
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : 
      48             : /*-----------------------------------------------------------------------*
      49             :  * Local constants
      50             :  *-----------------------------------------------------------------------*/
      51             : 
      52             : #define ISM_NUM_PARAM 5 /* number of coded metadata parameters */
      53             : 
      54             : #define ISM_MAX_AZIMUTH_DIFF_IDX   ( ISM_AZIMUTH_NBITS - 1 /*zero*/ - 1 /*sign*/ )
      55             : #define ISM_MAX_ELEVATION_DIFF_IDX ( ISM_ELEVATION_NBITS - 1 /*zero*/ - 1 /*sign*/ )
      56             : #define ISM_MAX_RADIUS_DIFF_IDX    ( ISM_RADIUS_NBITS - 1 /*zero*/ - 1 /*sign*/ )
      57             : 
      58             : #define ISM_MD_FEC_DIFF          10
      59             : #define ISM_MD_INC_DIFF_CNT_MAX  6
      60             : #define ISM_MD_FEC_CNT_MAX       25
      61             : #define ISM_MD_RAD_FEC_DIFF      1
      62             : #define INTER_OBJECT_PARAM_CHECK ( ( ISM_FEC_MAX / 2 ) - 2 ) /* note: constant must be less than (ISM_FEC_MAX / number of coded parameters)  */
      63             : 
      64             : 
      65             : /*-----------------------------------------------------------------------*
      66             :  * Local function declarations
      67             :  *-----------------------------------------------------------------------*/
      68             : 
      69             : static void encode_angle_indices( BSTR_ENC_HANDLE hBstr, ISM_METADATA_ANGLE_HANDLE angle, const int16_t last_ism_metadata_flag, const int16_t ini_frame, const int16_t idx_angle1_abs, const int16_t idx_angle2_abs, int16_t *flag_abs_angle1, int16_t *flag_abs_angle2 );
      70             : 
      71             : static void encode_radius( BSTR_ENC_HANDLE hBstr, int16_t *last_radius_idx, int16_t *radius_diff_cnt, const int16_t last_ism_metadata_flag, const int16_t idx_radius_abs, int16_t *flag_abs_radius );
      72             : 
      73             : 
      74             : /*-------------------------------------------------------------------------*
      75             :  * ivas_set_ism_metadata()
      76             :  *
      77             :  * Set metadata of one ISM MD handle
      78             :  *-------------------------------------------------------------------------*/
      79             : 
      80      433276 : ivas_error ivas_set_ism_metadata(
      81             :     ISM_METADATA_HANDLE hIsmMeta,   /* o  : ISM metadata handle   */
      82             :     const float azimuth,            /* i  : azimuth value         */
      83             :     const float elevation,          /* i  : elevation           */
      84             :     const float radius_meta,        /* i  : radius              */
      85             :     const float yaw,                /* i  : yaw                 */
      86             :     const float pitch,              /* i  : pitch               */
      87             :     const int16_t non_diegetic_flag /* i  : non-diegetic object flag*/
      88             : )
      89             : {
      90      433276 :     if ( hIsmMeta == NULL )
      91             :     {
      92           0 :         return IVAS_ERR_UNEXPECTED_NULL_POINTER;
      93             :     }
      94             : 
      95      433276 :     hIsmMeta->ism_metadata_flag = 1;
      96             : 
      97             :     /* save read metadata parameters to the internal codec structure */
      98      433276 :     hIsmMeta->azimuth = azimuth;
      99      433276 :     hIsmMeta->elevation = elevation;
     100      433276 :     hIsmMeta->radius = radius_meta;
     101      433276 :     hIsmMeta->yaw = yaw;
     102      433276 :     hIsmMeta->pitch = pitch;
     103      433276 :     hIsmMeta->non_diegetic_flag = non_diegetic_flag;
     104             : 
     105      433276 :     return IVAS_ERR_OK;
     106             : }
     107             : 
     108             : 
     109             : /*-------------------------------------------------------------------------*
     110             :  * rate_ism_importance()
     111             :  *
     112             :  * Rate importance of particular ISM streams
     113             :  *-------------------------------------------------------------------------*/
     114             : 
     115      101673 : static void rate_ism_importance(
     116             :     const int16_t nchan_transport,                        /* i  : number of transported channels  */
     117             :     ISM_METADATA_HANDLE hIsmMeta[],                       /* i/o: ISM metadata handles            */
     118             :     SCE_ENC_HANDLE hSCE[],                                /* i/o: SCE encoder handles             */
     119             :     const int16_t lowrate_metadata_flag[MAX_NUM_OBJECTS], /* i  : low-rate MD flag                */
     120             :     int16_t ism_imp[]                                     /* o  : ISM importance flags            */
     121             : )
     122             : {
     123             :     int16_t ch, ctype;
     124             : 
     125      365326 :     for ( ch = 0; ch < nchan_transport; ch++ )
     126             :     {
     127      263653 :         ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
     128             : 
     129      263653 :         if ( hSCE[ch]->hCoreCoder[0]->tcxonly )
     130             :         {
     131      101044 :             if ( hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
     132             :             {
     133       17341 :                 ctype = INACTIVE;
     134             :             }
     135       83703 :             else if ( ctype == UNVOICED )
     136             :             {
     137        6047 :                 ctype = GENERIC;
     138             :             }
     139             :         }
     140             : 
     141      263653 :         if ( ( hIsmMeta[ch]->ism_metadata_flag == 0 || lowrate_metadata_flag[ch] == 1 ) && hSCE[ch]->hCoreCoder[0]->localVAD == 0 )
     142             :         {
     143        8350 :             ism_imp[ch] = ISM_NO_META;
     144             :         }
     145      255303 :         else if ( ctype == INACTIVE || ctype == UNVOICED )
     146             :         {
     147       29108 :             ism_imp[ch] = ISM_LOW_IMP;
     148             :         }
     149      226195 :         else if ( ctype == VOICED )
     150             :         {
     151       72596 :             ism_imp[ch] = ISM_MEDIUM_IMP;
     152             :         }
     153             :         else /* GENERIC */
     154             :         {
     155      153599 :             ism_imp[ch] = ISM_HIGH_IMP;
     156             :         }
     157             :     }
     158             : 
     159      101673 :     return;
     160             : }
     161             : 
     162             : 
     163             : /*-------------------------------------------------------------------------*
     164             :  * ivas_ism_metadata_enc()
     165             :  *
     166             :  * quantize and encode ISM metadata
     167             :  *-------------------------------------------------------------------------*/
     168             : 
     169      128949 : ivas_error ivas_ism_metadata_enc(
     170             :     int32_t *ism_total_brate,                 /* i/o: ISM total bitrate               */
     171             :     const int16_t nchan_ism,                  /* i  : number of ISM channels          */
     172             :     const int16_t nchan_transport,            /* i  : number of transport channels    */
     173             :     ISM_METADATA_HANDLE hIsmMeta[],           /* i/o: ISM metadata handles            */
     174             :     SCE_ENC_HANDLE hSCE[],                    /* i/o: SCE encoder handles             */
     175             :     BSTR_ENC_HANDLE hBstr,                    /* i/o: bitstream handle                */
     176             :     int16_t nb_bits_metadata[],               /* o  : number of metadata bits         */
     177             :     const int16_t vad_flag[],                 /* i  : VAD flag                        */
     178             :     const int16_t ism_mode,                   /* i  : ISM mode                        */
     179             :     const PARAM_ISM_CONFIG_HANDLE hParamIsm,  /* i  : Param ISM Enc Handle            */
     180             :     const int16_t ism_extended_metadata_flag, /* i  : Extended metadata flag          */
     181             :     const float lp_noise_CPE,
     182             :     const int16_t flag_omasa_ener_brate, /* i  : less bitrate for objects in OMASA flag */
     183             :     int16_t *omasa_stereo_sw_cnt,
     184             :     const int16_t ini_frame )
     185             : {
     186      128949 :     int16_t i, ch, nb_bits_start = 0;
     187             :     int16_t flag_abs_azimuth[MAX_NUM_OBJECTS];
     188             :     int16_t flag_abs_elevation[MAX_NUM_OBJECTS];
     189      128949 :     int16_t idx_angle1_abs = 0;
     190      128949 :     int16_t idx_angle2_abs = 0;
     191             :     int16_t flag_abs_yaw[MAX_NUM_OBJECTS];
     192             :     int16_t flag_abs_pitch[MAX_NUM_OBJECTS];
     193      128949 :     int16_t idx_radius_abs = 0, flag_abs_radius[MAX_NUM_OBJECTS];
     194             :     float valQ;
     195             :     ISM_METADATA_HANDLE hIsmMetaData;
     196             :     int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS];
     197             :     int16_t ism_metadata_flag_global;
     198             :     int16_t non_diegetic_flag_global;
     199             :     int16_t ism_imp[MAX_NUM_OBJECTS];
     200             :     int16_t null_metadata_flag[MAX_NUM_OBJECTS];
     201             :     int16_t lowrate_metadata_flag[MAX_NUM_OBJECTS];
     202             :     int16_t nbands, nblocks;
     203             :     ivas_error error;
     204             : 
     205      128949 :     error = IVAS_ERR_OK;
     206      128949 :     push_wmops( "ism_meta_enc" );
     207             : 
     208             :     /* initialization */
     209      128949 :     ism_metadata_flag_global = 0;
     210      128949 :     non_diegetic_flag_global = 0;
     211      128949 :     set_s( nb_bits_metadata, 0, nchan_transport );
     212      128949 :     set_s( flag_abs_azimuth, 0, nchan_ism );
     213      128949 :     set_s( flag_abs_elevation, 0, nchan_ism );
     214      128949 :     set_s( flag_abs_yaw, 0, nchan_ism );
     215      128949 :     set_s( flag_abs_pitch, 0, nchan_ism );
     216      128949 :     set_s( flag_abs_radius, 0, nchan_ism );
     217      128949 :     set_s( null_metadata_flag, 0, nchan_ism );
     218      128949 :     set_s( lowrate_metadata_flag, 0, nchan_ism );
     219             : 
     220      128949 :     if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     221             :     {
     222             :         /*----------------------------------------------------------------*
     223             :          * Rate importance of particular ISM streams in combined format coding
     224             :          *----------------------------------------------------------------*/
     225             : 
     226        5196 :         ivas_set_ism_importance_interformat( *ism_total_brate, nchan_transport, hIsmMeta, hSCE, lp_noise_CPE, ism_imp );
     227             :     }
     228             :     else
     229             :     {
     230             :         /*----------------------------------------------------------------*
     231             :          * Set Metadata presence / importance flag
     232             :          *----------------------------------------------------------------*/
     233             : 
     234      490770 :         for ( ch = 0; ch < nchan_ism; ch++ )
     235             :         {
     236      367017 :             if ( ism_mode == ISM_MODE_PARAM )
     237             :             {
     238       74758 :                 hIsmMeta[ch]->ism_metadata_flag = 1;
     239             :             }
     240      292259 :             else if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC )
     241             :             {
     242      292259 :                 null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag;
     243             : 
     244      292259 :                 if ( hIsmMeta[ch]->ism_metadata_flag == 1 )
     245             :                 {
     246      287589 :                     if ( ism_mode != ISM_SBA_MODE_DISC )
     247             :                     {
     248             :                         /* In case of low level noise for low bitrate inactive frames, do not sent metadata */
     249      218229 :                         hIsmMeta[ch]->ism_metadata_flag = vad_flag[ch] || hSCE[ch]->hCoreCoder[0]->lp_noise > 10 || hSCE[ch]->hCoreCoder[0]->tcxonly;
     250             :                     }
     251             : 
     252             :                     /* in inactive frames, send MD 1) in ISM_MD_INC_DIFF_CNT_MAX consecutive frames when MD significantly change, 2) at least every ISM_MD_FEC_DIFF frames */
     253      287589 :                     if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
     254             :                     {
     255        6597 :                         if ( ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_true_azimuth ) > ISM_MD_FEC_DIFF ) ||
     256         875 :                              ( fabsf( hIsmMeta[ch]->elevation - hIsmMeta[ch]->last_true_elevation ) > ISM_MD_FEC_DIFF ) || ( fabsf( hIsmMeta[ch]->radius - hIsmMeta[ch]->last_true_radius ) > ISM_MD_RAD_FEC_DIFF ) )
     257             :                         {
     258             : 
     259        5817 :                             lowrate_metadata_flag[ch] = 1;
     260             : 
     261        5817 :                             hIsmMeta[ch]->ism_md_inc_diff_cnt = 0;
     262             :                         }
     263         780 :                         else if ( hIsmMeta[ch]->ism_md_inc_diff_cnt < ISM_MD_INC_DIFF_CNT_MAX )
     264             :                         {
     265             : 
     266         499 :                             lowrate_metadata_flag[ch] = 1;
     267             : 
     268         499 :                             if ( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 )
     269             :                             {
     270         191 :                                 hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     271             :                             }
     272             :                             else
     273             :                             {
     274         308 :                                 hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX;
     275             :                             }
     276             :                         }
     277         281 :                         else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX )
     278             :                         {
     279           6 :                             hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
     280           6 :                             lowrate_metadata_flag[ch] = 1;
     281             : 
     282           6 :                             hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     283             :                         }
     284             :                     }
     285             :                 }
     286             :             }
     287             :         }
     288             : 
     289             :         /*----------------------------------------------------------------*
     290             :          * Rate importance of particular ISM streams
     291             :          *----------------------------------------------------------------*/
     292             : 
     293      123753 :         if ( ism_mode != ISM_SBA_MODE_DISC )
     294             :         {
     295      101673 :             rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp );
     296             :         }
     297             :     }
     298             : 
     299             :     /*----------------------------------------------------------------*
     300             :      * Write ISM common signaling
     301             :      *----------------------------------------------------------------*/
     302             : 
     303      128949 :     if ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ && ism_mode != ISM_SBA_MODE_DISC )
     304             :     {
     305             :         /* write number of objects - unary coding */
     306      297657 :         for ( ch = 1; ch < nchan_ism; ch++ )
     307             :         {
     308      195984 :             push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
     309             :         }
     310      101673 :         push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
     311             :     }
     312             : 
     313      506480 :     for ( ch = 0; ch < nchan_ism; ch++ )
     314             :     {
     315      377531 :         ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag;
     316      377531 :         ism_metadata_flag_global |= lowrate_metadata_flag[ch];
     317      377531 :         non_diegetic_flag_global |= hIsmMeta[ch]->non_diegetic_flag;
     318             :     }
     319             : 
     320             :     /* write extended metadata presence flag */
     321      128949 :     if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && *ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
     322             :     {
     323       79985 :         push_indice( hBstr, IND_ISM_EXTENDED_FLAG, ism_extended_metadata_flag, ISM_EXTENDED_METADATA_BITS );
     324             : 
     325             :         /* Write global non-diegetic object flag */
     326       79985 :         if ( ism_extended_metadata_flag )
     327             :         {
     328        8166 :             push_indice( hBstr, IND_ISM_EXTENDED_NDP_FLAG, non_diegetic_flag_global, ISM_EXTENDED_METADATA_BITS );
     329             :         }
     330             :     }
     331             : 
     332             :     /* write ISM metadata flag (one per object) */
     333      472476 :     for ( ch = 0; ch < nchan_transport; ch++ )
     334             :     {
     335      343527 :         if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     336             :         {
     337             :             /* flags will be written in ivas_masa_encode() */
     338       10514 :             hIsmMeta[ch]->ism_imp = ism_imp[ch];
     339       10514 :             hIsmMeta[ch]->ism_md_null_flag = null_metadata_flag[ch];
     340       10514 :             hIsmMeta[ch]->ism_md_lowrate_flag = lowrate_metadata_flag[ch];
     341             :         }
     342             :         else
     343             :         {
     344      333013 :             if ( null_metadata_flag[ch] )
     345             :             {
     346             :                 /* signal NULL metadata frame */
     347        4670 :                 push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 1, ISM_METADATA_MD_FLAG_BITS );
     348             : 
     349             :                 /* write the ISM class to ISM_NO_META and again the true ISM class */
     350        4670 :                 if ( ism_mode != ISM_SBA_MODE_DISC )
     351             :                 {
     352        4670 :                     push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS );
     353        4670 :                     push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
     354             :                 }
     355             :                 else
     356             :                 {
     357           0 :                     push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, 1 );
     358             :                 }
     359             :             }
     360      328343 :             else if ( ism_mode != ISM_SBA_MODE_DISC )
     361             :             {
     362      258983 :                 push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
     363             : 
     364      258983 :                 if ( ism_imp[ch] == ISM_NO_META )
     365             :                 {
     366             :                     /* signal low-rate ISM_NO_META frame */
     367        6597 :                     push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 0, ISM_METADATA_MD_FLAG_BITS );
     368             : 
     369             :                     /* signal presence of MD in low-rate ISM_NO_META frame */
     370        6597 :                     push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, lowrate_metadata_flag[ch], ISM_METADATA_INACTIVE_FLAG_BITS );
     371             :                 }
     372             :             }
     373             :             else /*ism_mode == ISM_SBA_MODE_DISC*/
     374             :             {
     375             :                 /* all objects are considered active*/
     376       69360 :                 push_indice( hBstr, IND_ISM_METADATA_FLAG, 1, 1 );
     377             :             }
     378             :         }
     379             :     }
     380             : 
     381             : 
     382      128949 :     if ( ism_metadata_flag_global )
     383             :     {
     384             :         /*----------------------------------------------------------------*
     385             :          * Metadata quantization and coding, loop over all objects
     386             :          *----------------------------------------------------------------*/
     387             : 
     388      128932 :         int16_t total_bits_metadata = 0;
     389      128932 :         int16_t bits_metadata_ism = 0;
     390             :         int16_t nb_bits_objcod_written;
     391             : 
     392      128932 :         if ( ism_mode == ISM_MODE_PARAM )
     393             :         {
     394       20377 :             nb_bits_start = hBstr->nb_bits_tot;
     395             :         }
     396             : 
     397      506428 :         for ( ch = 0; ch < nchan_ism; ch++ )
     398             :         {
     399      377496 :             hIsmMetaData = hIsmMeta[ch];
     400      377496 :             if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC )
     401             :             {
     402      302738 :                 nb_bits_start = hBstr->nb_bits_tot;
     403             :             }
     404             : 
     405      377496 :             if ( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
     406             :             {
     407             :                 /*----------------------------------------------------------------*
     408             :                  * Quantize and encode azimuth and elevation
     409             :                  *----------------------------------------------------------------*/
     410             : 
     411      372586 :                 if ( ism_extended_metadata_flag && non_diegetic_flag_global )
     412             :                 {
     413             :                     /* Write non-diegetic flag for each object */
     414        2415 :                     push_indice( hBstr, IND_ISM_NDP_FLAG, hIsmMeta[ch]->non_diegetic_flag, ISM_METADATA_IS_NDP_BITS );
     415             :                 }
     416             : 
     417      372586 :                 if ( hIsmMeta[ch]->non_diegetic_flag && ism_extended_metadata_flag )
     418             :                 {
     419             :                     /* Map azimuth to panning range [-90:90] */
     420         805 :                     if ( hIsmMetaData->azimuth > 90.0f )
     421             :                     {
     422           0 :                         hIsmMetaData->azimuth = 180.0f - hIsmMetaData->azimuth;
     423             :                     }
     424             : 
     425         805 :                     if ( hIsmMetaData->azimuth < -90.0f )
     426             :                     {
     427           0 :                         hIsmMetaData->azimuth = -180.0f - hIsmMetaData->azimuth;
     428             :                     }
     429             : 
     430         805 :                     idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
     431             : 
     432         805 :                     encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, 0, &flag_abs_azimuth[ch], NULL );
     433             :                 }
     434             :                 else
     435             :                 {
     436      371781 :                     if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC )
     437             :                     {
     438      297023 :                         idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
     439      297023 :                         idx_angle2_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
     440             :                     }
     441             :                     else /* ISM_MODE_PARAM */
     442             :                     {
     443       74758 :                         idx_angle1_abs = hParamIsm->azi_index[ch];
     444       74758 :                         idx_angle2_abs = hParamIsm->ele_index[ch];
     445             :                     }
     446             : 
     447      371781 :                     encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] );
     448             : 
     449             :                     /*----------------------------------------------------------------*
     450             :                      * Quantize and encode radius, yaw, and pitch
     451             :                      *----------------------------------------------------------------*/
     452      371781 :                     if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && ism_extended_metadata_flag )
     453             :                     {
     454       25625 :                         idx_angle1_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
     455       25625 :                         idx_angle2_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
     456       25625 :                         idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS );
     457             : 
     458       25625 :                         encode_angle_indices( hBstr, &( hIsmMetaData->orientation_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_yaw[ch], &flag_abs_pitch[ch] );
     459       25625 :                         encode_radius( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] );
     460             :                     }
     461             :                 }
     462             : 
     463             :                 /* save number of metadata bits written */
     464      372586 :                 if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC )
     465             :                 {
     466      297828 :                     nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start;
     467             :                 }
     468             : 
     469             :                 /* Updates */
     470      372586 :                 hIsmMeta[ch]->last_true_azimuth = hIsmMeta[ch]->azimuth;
     471      372586 :                 hIsmMeta[ch]->last_true_elevation = hIsmMeta[ch]->elevation;
     472      372586 :                 hIsmMeta[ch]->last_true_radius = hIsmMeta[ch]->radius;
     473             :             }
     474             :         }
     475             : 
     476             :         /*----------------------------------------------------------------*
     477             :          * inter-object logic minimizing the use of several absolutely coded
     478             :          * indexes in the same frame
     479             :          *----------------------------------------------------------------*/
     480             : 
     481      128932 :         i = 0;
     482      257864 :         while ( i == 0 || i < nchan_ism / INTER_OBJECT_PARAM_CHECK )
     483             :         {
     484             :             int16_t num, abs_num, abs_first, abs_next, pos_zero;
     485             :             int16_t abs_matrice[INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM];
     486             : 
     487      128932 :             num = min( INTER_OBJECT_PARAM_CHECK, nchan_ism - i * INTER_OBJECT_PARAM_CHECK );
     488      128932 :             i++;
     489             : 
     490      128932 :             set_s( abs_matrice, 0, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
     491             : 
     492      448013 :             for ( ch = 0; ch < num; ch++ )
     493             :             {
     494      319081 :                 if ( flag_abs_azimuth[ch] == 1 )
     495             :                 {
     496      112055 :                     abs_matrice[ch * ISM_NUM_PARAM] = 1;
     497             :                 }
     498             : 
     499      319081 :                 if ( flag_abs_elevation[ch] == 1 )
     500             :                 {
     501       22129 :                     abs_matrice[ch * ISM_NUM_PARAM + 1] = 1;
     502             :                 }
     503             :             }
     504      128932 :             abs_num = sum_s( abs_matrice, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM );
     505             : 
     506      128932 :             abs_first = 0;
     507      164892 :             while ( abs_num > 1 )
     508             :             {
     509             :                 /* find first "1" entry */
     510      137858 :                 while ( abs_matrice[abs_first] == 0 )
     511             :                 {
     512      101898 :                     abs_first++;
     513             :                 }
     514             : 
     515             :                 /* find next "1" entry */
     516       35960 :                 abs_next = abs_first + 1;
     517      236324 :                 while ( abs_matrice[abs_next] == 0 )
     518             :                 {
     519      200364 :                     abs_next++;
     520             :                 }
     521             : 
     522             :                 /* find "0" position */
     523       35960 :                 pos_zero = 0;
     524       47720 :                 while ( abs_matrice[pos_zero] == 1 )
     525             :                 {
     526       11760 :                     pos_zero++;
     527             :                 }
     528             : 
     529       35960 :                 ch = abs_next / ISM_NUM_PARAM;
     530             : 
     531       35960 :                 if ( abs_next % ISM_NUM_PARAM == 0 )
     532             :                 {
     533       33905 :                     hIsmMeta[ch]->position_angle.angle1_diff_cnt = abs_num - 1;
     534             :                 }
     535             : 
     536       35960 :                 if ( abs_next % ISM_NUM_PARAM == 1 )
     537             :                 {
     538        2055 :                     hIsmMeta[ch]->position_angle.angle2_diff_cnt = abs_num - 1;
     539             :                     /*hIsmMeta[ch]->elevation_diff_cnt = min( hIsmMeta[ch]->elevation_diff_cnt, ISM_FEC_MAX );*/
     540             :                 }
     541             : 
     542       35960 :                 abs_first++;
     543       35960 :                 abs_num--;
     544             :             }
     545             :         }
     546             : 
     547      128932 :         if ( ism_mode == ISM_SBA_MODE_DISC )
     548             :         {
     549             :             int16_t md_diff_flag[MAX_NUM_OBJECTS];
     550             : 
     551       22080 :             set_s( md_diff_flag, 1, nchan_ism );
     552       91440 :             for ( ch = 0; ch < nchan_ism; ch++ )
     553             :             {
     554       69360 :                 hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     555             : 
     556       69360 :                 if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
     557             :                 {
     558           0 :                     hIsmMeta[ch]->ism_md_fec_cnt_enc++;
     559           0 :                     hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX );
     560             :                 }
     561             :                 else
     562             :                 {
     563       69360 :                     hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
     564             :                 }
     565       69360 :                 hIsmMeta[ch]->ism_md_inc_diff_cnt++;
     566       69360 :                 hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
     567             :             }
     568             : 
     569       22080 :             update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag );
     570             : 
     571       22080 :             pop_wmops();
     572       22080 :             return error;
     573             :         }
     574      106852 :         if ( ism_mode == ISM_MODE_PARAM )
     575             :         {
     576             :             /* Keep the metdata transmission as is during active parts */
     577             :             /* But send the flag with 1 bit */
     578       20377 :             push_next_indice( hBstr, hParamIsm->flag_noisy_speech, 1 );
     579             : 
     580             :             /* Loop over multiwave to write the object indices into bitstream */
     581       61131 :             for ( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ )
     582             :             {
     583      489048 :                 for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
     584             :                 {
     585      896588 :                     for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
     586             :                     {
     587      448294 :                         push_next_indice( hBstr, hParamIsm->obj_indices[nbands][nblocks][ch], PARAM_ISM_OBJ_IND_NBITS );
     588             :                     }
     589             :                 }
     590             :             }
     591             : 
     592             :             /* Loop over bands to write the power ratio's indices into bitstream */
     593      244524 :             for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ )
     594             :             {
     595      448294 :                 for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ )
     596             :                 {
     597      224147 :                     push_next_indice( hBstr, hParamIsm->power_ratios_idx[nbands][nblocks], PARAM_ISM_POW_RATIO_NBITS );
     598             :                 }
     599             :             }
     600             : 
     601             :             /* total metadata bits */
     602       20377 :             total_bits_metadata = hBstr->nb_bits_tot - nb_bits_start;
     603             : 
     604             :             /* bits per ISM*/
     605       20377 :             bits_metadata_ism = (int16_t) ( total_bits_metadata / nchan_transport );
     606             : 
     607             :             /* Divide the metadata bits into n_Isms*/
     608       20377 :             nb_bits_objcod_written = 0;
     609       61131 :             for ( ch = 0; ch < nchan_transport; ch++ )
     610             :             {
     611       40754 :                 if ( ch == nchan_transport - 1 )
     612             :                 {
     613       20377 :                     nb_bits_metadata[ch] = total_bits_metadata - nb_bits_objcod_written;
     614             :                 }
     615             :                 else
     616             :                 {
     617       20377 :                     nb_bits_metadata[ch] = bits_metadata_ism;
     618       20377 :                     nb_bits_objcod_written += bits_metadata_ism;
     619             :                 }
     620             :             }
     621             :         }
     622             :     }
     623          17 :     else if ( ism_mode == ISM_SBA_MODE_DISC )
     624             :     {
     625           0 :         pop_wmops();
     626           0 :         return error;
     627             :     }
     628             : 
     629             :     /*----------------------------------------------------------------*
     630             :      * Take into account the combined format bit-budget distribution
     631             :      *----------------------------------------------------------------*/
     632             : 
     633      106869 :     if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     634             :     {
     635             :         int16_t bits_ism, bits_element[MAX_NUM_OBJECTS];
     636             :         int16_t brate_limit_flag;
     637             :         int32_t ism_total_brate_ref;
     638        5196 :         ism_total_brate_ref = *ism_total_brate;
     639        5196 :         brate_limit_flag = calculate_brate_limit_flag( ism_imp, nchan_ism );
     640             : 
     641        5196 :         bits_ism = (int16_t) ( *ism_total_brate / FRAMES_PER_SEC );
     642        5196 :         set_s( bits_element, bits_ism / nchan_ism, nchan_ism );
     643        5196 :         bits_element[nchan_ism - 1] += bits_ism % nchan_ism;
     644        5196 :         bitbudget_to_brate( bits_element, element_brate, nchan_ism );
     645             : 
     646        5196 :         *ism_total_brate = 0;
     647       15710 :         for ( ch = 0; ch < nchan_ism; ch++ )
     648             :         {
     649       10514 :             *ism_total_brate += ivas_interformat_brate( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag );
     650             : 
     651       10514 :             if ( ism_imp[ch] > 1 && flag_omasa_ener_brate == 1 && brate_limit_flag >= 0 )
     652             :             {
     653         146 :                 *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
     654             :             }
     655             : 
     656       10514 :             if ( brate_limit_flag == -1 && ism_imp[ch] >= 1 && nchan_ism >= 3 && ( ism_total_brate_ref - *ism_total_brate > IVAS_48k ) )
     657             :             {
     658           0 :                 *ism_total_brate += ADJUST_ISM_BRATE_POS;
     659             :             }
     660             :         }
     661        5196 :         ism_metadata_flag_global = 1;
     662             : 
     663        5196 :         if ( ism_mode == ISM_MASA_MODE_DISC )
     664             :         {
     665        3142 :             brate_limit_flag = 0;
     666       11602 :             for ( int16_t n = 0; n < nchan_ism; n++ )
     667             :             {
     668        8460 :                 brate_limit_flag += ism_imp[n];
     669             :             }
     670             : 
     671        3142 :             if ( brate_limit_flag >= nchan_ism * ISM_HIGH_IMP - 2 )
     672             :             {
     673        2927 :                 *omasa_stereo_sw_cnt = OMASA_STEREO_SW_CNT_MAX;
     674             :             }
     675             :         }
     676             :     }
     677             : 
     678             :     /*----------------------------------------------------------------*
     679             :      * Configuration and decision about bitrates per channel
     680             :      *----------------------------------------------------------------*/
     681             : 
     682      106869 :     if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     683             :     {
     684        5196 :         if ( ( error = ivas_ism_config( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 1 ) ) != IVAS_ERR_OK )
     685             :         {
     686           0 :             return error;
     687             :         }
     688             :     }
     689             :     else
     690             :     {
     691      101673 :         if ( ( error = ivas_ism_config( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 0 ) ) != IVAS_ERR_OK )
     692             :         {
     693           0 :             return error;
     694             :         }
     695             :     }
     696             : 
     697      415040 :     for ( ch = 0; ch < nchan_ism; ch++ )
     698             :     {
     699      308171 :         hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
     700             : 
     701      308171 :         if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
     702             :         {
     703       11267 :             hIsmMeta[ch]->ism_md_fec_cnt_enc++;
     704       11267 :             hIsmMeta[ch]->ism_md_fec_cnt_enc = min( hIsmMeta[ch]->ism_md_fec_cnt_enc, ISM_MD_FEC_CNT_MAX );
     705             :         }
     706             :         else
     707             :         {
     708      296904 :             hIsmMeta[ch]->ism_md_fec_cnt_enc = 0;
     709             :         }
     710      308171 :         hIsmMeta[ch]->ism_md_inc_diff_cnt++;
     711      308171 :         hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
     712             :     }
     713             : 
     714      381036 :     for ( ch = 0; ch < nchan_transport; ch++ )
     715             :     {
     716      274167 :         hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
     717      274167 :         if ( ism_mode == ISM_MODE_DISC )
     718             :         {
     719      222899 :             if ( ism_imp[ch] == ISM_NO_META && ( ( total_brate[ch] < ACELP_8k00 && element_brate[ch] < SCE_CORE_16k_LOW_LIMIT ) ||
     720        6562 :                                                  ( total_brate[ch] <= ACELP_16k_LOW_LIMIT && element_brate[ch] >= SCE_CORE_16k_LOW_LIMIT ) ) )
     721             :             {
     722        7534 :                 hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
     723             :             }
     724             : 
     725      222899 :             hSCE[ch]->element_brate = element_brate[ch];
     726             :         }
     727       51268 :         else if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     728             :         {
     729       10514 :             if ( ism_imp[ch] == ISM_INACTIVE_IMP )
     730             :             {
     731           0 :                 hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
     732             :             }
     733             :         }
     734             : 
     735      274167 :         hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
     736             : 
     737             :         /* write metadata only in active frames */
     738      274167 :         if ( hSCE[0]->hCoreCoder[0]->core_brate > SID_2k40 )
     739             :         {
     740           0 :             reset_indices_enc( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot );
     741             :         }
     742             :     }
     743             : 
     744      106869 :     pop_wmops();
     745             : 
     746      106869 :     return error;
     747             : }
     748             : 
     749             : 
     750             : /*-------------------------------------------------------------------------
     751             :  * ivas_ism_metadata_enc_create()
     752             :  *
     753             :  * Create, allocate, initialize and configure IVAS encoder ISM metadata handles
     754             :  *-------------------------------------------------------------------------*/
     755             : 
     756         155 : ivas_error ivas_ism_metadata_enc_create(
     757             :     Encoder_Struct *st_ivas,    /* i/o: IVAS encoder structure      */
     758             :     const int16_t n_ISms,       /* i  : number of objects           */
     759             :     int32_t element_brate_tmp[] /* o  : element bitrate per object  */
     760             : )
     761             : {
     762             :     int16_t ch, nchan_transport;
     763             :     ivas_error error;
     764             : 
     765         155 :     nchan_transport = st_ivas->nchan_transport;
     766         155 :     if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
     767             :     {
     768          44 :         nchan_transport = MAX_PARAM_ISM_WAVE;
     769          44 :         ivas_set_omasa_TC( st_ivas->ism_mode, n_ISms, &st_ivas->nSCE, &st_ivas->nCPE );
     770             :     }
     771         111 :     else if ( st_ivas->hEncoderConfig->ivas_format == SBA_ISM_FORMAT )
     772             :     {
     773          37 :         nchan_transport = n_ISms;
     774             :     }
     775             :     else
     776             :     {
     777          74 :         if ( st_ivas->ism_mode == ISM_MODE_NONE )
     778             :         {
     779           0 :             nchan_transport = st_ivas->nchan_transport;
     780             : 
     781           0 :             if ( nchan_transport == 1 )
     782             :             {
     783           0 :                 st_ivas->nSCE = 1;
     784           0 :                 st_ivas->nCPE = 0;
     785             :             }
     786             :             else
     787             :             {
     788           0 :                 st_ivas->nSCE = 0;
     789           0 :                 st_ivas->nCPE = 1;
     790             :             }
     791             :         }
     792          74 :         else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
     793             :         {
     794          17 :             nchan_transport = 2;
     795             :         }
     796             :         else
     797             :         {
     798          57 :             nchan_transport = n_ISms;
     799             :         }
     800             : 
     801          74 :         st_ivas->nchan_transport = nchan_transport;
     802          74 :         st_ivas->nSCE = nchan_transport;
     803          74 :         st_ivas->nCPE = 0;
     804             :     }
     805             : 
     806             :     /* allocate ISM metadata handles */
     807         620 :     for ( ch = 0; ch < n_ISms; ch++ )
     808             :     {
     809         465 :         if ( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL )
     810             :         {
     811           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) );
     812             :         }
     813         465 :         st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0;
     814         465 :         st_ivas->hIsmMetaData[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     815         465 :         st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 0;
     816         465 :         st_ivas->hIsmMetaData[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX - 1;
     817         465 :         st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0;
     818         465 :         st_ivas->hIsmMetaData[ch]->orientation_angle.angle1_diff_cnt = ISM_FEC_MAX - 2;
     819         465 :         st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 0;
     820         465 :         st_ivas->hIsmMetaData[ch]->orientation_angle.angle2_diff_cnt = ISM_FEC_MAX - 2;
     821         465 :         st_ivas->hIsmMetaData[ch]->last_radius_idx = 0;
     822         465 :         st_ivas->hIsmMetaData[ch]->radius_diff_cnt = ISM_FEC_MAX - 2;
     823         465 :         st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0;
     824             : 
     825         465 :         st_ivas->hIsmMetaData[ch]->ism_imp = -1;
     826         465 :         st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
     827         465 :         st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
     828         465 :         st_ivas->hIsmMetaData[ch]->q_azimuth_old = 0.0f;
     829         465 :         st_ivas->hIsmMetaData[ch]->q_elevation_old = 0.0f;
     830             : 
     831         465 :         ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] );
     832             : 
     833         465 :         st_ivas->hIsmMetaData[ch]->last_azimuth = 0.0f;
     834         465 :         st_ivas->hIsmMetaData[ch]->last_elevation = 0.0f;
     835             : 
     836         465 :         st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0.0f;
     837         465 :         st_ivas->hIsmMetaData[ch]->last_true_elevation = 0.0f;
     838         465 :         st_ivas->hIsmMetaData[ch]->ism_md_fec_cnt_enc = 0;
     839         465 :         st_ivas->hIsmMetaData[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
     840         465 :         st_ivas->hIsmMetaData[ch]->last_true_radius = 1.0f;
     841             :     }
     842             : 
     843         155 :     if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
     844             :     {
     845          44 :         if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     846             :         {
     847          20 :             if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, 1, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
     848             :             {
     849           0 :                 return error;
     850             :             }
     851             :         }
     852          24 :         else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
     853             :         {
     854          17 :             if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
     855             :             {
     856           0 :                 return error;
     857             :             }
     858             :         }
     859             :     }
     860             :     else
     861             :     {
     862         111 :         if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK )
     863             :         {
     864           0 :             return error;
     865             :         }
     866             :     }
     867             : 
     868         155 :     return IVAS_ERR_OK;
     869             : }
     870             : 
     871             : 
     872             : /*-------------------------------------------------------------------------
     873             :  * encode_radius()
     874             :  *
     875             :  * Radius index encoding
     876             :  *-------------------------------------------------------------------------*/
     877             : 
     878       25625 : static void encode_radius(
     879             :     BSTR_ENC_HANDLE hBstr,                /* i/o: bitstream handle           */
     880             :     int16_t *last_radius_idx,             /* i/o: last radius index          */
     881             :     int16_t *radius_diff_cnt,             /* i/o: radius diff coding counter */
     882             :     const int16_t last_ism_metadata_flag, /* last frame ism_metadata_flag    */
     883             :     const int16_t idx_radius_abs,         /* i  : Azimuth index              */
     884             :     int16_t *flag_abs_radius              /* o  : Radius encoding mode       */
     885             : )
     886             : {
     887             :     int16_t idx_radius, nbits_diff_radius, diff;
     888             : 
     889       25625 :     idx_radius = idx_radius_abs;
     890       25625 :     nbits_diff_radius = 0;
     891       25625 :     *flag_abs_radius = 0; /* differential coding by default */
     892             : 
     893       25625 :     if ( *radius_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */
     894       23791 :          || last_ism_metadata_flag == 0  /* If last frame had no metadata coded, do not use differential coding */
     895             :     )
     896             :     {
     897        2184 :         *flag_abs_radius = 1;
     898             :     }
     899             : 
     900       25625 :     diff = idx_radius_abs - *last_radius_idx;
     901             : 
     902             :     /* try differential coding */
     903       25625 :     if ( *flag_abs_radius == 0 )
     904             :     {
     905       23441 :         if ( diff == 0 )
     906             :         {
     907       15315 :             idx_radius = 0;
     908       15315 :             nbits_diff_radius = 1;
     909             :         }
     910        8126 :         else if ( ABSVAL( diff ) <= ISM_MAX_RADIUS_DIFF_IDX )
     911             :         {
     912        3098 :             idx_radius = 1 << 1;
     913        3098 :             nbits_diff_radius = 1;
     914             : 
     915        3098 :             if ( diff < 0 )
     916             :             {
     917        1428 :                 idx_radius += 1; /* negative sign */
     918        1428 :                 diff *= -1;
     919             :             }
     920             :             else
     921             :             {
     922        1670 :                 idx_radius += 0; /* positive sign */
     923             :             }
     924             : 
     925        3098 :             idx_radius = idx_radius << diff;
     926        3098 :             nbits_diff_radius++;
     927             : 
     928             :             /* unary coding of "diff */
     929        3098 :             idx_radius += ( ( 1 << diff ) - 1 );
     930        3098 :             nbits_diff_radius += diff;
     931             : 
     932        3098 :             if ( nbits_diff_radius < ISM_RADIUS_NBITS )
     933             :             {
     934             :                 /* add stop bit */
     935        2911 :                 idx_radius = idx_radius << 1;
     936        2911 :                 nbits_diff_radius++;
     937             :             }
     938             :         }
     939             :         else
     940             :         {
     941        5028 :             *flag_abs_radius = 1;
     942             :         }
     943             :     }
     944             : 
     945             :     /* update counter */
     946       25625 :     if ( *flag_abs_radius == 0 )
     947             :     {
     948       18413 :         ( *radius_diff_cnt )++;
     949       18413 :         *radius_diff_cnt = min( *radius_diff_cnt, ISM_FEC_MAX );
     950             :     }
     951             :     else
     952             :     {
     953        7212 :         *radius_diff_cnt = 0;
     954             :     }
     955             : 
     956             :     /* Write radius */
     957       25625 :     push_indice( hBstr, IND_ISM_RADIUS_DIFF_FLAG, *flag_abs_radius, 1 );
     958             : 
     959       25625 :     if ( *flag_abs_radius )
     960             :     {
     961        7212 :         push_indice( hBstr, IND_ISM_RADIUS, idx_radius, ISM_RADIUS_NBITS );
     962             :     }
     963             :     else
     964             :     {
     965       18413 :         push_indice( hBstr, IND_ISM_RADIUS, idx_radius, nbits_diff_radius );
     966             :     }
     967             : 
     968             :     /* Updates */
     969       25625 :     *last_radius_idx = idx_radius_abs;
     970             : 
     971       25625 :     return;
     972             : }
     973             : 
     974             : 
     975             : /*----------------------------------------------------------------*
     976             :  * encode_angle_indices()
     977             :  *
     978             :  * Encoding of an angle
     979             :  *----------------------------------------------------------------*/
     980             : 
     981      398211 : static void encode_angle_indices(
     982             :     BSTR_ENC_HANDLE hBstr,                /* i/o: bitstream handle              */
     983             :     ISM_METADATA_ANGLE_HANDLE angle,      /* i/o: angle handle                  */
     984             :     const int16_t last_ism_metadata_flag, /* i  : last frame ism_metadata_flag  */
     985             :     const int16_t ini_frame,              /* i  : initialization frames counter */
     986             :     const int16_t idx_angle1_abs,         /* i  : Azimuth index                 */
     987             :     const int16_t idx_angle2_abs,         /* i  : Elevation index               */
     988             :     int16_t *flag_abs_angle1,             /* o  : Azimuth/yaw encoding mode     */
     989             :     int16_t *flag_abs_angle2              /* o  : Elevation/pitch encoding mode */
     990             : )
     991             : {
     992             :     int16_t idx_angle1, nbits_diff_angle1, diff;
     993             :     int16_t idx_angle2, nbits_diff_angle2;
     994             : 
     995             :     /*----------------------------------------------------------------*
     996             :      * Azimuth/yaw index encoding
     997             :      *----------------------------------------------------------------*/
     998             : 
     999      398211 :     idx_angle1 = idx_angle1_abs;
    1000             : 
    1001      398211 :     nbits_diff_angle1 = 0;
    1002             : 
    1003      398211 :     *flag_abs_angle1 = 0;                      /* differential coding by default */
    1004      398211 :     if ( angle->angle1_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */
    1005      370706 :          || last_ism_metadata_flag == 0        /* If last frame had no metadata coded, do not use differential coding */
    1006             :     )
    1007             :     {
    1008       34087 :         *flag_abs_angle1 = 1;
    1009             :     }
    1010             : 
    1011             :     /* try differential coding */
    1012      398211 :     if ( *flag_abs_angle1 == 0 )
    1013             :     {
    1014      364124 :         diff = idx_angle1_abs - angle->last_angle1_idx;
    1015             : 
    1016             :         /* azimuth is on a circle - check for diff coding for -180° -> 180° and vice versa changes */
    1017      364124 :         if ( abs( diff ) > ( ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - ISM_MAX_AZIMUTH_DIFF_IDX )
    1018             :         {
    1019        3996 :             if ( diff > 0 )
    1020             :             {
    1021        1447 :                 diff -= ( 1 << ISM_AZIMUTH_NBITS ) - 1;
    1022             :             }
    1023             :             else
    1024             :             {
    1025        2549 :                 diff += ( 1 << ISM_AZIMUTH_NBITS ) - 1;
    1026             :             }
    1027             :         }
    1028             : 
    1029      364124 :         if ( diff == 0 )
    1030             :         {
    1031       62131 :             idx_angle1 = 0;
    1032       62131 :             nbits_diff_angle1 = 1;
    1033             :         }
    1034      301993 :         else if ( ABSVAL( diff ) < ISM_MAX_AZIMUTH_DIFF_IDX ) /* when diff bits >= abs bits, prefer abs */
    1035             :         {
    1036      209539 :             idx_angle1 = 1 << 1;
    1037      209539 :             nbits_diff_angle1 = 1;
    1038             : 
    1039      209539 :             if ( diff < 0 )
    1040             :             {
    1041       68454 :                 idx_angle1 += 1; /* negative sign */
    1042       68454 :                 diff *= -1;
    1043             :             }
    1044             :             else
    1045             :             {
    1046      141085 :                 idx_angle1 += 0; /* positive sign */
    1047             :             }
    1048             : 
    1049      209539 :             idx_angle1 = idx_angle1 << diff;
    1050      209539 :             nbits_diff_angle1++;
    1051             : 
    1052             :             /* unary coding of "diff */
    1053      209539 :             idx_angle1 += ( ( 1 << diff ) - 1 );
    1054      209539 :             nbits_diff_angle1 += diff;
    1055             : 
    1056      209539 :             if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 )
    1057             :             {
    1058             :                 /* add stop bit - only for codewords shorter than ISM_AZIMUTH_NBITS */
    1059      191731 :                 idx_angle1 = idx_angle1 << 1;
    1060      191731 :                 nbits_diff_angle1++;
    1061             :             }
    1062             :         }
    1063             :         else
    1064             :         {
    1065       92454 :             *flag_abs_angle1 = 1;
    1066             :         }
    1067             :     }
    1068             : 
    1069             :     /* update counter */
    1070      398211 :     if ( *flag_abs_angle1 == 0 )
    1071             :     {
    1072      271670 :         angle->angle1_diff_cnt++;
    1073      271670 :         angle->angle1_diff_cnt = min( angle->angle1_diff_cnt, ISM_FEC_MAX );
    1074             :     }
    1075             :     else
    1076             :     {
    1077      126541 :         angle->angle1_diff_cnt = 0;
    1078             :     }
    1079             : 
    1080             :     /* Write azimuth/yaw */
    1081      398211 :     push_indice( hBstr, IND_ISM_AZIMUTH_DIFF_FLAG, *flag_abs_angle1, 1 );
    1082             : 
    1083      398211 :     if ( *flag_abs_angle1 )
    1084             :     {
    1085      126541 :         push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, ISM_AZIMUTH_NBITS );
    1086             :     }
    1087             :     else
    1088             :     {
    1089      271670 :         push_indice( hBstr, IND_ISM_AZIMUTH, idx_angle1, nbits_diff_angle1 );
    1090             :     }
    1091             : 
    1092             :     /*----------------------------------------------------------------*
    1093             :      * Elevation/pitch index encoding
    1094             :      *----------------------------------------------------------------*/
    1095             : 
    1096      398211 :     if ( flag_abs_angle2 )
    1097             :     {
    1098      397406 :         idx_angle2 = idx_angle2_abs;
    1099      397406 :         nbits_diff_angle2 = 0;
    1100      397406 :         *flag_abs_angle2 = 0;                      /* differential coding by default */
    1101      397406 :         if ( angle->angle2_diff_cnt == ISM_FEC_MAX /* make differential encoding in ISM_FEC_MAX consecutive frames at maximum (in order to control the decoding in FEC) */
    1102      282318 :              || last_ism_metadata_flag == 0        /* If last frame had no metadata coded, do not use differential coding */
    1103             :         )
    1104             :         {
    1105      115705 :             *flag_abs_angle2 = 1;
    1106             :         }
    1107             : 
    1108             :         /* note: elevation/pitch is coded starting from the second frame only (it is meaningless in the init_frame) */
    1109      397406 :         if ( ini_frame == 0 )
    1110             :         {
    1111        1377 :             *flag_abs_angle2 = 1;
    1112        1377 :             angle->last_angle2_idx = idx_angle2_abs;
    1113             :         }
    1114             : 
    1115      397406 :         diff = idx_angle2_abs - angle->last_angle2_idx;
    1116             : 
    1117             :         /* avoid absolute coding of elevation/pitch if absolute coding was already used for azimuth/yaw */
    1118      397406 :         if ( *flag_abs_angle1 == 1 )
    1119             :         {
    1120      126466 :             int16_t diff_orig = diff;
    1121             : 
    1122      126466 :             *flag_abs_angle2 = 0;
    1123             : 
    1124             : 
    1125      126466 :             if ( diff >= 0 )
    1126             :             {
    1127       79202 :                 diff = min( diff, ISM_MAX_ELEVATION_DIFF_IDX );
    1128             :             }
    1129             :             else
    1130             :             {
    1131       47264 :                 diff = -1 * min( -diff, ISM_MAX_ELEVATION_DIFF_IDX );
    1132             :             }
    1133             : 
    1134      126466 :             if ( last_ism_metadata_flag == 0 || abs( diff_orig - diff ) > ISM_MAX_ELEVATION_DIFF_IDX )
    1135             :             {
    1136       48670 :                 angle->angle2_diff_cnt = ISM_FEC_MAX - 1;
    1137             :             }
    1138             :         }
    1139             : 
    1140             :         /* try differential coding */
    1141      397406 :         if ( *flag_abs_angle2 == 0 )
    1142             :         {
    1143      368497 :             if ( diff == 0 )
    1144             :             {
    1145      149539 :                 idx_angle2 = 0;
    1146      149539 :                 nbits_diff_angle2 = 1;
    1147             :             }
    1148      218958 :             else if ( ABSVAL( diff ) <= ISM_MAX_ELEVATION_DIFF_IDX )
    1149             :             {
    1150      214547 :                 idx_angle2 = 1 << 1;
    1151      214547 :                 nbits_diff_angle2 = 1;
    1152             : 
    1153      214547 :                 if ( diff < 0 )
    1154             :                 {
    1155      107514 :                     idx_angle2 += 1; /* negative sign */
    1156      107514 :                     diff *= -1;
    1157             :                 }
    1158             :                 else
    1159             :                 {
    1160      107033 :                     idx_angle2 += 0; /* positive sign */
    1161             :                 }
    1162             : 
    1163      214547 :                 idx_angle2 = idx_angle2 << diff;
    1164      214547 :                 nbits_diff_angle2++;
    1165             : 
    1166             :                 /* unary coding of "diff */
    1167      214547 :                 idx_angle2 += ( ( 1 << diff ) - 1 );
    1168      214547 :                 nbits_diff_angle2 += diff;
    1169             : 
    1170      214547 :                 if ( nbits_diff_angle2 < ISM_ELEVATION_NBITS )
    1171             :                 {
    1172             :                     /* add stop bit */
    1173      142343 :                     idx_angle2 = idx_angle2 << 1;
    1174      142343 :                     nbits_diff_angle2++;
    1175             :                 }
    1176             :             }
    1177             :             else
    1178             :             {
    1179        4411 :                 *flag_abs_angle2 = 1;
    1180             :             }
    1181             :         }
    1182             : 
    1183             :         /* update counter */
    1184      397406 :         if ( *flag_abs_angle2 == 0 )
    1185             :         {
    1186      364086 :             angle->angle2_diff_cnt++;
    1187      364086 :             angle->angle2_diff_cnt = min( angle->angle2_diff_cnt, ISM_FEC_MAX );
    1188             :         }
    1189             :         else
    1190             :         {
    1191       33320 :             angle->angle2_diff_cnt = 0;
    1192             :         }
    1193             : 
    1194             :         /* Write elevation */
    1195      397406 :         if ( *flag_abs_angle1 == 0 ) /* do not write "flag_abs_elevation/pitch" if "flag_abs_azimuth/yaw == 1" */
    1196             :         {
    1197      270940 :             push_indice( hBstr, IND_ISM_ELEVATION_DIFF_FLAG, *flag_abs_angle2, 1 );
    1198             :         }
    1199             : 
    1200      397406 :         if ( *flag_abs_angle2 )
    1201             :         {
    1202       33320 :             push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, ISM_ELEVATION_NBITS );
    1203             :         }
    1204             :         else
    1205             :         {
    1206      364086 :             push_indice( hBstr, IND_ISM_ELEVATION, idx_angle2, nbits_diff_angle2 );
    1207             :         }
    1208             :     }
    1209             : 
    1210             :     /*----------------------------------------------------------------*
    1211             :      * Updates
    1212             :      *----------------------------------------------------------------*/
    1213             : 
    1214      398211 :     angle->last_angle1_idx = idx_angle1_abs;
    1215      398211 :     angle->last_angle2_idx = idx_angle2_abs;
    1216             : 
    1217      398211 :     return;
    1218             : }
    1219             : 
    1220             : 
    1221             : /*-------------------------------------------------------------------*
    1222             :  * ivas_ism_metadata_sid_enc()
    1223             :  *
    1224             :  * Quantize and encode ISM metadata in SID frame
    1225             :  *-------------------------------------------------------------------*/
    1226             : 
    1227        2153 : void ivas_ism_metadata_sid_enc(
    1228             :     ISM_DTX_HANDLE hISMDTX,          /* i/o: ISM DTX handle                 */
    1229             :     const int16_t flag_noisy_speech, /* i  : noisy speech flag              */
    1230             :     const int16_t nchan_ism,         /* i  : number of objects              */
    1231             :     const int16_t nchan_transport,   /* i  : number of transport channels   */
    1232             :     const ISM_MODE ism_mode,         /* i  : ISM mode                       */
    1233             :     ISM_METADATA_HANDLE hIsmMeta[],  /* i/o: ISM metadata handles           */
    1234             :     const int16_t sid_flag,          /* i  : indication of SID frame        */
    1235             :     const int16_t md_diff_flag[],    /* i  : metadata differental flag      */
    1236             :     BSTR_ENC_HANDLE hBstr,           /* i/o: bitstream handle               */
    1237             :     int16_t nb_bits_metadata[]       /* o  : number of metadata bits        */
    1238             : )
    1239             : {
    1240             :     int16_t i, ch, nBits, nBits_start, nBits_unused;
    1241             :     float q_step, q_step_border;
    1242             :     int16_t idx, idx_azimuth, idx_elevation;
    1243             :     int16_t nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id;
    1244             :     float valQ;
    1245             :     ISM_METADATA_HANDLE hIsmMetaData;
    1246             : 
    1247        2153 :     if ( sid_flag )
    1248             :     {
    1249         555 :         nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
    1250         555 :         nBits -= SID_FORMAT_NBITS;
    1251         555 :         nBits_start = hBstr->nb_bits_tot;
    1252             : 
    1253             :         /*----------------------------------------------------------------*
    1254             :          * Write ISm common signaling
    1255             :          *----------------------------------------------------------------*/
    1256             : 
    1257             :         /* write number of objects - unary coding */
    1258        1833 :         for ( ch = 1; ch < nchan_ism; ch++ )
    1259             :         {
    1260        1278 :             push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
    1261             :         }
    1262         555 :         push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
    1263             : 
    1264             :         /* write SID metadata flag (one per object) */
    1265        2388 :         for ( ch = 0; ch < nchan_ism; ch++ )
    1266             :         {
    1267        1833 :             push_indice( hBstr, IND_ISM_METADATA_FLAG, md_diff_flag[ch], 1 );
    1268             :         }
    1269             : 
    1270             :         /*----------------------------------------------------------------*
    1271             :          * Set quantization bits based on the number of coded objects
    1272             :          *----------------------------------------------------------------*/
    1273             : 
    1274         555 :         ivas_get_ism_sid_quan_bitbudget( nchan_ism, &nBits_azimuth, &nBits_elevation, &q_step, &q_step_border, &nBits_coh, &nBits_sce_id );
    1275             : 
    1276             :         /*----------------------------------------------------------------*
    1277             :          * Spatial parameters, loop over TCs - 1
    1278             :          *----------------------------------------------------------------*/
    1279             : 
    1280             :         /* write ISM mode flag to explicitly signal number of spatial parameters */
    1281         555 :         if ( nchan_ism > 2 )
    1282             :         {
    1283         389 :             if ( ism_mode == ISM_MODE_DISC )
    1284             :             {
    1285         282 :                 push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 0, 1 );
    1286             :             }
    1287             :             else
    1288             :             {
    1289         107 :                 push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 1, 1 );
    1290             :             }
    1291             : 
    1292         389 :             if ( ism_mode == ISM_MODE_PARAM )
    1293             :             {
    1294             :                 /* write noisy speech flag */
    1295         107 :                 push_indice( hBstr, IND_ISM_NOISY_SPEECH_FLAG, flag_noisy_speech, 1 );
    1296         107 :                 nBits_sce_id = 1;
    1297             :             }
    1298             :         }
    1299             : 
    1300         555 :         if ( nchan_transport > 1 )
    1301             :         {
    1302             :             /* write sce id */
    1303         500 :             push_indice( hBstr, IND_ISM_SCE_ID_DTX, hISMDTX->sce_id_dtx, nBits_sce_id );
    1304             : 
    1305             :             /* quantize and write coherence */
    1306        2064 :             for ( ch = 0; ch < nchan_transport; ch++ )
    1307             :             {
    1308        1564 :                 if ( ch == hISMDTX->sce_id_dtx )
    1309             :                 {
    1310         500 :                     continue;
    1311             :                 }
    1312             : 
    1313        1064 :                 idx = (int16_t) ( hISMDTX->coh[ch] * ( ( 1 << nBits_coh ) - 1 ) + 0.5f );
    1314        1064 :                 assert( ( idx >= 0 ) && ( idx <= ( ( 1 << nBits_coh ) - 1 ) ) );
    1315        1064 :                 push_indice( hBstr, IND_ISM_DTX_COH_SCA, idx, nBits_coh );
    1316             :             }
    1317             :         }
    1318             : 
    1319             :         /*----------------------------------------------------------------*
    1320             :          * Metadata quantization and coding, loop over all objects
    1321             :          *----------------------------------------------------------------*/
    1322             : 
    1323        2388 :         for ( ch = 0; ch < nchan_ism; ch++ )
    1324             :         {
    1325        1833 :             if ( md_diff_flag[ch] == 1 )
    1326             :             {
    1327         647 :                 hIsmMetaData = hIsmMeta[ch];
    1328             : 
    1329         647 :                 idx_azimuth = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, q_step, q_step_border, 1 << nBits_azimuth );
    1330         647 :                 idx_elevation = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, q_step, q_step_border, 1 << nBits_elevation );
    1331             : 
    1332         647 :                 push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, nBits_azimuth );
    1333         647 :                 push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, nBits_elevation );
    1334             : 
    1335             :                 /* update last indexes to correspond to active frames coding */
    1336         647 :                 if ( nBits_azimuth > ISM_AZIMUTH_NBITS )
    1337             :                 {
    1338         210 :                     hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS );
    1339         210 :                     hIsmMetaData->position_angle.last_angle2_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS );
    1340             :                 }
    1341             :                 else
    1342             :                 {
    1343         437 :                     hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth );
    1344         437 :                     hIsmMetaData->position_angle.last_angle2_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation );
    1345             :                 }
    1346             : 
    1347         647 :                 hIsmMetaData->ism_md_fec_cnt_enc = 0;
    1348         647 :                 hIsmMeta[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX;
    1349             :             }
    1350             :         }
    1351             : 
    1352             :         /* Write unused (padding) bits */
    1353         555 :         nBits_unused = nBits - hBstr->nb_bits_tot;
    1354        1614 :         while ( nBits_unused > 0 )
    1355             :         {
    1356        1059 :             i = min( nBits_unused, 16 );
    1357        1059 :             push_indice( hBstr, IND_UNUSED, 0, i );
    1358        1059 :             nBits_unused -= i;
    1359             :         }
    1360             : 
    1361         555 :         nb_bits_metadata[0] = hBstr->nb_bits_tot - nBits_start;
    1362             :     }
    1363             : 
    1364        2153 :     return;
    1365             : }

Generated by: LCOV version 1.14