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

Generated by: LCOV version 1.14