LCOV - code coverage report
Current view: top level - lib_enc - ivas_omasa_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 715 741 96.5 %
Date: 2025-09-14 03:13:15 Functions: 13 13 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 "options.h"
      34             : #include <stdlib.h>
      35             : #include <assert.h>
      36             : #include <math.h>
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_prot_fx.h"
      39             : #include "prot_fx.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_rom_enc.h"
      42             : #include "wmc_auto.h"
      43             : #ifdef DEBUGGING
      44             : #include "debug.h"
      45             : #endif
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------------
      49             :  * Local constants
      50             :  *------------------------------------------------------------------------*/
      51             : 
      52             : #define OMASA_FEC_MAX 5
      53             : 
      54             : 
      55             : /*-------------------------------------------------------------------------
      56             :  * Local function prototypes
      57             :  *------------------------------------------------------------------------*/
      58             : 
      59             : static void ivas_omasa_param_est_enc_fx(
      60             :     OMASA_ENC_HANDLE hOMasa,
      61             :     OMASA_ENCODER_DATA_HANDLE hOmasaData,
      62             :     ISM_METADATA_HANDLE hIsmMeta[],
      63             :     Word32 *data[],                                                                  /*i:q_data*/
      64             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/
      65             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   /*o:q22*/
      66             :     Word32 energyRatio_fx[MASA_FREQUENCY_BANDS],                                     /*o:Q30*/
      67             :     Word16 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],    /*o:Q15*/
      68             :     Word16 surroundingCoherence_fx[MASA_FREQUENCY_BANDS],                            /*o:Q15*/
      69             :     Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS],                                   /*o:q30*/
      70             :     const Word16 input_frame,
      71             :     const Word16 nchan_ism,
      72             :     Word16 q_data /*i: Qfactor for data*/
      73             : );
      74             : 
      75             : static void ivas_omasa_energy_and_ratio_est_fx(
      76             :     OMASA_ENC_HANDLE hOMasa,
      77             :     OMASA_ENCODER_DATA_HANDLE hOmasaData,
      78             :     Word32 *data_fx[],
      79             :     const Word16 input_frame,
      80             :     const Word16 nchan_ism,
      81             :     const Word16 q_data );
      82             : 
      83             : static void ivas_omasa_dmx_fx(
      84             :     Word32 *data_in[],                                /*i:Qx*/
      85             :     Word32 data_out[][L_FRAME48k],                    /*i:Qx*/
      86             :     const Word16 input_frame,                         /*i:q0*/
      87             :     const Word16 nchan_transport,                     /*i:q0*/
      88             :     const Word16 nchan_ism,                           /*i:q0*/
      89             :     ISM_METADATA_HANDLE hIsmMeta[],                   /*i*/
      90             :     Word16 prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], /*o:q15*/
      91             :     const Word16 interpolator[L_FRAME48k]             /*i:q15*/
      92             : );
      93             : 
      94             : void computeIntensityVector_enc_fx(
      95             :     const Word16 *band_grouping,
      96             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
      97             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
      98             :     const Word16 num_frequency_bands,
      99             :     Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /*exp: exp_intensity_real*/
     100             :     Word16 q_intensity_real[MASA_FREQUENCY_BANDS],
     101             :     Word16 inp_q );
     102             : 
     103             : static void computeReferencePower_omasa_ivas_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 *reference_power, const Word16 enc_param_start_band, const Word16 num_freq_bands, Word16 q_Cldfb, Word16 q_reference_power[CLDFB_NO_CHANNELS_MAX] );
     104             : 
     105             : 
     106             : /*--------------------------------------------------------------------------*
     107             :  * ivas_omasa_enc_open()
     108             :  *
     109             :  * Allocate and initialize OMASA handle
     110             :  *--------------------------------------------------------------------------*/
     111             : 
     112         464 : ivas_error ivas_omasa_enc_open_fx(
     113             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder handle          */
     114             : )
     115             : {
     116             :     Word16 i, j;
     117             :     OMASA_ENC_HANDLE hOMasa;
     118             :     Word16 numAnalysisChannels;
     119             :     Word16 input_frame;
     120             :     ivas_error error;
     121             : 
     122         464 :     error = IVAS_ERR_OK;
     123         464 :     move16();
     124             : 
     125         464 :     assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
     126             : 
     127         464 :     IF( ( hOMasa = (OMASA_ENC_HANDLE) malloc( sizeof( OMASA_ENC_STATE ) ) ) == NULL )
     128             :     {
     129           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) );
     130             :     }
     131             : 
     132         464 :     numAnalysisChannels = st_ivas->hEncoderConfig->nchan_ism;
     133         464 :     move16();
     134             : 
     135             :     /* open/initialize CLDFB */
     136         464 :     hOMasa->num_Cldfb_instances = numAnalysisChannels;
     137         464 :     move16();
     138        1906 :     FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
     139             :     {
     140        1442 :         IF( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS, ENC ) ) != IVAS_ERR_OK )
     141             :         {
     142           0 :             return error;
     143             :         }
     144             :     }
     145         464 :     set_zero_fx( &hOMasa->chnlToFoaMtx_fx[0][0], DIRAC_MAX_ANA_CHANS * MCMASA_MAX_ANA_CHANS );
     146             : 
     147             :     /* intensity 3-dim */
     148        1856 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     149             :     {
     150        1392 :         hOMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) );
     151             : 
     152        6960 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     153             :         {
     154        5568 :             IF( ( hOMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     155             :             {
     156           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     157             :             }
     158        5568 :             set_zero_fx( hOMasa->direction_vector_m_fx[i][j], MASA_FREQUENCY_BANDS );
     159             :         }
     160        1392 :         hOMasa->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) );
     161             : 
     162        6960 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     163             :         {
     164        5568 :             IF( ( hOMasa->direction_vector_e[i][j] = (Word16 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word16 ) ) ) == NULL )
     165             :             {
     166           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     167             :             }
     168        5568 :             set16_fx( hOMasa->direction_vector_e[i][j], 0, MASA_FREQUENCY_BANDS );
     169             :         }
     170             :     }
     171             : 
     172        1856 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     173             :     {
     174       45936 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     175             :         {
     176       44544 :             IF( ( hOMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     177             :             {
     178           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     179             :             }
     180       44544 :             set_zero_fx( hOMasa->buffer_intensity_real_fx[i][j], MASA_FREQUENCY_BANDS );
     181             :         }
     182             :     }
     183         464 :     set16_fx( hOMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
     184         464 :     set_zero_fx( hOMasa->buffer_energy_fx, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     185         464 :     set16_fx( hOMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
     186             : 
     187        2320 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
     188             :     {
     189        1856 :         set16_fx( hOMasa->prev_object_dm_gains_fx[i], INV_SQRT_2_Q15, MASA_MAX_TRANSPORT_CHANNELS ); /*q15*/
     190             :     }
     191         464 :     set_zero_fx( hOMasa->broadband_energy_sm_fx, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
     192         464 :     hOMasa->broadband_energy_sm_e = 0;
     193         464 :     move16();
     194         464 :     set_zero_fx( hOMasa->broadband_energy_prev_fx, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
     195         464 :     hOMasa->broadband_energy_prev_e = 0;
     196         464 :     move16();
     197             : 
     198         464 :     hOMasa->prev_selected_object = 0;
     199         464 :     hOMasa->changing_object = 0;
     200         464 :     hOMasa->since_obj_change_cnt = 0;
     201         464 :     move16();
     202         464 :     move16();
     203         464 :     move16();
     204             : 
     205         464 :     input_frame = extract_l( Mult_32_16( st_ivas->hEncoderConfig->input_Fs /*q0*/, INV_FRAME_PER_SEC_Q15 /*q15*/ ) ); /*Q0+Q15-Q15->Q0*/
     206      420304 :     FOR( i = 0; i < input_frame; i++ )
     207             :     {
     208      419840 :         hOMasa->interpolator_fx[i] = divide1616( i, input_frame );                                                                                                                                                                                                                       /*q15*/
     209      419840 :         hOMasa->fade_out_gain_fx[i] = add( 16384 /*0.5 in q15*/, shr( getCosWord16R2( mult( hOMasa->interpolator_fx[i], 32767 / 2 ) /*15+15-15=>15*/ ), 1 ) /*q15*/ ); /*(angle in degrees=((float)i/(float)input_frame *pi)*180/pi)/360*32767 =>(float)i/(float)input_frame )*32767/2*/ /*q15*/
     210      419840 :         hOMasa->fade_in_gain_fx[i] = sub( 32767 /*1.0 in Q15*/, hOMasa->fade_out_gain_fx[i] );                                                                                                                                                                                           /*q15*/
     211      419840 :         move16();
     212      419840 :         move16();
     213      419840 :         move16();
     214             :     }
     215             : 
     216         464 :     hOMasa->index_buffer_intensity = 0;
     217         464 :     move16();
     218             : 
     219         464 :     st_ivas->hOMasa = hOMasa;
     220             : 
     221         464 :     return error;
     222             : }
     223             : 
     224             : 
     225             : /*--------------------------------------------------------------------------*
     226             :  * ivas_omasa_enc_close()
     227             :  *
     228             :  * Close OMASA handle
     229             :  *--------------------------------------------------------------------------*/
     230             : 
     231        1066 : void ivas_omasa_enc_close_fx(
     232             :     OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
     233             : )
     234             : {
     235             :     Word16 i, j;
     236             : 
     237        1066 :     test();
     238        1066 :     IF( hOMasa == NULL || *hOMasa == NULL )
     239             :     {
     240         602 :         return;
     241             :     }
     242             : 
     243        1906 :     FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
     244             :     {
     245        1442 :         deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
     246             :     }
     247             : 
     248        1856 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     249             :     {
     250        6960 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     251             :         {
     252        5568 :             free( ( *hOMasa )->direction_vector_m_fx[i][j] );
     253        5568 :             ( *hOMasa )->direction_vector_m_fx[i][j] = NULL;
     254        5568 :             free( ( *hOMasa )->direction_vector_e[i][j] );
     255        5568 :             ( *hOMasa )->direction_vector_e[i][j] = NULL;
     256             :         }
     257             : 
     258       45936 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     259             :         {
     260       44544 :             free( ( *hOMasa )->buffer_intensity_real_fx[i][j] );
     261       44544 :             ( *hOMasa )->buffer_intensity_real_fx[i][j] = NULL;
     262             :         }
     263        1392 :         free( ( *hOMasa )->direction_vector_m_fx[i] );
     264        1392 :         ( *hOMasa )->direction_vector_m_fx[i] = NULL;
     265        1392 :         free( ( *hOMasa )->direction_vector_e[i] );
     266        1392 :         ( *hOMasa )->direction_vector_e[i] = NULL;
     267             :     }
     268             : 
     269         464 :     free( *hOMasa );
     270         464 :     ( *hOMasa ) = NULL;
     271             : 
     272         464 :     return;
     273             : }
     274             : 
     275             : 
     276             : /*--------------------------------------------------------------------------*
     277             :  * ivas_omasa_enc_config()
     278             :  *
     279             :  * oMASA encoder configuration
     280             :  *--------------------------------------------------------------------------*/
     281             : 
     282        9000 : ivas_error ivas_omasa_enc_config_fx(
     283             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
     284             : )
     285             : {
     286             :     Word16 k, sce_id, nSCE_old;
     287             :     Word32 ivas_total_brate, ism_total_brate;
     288             :     ENCODER_CONFIG_HANDLE hEncoderConfig;
     289             :     ivas_error error;
     290             : 
     291        9000 :     hEncoderConfig = st_ivas->hEncoderConfig;
     292        9000 :     ivas_total_brate = hEncoderConfig->ivas_total_brate;
     293        9000 :     nSCE_old = st_ivas->nSCE;
     294        9000 :     move16();
     295        9000 :     move32(); /*hEncoderConfig->ivas_total_brate*/
     296             : 
     297        9000 :     st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, hEncoderConfig->nchan_ism );
     298        9000 :     move16();
     299        9000 :     st_ivas->nchan_transport = 2;
     300        9000 :     move16();
     301             : 
     302             :     /* reconfiguration in case of bitrate switching */
     303        9000 :     IF( NE_32( hEncoderConfig->last_ivas_total_brate, ivas_total_brate ) )
     304             :     {
     305        1634 :         ivas_set_omasa_TC_fx( st_ivas->ism_mode, hEncoderConfig->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
     306             : 
     307        1634 :         k = 0;
     308        1634 :         move16();
     309       12910 :         WHILE( ( k < SIZE_IVAS_BRATE_TBL ) && ( ivas_total_brate != ivas_brate_tbl[k] ) )
     310             :         {
     311       11276 :             test();
     312       11276 :             k = add( k, 1 );
     313             :         }
     314             : 
     315        1634 :         ism_total_brate = 0;
     316        1634 :         move32();
     317        3746 :         FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
     318             :         {
     319        2112 :             ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] );
     320             :         }
     321             : 
     322        1634 :         IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     323             :         {
     324         403 :             IF( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
     325             :             {
     326           0 :                 return error;
     327             :             }
     328             :         }
     329        1231 :         ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     330             :         {
     331         439 :             IF( ( error = ivas_ism_config_fx( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nSCE, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
     332             :             {
     333           0 :                 return error;
     334             :             }
     335             :         }
     336             : 
     337             :         /* reconfigure core-coders for ISMs */
     338        1634 :         IF( st_ivas->nSCE > 0 )
     339             :         {
     340        1190 :             IF( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, 1, 2, sep_object_brate[k - 2][st_ivas->nSCE - 1], L_sub( ivas_total_brate, ism_total_brate ), MC_MODE_NONE ) ) != IVAS_ERR_OK )
     341             :             {
     342           0 :                 return error;
     343             :             }
     344             :         }
     345             :         ELSE
     346             :         {
     347         444 :             IF( ( error = ivas_corecoder_enc_reconfig_fx( st_ivas, nSCE_old, 1, 2, 0, L_sub( ivas_total_brate, ism_total_brate ), MC_MODE_NONE ) ) != IVAS_ERR_OK )
     348             :             {
     349           0 :                 return error;
     350             :             }
     351             :         }
     352             : 
     353             :         /* re-write IVAS format signalling - actual 'ism_mode' was not known before */
     354        1634 :         IF( st_ivas->nSCE > 0 )
     355             :         {
     356        1190 :             reset_indices_enc_fx( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
     357             :         }
     358             :         ELSE
     359             :         {
     360         444 :             reset_indices_enc_fx( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
     361             :         }
     362             : 
     363        1634 :         ivas_write_format_fx( st_ivas );
     364             : 
     365             :         /* OMASA encoder handle */
     366        1634 :         test();
     367        1634 :         test();
     368        1634 :         IF( NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hOMasa == NULL )
     369             :         {
     370         437 :             IF( ( error = ivas_omasa_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK )
     371             :             {
     372           0 :                 return error;
     373             :             }
     374             :         }
     375        1197 :         ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hOMasa != NULL )
     376             :         {
     377         439 :             ivas_omasa_enc_close_fx( &( st_ivas->hOMasa ) );
     378         439 :             st_ivas->hOMasa = NULL;
     379             :         }
     380             : 
     381             :         /* OMASA energy handle */
     382        1634 :         test();
     383        1634 :         test();
     384        1634 :         IF( NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy == NULL )
     385             :         {
     386         437 :             IF( ( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = (OMASA_ENCODER_ENERGY_HANDLE) malloc( sizeof( OMASA_ENCODER_ENERGY_STATE ) ) ) == NULL )
     387             :             {
     388           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA energy handle\n" ) );
     389             :             }
     390             :         }
     391        1197 :         ELSE IF( EQ_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) && st_ivas->hMasa->data.hOmasaData->hOmasaEnergy != NULL )
     392             :         {
     393         439 :             free( st_ivas->hMasa->data.hOmasaData->hOmasaEnergy );
     394         439 :             st_ivas->hMasa->data.hOmasaData->hOmasaEnergy = NULL;
     395             :         }
     396             : 
     397        1634 :         st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate );
     398        1634 :         move32();
     399             : 
     400        1634 :         IF( GE_32( L_sub( ivas_total_brate, ism_total_brate ), MIN_BRATE_MDCT_STEREO ) )
     401             :         {
     402         709 :             hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
     403             :         }
     404             :         ELSE
     405             :         {
     406         925 :             hEncoderConfig->element_mode_init = IVAS_CPE_DFT;
     407             :         }
     408        1634 :         move16();
     409             :     }
     410             : 
     411             :     /* Configure MASA encoder based on frame parameters */
     412        9000 :     IF( ( error = ivas_masa_enc_config_fx( st_ivas ) ) != IVAS_ERR_OK )
     413             :     {
     414           0 :         return error;
     415             :     }
     416             : 
     417        9000 :     IF( NE_16( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     418             :     {
     419             :         /* Configure oMASA analysis based on MASA config */
     420        5858 :         ivas_omasa_set_config_fx( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode );
     421             :     }
     422             : 
     423        9000 :     return IVAS_ERR_OK;
     424             : }
     425             : 
     426             : 
     427             : /*--------------------------------------------------------------------------*
     428             :  * ivas_omasa_set_config()
     429             :  *
     430             :  * Frame-by-frame config for oMASA
     431             :  *--------------------------------------------------------------------------*/
     432             : 
     433        5858 : void ivas_omasa_set_config_fx(
     434             :     OMASA_ENC_HANDLE hOMasa,   /* i/o: OMASA encoder handle */
     435             :     MASA_ENCODER_HANDLE hMasa, /* i  : MASA encoder handle  */
     436             :     const Word32 input_Fs,     /* i  : Input sample rate    */
     437             :     const ISM_MODE ism_mode    /* i  : ISM mode             */
     438             : )
     439             : {
     440             :     UWord8 i, maxBin;
     441             : 
     442             :     /* Determine the number of bands */
     443        5858 :     test();
     444        5858 :     IF( EQ_16( ism_mode, ISM_MODE_NONE ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     445             :     {
     446             :         /* use full resolution for the ISM+MASA merge and reduce later */
     447        3996 :         hOMasa->nbands = 24;
     448             :     }
     449             :     ELSE
     450             :     {
     451        1862 :         hOMasa->nbands = hMasa->config.numCodingBands;
     452             :     }
     453        5858 :     move16();
     454             : 
     455        5858 :     hOMasa->nCodingBands = hMasa->config.numCodingBands;
     456        5858 :     move16();
     457             : 
     458             :     /* Determine the number of subframes */
     459        5858 :     IF( EQ_16( hMasa->config.joinedSubframes, TRUE ) )
     460        1426 :     hOMasa->nSubframes = 1;
     461             :     ELSE
     462        4432 :         hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES;
     463        5858 :     move16();
     464             : 
     465             :     /* Determine band grouping */
     466        5858 :     IF( EQ_16( hOMasa->nbands, 24 ) )
     467             :     {
     468        3996 :         Copy( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
     469             :     }
     470             :     ELSE
     471             :     {
     472       15680 :         FOR( i = 0; i < hOMasa->nbands + 1; i++ )
     473             :         {
     474       13818 :             hOMasa->band_grouping[i] = MASA_band_grouping_24[hMasa->data.band_mapping[i]];
     475       13818 :             move16();
     476             :         }
     477             :     }
     478             : 
     479        5858 :     maxBin = (UWord8) L_shr( L_add( Mpy_32_32( L_shl( input_Fs, 1 ), INV_CLDFB_BANDWIDTH_Q31 ), 1 ), 1 ); /*(uint8_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f )*/
     480        5858 :     move16();
     481             : 
     482      106960 :     FOR( i = 1; i < hOMasa->nbands + 1; i++ )
     483             :     {
     484      106960 :         IF( GE_16( hOMasa->band_grouping[i], maxBin ) )
     485             :         {
     486        5858 :             hOMasa->band_grouping[i] = maxBin;
     487        5858 :             hOMasa->nbands = i;
     488        5858 :             move16();
     489        5858 :             move16();
     490        5858 :             BREAK;
     491             :         }
     492             :     }
     493             : 
     494        5858 :     Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); // Q0
     495        5858 :     IF( EQ_16( hOMasa->nSubframes, 1 ) )
     496             :     {
     497        1426 :         hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES];
     498        1426 :         move16();
     499             :     }
     500             : 
     501        5858 :     return;
     502             : }
     503             : 
     504             : 
     505             : /*--------------------------------------------------------------------------*
     506             :  * ivas_omasa_enc()
     507             :  *
     508             :  * Main OMASA encoding function
     509             :  *--------------------------------------------------------------------------*/
     510             : 
     511        5858 : void ivas_omasa_enc_fx(
     512             :     OMASA_ENC_HANDLE hOMasa,          /* i/o: OMASA encoder handle                        */
     513             :     MASA_ENCODER_HANDLE hMasa,        /* i/o: MASA encoder handle                         */
     514             :     ISM_METADATA_HANDLE hIsmMeta[],   /* i/o: ISM metadata handle                         */
     515             :     Word32 *data_in[],                /* i/o: Input / transport audio signals       q_data*/
     516             :     Word16 q_data,                    /* i  : Q0 Stores the q for data_in                 */
     517             :     const Word16 input_frame,         /* i  : Input frame size                            */
     518             :     const Word16 nchan_transport,     /* i  : Number of transport channels                */
     519             :     const Word16 nchan_ism,           /* i  : Number of objects for parameter analysis    */
     520             :     const ISM_MODE ism_mode,          /* i  : ISM mode                                    */
     521             :     Word32 *data_separated_object_fx, /* o  : Separated object audio signal               */
     522             :     Word16 *idx_separated_object      /* o  : Index of the separated object               */
     523             : )
     524             : {
     525             :     Word16 i, j;
     526             :     Word32 data_out[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
     527             : 
     528             :     /* Determine separated object (when applicable) */
     529        5858 :     test();
     530        5858 :     IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     531             :     {
     532             :         Word32 broadband_energy_fx[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
     533             :         Word16 broadband_energy_e[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
     534        3916 :         Word16 max_broadband_energy_e = MIN_16;
     535        3916 :         move16();
     536             :         Word16 loudest_object;
     537             :         Word16 selected_object;
     538             :         Word16 nchan_all_inp;
     539             :         UWord8 fade_out_separate_object;
     540             :         UWord8 fade_in_separate_object;
     541             :         Word32 temp32; /*temp32_e*/
     542             : 
     543             :         /* Estimate broadband energies */
     544        3916 :         nchan_all_inp = add( nchan_ism, nchan_transport );
     545        3916 :         set_zero_fx( broadband_energy_fx, nchan_all_inp );
     546        3916 :         set16_fx( broadband_energy_e, 0, nchan_all_inp );
     547             : 
     548       25272 :         FOR( i = 0; i < nchan_all_inp; i++ )
     549             :         {
     550    19569516 :             FOR( j = 0; j < input_frame; j++ )
     551             :             {
     552    19548160 :                 temp32 = L_shl( data_in[i][j], 6 ); /* scaling data_in to prevent zeroes values in Mpy_32_32 due to precision loss*/
     553    19548160 :                 broadband_energy_fx[i] = BASOP_Util_Add_Mant32Exp( broadband_energy_fx[i], broadband_energy_e[i], Mpy_32_32( temp32, temp32 ), sub( 50, shl( q_data, 1 ) ) /*exponent=62-2*(q+6)*/, &broadband_energy_e[i] );
     554    19548160 :                 move32();
     555             :             }
     556       21356 :             max_broadband_energy_e = s_max( max_broadband_energy_e, broadband_energy_e[i] ); /*calculating maximum exponent for all values in broadband_energy_e*/
     557             :         }
     558             : 
     559             :         /*scaling all the values in broadband_energy_fx to max_broadband_energy_e*/
     560       25272 :         FOR( i = 0; i < nchan_all_inp; i++ )
     561             :         {
     562       21356 :             broadband_energy_fx[i] = L_shr( broadband_energy_fx[i], sub( max_broadband_energy_e, broadband_energy_e[i] ) );
     563       21356 :             move32();
     564             :         }
     565             :         /*making exponent for hOMasa->broadband_energy_sm_fx and broadband_energy_fx equal as they are used in addition later*/
     566        3916 :         IF( GT_16( max_broadband_energy_e, hOMasa->broadband_energy_sm_e ) )
     567             :         {
     568         680 :             Scale_sig32( hOMasa->broadband_energy_sm_fx, nchan_all_inp, sub( hOMasa->broadband_energy_sm_e, max_broadband_energy_e ) );
     569         680 :             hOMasa->broadband_energy_sm_e = max_broadband_energy_e;
     570         680 :             move16();
     571             :         }
     572             :         ELSE
     573             :         {
     574        3236 :             Scale_sig32( broadband_energy_fx, nchan_all_inp, sub( max_broadband_energy_e, hOMasa->broadband_energy_sm_e ) );
     575        3236 :             max_broadband_energy_e = hOMasa->broadband_energy_sm_e;
     576        3236 :             move16();
     577             :         }
     578             : 
     579             :         /* Temporal averaging */
     580             :         // alpha = 26214;/*0.8 Q15*/
     581       25272 :         FOR( i = 0; i < nchan_all_inp; i++ )
     582             :         {
     583       21356 :             hOMasa->broadband_energy_sm_fx[i] = L_add( Mpy_32_16_1( broadband_energy_fx[i], 6554 /*0.2 Q15*/ ), Mpy_32_16_1( hOMasa->broadband_energy_sm_fx[i], 26214 /*0.8 Q15*/ ) );
     584       21356 :             move32();
     585             :         }
     586             : 
     587             :         /* Determine loudest object */
     588        3916 :         loudest_object = 0;
     589        3916 :         move16();
     590       13524 :         FOR( i = 1; i < nchan_ism; i++ )
     591             :         {
     592        9608 :             if ( GT_32( hOMasa->broadband_energy_sm_fx[i], hOMasa->broadband_energy_sm_fx[loudest_object] ) )
     593             :             {
     594        1998 :                 loudest_object = i;
     595        1998 :                 move16();
     596             :             }
     597             :         }
     598             : 
     599             :         /* Determine object to separate */
     600        3916 :         selected_object = hOMasa->prev_selected_object;
     601        3916 :         fade_out_separate_object = 0;
     602        3916 :         fade_in_separate_object = 0;
     603        3916 :         move16();
     604        3916 :         move16();
     605        3916 :         move16();
     606        3916 :         IF( hOMasa->changing_object )
     607             :         {
     608         125 :             hOMasa->changing_object = 0;
     609         125 :             selected_object = loudest_object;
     610         125 :             fade_in_separate_object = 1;
     611         125 :             move16();
     612         125 :             move16();
     613         125 :             move16();
     614             :         }
     615             :         ELSE
     616             :         {
     617        3791 :             IF( NE_16( loudest_object, hOMasa->prev_selected_object ) )
     618             :             {
     619             :                 Word32 selected_ene_fx; /*selected_ene_e*/
     620             :                 Word16 selected_ene_e;
     621             :                 Word32 total_ene_fx; /*total_ene_e*/
     622             :                 Word16 total_ene_e;
     623             :                 Word32 selected_ratio_fx; /*selected_ratio_e*/
     624             :                 Word16 selected_ratio_e;
     625             :                 Word32 adaptive_threshold_dB_fx;
     626             :                 Word32 ratio_objects_dB_fx;
     627             :                 Word32 hardswitch_threshold_fx; /*(0.25 q30) as selected_ratio_fx is in q30(both are compared later)*/
     628             :                 Word16 temp32_e;
     629         763 :                 selected_ene_e = 0;
     630         763 :                 temp32_e = 0;
     631         763 :                 hardswitch_threshold_fx = 268435456; /*(0.25 q30)*/
     632         763 :                 selected_ratio_e = 0;
     633         763 :                 total_ene_e = 0;
     634         763 :                 move16();
     635         763 :                 move16();
     636         763 :                 move16();
     637         763 :                 move16();
     638         763 :                 move32();
     639             : 
     640             :                 /* Compute the energy of the current and the previous selected object in the current and the previous frame */
     641             :                 /*scaling broadband_energy_fx and broadband_energy_prev_fx by 1 (guard bit for addition operation)*/
     642         763 :                 selected_ene_fx = BASOP_Util_Add_Mant32Exp( L_add( L_shr( broadband_energy_fx[loudest_object], 1 ), L_shr( broadband_energy_fx[hOMasa->prev_selected_object], 1 ) ), add( max_broadband_energy_e, 1 ), L_add( L_shr( hOMasa->broadband_energy_prev_fx[loudest_object], 1 ), L_shr( hOMasa->broadband_energy_prev_fx[hOMasa->prev_selected_object], 1 ) ), add( hOMasa->broadband_energy_prev_e, 1 ), &selected_ene_e );
     643             : 
     644             :                 /* Compute the energy of all objects and MASA channels in the current and the previous frame */
     645         763 :                 total_ene_fx = 0;
     646         763 :                 move32();
     647        4917 :                 FOR( i = 0; i < nchan_all_inp; i++ )
     648             :                 {
     649        4154 :                     total_ene_fx = BASOP_Util_Add_Mant32Exp( total_ene_fx, total_ene_e, broadband_energy_fx[i], max_broadband_energy_e, &total_ene_e );
     650        4154 :                     total_ene_fx = BASOP_Util_Add_Mant32Exp( total_ene_fx, total_ene_e, hOMasa->broadband_energy_prev_fx[i], hOMasa->broadband_energy_prev_e, &total_ene_e );
     651             :                 }
     652             : 
     653             :                 /* Compute the ratio */
     654         763 :                 selected_ratio_fx = BASOP_Util_Divide3232_Scale( selected_ene_fx, L_add_sat( total_ene_fx, EPSILON_FX ), &selected_ratio_e );
     655         763 :                 selected_ratio_e = add( selected_ratio_e, sub( selected_ene_e, total_ene_e ) );
     656         763 :                 selected_ratio_fx = L_shl( selected_ratio_fx, add( selected_ratio_e, 15 ) );                                                                                             /*scaling to q30 as the value will always be <=1*/
     657         763 :                 adaptive_threshold_dB_fx = L_add( Mpy_32_16_1( selected_ratio_fx /*q30*/, 576 /*9 in q6*/ ), ONE_IN_Q21 ); /* selected ratio = 0 -> 1 dB, selected ratio = 1 -> 10 dB */ /*q21*/
     658         763 :                 temp32 = BASOP_Util_Divide3232_Scale( hOMasa->broadband_energy_sm_fx[loudest_object], L_add_sat( hOMasa->broadband_energy_sm_fx[hOMasa->prev_selected_object], EPSILON_FX ), &temp32_e );
     659         763 :                 ratio_objects_dB_fx = Mult_32_16( BASOP_Util_Log10( temp32, add( 16, temp32_e ) ) /*q25*/, 20480 /*10 in q11*/ ); /*q21 as the maximum value can go up to 320*/
     660             : 
     661             :                 /* Adaptively determine whether to change the separated object. If they are quiet compared to the total energy, change easier, as other signals mask the change. */
     662         763 :                 IF( GT_32( ratio_objects_dB_fx, adaptive_threshold_dB_fx ) )
     663             :                 {
     664         184 :                     IF( LT_32( selected_ratio_fx, hardswitch_threshold_fx ) ) /* If low level compared to all audio channels, perform hardswitch */
     665             :                     {
     666          53 :                         selected_object = loudest_object;
     667          53 :                         move16();
     668             :                     }
     669             :                     ELSE /* If high level compared to all audio channels, perform switch via fade out fade in */
     670             :                     {
     671         131 :                         hOMasa->changing_object = 1;
     672         131 :                         fade_out_separate_object = 1;
     673         131 :                         move16();
     674         131 :                         move16();
     675             :                     }
     676             :                 }
     677             :             }
     678             :         }
     679             : 
     680             :         /* Set values for next frame */
     681       25272 :         FOR( i = 0; i < nchan_all_inp; i++ )
     682             :         {
     683       21356 :             hOMasa->broadband_energy_prev_fx[i] = broadband_energy_fx[i];
     684       21356 :             hOMasa->broadband_energy_prev_e = max_broadband_energy_e;
     685       21356 :             move32();
     686       21356 :             move16();
     687             :         }
     688             : 
     689             :         /* force absolute MD coding in case of change of separated object */
     690        3916 :         IF( NE_16( hOMasa->prev_selected_object, selected_object ) )
     691             :         {
     692         178 :             hOMasa->since_obj_change_cnt = 0;
     693         178 :             hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     694         178 :             move16();
     695         178 :             move16();
     696             :         }
     697             :         ELSE
     698             :         {
     699        3738 :             hOMasa->since_obj_change_cnt = add( hOMasa->since_obj_change_cnt, 1 );
     700        3738 :             hOMasa->since_obj_change_cnt = s_min( OMASA_FEC_MAX, hOMasa->since_obj_change_cnt );
     701        3738 :             IF( LT_16( hOMasa->since_obj_change_cnt, OMASA_FEC_MAX ) )
     702             :             {
     703        1293 :                 hIsmMeta[0]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
     704        1293 :                 move16();
     705             :             }
     706             :         }
     707        3916 :         hOMasa->prev_selected_object = selected_object;
     708        3916 :         move16();
     709             : 
     710             :         /* Separate the selected object */
     711        3916 :         *idx_separated_object = selected_object;
     712        3916 :         move16();
     713        3916 :         Copy32( data_in[selected_object], data_separated_object_fx, input_frame );
     714        3916 :         IF( fade_out_separate_object )
     715             :         {
     716         131 :             v_L_mult_3216( data_separated_object_fx, hOMasa->fade_out_gain_fx, data_separated_object_fx, input_frame ); /*q_data + q15 -q15*/
     717         131 :             v_L_mult_3216( data_in[selected_object], hOMasa->fade_in_gain_fx, data_in[selected_object], input_frame );  /*q_data + q15 -q15*/
     718             :         }
     719        3785 :         ELSE IF( fade_in_separate_object )
     720             :         {
     721         125 :             v_L_mult_3216( data_separated_object_fx, hOMasa->fade_in_gain_fx, data_separated_object_fx, input_frame );  /*q_data + q15 -q15*/
     722         125 :             v_L_mult_3216( data_in[selected_object], hOMasa->fade_out_gain_fx, data_in[selected_object], input_frame ); /*q_data + q15 -q15*/
     723             :         }
     724             :         ELSE
     725             :         {
     726        3660 :             set_zero_fx( data_in[selected_object], input_frame );
     727             :         }
     728             :     }
     729             : 
     730             :     /* Analysis */
     731        5858 :     test();
     732        5858 :     IF( EQ_16( ism_mode, ISM_MODE_NONE ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     733        3996 :     {
     734             :         OMASA_SPATIAL_META OMasaMeta; /* working memory for the ISM-object MASA-parameters */
     735             :         OMASA_SPATIAL_META_HANDLE hOMasaMeta;
     736             :         UWord8 n_bands_orig, n_subframes_orig;
     737             :         UWord8 numCodingBands_orig, joinedSubframes_orig;
     738             : 
     739        3996 :         hOMasaMeta = &OMasaMeta;
     740        3996 :         hOMasaMeta->num_dirs = 1;
     741        3996 :         move16();
     742             : 
     743             :         /* merge MASA directions before adding ISM to the mixture */
     744        3996 :         IF( EQ_16( hMasa->config.numberOfDirections, 2 ) )
     745             :         {
     746        2198 :             n_bands_orig = hMasa->config.numCodingBands;
     747        2198 :             move16();
     748        2198 :             hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS;
     749        2198 :             move16();
     750             :             /* Estimate the importance of having two directions instead of one */
     751             : 
     752        2198 :             ivas_masa_combine_directions_fx( hMasa );
     753             : 
     754        2198 :             hMasa->config.numCodingBands = (Word8) n_bands_orig;
     755        2198 :             move16();
     756             :         }
     757             : 
     758             :         /* force computation into high resolution */
     759             : 
     760        3996 :         n_subframes_orig = hOMasa->nSubframes;
     761        3996 :         hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES;
     762        3996 :         move16();
     763        3996 :         move16();
     764             : 
     765             :         /* Estimate MASA parameters from the objects */
     766             :         /* NB: only first direction is populated */
     767             :         /* NB2: in energy_ratios and surround_coherence only first sub-frame contains valid data */
     768        3996 :         ivas_omasa_param_est_enc_fx( hOMasa, hMasa->data.hOmasaData, hIsmMeta, data_in, hOMasaMeta->directional_meta[0].elevation_fx, hOMasaMeta->directional_meta[0].azimuth_fx, hOMasaMeta->directional_meta[0].energy_ratio_fx[0], hOMasaMeta->directional_meta[0].spread_coherence_fx, hOMasaMeta->common_meta.surround_coherence_fx[0],
     769        3996 :                                      hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0], input_frame, nchan_ism, q_data );
     770             : 
     771             :         /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */
     772       15984 :         FOR( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     773             :         {
     774       11988 :             Copy32( hOMasaMeta->directional_meta[0].energy_ratio_fx[0], hOMasaMeta->directional_meta[0].energy_ratio_fx[i], MASA_FREQUENCY_BANDS );     /*q30*/
     775       11988 :             Copy( hOMasaMeta->common_meta.surround_coherence_fx[0], hOMasaMeta->common_meta.surround_coherence_fx[i], MASA_FREQUENCY_BANDS );           /*q14*/
     776       11988 :             Copy32( hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0], hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[i], MASA_FREQUENCY_BANDS ); /*q30*/
     777             :         }
     778             : 
     779             :         /* restore resolution parameters */
     780        3996 :         hOMasa->nSubframes = n_subframes_orig;
     781        3996 :         move16();
     782             : 
     783             :         /* perform MASA+ISM merge in full resolution */
     784        3996 :         numCodingBands_orig = hMasa->config.numCodingBands;
     785        3996 :         joinedSubframes_orig = hMasa->config.joinedSubframes;
     786        3996 :         move16();
     787        3996 :         move16();
     788             : 
     789        3996 :         hMasa->config.numCodingBands = hOMasa->nbands;
     790        3996 :         hMasa->config.joinedSubframes = 0;
     791        3996 :         move16();
     792        3996 :         move16();
     793             : 
     794        3996 :         ivas_merge_masa_metadata_fx( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */
     795             : 
     796        3996 :         hMasa->config.numCodingBands = numCodingBands_orig;
     797        3996 :         hMasa->config.joinedSubframes = joinedSubframes_orig;
     798        3996 :         move16();
     799        3996 :         move16();
     800             :     }
     801        1862 :     ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     802             :     {
     803             :         /* Estimate energies and ratios */
     804        1862 :         ivas_omasa_energy_and_ratio_est_fx( hOMasa, hMasa->data.hOmasaData, data_in, input_frame, nchan_ism, q_data );
     805             :     }
     806             : 
     807             :     /* Downmix */
     808             : 
     809        5858 :     ivas_omasa_dmx_fx( data_in, data_out, input_frame, nchan_transport, nchan_ism, hIsmMeta, hOMasa->prev_object_dm_gains_fx, hOMasa->interpolator_fx );
     810             :     /* Move the ISM metadata to the first entry for encoding in the MASA_ONE_OBJ mode */
     811        5858 :     IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     812             :     {
     813        2054 :         hIsmMeta[0]->azimuth_fx = hIsmMeta[*idx_separated_object]->azimuth_fx;     // Q22
     814        2054 :         hIsmMeta[0]->elevation_fx = hIsmMeta[*idx_separated_object]->elevation_fx; // Q22
     815        2054 :         move32();
     816        2054 :         move32();
     817             :     }
     818             : 
     819             :     /* Merge transport signals */
     820        5858 :     ivas_merge_masa_transports_fx( data_out, &( data_in[nchan_ism] ), data_in, input_frame, nchan_transport );
     821             : 
     822        5858 :     return;
     823             : }
     824             : 
     825             : 
     826             : /*-------------------------------------------------------------------------*
     827             :  * ivas_set_ism_importance_interformat()
     828             :  *
     829             :  * Set the importance of particular ISM streams in combined-format coding
     830             :  *-------------------------------------------------------------------------*/
     831             : 
     832        7058 : void ivas_set_ism_importance_interformat_fx(
     833             :     const Word32 ism_total_brate,   /* i/o: ISms total bitrate                    */
     834             :     const Word16 nchan_transport,   /* i  : number of transported channels        */
     835             :     ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles                  */
     836             :     SCE_ENC_HANDLE hSCE[],          /* i/o: SCE encoder handles                   */
     837             :     const Word16 lp_noise_CPE_fx,   /* i  : LP filtered total noise estimation Q8 */
     838             :     Word16 ism_imp[]                /* o  : ISM importance flags                  */
     839             : )
     840             : {
     841             :     Encoder_State *st;
     842             :     Word16 ch, ctype, active_flag;
     843             : 
     844       19434 :     FOR( ch = 0; ch < nchan_transport; ch++ )
     845             :     {
     846       12376 :         st = hSCE[ch]->hCoreCoder[0];
     847             : 
     848       12376 :         active_flag = st->vad_flag;
     849       12376 :         move16();
     850             : 
     851       12376 :         IF( active_flag == 0 )
     852             :         {
     853         272 :             test();
     854         272 :             if ( GT_32( st->lp_noise_32fx, 251658240 /* 15 in Q24 */ ) || LT_16( sub( lp_noise_CPE_fx, extract_h( st->lp_noise_32fx ) ), 7680 /* 30 in Q8 */ ) )
     855             :             {
     856         272 :                 active_flag = 1;
     857         272 :                 move16();
     858             :             }
     859             :         }
     860             : 
     861             :         Word32 quo, rem;
     862       12376 :         iDiv_and_mod_32( ism_total_brate, nchan_transport, &quo, &rem, 0 );
     863             : 
     864             :         /* do not use the low-rate core-coder mode at highest bit-rates */
     865       12376 :         if ( GT_32( quo, IVAS_48k ) )
     866             :         {
     867        1428 :             active_flag = 1;
     868        1428 :             move16();
     869             :         }
     870             : 
     871       12376 :         ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
     872       12376 :         move16();
     873             : 
     874       12376 :         st->low_rate_mode = 0;
     875       12376 :         move16();
     876       12376 :         test();
     877       12376 :         IF( active_flag == 0 )
     878             :         {
     879           0 :             ism_imp[ch] = ISM_INACTIVE_IMP;
     880           0 :             move16();
     881           0 :             st->low_rate_mode = 1;
     882           0 :             move16();
     883             :         }
     884       12376 :         ELSE IF( EQ_16( ctype, INACTIVE ) || EQ_16( ctype, UNVOICED ) )
     885             :         {
     886         449 :             ism_imp[ch] = ISM_LOW_IMP;
     887         449 :             move16();
     888             :         }
     889       11927 :         ELSE IF( EQ_16( ctype, VOICED ) )
     890             :         {
     891        3105 :             ism_imp[ch] = ISM_MEDIUM_IMP;
     892        3105 :             move16();
     893             :         }
     894             :         ELSE /* GENERIC */
     895             :         {
     896        8822 :             ism_imp[ch] = ISM_HIGH_IMP;
     897        8822 :             move16();
     898             :         }
     899             : 
     900       12376 :         hIsmMeta[ch]->ism_metadata_flag = active_flag; /* flag is needed for the MD coding */
     901       12376 :         move16();
     902             :     }
     903             : 
     904        7058 :     return;
     905             : }
     906             : 
     907             : 
     908             : /*--------------------------------------------------------------------------*
     909             :  * ivas_set_surplus_brate_enc()
     910             :  *
     911             :  * set bit-rate surplus in combined format coding
     912             :  *--------------------------------------------------------------------------*/
     913             : 
     914        9000 : void ivas_set_surplus_brate_enc(
     915             :     Encoder_Struct *st_ivas /* i/o: IVAS encoder structure  */
     916             : #ifdef DEBUG_MODE_INFO
     917             :     ,
     918             :     const int16_t *nb_bits_metadata /* i  : number of metadata bits */
     919             : #endif
     920             : )
     921             : {
     922        9000 :     test();
     923        9000 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     924             :     {
     925        1862 :         st_ivas->hCPE[0]->brate_surplus = L_sub( st_ivas->hSCE[0]->element_brate, ivas_interformat_brate_fx( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 ) );
     926        1862 :         move32();
     927             :         /* note: ISM st->total_brate is iset in ivas_sce_enc() */
     928             :     }
     929        7138 :     ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     930             :     {
     931             :         /* it is already set in ivas_ism_enc() */
     932             :     }
     933             :     ELSE
     934             :     {
     935        1942 :         st_ivas->hCPE[0]->brate_surplus = 0;
     936        1942 :         move32();
     937             :     }
     938             : 
     939             : #ifdef DEBUG_MODE_INFO
     940             :     if ( st_ivas->hSCE[0] != NULL )
     941             :     {
     942             :         int16_t input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
     943             :         float tmpF = 0;
     944             : 
     945             :         if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
     946             :         {
     947             :             tmpF += st_ivas->hSCE[0]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[1] * 50 );
     948             :         }
     949             :         else
     950             :         {
     951             :             for ( int16_t i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
     952             :             {
     953             :                 tmpF += st_ivas->hSCE[i]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[i + 1] * 50 );
     954             :             }
     955             :         }
     956             :         tmpF /= 1000.f;
     957             :         dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_ISM" ); /* == ism_total_brate incl. ISM MD */
     958             :         tmpF = st_ivas->hEncoderConfig->ivas_total_brate / 1000.0f - tmpF;
     959             :         dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA" ); /* == masa_total_brate incl. MASA MD */
     960             :         tmpF = nb_bits_metadata[0] * FRAMES_PER_SEC / 1000.0f;
     961             :         dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA_MD" ); /* == MASA MD bitrate */
     962             :     }
     963             : #endif
     964             : 
     965        9000 :     return;
     966             : }
     967             : 
     968             : 
     969             : /*--------------------------------------------------------------------------*
     970             :  * ivas_omasa_ener_brate()
     971             :  *
     972             :  *
     973             :  *--------------------------------------------------------------------------*/
     974             : 
     975             : /*! r: OMASA energy bitrate flag */
     976        3142 : Word16 ivas_omasa_ener_brate_fx(
     977             :     const Word16 nchan_ism,        /* i  : number of ISMs                           */
     978             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate                       */
     979             :     Word32 *data_f[],              /* i  : Input / transport audio signals    data_e*/
     980             :     const Word16 input_frame,      /* i  : Input frame size                         */
     981             :     const Word16 data_e            /* i  : exponent for data_f                      */
     982             : )
     983             : {
     984             :     Word16 i, flag_omasa_ener_brate;
     985             :     Word32 energy_ism, energy_masa;
     986             :     Word16 energy_ism_e, energy_masa_e;
     987             :     Word32 temp_32;
     988             :     Word16 temp, temp_e;
     989             : 
     990        3142 :     flag_omasa_ener_brate = 0;
     991        3142 :     energy_ism_e = 0;
     992        3142 :     energy_masa_e = 0;
     993        3142 :     move16();
     994        3142 :     move16();
     995        3142 :     move16();
     996             : 
     997        3142 :     test();
     998        3142 :     IF( GE_16( nchan_ism, 3 ) && EQ_32( ivas_total_brate, IVAS_128k ) )
     999             :     {
    1000         126 :         energy_ism = 0;
    1001         126 :         move32();
    1002         570 :         FOR( i = 0; i < nchan_ism; i++ )
    1003             :         {
    1004         444 :             temp_e = data_e;
    1005         444 :             move16();
    1006         444 :             temp_32 = sum2_32_fx( data_f[i], input_frame, &temp_e );
    1007         444 :             energy_ism = BASOP_Util_Add_Mant32Exp( energy_ism, energy_ism_e, temp_32, temp_e, &energy_ism_e );
    1008             :         }
    1009             : 
    1010         126 :         energy_masa = 0;
    1011         126 :         move32();
    1012         378 :         FOR( i = nchan_ism; i < nchan_ism + MASA_MAXIMUM_DIRECTIONS; i++ )
    1013             :         {
    1014         252 :             temp_e = data_e;
    1015         252 :             move16();
    1016         252 :             temp_32 = sum2_32_fx( data_f[i], input_frame, &temp_e );
    1017         252 :             energy_masa = BASOP_Util_Add_Mant32Exp( energy_masa, energy_masa_e, temp_32, temp_e, &energy_masa_e );
    1018             :         }
    1019         126 :         IF( energy_masa_e < 0 )
    1020             :         {
    1021           0 :             energy_masa = L_shl( energy_masa, energy_masa_e );
    1022           0 :             energy_masa_e = 0;
    1023           0 :             move16();
    1024             :         }
    1025         126 :         energy_masa = L_shr( energy_masa, 1 );
    1026         126 :         energy_masa_e = add( energy_masa_e, 1 );
    1027         126 :         temp = divide1616( 2, nchan_ism ); /*q15*/
    1028         126 :         energy_ism = BASOP_Util_Divide3232_Scale( energy_ism, L_add( energy_masa, L_shr( ONE_IN_Q31, energy_masa_e ) ), &temp_e );
    1029         126 :         energy_ism_e = add( temp_e, sub( energy_ism_e, energy_masa_e ) );
    1030         126 :         energy_ism = Mpy_32_16_1( energy_ism, temp );
    1031         126 :         IF( energy_ism_e < 0 )
    1032             :         {
    1033          15 :             energy_ism = L_shl( energy_ism, energy_ism_e ); // Q31
    1034          15 :             energy_ism_e = 0;
    1035          15 :             move16();
    1036             :         }
    1037             : 
    1038         126 :         IF( LT_32( energy_ism, L_shr( ONE_IN_Q31, energy_ism_e ) ) )
    1039             :         {
    1040         126 :             flag_omasa_ener_brate = 1;
    1041         126 :             move16();
    1042             :         }
    1043             :     }
    1044             : 
    1045        3142 :     return flag_omasa_ener_brate;
    1046             : }
    1047             : 
    1048             : 
    1049             : /*--------------------------------------------------------------------------*
    1050             :  * Local functions
    1051             :  *--------------------------------------------------------------------------*/
    1052             : 
    1053             : /* Estimate MASA parameters from the objects */
    1054        3996 : static void ivas_omasa_param_est_enc_fx(
    1055             :     OMASA_ENC_HANDLE hOMasa,
    1056             :     OMASA_ENCODER_DATA_HANDLE hOmasaData,
    1057             :     ISM_METADATA_HANDLE hIsmMeta[],
    1058             :     Word32 *data[],                                                                  /*i:q_data*/
    1059             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/
    1060             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   /*o:q22*/
    1061             :     Word32 energyRatio_fx[MASA_FREQUENCY_BANDS],                                     /*o:Q30*/
    1062             :     Word16 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],    /*o:Q15*/
    1063             :     Word16 surroundingCoherence_fx[MASA_FREQUENCY_BANDS],                            /*o:Q15*/
    1064             :     Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS],                                   /*o:q30*/
    1065             :     const Word16 input_frame,
    1066             :     const Word16 nchan_ism,
    1067             :     Word16 q_data /*i: Qfactor for data*/
    1068             : )
    1069             : {
    1070             :     Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; // Q(31-ref_exp)
    1071             :     Word16 ref_exp;
    1072             :     Word16 ts, i, j, d, k;
    1073             :     Word16 num_freq_bins, num_freq_bands, index;
    1074             :     Word32 dir_v_fx[DIRAC_NUM_DIMS];
    1075             :     Word16 dir_v_e;
    1076             :     Word16 l_ts;
    1077             :     Word32 Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
    1078             :     Word32 Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
    1079             :     Word16 norm_buff;
    1080             :     Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
    1081             :     Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
    1082             :     Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
    1083             :     Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
    1084             :     Word16 intensity_real_e; /*exponent for intensity_real_fx*/
    1085             :     Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
    1086             :     Word16 q_diffuseness_vector;
    1087             :     Word32 norm_tmp_fx;
    1088             :     Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
    1089             :     Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
    1090             :     Word16 band_m_idx, block_m_idx;
    1091             :     Word16 mrange[2], brange[2];
    1092             :     Word16 diffuseness_e[MASA_FREQUENCY_BANDS];
    1093             :     Word16 azimuth_16, elevation_16;
    1094             :     Word16 band_grouping_diff[MASA_FREQUENCY_BANDS], guard_bits, max_band_grouping_diff;
    1095             :     Word16 q; /*stores q for cldfb buffers*/
    1096             :     Word32 temp;
    1097             :     Word16 temp_e;
    1098             :     Word16 q_intensity_real_fx[MASA_FREQUENCY_BANDS], q_reference_power_fx[CLDFB_NO_CHANNELS_MAX];
    1099        3996 :     OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
    1100             : 
    1101        3996 :     ref_exp = 0;
    1102        3996 :     norm_buff = MAX16B;
    1103        3996 :     dir_v_e = MIN_16;
    1104        3996 :     num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
    1105        3996 :     num_freq_bands = hOMasa->nbands;
    1106        3996 :     l_ts = shr( input_frame, CLDFB_NO_COL_MAX_LOG2 );
    1107        3996 :     move16();
    1108        3996 :     move16();
    1109        3996 :     move16();
    1110        3996 :     move16();
    1111        3996 :     move16();
    1112             : 
    1113             :     /* Need to initialize renormalization_factors, and variables to be normalized */
    1114        3996 :     set_zero_fx( &Foa_RealBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX );
    1115        3996 :     set_zero_fx( &Foa_ImagBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX );
    1116             : 
    1117        3996 :     set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands );
    1118        3996 :     set_zero_fx( diffuseness_m_fx, hOMasa->nbands );
    1119        3996 :     set16_fx( renormalization_factor_diff_e, 0, hOMasa->nbands );
    1120        3996 :     set16_fx( diffuseness_e, 0, hOMasa->nbands );
    1121       17156 :     FOR( i = 0; i < nchan_ism; i++ )
    1122             :     {
    1123       13160 :         set_zero_fx( Chnl_RealBuffer_fx[i], 60 );
    1124       13160 :         set_zero_fx( Chnl_ImagBuffer_fx[i], 60 );
    1125             :     }
    1126             :     /* Compute ISM to FOA matrices */
    1127       17156 :     FOR( i = 0; i < nchan_ism; i++ )
    1128             :     {
    1129       13160 :         azimuth_16 = extract_l( Mpy_32_32( hIsmMeta[i]->azimuth_fx, 46603 /*1<<24/360*/ ) );                     /*q15*/
    1130       13160 :         elevation_16 = extract_l( Mpy_32_32( hIsmMeta[i]->elevation_fx, 46603 /*1<<24/360*/ ) );                 /*q15*/
    1131       13160 :         hOMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31;                                                              /*q31*/
    1132       13160 :         hOMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( azimuth_16 ), getCosWord16R2( elevation_16 ) ); /*q31*/
    1133       13160 :         hOMasa->chnlToFoaMtx_fx[2][i] = L_deposit_h( getSineWord16R2( elevation_16 ) );                          /*q31*/
    1134       13160 :         hOMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( azimuth_16 ), getCosWord16R2( elevation_16 ) );  /*q31*/
    1135       13160 :         move32();
    1136       13160 :         move32();
    1137       13160 :         move32();
    1138       13160 :         move32();
    1139             :     }
    1140             : 
    1141        3996 :     q = q_data;
    1142        3996 :     move16();
    1143             :     /* do processing over all CLDFB time slots */
    1144       19980 :     FOR( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
    1145             :     {
    1146       15984 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
    1147       15984 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
    1148       15984 :         move16();
    1149       15984 :         move16();
    1150             : 
    1151      396000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
    1152             :         {
    1153      380016 :             hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
    1154      380016 :             hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
    1155      380016 :             hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
    1156      380016 :             hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] = 0;
    1157      380016 :             hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] = 0;
    1158      380016 :             hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] = 0;
    1159      380016 :             move32();
    1160      380016 :             move32();
    1161      380016 :             move32();
    1162      380016 :             move16();
    1163      380016 :             move16();
    1164      380016 :             move16();
    1165             :         }
    1166       15984 :         set_zero_fx( hOmasaEnergy->energy_ism_fx[block_m_idx], num_freq_bands );
    1167       15984 :         set16_fx( hOmasaEnergy->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
    1168             : 
    1169       88304 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
    1170             :         {
    1171       72320 :             norm_buff = MAX16B;
    1172       72320 :             move16();
    1173      311616 :             FOR( i = 0; i < nchan_ism; i++ )
    1174             :             {
    1175      239296 :                 q = q_data;
    1176      239296 :                 move16();
    1177      239296 :                 cldfbAnalysis_ts_fx_var_q( &( data[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q ); /*q_data-5*/
    1178      239296 :                 norm_buff = s_min( norm_buff, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) );
    1179      239296 :                 norm_buff = s_min( norm_buff, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) );
    1180             :             }
    1181             :             /* Compute energy */
    1182     1792416 :             FOR( i = 0; i < num_freq_bands; i++ )
    1183             :             {
    1184     1720096 :                 band_grouping_diff[i] = sub( hOMasa->band_grouping[i + 1], hOMasa->band_grouping[i] );
    1185     1720096 :                 move16();
    1186             :             }
    1187       72320 :             maximum_abs_16_fx( band_grouping_diff, num_freq_bands, &max_band_grouping_diff );
    1188       72320 :             guard_bits = find_guarded_bits_fx( num_freq_bins );
    1189       72320 :             norm_buff = sub( norm_buff, guard_bits );
    1190      311616 :             FOR( i = 0; i < nchan_ism; i++ )
    1191             :             {
    1192      239296 :                 scale_sig32( Chnl_RealBuffer_fx[i], 60, norm_buff );
    1193      239296 :                 scale_sig32( Chnl_ImagBuffer_fx[i], 60, norm_buff );
    1194             :             }
    1195       72320 :             q = add( q, norm_buff );
    1196     1792416 :             FOR( i = 0; i < num_freq_bands; i++ )
    1197             :             {
    1198     1720096 :                 brange[0] = hOMasa->band_grouping[i];
    1199     1720096 :                 brange[1] = hOMasa->band_grouping[i + 1];
    1200     1720096 :                 move16();
    1201     1720096 :                 move16();
    1202     7426048 :                 FOR( k = 0; k < nchan_ism; k++ )
    1203             :                 {
    1204    19512672 :                     FOR( j = brange[0]; j < brange[1]; j++ )
    1205             :                     {
    1206    13806720 :                         temp = L_add( Mpy_32_32( Chnl_RealBuffer_fx[k][j], Chnl_RealBuffer_fx[k][j] ), Mpy_32_32( Chnl_ImagBuffer_fx[k][j], Chnl_ImagBuffer_fx[k][j] ) );
    1207    13806720 :                         temp_e = sub( 62, shl( q, 1 ) );
    1208    13806720 :                         hOmasaEnergy->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaEnergy->energy_ism_fx[block_m_idx][i], hOmasaEnergy->energy_ism_fx_e[block_m_idx][i], temp, temp_e, &hOmasaEnergy->energy_ism_fx_e[block_m_idx][i] ); /*2q-31*/
    1209    13806720 :                         move32();
    1210             :                     }
    1211             :                 }
    1212             :             }
    1213             : 
    1214             :             /* Compute FOA */
    1215             :             /* W */
    1216       72320 :             Copy32( Chnl_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); /*q*/
    1217       72320 :             Copy32( Chnl_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); /*q*/
    1218      239296 :             FOR( i = 1; i < nchan_ism; i++ )
    1219             :             {
    1220      166976 :                 v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins );
    1221      166976 :                 v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins );
    1222             :             }
    1223             : 
    1224             :             /* Y */
    1225       72320 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/
    1226       72320 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/
    1227      239296 :             FOR( i = 1; i < nchan_ism; i++ )
    1228             :             {
    1229      166976 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/
    1230      166976 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/
    1231             :             }
    1232             : 
    1233             :             /* Z */
    1234       72320 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/
    1235       72320 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/
    1236      239296 :             FOR( i = 1; i < nchan_ism; i++ )
    1237             :             {
    1238      166976 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/
    1239      166976 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/
    1240             :             }
    1241             : 
    1242             : 
    1243             :             /* X */
    1244       72320 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/
    1245       72320 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/
    1246      239296 :             FOR( i = 1; i < nchan_ism; i++ )
    1247             :             {
    1248      166976 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/
    1249      166976 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/
    1250             :             }
    1251             :             /* Direction estimation */
    1252       72320 :             computeIntensityVector_enc_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, q_intensity_real_fx, q );
    1253             : 
    1254       72320 :             computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], 0, q_intensity_real_fx );
    1255             : 
    1256             :             /* Power estimation for diffuseness */
    1257             : 
    1258       72320 :             computeReferencePower_omasa_ivas_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], 0, num_freq_bands, q, q_reference_power_fx );
    1259             : 
    1260       72320 :             minimum_fx( q_intensity_real_fx, num_freq_bands, &intensity_real_e );
    1261       72320 :             minimum_fx( q_reference_power_fx, num_freq_bands, &ref_exp );
    1262             : 
    1263             :             Word16 tmp;
    1264     1792416 :             FOR( i = 0; i < num_freq_bands; i++ )
    1265             :             {
    1266     1720096 :                 tmp = sub( intensity_real_e, q_intensity_real_fx[i] );
    1267     1720096 :                 intensity_real_fx[0][i] = L_shl( intensity_real_fx[0][i], tmp ); // intensity_real_e
    1268     1720096 :                 move32();
    1269     1720096 :                 intensity_real_fx[1][i] = L_shl( intensity_real_fx[1][i], tmp ); // intensity_real_e
    1270     1720096 :                 move32();
    1271     1720096 :                 intensity_real_fx[2][i] = L_shl( intensity_real_fx[2][i], tmp ); // intensity_real_e
    1272     1720096 :                 move32();
    1273             : 
    1274     1720096 :                 tmp = sub( ref_exp, q_reference_power_fx[i] );
    1275     1720096 :                 reference_power_fx[ts][i] = L_shl( reference_power_fx[ts][i], tmp ); // ref_exp
    1276             :             }
    1277             : 
    1278       72320 :             intensity_real_e = sub( Q31, intensity_real_e );
    1279       72320 :             ref_exp = sub( Q31, ref_exp );
    1280             : 
    1281             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
    1282       72320 :             hOMasa->index_buffer_intensity = add( ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
    1283       72320 :             index = hOMasa->index_buffer_intensity;
    1284       72320 :             move16();
    1285       72320 :             move16();
    1286      289280 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
    1287             :             {
    1288             :                 /* only real part needed */
    1289      216960 :                 Copy32( intensity_real_fx[i], &( hOMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands );
    1290             :             }
    1291       72320 :             hOMasa->buffer_intensity_real_q[index - 1] = sub( 31, intensity_real_e );
    1292       72320 :             move16();
    1293       72320 :             Copy32( reference_power_fx[ts], &( hOMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
    1294       72320 :             hOMasa->buffer_energy_q[( index - 1 )] = sub( 31, ref_exp );
    1295       72320 :             move16();
    1296       72320 :             computeDiffuseness_fixed( hOMasa->buffer_intensity_real_fx, hOMasa->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hOMasa->buffer_intensity_real_q, hOMasa->buffer_energy_q, &q_diffuseness_vector );
    1297             : 
    1298     1792416 :             FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
    1299             :             {
    1300     1720096 :                 temp_e = norm_l( reference_power_fx[ts][band_m_idx] );
    1301     1720096 :                 reference_power_fx[ts][band_m_idx] = L_shl( reference_power_fx[ts][band_m_idx], temp_e );
    1302     1720096 :                 move32();
    1303     1720096 :                 norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], L_sub( L_shl( 1, q_diffuseness_vector ), diffuseness_vector_fx[band_m_idx] ) ); /*30+(31-(ref_exp-temp_e))-31*/
    1304             : 
    1305     1720096 :                 hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hOMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), sub( add( ref_exp, 2 ), temp_e ), &hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] ); /*hOMasa->direction_vector_e[0][block_m_idx][band_m_idx]*/
    1306     1720096 :                 hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hOMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), sub( add( ref_exp, 2 ), temp_e ), &hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] ); /*hOMasa->direction_vector_e[1][block_m_idx][band_m_idx]*/
    1307     1720096 :                 hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hOMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), sub( add( ref_exp, 2 ), temp_e ), &hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] ); /*hOMasa->direction_vector_e[2][block_m_idx][band_m_idx]*/
    1308     1720096 :                 move32();
    1309     1720096 :                 move32();
    1310     1720096 :                 move32();
    1311             : 
    1312     1720096 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], W_extract_l( W_shr( W_mult0_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), 30 ) ), sub( ref_exp, temp_e ), &diffuseness_e[band_m_idx] ); /*diffuseness_e[band_m_idx]*/
    1313     1720096 :                 renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], sub( ref_exp, temp_e ), &renormalization_factor_diff_e[band_m_idx] );                     /*renormalization_factor_diff_e[band_m_idx]*/
    1314     1720096 :                 move32();
    1315     1720096 :                 move32();
    1316             :             }
    1317             :         }
    1318             : 
    1319      396000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
    1320             :         {
    1321      380016 :             dir_v_e = MIN_16;
    1322      380016 :             move16();
    1323     1520064 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
    1324             :             {
    1325     1140048 :                 dir_v_fx[d] = hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx];
    1326     1140048 :                 move32();
    1327     1140048 :                 dir_v_e = s_max( dir_v_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) + 1;
    1328             :             }
    1329     1520064 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
    1330             :             {
    1331     1140048 :                 dir_v_fx[d] = L_shr( hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( dir_v_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) );
    1332     1140048 :                 move32();
    1333             :             }
    1334             : 
    1335      380016 :             ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, sub( 31, dir_v_e ), &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
    1336             :         }
    1337             : 
    1338             :         /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
    1339      396000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
    1340             :         {
    1341      380016 :             spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
    1342      380016 :             surroundingCoherence_fx[band_m_idx] = 0;
    1343      380016 :             move16();
    1344      380016 :             move16();
    1345             :         }
    1346             :     }
    1347             : 
    1348             :     /* Determine energy ratios */
    1349       99000 :     FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
    1350             :     {
    1351       95004 :         IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], 1 /*EPSILON Q50*/, -19 ), 1 ) )
    1352             :         {
    1353       95004 :             diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], L_add( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ), &temp_e ); // Q=15-temp_e
    1354       95004 :             temp_e = add( temp_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
    1355             :         }
    1356             :         ELSE
    1357             :         {
    1358           0 :             diffuseness_m_fx[band_m_idx] = 0;
    1359           0 :             temp_e = 0;
    1360           0 :             move16();
    1361             :         }
    1362       95004 :         move32();
    1363       95004 :         diffuseness_m_fx[band_m_idx] = L_shl( diffuseness_m_fx[band_m_idx], add( 15, temp_e ) ); // Scaling to Q30
    1364       95004 :         energyRatio_fx[band_m_idx] = L_sub( ONE_IN_Q30, diffuseness_m_fx[band_m_idx] );          // Q30
    1365       95004 :         move32();
    1366       95004 :         move32();
    1367             :     }
    1368             : 
    1369        3996 :     return;
    1370             : }
    1371             : 
    1372             : 
    1373             : /* Estimate energies and ratios */
    1374        1862 : static void ivas_omasa_energy_and_ratio_est_fx(
    1375             :     OMASA_ENC_HANDLE hOMasa,
    1376             :     OMASA_ENCODER_DATA_HANDLE hOmasaData,
    1377             :     Word32 *data_fx[], /*i: q_data*/
    1378             :     const Word16 input_frame,
    1379             :     const Word16 nchan_ism,
    1380             :     const Word16 q_data /*i: stoes the q for data_fx*/
    1381             : )
    1382             : {
    1383             :     Word16 ts, i, j, k;
    1384             :     Word16 num_freq_bands;
    1385             :     Word16 l_ts;
    1386             :     Word32 Chnl_RealBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
    1387             :     Word32 Chnl_ImagBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
    1388             :     Word16 block_m_idx;
    1389             :     Word16 mrange[2], brange[2];
    1390             :     Word32 tftile_energy_fx;
    1391             :     Word16 tftile_energy_e;
    1392             :     Word64 ism_ratio_sum_fx;
    1393             :     Word16 q_cldfb;
    1394             :     Word16 norm_Chnl;
    1395             :     Word16 temp_e;                                                                                 /* to store temporary exp*/
    1396             :     Word16 energy_ratio_ism_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /*q30*/
    1397        1862 :     OMASA_ENCODER_ENERGY_HANDLE hOmasaEnergy = hOmasaData->hOmasaEnergy;
    1398             : 
    1399        1862 :     num_freq_bands = hOMasa->nbands;
    1400        1862 :     l_ts = shr( input_frame, 4 ); /*input_frame / CLDFB_NO_COL_MAX*/
    1401        1862 :     q_cldfb = q_data;
    1402        1862 :     move16(); /*num_freq_bands*/
    1403        1862 :     move16(); /*q_cldfb*/
    1404        1862 :     set_zero_fx( &Chnl_RealBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX );
    1405        1862 :     set_zero_fx( &Chnl_ImagBuffer_fx[0][0], MAX_NUM_OBJECTS * CLDFB_NO_CHANNELS_MAX );
    1406             : 
    1407             :     /* do processing over all CLDFB time slots */
    1408        8176 :     FOR( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
    1409             :     {
    1410        6314 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
    1411        6314 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
    1412        6314 :         move16();
    1413        6314 :         move16();
    1414             : 
    1415             :         /* Reset variable */
    1416       40530 :         FOR( i = 0; i < hOMasa->nbands; i++ )
    1417             :         {
    1418       34216 :             set_zero_fx( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i], nchan_ism );
    1419       34216 :             set16_fx( energy_ratio_ism_e[block_m_idx][i], 0, nchan_ism );
    1420             :         }
    1421        6314 :         set_zero_fx( hOmasaEnergy->energy_ism_fx[block_m_idx], num_freq_bands );
    1422        6314 :         set16_fx( hOmasaEnergy->energy_ism_fx_e[block_m_idx], 0, num_freq_bands );
    1423             : 
    1424             :         /* Compute CLDFB */
    1425       36106 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
    1426             :         {
    1427       29792 :             norm_Chnl = MAX_16;
    1428       29792 :             move16();
    1429      130272 :             FOR( i = 0; i < nchan_ism; i++ )
    1430             :             {
    1431      100480 :                 q_cldfb = q_data;
    1432      100480 :                 move16();
    1433             : #ifdef FIX_1987_CRASH_OMASA_ENERGY
    1434      100480 :                 cldfbAnalysis_ts_fx_var_q( &( data_fx[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q_cldfb );
    1435             : #else
    1436             :                 scale_sig32( hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, hOMasa->cldfbAnaEnc[i]->cldfb_state_length, sub( q_cldfb, hOMasa->cldfbAnaEnc[i]->Q_cldfb_state ) );
    1437             :                 hOMasa->cldfbAnaEnc[i]->Q_cldfb_state = q_cldfb;
    1438             :                 move16();
    1439             :                 cldfbAnalysis_ts_fx_fixed_q( &( data_fx[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q_cldfb );
    1440             : #endif
    1441      100480 :                 norm_Chnl = s_min( norm_Chnl, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) );
    1442      100480 :                 norm_Chnl = s_min( norm_Chnl, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) );
    1443             :             }
    1444       29792 :             norm_Chnl = sub( norm_Chnl, 1 );
    1445             :             /*scaling cldfb buffers to avoid loss of values in Mpy_32_32*/
    1446      130272 :             FOR( i = 0; i < nchan_ism; i++ )
    1447             :             {
    1448      100480 :                 scale_sig32( Chnl_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, norm_Chnl );
    1449      100480 :                 scale_sig32( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, norm_Chnl );
    1450             :             }
    1451       29792 :             q_cldfb = add( q_cldfb, norm_Chnl );
    1452             : 
    1453             :             /* Compute energy */
    1454      221088 :             FOR( i = 0; i < num_freq_bands; i++ )
    1455             :             {
    1456      191296 :                 brange[0] = hOMasa->band_grouping[i];
    1457      191296 :                 brange[1] = hOMasa->band_grouping[i + 1];
    1458      191296 :                 move16();
    1459      191296 :                 move16();
    1460     1835456 :                 FOR( j = brange[0]; j < brange[1]; j++ )
    1461             :                 {
    1462     7242880 :                     FOR( k = 0; k < nchan_ism; k++ )
    1463             :                     {
    1464             :                         Word64 tmp64;
    1465             :                         Word16 tmpNorm;
    1466     5598720 :                         tmp64 = W_add( W_mult0_32_32( Chnl_RealBuffer_fx[k][j], Chnl_RealBuffer_fx[k][j] ), W_mult0_32_32( Chnl_ImagBuffer_fx[k][j], Chnl_ImagBuffer_fx[k][j] ) ); // exp: 2 * (31 - q_cldfb) + 1
    1467     5598720 :                         tftile_energy_e = sub( 63, shl( q_cldfb, 1 ) );
    1468     5598720 :                         tmpNorm = W_norm( tmp64 );
    1469     5598720 :                         tmp64 = W_shl( tmp64, tmpNorm );
    1470     5598720 :                         tftile_energy_fx = W_extract_h( tmp64 );
    1471     5598720 :                         tftile_energy_e = sub( tftile_energy_e, tmpNorm );
    1472     5598720 :                         hOmasaEnergy->energy_ism_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hOmasaEnergy->energy_ism_fx[block_m_idx][i], hOmasaEnergy->energy_ism_fx_e[block_m_idx][i], tftile_energy_fx, tftile_energy_e, &hOmasaEnergy->energy_ism_fx_e[block_m_idx][i] );
    1473     5598720 :                         hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][k] = BASOP_Util_Add_Mant32Exp( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][k], energy_ratio_ism_e[block_m_idx][i][k], tftile_energy_fx, tftile_energy_e, &energy_ratio_ism_e[block_m_idx][i][k] );
    1474     5598720 :                         move32();
    1475     5598720 :                         move32();
    1476             :                     }
    1477             :                 }
    1478             :             }
    1479             :         }
    1480             : 
    1481             :         /* Compute ISM energy ratios */
    1482       40530 :         FOR( i = 0; i < num_freq_bands; i++ )
    1483             :         {
    1484       34216 :             ism_ratio_sum_fx = 0;
    1485       34216 :             move64();
    1486      148936 :             FOR( j = 0; j < nchan_ism; j++ )
    1487             :             {
    1488      114720 :                 hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] = L_deposit_h( BASOP_Util_Divide3232_Scale( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j], L_add( hOmasaEnergy->energy_ism_fx[block_m_idx][i], EPSILON_FX ), &temp_e ) );
    1489      114720 :                 move32();
    1490      114720 :                 temp_e = add( temp_e, sub( energy_ratio_ism_e[block_m_idx][i][j], hOmasaEnergy->energy_ism_fx_e[block_m_idx][i] ) );
    1491             : 
    1492      114720 :                 hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j], sub( temp_e, 1 ) ); /* scaling to q30 */
    1493      114720 :                 move32();
    1494      114720 :                 ism_ratio_sum_fx = W_add( ism_ratio_sum_fx, hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] );
    1495             :             }
    1496       34216 :             IF( ism_ratio_sum_fx == 0 )
    1497             :             {
    1498           0 :                 Word16 temp_ism_ratio = BASOP_Util_Divide1616_Scale( 1, nchan_ism, &temp_e );
    1499           0 :                 FOR( j = 0; j < nchan_ism; j++ )
    1500             :                 {
    1501           0 :                     hOmasaEnergy->energy_ratio_ism_fx[block_m_idx][i][j] = L_shl( temp_ism_ratio, add( temp_e, 15 ) ); /*scaling to q30*/
    1502           0 :                     move32();
    1503             :                 }
    1504             :             }
    1505             :         }
    1506             :     }
    1507             : 
    1508        1862 :     return;
    1509             : }
    1510             : 
    1511             : 
    1512             : /* Compute downmix */
    1513        5858 : static void ivas_omasa_dmx_fx(
    1514             :     Word32 *data_in[],                                /*i:Qx*/
    1515             :     Word32 data_out[][L_FRAME48k],                    /*i:Qx*/
    1516             :     const Word16 input_frame,                         /*i:q0*/
    1517             :     const Word16 nchan_transport,                     /*i:q0*/
    1518             :     const Word16 nchan_ism,                           /*i:q0*/
    1519             :     ISM_METADATA_HANDLE hIsmMeta[],                   /*i*/
    1520             :     Word16 prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], /*o:q15*/
    1521             :     const Word16 interpolator[L_FRAME48k]             /*i:q15*/
    1522             : )
    1523             : {
    1524             :     Word16 i, j, k;
    1525             :     Word16 azimuth, elevation;
    1526             :     Word16 gains[MASA_MAX_TRANSPORT_CHANNELS];
    1527             :     Word16 g1, g2;
    1528             : 
    1529       17574 :     FOR( i = 0; i < nchan_transport; i++ )
    1530             :     {
    1531       11716 :         set_zero_fx( data_out[i], input_frame );
    1532             :     }
    1533             : 
    1534       25298 :     FOR( i = 0; i < nchan_ism; i++ )
    1535             :     {
    1536       19440 :         azimuth = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, ONE_IN_Q21 ), 22 ) );     /* scaling from q22 to q0 for ivas_get_stereo_panning_gains_fx*/
    1537       19440 :         elevation = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, ONE_IN_Q21 ), 22 ) ); /* scaling from q22 to q0 for ivas_get_stereo_panning_gains_fx*/
    1538             : 
    1539             :         /*gains is q15*/
    1540             :         /*azimuth is q0*/
    1541             :         /*elevation is q0*/
    1542       19440 :         ivas_get_stereo_panning_gains_fx( azimuth, elevation, gains );
    1543             : 
    1544             :         /* Downmix using the panning gains */
    1545       58320 :         FOR( j = 0; j < nchan_transport; j++ )
    1546             :         {
    1547       38880 :             test();
    1548       38880 :             IF( abs_s( gains[j] ) > 0 || abs_s( prev_gains[i][j] ) > 0 )
    1549             :             {
    1550    32614184 :                 FOR( k = 0; k < input_frame; k++ )
    1551             :                 {
    1552    32578560 :                     g1 = interpolator[k];
    1553    32578560 :                     move16();
    1554    32578560 :                     g2 = sub( MAX_WORD16, g1 );                                                                                                                    /*q15*/
    1555    32578560 :                     data_out[j][k] = L_add( data_out[j][k], Mpy_32_32( L_add( L_mult( g1, gains[j] ), L_mult( g2, prev_gains[i][j] ) ) /*q31*/, data_in[i][k] ) ); /*Qx*/
    1556    32578560 :                     move32();
    1557             :                 }
    1558             :             }
    1559       38880 :             prev_gains[i][j] = gains[j]; /*q15*/
    1560       38880 :             move16();
    1561             :         }
    1562             :     }
    1563             : 
    1564        5858 :     return;
    1565             : }
    1566             : 
    1567       72320 : void computeIntensityVector_enc_fx(
    1568             :     const Word16 *band_grouping,
    1569             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
    1570             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /*inp_q*/
    1571             :     const Word16 num_frequency_bands,
    1572             :     Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS], /*exp: exp_intensity_real*/
    1573             :     Word16 q_intensity_real[MASA_FREQUENCY_BANDS],
    1574             :     Word16 inp_q )
    1575             : {
    1576             :     Word16 i, j;
    1577             :     Word32 real, img;
    1578             :     Word16 brange[2];
    1579             :     Word16 shift_intensity_real, num_bins, guard_bits, norm;
    1580             : 
    1581             :     Word64 intensity_real64[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
    1582             : 
    1583      289280 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
    1584             :     {
    1585      216960 :         set64_fx( intensity_real64[i], 0, MASA_FREQUENCY_BANDS );
    1586             :     }
    1587             : 
    1588       72320 :     shift_intensity_real = sub( shl( inp_q, 1 ), 32 );
    1589             : 
    1590     1792416 :     FOR( i = 0; i < num_frequency_bands; i++ )
    1591             :     {
    1592     1720096 :         brange[0] = band_grouping[i];
    1593     1720096 :         move16();
    1594     1720096 :         brange[1] = band_grouping[i + 1];
    1595     1720096 :         move16();
    1596             : 
    1597     1720096 :         num_bins = sub( brange[1], brange[0] );
    1598     1720096 :         guard_bits = find_guarded_bits_fx( num_bins );
    1599             : 
    1600     5843616 :         FOR( j = brange[0]; j < brange[1]; j++ )
    1601             :         {
    1602     4123520 :             real = Cldfb_RealBuffer[0][j];
    1603     4123520 :             move32();
    1604     4123520 :             img = Cldfb_ImagBuffer[0][j];
    1605     4123520 :             move32();
    1606             :             /* Intensity is XYZ order, audio is WYZX order. */
    1607     4123520 :             intensity_real64[0][i] = W_add( intensity_real64[0][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[3][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[3][j], img ) ), guard_bits ) ); // output Q= 2* input_q -guard_bits
    1608     4123520 :             move64();
    1609     4123520 :             intensity_real64[1][i] = W_add( intensity_real64[1][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[1][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[1][j], img ) ), guard_bits ) ); // output Q= 2* input_q - guard_bits
    1610     4123520 :             move64();
    1611     4123520 :             intensity_real64[2][i] = W_add( intensity_real64[2][i], W_shr( W_add( W_mult0_32_32( Cldfb_RealBuffer[2][j], real ), W_mult0_32_32( Cldfb_ImagBuffer[2][j], img ) ), guard_bits ) ); // output Q= 2* input_q - guard_bits
    1612     4123520 :             move64();
    1613             :         }
    1614     1720096 :         norm = 63;
    1615     1720096 :         move16();
    1616             : 
    1617     1720096 :         IF( intensity_real64[0][i] != 0 )
    1618             :         {
    1619     1720096 :             norm = s_min( norm, W_norm( intensity_real64[0][i] ) );
    1620             :         }
    1621     1720096 :         IF( intensity_real64[1][i] != 0 )
    1622             :         {
    1623     1580944 :             norm = s_min( norm, W_norm( intensity_real64[1][i] ) );
    1624             :         }
    1625     1720096 :         IF( intensity_real64[2][i] != 0 )
    1626             :         {
    1627     1552560 :             norm = s_min( norm, W_norm( intensity_real64[2][i] ) );
    1628             :         }
    1629     1720096 :         intensity_real[0][i] = W_extract_h( W_shl( intensity_real64[0][i], norm ) ); // output Q = 2 * inp_q - guard_bits + norm - 32
    1630     1720096 :         move32();
    1631     1720096 :         intensity_real[1][i] = W_extract_h( W_shl( intensity_real64[1][i], norm ) ); // output Q = 2 * inp_q - guard_bits + norm - 32
    1632     1720096 :         move32();
    1633     1720096 :         intensity_real[2][i] = W_extract_h( W_shl( intensity_real64[2][i], norm ) ); // output Q = 2 * inp_q - guard_bits + norm - 32
    1634     1720096 :         move32();
    1635     1720096 :         q_intensity_real[i] = add( shift_intensity_real, sub( norm, guard_bits ) );
    1636     1720096 :         move16();
    1637             :     }
    1638             : 
    1639       72320 :     return;
    1640             : }
    1641             : 
    1642             : 
    1643       72320 : static void computeReferencePower_omasa_ivas_fx(
    1644             :     const Word16 *band_grouping,                                  /* i  : Band grouping for estimation    */
    1645             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal       Q6*/
    1646             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal       Q6*/
    1647             :     Word32 *reference_power,                                      /* o  : Estimated power                 Q(31-ref_exp)*/
    1648             :     const Word16 enc_param_start_band,                            /* i  : first band to process           */
    1649             :     const Word16 num_freq_bands,                                  /* i  : Number of frequency bands       */
    1650             :     Word16 q_Cldfb,
    1651             :     Word16 q_reference_power[CLDFB_NO_CHANNELS_MAX] )
    1652             : {
    1653             :     Word16 brange[2];
    1654             :     Word16 ch_idx, i, j;
    1655             :     Word64 reference_power_tmp[CLDFB_NO_CHANNELS_MAX];
    1656             :     Word16 shift_ref_power, num_bins, guard_bits, norm;
    1657             : 
    1658       72320 :     shift_ref_power = sub( shl( q_Cldfb, 1 ), 30 );
    1659             : 
    1660     1792416 :     FOR( i = 0; i < num_freq_bands; i++ )
    1661             :     {
    1662     1720096 :         brange[0] = band_grouping[i + enc_param_start_band];
    1663     1720096 :         move16();
    1664     1720096 :         brange[1] = band_grouping[i + enc_param_start_band + 1];
    1665     1720096 :         move16();
    1666     1720096 :         reference_power[i] = 0;
    1667     1720096 :         move32();
    1668     1720096 :         reference_power_tmp[i] = 0;
    1669     1720096 :         move64();
    1670             : 
    1671     1720096 :         num_bins = sub( brange[1], brange[0] );
    1672     1720096 :         guard_bits = find_guarded_bits_fx( num_bins );
    1673             : 
    1674     8600480 :         FOR( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
    1675             :         {
    1676             :             /* abs()^2 */
    1677    23374464 :             FOR( j = brange[0]; j < brange[1]; j++ )
    1678             :             {
    1679    16494080 :                 reference_power_tmp[i] = W_add( reference_power_tmp[i], W_shr( W_mac_32_32( W_mult_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ), guard_bits ) ); // output Q = 2 * q_cldfb + 1 - guard_bits
    1680    16494080 :                 move64();
    1681             :             }
    1682             :         }
    1683     1720096 :         norm = 63;
    1684     1720096 :         move16();
    1685     1720096 :         IF( reference_power_tmp[i] != 0 )
    1686             :         {
    1687     1720096 :             norm = W_norm( reference_power_tmp[i] );
    1688             :         }
    1689     1720096 :         reference_power[i] = W_extract_h( W_shl( reference_power_tmp[i], norm ) ); // output Q = 2 * q_cldfb + 2 - guard_bits + norm - 32
    1690     1720096 :         move32();
    1691     1720096 :         q_reference_power[i] = add( shift_ref_power, sub( norm, guard_bits ) );
    1692     1720096 :         move16();
    1693             :     }
    1694             : 
    1695       72320 :     return;
    1696             : }

Generated by: LCOV version 1.14