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

Generated by: LCOV version 1.14