LCOV - code coverage report
Current view: top level - lib_rend - ivas_omasa_ana_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 384 392 98.0 %
Date: 2025-05-03 01:55:50 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include "options.h"
      34             : #include <stdlib.h>
      35             : #include <math.h>
      36             : #include "ivas_cnst.h"
      37             : #include "ivas_prot_rend_fx.h"
      38             : #include "ivas_prot_fx.h"
      39             : #include "prot_fx.h"
      40             : #include "ivas_stat_rend.h"
      41             : #include "ivas_rom_com.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : 
      45             : /*-------------------------------------------------------------------------
      46             :  * Local function prototypes
      47             :  *------------------------------------------------------------------------*/
      48             : 
      49             : 
      50             : static void ivas_omasa_dmx_fx(
      51             :     Word32 data_in_f_fx[][L_FRAME48k],
      52             :     Word16 *data_in_q,
      53             :     const Word16 input_frame,
      54             :     const Word16 nchan_transport,
      55             :     const Word16 nchan_ism,
      56             :     const Word32 ism_azimuth_fx[MAX_NUM_OBJECTS],
      57             :     const Word32 ism_elevation_fx[MAX_NUM_OBJECTS],
      58             :     Word32 prev_gains_fx[][MASA_MAX_TRANSPORT_CHANNELS],
      59             :     const Word16 interpolator_fx[L_FRAME48k] );
      60             : 
      61             : 
      62             : static void ivas_omasa_param_est_ana_fx(
      63             :     OMASA_ANA_HANDLE hOMasa,
      64             :     Word32 data_f_fx[][L_FRAME48k],
      65             :     Word16 data_f_q,
      66             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
      67             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   // Q22
      68             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
      69             :     Word16 *energyRatio_q,
      70             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
      71             :     Word16 *spreadCoherence_q,
      72             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
      73             :     Word16 *surroundingCoherence_q,
      74             :     const Word16 input_frame,
      75             :     const Word16 nchan_ism );
      76             : 
      77             : /*--------------------------------------------------------------------------*
      78             :  * ivas_omasa_ana_open()
      79             :  *
      80             :  * Allocate and initialize OMASA handle
      81             :  *--------------------------------------------------------------------------*/
      82             : 
      83           1 : ivas_error ivas_omasa_ana_open(
      84             :     OMASA_ANA_HANDLE *hOMasaPtr, /* i/o: OMASA data handle pointer */
      85             :     Word32 input_Fs,             /* i  : Sampling frequency        */
      86             :     UWord16 total_num_objects    /* i  : Number of objects         */
      87             : )
      88             : {
      89             :     Word16 i, j;
      90             :     OMASA_ANA_HANDLE hOMasa;
      91             :     Word16 numAnalysisChannels;
      92             :     Word16 maxBin, input_frame;
      93             :     ivas_error error;
      94             :     Word16 scale;
      95             : 
      96           1 :     error = IVAS_ERR_OK;
      97           1 :     move32();
      98             : 
      99           1 :     IF( ( hOMasa = (OMASA_ANA_HANDLE) malloc( sizeof( OMASA_ANA_DATA ) ) ) == NULL )
     100             :     {
     101           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA\n" ) );
     102             :     }
     103             : 
     104           1 :     numAnalysisChannels = (Word16) total_num_objects;
     105           1 :     move16();
     106             : 
     107             :     /* Determine the number of bands */
     108           1 :     hOMasa->nbands = MASA_FREQUENCY_BANDS;
     109           1 :     move16();
     110             : 
     111             :     /* Determine band grouping */
     112           1 :     Copy( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
     113             : 
     114             :     /* maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); */
     115           1 :     maxBin = extract_l( Mpy_32_32( input_Fs, 2684355 /* INV_CLDFB_BANDWIDTH in Q31 */ ) ); // Q: ( ( Q0 + Q31 ) - Q31 ) -> Q0
     116             : 
     117          24 :     FOR( i = 1; i < hOMasa->nbands + 1; i++ )
     118             :     {
     119          24 :         IF( GE_16( hOMasa->band_grouping[i], maxBin ) )
     120             :         {
     121           1 :             hOMasa->band_grouping[i] = maxBin;
     122           1 :             move16();
     123           1 :             hOMasa->nbands = i;
     124           1 :             move16();
     125           1 :             BREAK;
     126             :         }
     127             :     }
     128             : 
     129             :     /* Determine block grouping */
     130           1 :     Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     131             : 
     132             :     /* open/initialize CLDFB */
     133           1 :     hOMasa->num_Cldfb_instances = numAnalysisChannels;
     134           5 :     FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
     135             :     {
     136           4 :         IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
     137             :         {
     138           0 :             return error;
     139             :         }
     140             :     }
     141             : 
     142           1 :     FOR( ; i < MAX_NUM_OBJECTS; i++ )
     143             :     {
     144           0 :         hOMasa->cldfbAnaEnc[i] = NULL;
     145             :     }
     146             : 
     147           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     148             :     {
     149           3 :         IF( ( hOMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL )
     150             :         {
     151           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     152             :         }
     153             : 
     154          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     155             :         {
     156          12 :             IF( ( hOMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     157             :             {
     158           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     159             :             }
     160          12 :             set_zero_fx( hOMasa->direction_vector_m_fx[i][j], MASA_FREQUENCY_BANDS );
     161             :         }
     162             :     }
     163             : 
     164           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     165             :     {
     166          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     167             :         {
     168          96 :             IF( ( hOMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     169             :             {
     170           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     171             :             }
     172          96 :             set_zero_fx( hOMasa->buffer_intensity_real_fx[i][j], MASA_FREQUENCY_BANDS );
     173             :         }
     174             :     }
     175             : 
     176           1 :     set_zero_fx( hOMasa->buffer_energy_fx, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     177             : 
     178           5 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
     179             :     {
     180           4 :         set32_fx( hOMasa->prev_object_dm_gains_fx[i], INV_SQRT_2_Q31, MASA_MAX_TRANSPORT_CHANNELS );
     181             :     }
     182             : 
     183             :     /* input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); */
     184           1 :     input_frame = extract_l( Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     185         961 :     FOR( i = 0; i < input_frame; i++ )
     186             :     {
     187         960 :         hOMasa->interpolator_fx[i] = BASOP_Util_Divide1616_Scale( i, input_frame, &scale );
     188         960 :         move16();
     189         960 :         hOMasa->interpolator_fx[i] = shl( hOMasa->interpolator_fx[i], scale ); // Q15
     190         960 :         move16();
     191             :     }
     192             : 
     193           1 :     hOMasa->index_buffer_intensity = 0;
     194           1 :     move16();
     195             : 
     196           1 :     IF( ( hOMasa->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     197             :     {
     198           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     199             :     }
     200             : 
     201           1 :     IF( ( hOMasa->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     202             :     {
     203           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     204             :     }
     205             : 
     206           1 :     generate_gridEq_fx( hOMasa->sph_grid16 );
     207             : 
     208           5 :     FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     209             :     {
     210           4 :         set_zero_fx( hOMasa->energy_fx[i], MASA_FREQUENCY_BANDS );
     211             :     }
     212             : 
     213           1 :     set_zero_fx( hOMasa->ism_azimuth_fx, MAX_NUM_OBJECTS );
     214           1 :     set_zero_fx( hOMasa->ism_elevation_fx, MAX_NUM_OBJECTS );
     215             : 
     216           1 :     ( *hOMasaPtr ) = hOMasa;
     217             : 
     218           1 :     return error;
     219             : }
     220             : 
     221             : /*--------------------------------------------------------------------------*
     222             :  * ivas_omasa_ana_close()
     223             :  *
     224             :  * Close OMASA handle
     225             :  *--------------------------------------------------------------------------*/
     226             : 
     227        2632 : void ivas_omasa_ana_close(
     228             :     OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
     229             : )
     230             : {
     231             :     Word16 i, j;
     232             : 
     233        2632 :     test();
     234        2632 :     IF( hOMasa == NULL || *hOMasa == NULL )
     235             :     {
     236        2631 :         return;
     237             :     }
     238             : 
     239           5 :     FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
     240             :     {
     241           4 :         deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
     242             :     }
     243             : 
     244           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     245             :     {
     246          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     247             :         {
     248          12 :             free( ( *hOMasa )->direction_vector_m_fx[i][j] );
     249          12 :             ( *hOMasa )->direction_vector_m_fx[i][j] = NULL;
     250             :         }
     251             : 
     252          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     253             :         {
     254          96 :             free( ( *hOMasa )->buffer_intensity_real_fx[i][j] );
     255          96 :             ( *hOMasa )->buffer_intensity_real_fx[i][j] = NULL;
     256             :         }
     257             : 
     258           3 :         free( ( *hOMasa )->direction_vector_m_fx[i] );
     259           3 :         ( *hOMasa )->direction_vector_m_fx[i] = NULL;
     260             :     }
     261             : 
     262           1 :     free( ( *hOMasa )->hMasaOut );
     263           1 :     ( *hOMasa )->hMasaOut = NULL;
     264           1 :     free( ( *hOMasa )->sph_grid16 );
     265           1 :     ( *hOMasa )->sph_grid16 = NULL;
     266             : 
     267           1 :     free( ( *hOMasa ) );
     268           1 :     ( *hOMasa ) = NULL;
     269             : 
     270           1 :     return;
     271             : }
     272             : 
     273             : /*--------------------------------------------------------------------------*
     274             :  * ivas_omasa_ana()
     275             :  *
     276             :  * OMASA analysis function
     277             :  *--------------------------------------------------------------------------*/
     278             : 
     279             : 
     280         150 : void ivas_omasa_ana_fx(
     281             :     OMASA_ANA_HANDLE hOMasa,           /* i/o: OMASA analysis handle                       */
     282             :     Word32 data_in_f_fx[][L_FRAME48k], /* i/o: Input / transport audio signals             */
     283             :     Word16 *data_in_q,
     284             :     const Word16 input_frame,     /* i  : Input frame size                            */
     285             :     const Word16 nchan_transport, /* i  : Number of transport channels                */
     286             :     const Word16 nchan_ism        /* i  : Number of objects for parameter analysis    */
     287             : )
     288             : {
     289             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     290             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     291             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     292             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     293             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     294             :     Word16 spreadCoherence_q, sorroundingCoherence_q, energyRatio_q;
     295             : 
     296             :     /* Estimate MASA parameters from the objects */
     297         150 :     ivas_omasa_param_est_ana_fx( hOMasa, data_in_f_fx, *data_in_q, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, &energyRatio_q, spreadCoherence_fx, &spreadCoherence_q, surroundingCoherence_fx, &sorroundingCoherence_q, input_frame, nchan_ism );
     298             : 
     299             :     /* Create MASA metadata buffer from the estimated values */
     300             : 
     301         150 :     ivas_create_masa_out_meta_fx( hOMasa->hMasaOut, hOMasa->sph_grid16, nchan_transport, elevation_m_values_fx, azimuth_m_values_fx, energyRatio_fx, spreadCoherence_fx, surroundingCoherence_fx, energyRatio_q, spreadCoherence_q, sorroundingCoherence_q );
     302             : 
     303             :     /* Downmix */
     304         150 :     ivas_omasa_dmx_fx( data_in_f_fx, data_in_q, input_frame, nchan_transport, nchan_ism, hOMasa->ism_azimuth_fx, hOMasa->ism_elevation_fx, hOMasa->prev_object_dm_gains_fx, hOMasa->interpolator_fx );
     305         150 :     return;
     306             : }
     307             : 
     308             : 
     309             : /*--------------------------------------------------------------------------*
     310             :  * Local functions
     311             :  *--------------------------------------------------------------------------*/
     312             : 
     313             : /* Estimate MASA parameters from the objects */
     314             : 
     315             : 
     316         150 : static void ivas_omasa_param_est_ana_fx(
     317             :     OMASA_ANA_HANDLE hOMasa,
     318             :     Word32 data_f_fx[][L_FRAME48k],
     319             :     Word16 data_f_q,
     320             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
     321             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   // Q22
     322             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     323             :     Word16 *energyRatio_q,
     324             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     325             :     Word16 *spreadCoherence_q,
     326             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     327             :     Word16 *surroundingCoherence_q,
     328             :     const Word16 input_frame,
     329             :     const Word16 nchan_ism )
     330             : {
     331             :     Word16 ts, i, d, j;
     332             :     Word16 num_freq_bins, num_freq_bands, index;
     333             :     Word16 l_ts;
     334             : 
     335             :     Word32 reference_power_fx[MASA_FREQUENCY_BANDS];
     336             :     Word32 Chnl_RealBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
     337             :     Word16 Chnl_RealBuffer_q[MAX_NUM_OBJECTS];
     338             :     Word16 Chnl_ImagBuffer_q[MAX_NUM_OBJECTS];
     339             :     Word32 Chnl_ImagBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
     340             :     Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     341             :     Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     342             :     Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     343             :     Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     344             :     Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
     345         150 :     Word16 diffuseness_q = 0;
     346         150 :     move16();
     347             :     Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
     348         150 :     Word16 diffuseness_m_q = 0;
     349         150 :     move16();
     350             :     Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
     351         150 :     Word16 renormalization_factor_diff_q = 0;
     352         150 :     move16();
     353             :     Word32 norm_tmp_fx;
     354             :     Word16 scale;
     355             :     Word16 tmp_ener_e[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     356             : 
     357             :     Word32 dir_v_fx[DIRAC_NUM_DIMS], L_tmp1, L_tmp2;
     358             :     Word16 dir_v_q, norm_tmp_q;
     359             :     Word16 foa_q;
     360             : 
     361             :     Word16 band_m_idx, block_m_idx;
     362             : 
     363             :     Word16 mrange[2];
     364             :     Word16 brange[2];
     365             : 
     366         150 :     num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
     367         150 :     move16();
     368         150 :     num_freq_bands = hOMasa->nbands;
     369         150 :     move16();
     370             : 
     371             :     // l_ts = input_frame / CLDFB_NO_COL_MAX;
     372         150 :     l_ts = shr( input_frame, 4 );
     373         150 :     move16();
     374             : 
     375             :     Word16 intensity_q;
     376             :     Word16 direction_q, reference_power_q;
     377             : 
     378         150 :     set16_zero_fx( Chnl_RealBuffer_q, MAX_NUM_OBJECTS );
     379         150 :     set16_zero_fx( Chnl_ImagBuffer_q, MAX_NUM_OBJECTS );
     380             : 
     381             :     /* Compute ISM to FOA matrices */
     382         750 :     FOR( i = 0; i < nchan_ism; i++ )
     383             :     {
     384             :         Word16 tmp, tmp1;
     385             :         // 180 in Q22 754974720
     386         600 :         hOMasa->chnlToFoaMtx_fx[0][i] = 32767; // 1 in Q15
     387         600 :         move16();
     388             : 
     389         600 :         tmp = BASOP_Util_Divide3232_Scale( hOMasa->ism_azimuth_fx[i], 754974720, &scale );
     390         600 :         tmp = mult( tmp, EVS_PI_FX ); // Q13 + Q15 - Q15 --> Q13
     391         600 :         tmp = getSinWord16( tmp );    // Q15 sine value
     392             : 
     393         600 :         tmp1 = BASOP_Util_Divide3232_Scale( hOMasa->ism_elevation_fx[i], 754974720, &scale );
     394         600 :         tmp1 = mult( tmp1, EVS_PI_FX );
     395         600 :         tmp1 = getCosWord16( tmp1 );
     396         600 :         hOMasa->chnlToFoaMtx_fx[1][i] = shl( mult( tmp, tmp1 ), 1 ); // Q14 + Q15 - Q15 + Q1 -> Q15
     397         600 :         move16();
     398             : 
     399         600 :         tmp = BASOP_Util_Divide3232_Scale( hOMasa->ism_elevation_fx[i], 754974720, &scale );
     400         600 :         tmp = mult( tmp, EVS_PI_FX );                        // Q13 + Q15 - Q15 --> Q13
     401         600 :         hOMasa->chnlToFoaMtx_fx[2][i] = getSinWord16( tmp ); // Q15
     402         600 :         move16();
     403             : 
     404         600 :         tmp = BASOP_Util_Divide3232_Scale( hOMasa->ism_azimuth_fx[i], 754974720, &scale );
     405         600 :         tmp = mult( tmp, EVS_PI_FX ); // Q13 + Q15 - Q15 --> Q13
     406         600 :         tmp = getCosWord16( tmp );    // Q14
     407             : 
     408             : 
     409         600 :         tmp1 = BASOP_Util_Divide3232_Scale( hOMasa->ism_elevation_fx[i], 754974720, &scale );
     410         600 :         tmp1 = mult( tmp, EVS_PI_FX ); // Q13 + Q15 - Q15 --> Q13
     411         600 :         tmp1 = getCosWord16( tmp );    // Q14
     412             : 
     413         600 :         hOMasa->chnlToFoaMtx_fx[3][i] = shl( mult( tmp, tmp1 ), 2 ); // Q14 + Q14 - Q15 + Q2-> Q13 + Q2 -> Q15
     414         600 :         move16();
     415             :     }
     416             : 
     417             :     /* do processing over all CLDFB time slots */
     418         750 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     419             :     {
     420         600 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
     421         600 :         move16();
     422         600 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
     423         600 :         move16();
     424             : 
     425       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     426             :         {
     427       14400 :             hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
     428       14400 :             move32();
     429       14400 :             hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
     430       14400 :             move32();
     431       14400 :             hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
     432       14400 :             move32();
     433             :         }
     434             : 
     435             :         /* Need to initialize renormalization_factors, and variables to be normalized */
     436             : 
     437         600 :         set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands );
     438         600 :         set_zero_fx( diffuseness_m_fx, hOMasa->nbands );
     439         600 :         set_zero_fx( hOMasa->energy_fx[block_m_idx], MASA_FREQUENCY_BANDS );
     440             : 
     441         600 :         set16_fx( tmp_ener_e[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     442             : 
     443        3000 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
     444             :         {
     445       12000 :             FOR( i = 0; i < nchan_ism; i++ )
     446             :             {
     447        9600 :                 Word16 in_q = Q11;
     448        9600 :                 move16();
     449             : 
     450             :                 /* Keep input to cldfbAnalysis_ts_fx in Q11 */
     451        9600 :                 IF( NE_16( in_q, data_f_q ) )
     452             :                 {
     453        8896 :                     scale_sig32( &( data_f_fx[i][i_mult( l_ts, ts )] ), l_ts, sub( in_q, data_f_q ) ); /* Q11 */
     454             :                 }
     455             : 
     456        9600 :                 cldfbAnalysis_ts_fx( &( data_f_fx[i][i_mult( l_ts, ts )] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &in_q );
     457             : 
     458             :                 /* Restore data_f_fx to it's original Q */
     459        9600 :                 IF( NE_16( data_f_q, Q11 ) )
     460             :                 {
     461        8896 :                     scale_sig32( &( data_f_fx[i][i_mult( l_ts, ts )] ), l_ts, sub( data_f_q, Q11 ) ); /* Q(data_f_q) */
     462             :                 }
     463             : 
     464      585600 :                 FOR( Word16 ind = 0; ind < CLDFB_NO_CHANNELS_MAX; ind++ )
     465             :                 {
     466      576000 :                     Chnl_RealBuffer_fx[i][ind] = L_shr( Chnl_RealBuffer_fx[i][ind], 4 ); // Q: in_q - 4
     467      576000 :                     move32();
     468      576000 :                     Chnl_ImagBuffer_fx[i][ind] = L_shr( Chnl_ImagBuffer_fx[i][ind], 4 ); // Q: in_q - 4
     469      576000 :                     move32();
     470             :                 }
     471             : 
     472        9600 :                 Chnl_RealBuffer_q[i] = sub( in_q, 4 );
     473        9600 :                 move16();
     474        9600 :                 Chnl_ImagBuffer_q[i] = sub( in_q, 4 );
     475        9600 :                 move16();
     476             :             }
     477             : 
     478        2400 :             IF( GT_16( nchan_ism, 1 ) )
     479             :             {
     480             :                 Word16 anaBuf_com_q;
     481        2400 :                 minimum_fx( Chnl_RealBuffer_q, nchan_ism, &anaBuf_com_q );
     482             : 
     483       12000 :                 FOR( i = 0; i < nchan_ism; i++ )
     484             :                 {
     485        9600 :                     IF( NE_16( anaBuf_com_q, Chnl_RealBuffer_q[i] ) )
     486             :                     {
     487      412055 :                         FOR( Word16 ind = 0; ind < CLDFB_NO_CHANNELS_MAX; ind++ )
     488             :                         {
     489      405300 :                             Chnl_RealBuffer_fx[i][ind] = L_shr( Chnl_RealBuffer_fx[i][ind], sub( Chnl_RealBuffer_q[i], anaBuf_com_q ) ); // Q: anaBuf_com_q
     490      405300 :                             move32();
     491      405300 :                             Chnl_ImagBuffer_fx[i][ind] = L_shr( Chnl_ImagBuffer_fx[i][ind], sub( Chnl_ImagBuffer_q[i], anaBuf_com_q ) ); // Q: anaBuf_com_q
     492      405300 :                             move32();
     493             :                         }
     494        6755 :                         Chnl_ImagBuffer_q[i] = anaBuf_com_q;
     495        6755 :                         move16();
     496        6755 :                         Chnl_RealBuffer_q[i] = anaBuf_com_q;
     497        6755 :                         move16();
     498             :                     }
     499             :                 }
     500             :             }
     501             : 
     502             : 
     503             :             /* Compute channel-based energy for metadata processing */
     504       60000 :             FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     505             :             {
     506       57600 :                 brange[0] = hOMasa->band_grouping[band_m_idx];
     507       57600 :                 move16();
     508       57600 :                 brange[1] = hOMasa->band_grouping[band_m_idx + 1];
     509       57600 :                 move16();
     510      201600 :                 FOR( j = brange[0]; j < brange[1]; j++ )
     511             :                 {
     512      720000 :                     FOR( i = 0; i < nchan_ism; i++ )
     513             :                     {
     514             :                         Word16 tmp_e, tmp_r_q, tmp_i_q;
     515             :                         Word32 tmp_r, tmp_i, L_tmp_sum;
     516      576000 :                         tmp_r_q = norm_l( Chnl_RealBuffer_fx[i][j] );
     517      576000 :                         tmp_r = L_shl( Chnl_RealBuffer_fx[i][j], tmp_r_q ); /* Q(Chnl_RealBuffer_q[i] + tmp_r_q) */
     518      576000 :                         tmp_r_q = add( tmp_r_q, Chnl_RealBuffer_q[i] );
     519      576000 :                         L_tmp1 = Mpy_32_32( tmp_r, tmp_r ); /* Q(2*tmp_r_q - 31)*/
     520      576000 :                         tmp_r_q = sub( add( tmp_r_q, tmp_r_q ), 31 );
     521      576000 :                         tmp_i_q = norm_l( Chnl_ImagBuffer_fx[i][j] );
     522      576000 :                         tmp_i = L_shl( Chnl_ImagBuffer_fx[i][j], tmp_i_q ); /* Q(Chnl_ImagBuffer_q[i] + tmp_i_q)*/
     523      576000 :                         tmp_i_q = add( tmp_i_q, Chnl_ImagBuffer_q[i] );
     524      576000 :                         tmp_i_q = sub( add( tmp_i_q, tmp_i_q ), 31 );
     525      576000 :                         L_tmp2 = Mpy_32_32( tmp_i, tmp_i );                                                                                                                                                                               /* Q(2*tmp_i_q - 31) */
     526      576000 :                         L_tmp_sum = BASOP_Util_Add_Mant32Exp( L_tmp1, sub( 31, tmp_r_q ), L_tmp2, sub( 31, tmp_i_q ), &tmp_e );                                                                                                           /* Q(31 - tmp_e) */
     527      576000 :                         hOMasa->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->energy_fx[block_m_idx][band_m_idx], tmp_ener_e[block_m_idx][band_m_idx], L_tmp_sum, tmp_e, &tmp_ener_e[block_m_idx][band_m_idx] ); /* Q(31 - tmp_ener_e[block_m_idx][band_m_idx]) */
     528      576000 :                         move32();
     529             :                     }
     530             :                 }
     531             :             }
     532             : 
     533             :             /* Compute FOA */
     534             :             /* W */
     535             : 
     536        2400 :             Copy32( Chnl_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins );
     537        2400 :             Copy32( Chnl_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins );
     538             : 
     539        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     540             :             {
     541             : #ifdef VEC_ARITH_OPT_v1
     542        7200 :                 v_add_fixed_no_hdrm( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // Q:  Chnl_RealBuffer_q
     543        7200 :                 v_add_fixed_no_hdrm( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); // Q:  Chnl_ImagBuffer_q
     544             : #else                                                                                                                    /* VEC_ARITH_OPT_v1 */
     545             :                 v_add_fixed( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins, 0 ); // Q:  Chnl_RealBuffer_q
     546             :                 v_add_fixed( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins, 0 ); // Q:  Chnl_ImagBuffer_q
     547             : #endif                                                                                                                   /* VEC_ARITH_OPT_v1 */
     548             :             }
     549             : 
     550             :             /* Y */
     551             : 
     552        2400 :             v_multc_fixed( Chnl_RealBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[1][0] ), Foa_RealBuffer_fx[1], num_freq_bins ); // Q: Chnl_RealBuffer_q
     553        2400 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[1][0] ), Foa_ImagBuffer_fx[1], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     554             : 
     555        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     556             :             {
     557        7200 :                 v_multc_acc_32_16( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); // Q: Chnl_RealBuffer_q
     558        7200 :                 v_multc_acc_32_16( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     559             :             }
     560             : 
     561             :             /* Z */
     562             : 
     563        2400 :             v_multc_fixed( Chnl_RealBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[2][0] ), Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
     564        2400 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[2][0] ), Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     565             : 
     566        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     567             :             {
     568        7200 :                 v_multc_acc_32_16( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
     569        7200 :                 v_multc_acc_32_16( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     570             :             }
     571             : 
     572        2400 :             v_multc_fixed( Chnl_RealBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[3][0] ), Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
     573        2400 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], L_deposit_h( hOMasa->chnlToFoaMtx_fx[3][0] ), Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     574             : 
     575        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     576             :             {
     577        7200 :                 v_multc_acc_32_16( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // Q: Chnl_RealBuffer_q
     578        7200 :                 v_multc_acc_32_16( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     579             :             }
     580             : 
     581             :             /* Direction estimation */
     582       12000 :             FOR( i = 0; i < FOA_CHANNELS; i++ )
     583             :             {
     584      585600 :                 FOR( j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ )
     585             :                 {
     586      576000 :                     Foa_RealBuffer_fx[i][j] = L_shr( Foa_RealBuffer_fx[i][j], 5 ); // Q: ( Chnl_RealBuffer_q - 5 )
     587      576000 :                     move32();
     588      576000 :                     Foa_ImagBuffer_fx[i][j] = L_shr( Foa_ImagBuffer_fx[i][j], 5 ); // Q: ( Chnl_RealBuffer_q - 5 )
     589      576000 :                     move32();
     590             :                 }
     591             :             }
     592        2400 :             foa_q = sub( Chnl_ImagBuffer_q[0], 5 );
     593        2400 :             computeIntensityVector_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx );
     594             : 
     595        2400 :             intensity_q = sub( shl( add( foa_q, Q1 ), 1 ), 31 );
     596        2400 :             direction_q = intensity_q;
     597        2400 :             move16();
     598             : 
     599        2400 :             computeDirectionVectors_fx( 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], &direction_q );
     600             : 
     601             :             /* Power estimation for diffuseness */
     602             : 
     603        2400 :             computeReferencePower_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx, num_freq_bands ); // 2 * inputq - 30
     604        2400 :             reference_power_q = sub( shl( Chnl_ImagBuffer_q[0], 1 ), 30 );
     605             : 
     606             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
     607        2400 :             hOMasa->index_buffer_intensity = add( ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
     608        2400 :             move16();
     609        2400 :             index = hOMasa->index_buffer_intensity;
     610        2400 :             move16();
     611             : 
     612        9600 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     613             :             {
     614             :                 /* only real part needed */
     615        7200 :                 Copy32( intensity_real_fx[i], &( hOMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // intensity_q
     616             :             }
     617        2400 :             hOMasa->buffer_intensity_real_q[index - 1] = intensity_q;
     618        2400 :             move16();
     619        2400 :             Copy32( reference_power_fx, &( hOMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     620        2400 :             hOMasa->buffer_energy_q[index - 1] = reference_power_q;
     621        2400 :             move16();
     622             : 
     623        2400 :             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, &diffuseness_q );
     624             : 
     625       60000 :             FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     626             :             {
     627       57600 :                 norm_tmp_fx = Mpy_32_32( reference_power_fx[band_m_idx], L_sub( ONE_IN_Q30, diffuseness_vector_fx[band_m_idx] ) ); // reference_power_q + 30 - 31
     628       57600 :                 norm_tmp_q = sub( add( reference_power_q, 30 ), 31 );
     629             : 
     630       57600 :                 hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = L_add( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ) ); // Q: hOMasa->direction_vector_m_q: ( ( norm_tmp_q + direction_q ) - 31 )
     631       57600 :                 move32();
     632             : 
     633       57600 :                 hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = L_add( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ) ); // Q: hOMasa->direction_vector_m_q: ( ( norm_tmp_q + direction_q ) - 31 )
     634       57600 :                 move32();
     635       57600 :                 hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = L_add( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ) ); // Q: hOMasa->direction_vector_m_q: ( ( norm_tmp_q + direction_q ) - 31 )
     636       57600 :                 move32();
     637             : 
     638       57600 :                 hOMasa->direction_vector_m_q = sub( add( norm_tmp_q, direction_q ), 31 );
     639             : 
     640             : 
     641       57600 :                 diffuseness_m_fx[band_m_idx] = L_add( diffuseness_m_fx[band_m_idx], Mpy_32_32( reference_power_fx[band_m_idx], diffuseness_vector_fx[band_m_idx] ) ); // diffuseness_m_q: ( ( reference_power_q + diffuseness_q ) - 31 );
     642       57600 :                 move32();
     643       57600 :                 diffuseness_m_q = sub( add( reference_power_q, diffuseness_q ), 31 );
     644       57600 :                 renormalization_factor_diff_fx[band_m_idx] = L_add( renormalization_factor_diff_fx[band_m_idx], reference_power_fx[band_m_idx] );
     645       57600 :                 move32();
     646       57600 :                 renormalization_factor_diff_q = reference_power_q;
     647       57600 :                 move16();
     648             :             }
     649             :         }
     650             : 
     651       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     652             :         {
     653       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     654             :             {
     655       43200 :                 dir_v_fx[d] = hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx];
     656       43200 :                 move32();
     657             :             }
     658       14400 :             dir_v_q = hOMasa->direction_vector_m_q;
     659       14400 :             move16();
     660             : 
     661       57600 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     662             :             {
     663       43200 :                 dir_v_fx[i] = L_shr( dir_v_fx[i], 1 );
     664       43200 :                 move32();
     665             :             }
     666             : 
     667       14400 :             dir_v_q = sub( dir_v_q, 1 );
     668       14400 :             ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, dir_v_q, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] );
     669             :         }
     670             : 
     671             :         /* Determine energy ratios */
     672       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     673             :         {
     674       14400 :             IF( BASOP_Util_Cmp_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], sub( 31, renormalization_factor_diff_q ), L_deposit_h( EPSILON_FX ), 2 ) > 0 )
     675             :             {
     676        3861 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &scale );
     677        3861 :                 move32();
     678        3861 :                 scale = add( scale, sub( sub( 31, diffuseness_m_q ), sub( 31, renormalization_factor_diff_q ) ) );
     679             : 
     680        3861 :                 diffuseness_m_fx[band_m_idx] = L_shr( diffuseness_m_fx[band_m_idx], sub( 31, add( scale, diffuseness_m_q ) ) );
     681        3861 :                 move32();
     682             :             }
     683             :             ELSE
     684             :             {
     685       10539 :                 diffuseness_m_fx[band_m_idx] = 0;
     686       10539 :                 move32();
     687             :             }
     688       14400 :             energyRatio_fx[block_m_idx][band_m_idx] = L_sub( L_shl( 1, diffuseness_m_q ), diffuseness_m_fx[band_m_idx] ); // Q: diffuseness_m_q
     689       14400 :             move32();
     690             :         }
     691             : 
     692             :         /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
     693       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     694             :         {
     695       14400 :             spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
     696       14400 :             move32();
     697       14400 :             surroundingCoherence_fx[block_m_idx][band_m_idx] = 0;
     698       14400 :             move32();
     699             :         }
     700             :     }
     701             : 
     702         150 :     Word16 q_ener_min = MAX_16;
     703         150 :     move16();
     704         750 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     705             :     {
     706             :         Word16 e_max;
     707         600 :         maximum_fx( tmp_ener_e[block_m_idx], num_freq_bands, &e_max );
     708         600 :         e_max = sub( 31, e_max );
     709         600 :         if ( GT_16( q_ener_min, e_max ) )
     710             :         {
     711         256 :             q_ener_min = e_max;
     712         256 :             move16();
     713             :         }
     714             :     }
     715             : 
     716         750 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     717             :     {
     718       15000 :         FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     719             :         {
     720       14400 :             hOMasa->energy_fx[block_m_idx][band_m_idx] = L_shr( hOMasa->energy_fx[block_m_idx][band_m_idx], sub( sub( 31, tmp_ener_e[block_m_idx][band_m_idx] ), q_ener_min ) ); /* Q(q_ener_min) */
     721       14400 :             move32();
     722             :         }
     723             :     }
     724             : 
     725         150 :     hOMasa->energy_q = q_ener_min;
     726         150 :     move16();
     727             : 
     728         150 :     *spreadCoherence_q = 0;
     729         150 :     move16();
     730         150 :     *surroundingCoherence_q = 0;
     731         150 :     move16();
     732         150 :     *energyRatio_q = 0;
     733         150 :     move16();
     734             : 
     735         150 :     return;
     736             : }
     737             : 
     738             : 
     739             : /* Compute downmix */
     740         150 : static void ivas_omasa_dmx_fx(
     741             :     Word32 data_in_f_fx[][L_FRAME48k],
     742             :     Word16 *data_in_q,
     743             :     const Word16 input_frame,
     744             :     const Word16 nchan_transport,
     745             :     const Word16 nchan_ism,
     746             :     const Word32 ism_azimuth_fx[MAX_NUM_OBJECTS],
     747             :     const Word32 ism_elevation_fx[MAX_NUM_OBJECTS],
     748             :     Word32 prev_gains_fx[][MASA_MAX_TRANSPORT_CHANNELS],
     749             :     const Word16 interpolator_fx[L_FRAME48k] )
     750             : {
     751             :     Word16 i, j, k, l, tmp1, tmp2;
     752             : 
     753             :     Word16 azimuth_fx, elevation_fx;
     754             :     Word16 gains_fx[MASA_MAX_TRANSPORT_CHANNELS];
     755             :     Word16 g1_fx, g2_fx, scale;
     756             :     Word32 data_out_f_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k], L_tmp;
     757             :     Word16 max_e, tmp_e;
     758             :     Word16 in_e[960];
     759             :     Word16 data_e[4];
     760             : 
     761         450 :     FOR( i = 0; i < nchan_transport; i++ )
     762             :     {
     763         300 :         set_zero_fx( data_out_f_fx[i], input_frame );
     764             :     }
     765         150 :     set16_fx( data_e, 0, 4 );
     766         150 :     set16_fx( in_e, 0, 960 );
     767             : 
     768         750 :     FOR( i = 0; i < nchan_ism; i++ )
     769             :     {
     770             : 
     771         600 :         azimuth_fx = extract_l( L_shr( ism_azimuth_fx[i], Q22 ) );     // Q0
     772         600 :         elevation_fx = extract_l( L_shr( ism_elevation_fx[i], Q22 ) ); // Q0
     773             : 
     774         600 :         ivas_ism_get_stereo_gains_fx( azimuth_fx, elevation_fx, &gains_fx[0], &gains_fx[1] );
     775             : 
     776             :         /* Downmix using the panning gains */
     777        1800 :         FOR( j = 0; j < nchan_transport; j++ )
     778             :         {
     779        1200 :             test();
     780        1200 :             IF( abs_s( gains_fx[j] ) > 0 || L_abs( prev_gains_fx[i][j] ) > 0 )
     781             :             {
     782     1060944 :                 FOR( k = 0; k < input_frame; k++ )
     783             :                 {
     784             : 
     785     1059840 :                     g1_fx = interpolator_fx[k]; // Q15
     786     1059840 :                     move16();
     787     1059840 :                     scale = BASOP_Util_Add_MantExp( 16384, 1, negate( g1_fx ), 0, &g2_fx );
     788             : 
     789     1059840 :                     tmp1 = mult( g1_fx, gains_fx[j] );
     790     1059840 :                     tmp2 = mult( g2_fx, (Word16) L_shr( prev_gains_fx[i][j], 16 ) ); // Q: ( ( ( 15 - scale ) + ( Q31 - Q16 ) ) - Q15 ) -> ( 15 - scale )
     791     1059840 :                     scale = BASOP_Util_Add_MantExp( tmp1, 0, tmp2, scale, &tmp1 );
     792             : 
     793     1059840 :                     L_tmp = data_in_f_fx[i][k]; // data_in_q
     794     1059840 :                     move32();
     795     1059840 :                     tmp_e = sub( 31, *data_in_q );
     796     1059840 :                     move16();
     797             : 
     798     1059840 :                     L_tmp = Mpy_32_16_1( L_tmp, tmp1 );
     799     1059840 :                     scale = add( scale, tmp_e );
     800             : 
     801     1059840 :                     data_out_f_fx[j][k] = BASOP_Util_Add_Mant32Exp( data_out_f_fx[j][k], data_e[j], L_tmp, scale, &in_e[k] );
     802     1059840 :                     move32();
     803             :                 }
     804             :             }
     805        1200 :             max_e = in_e[0];
     806        1200 :             move16();
     807     1152000 :             FOR( l = 1; l < L_FRAME48k; l++ )
     808             :             {
     809     1150800 :                 IF( LT_16( max_e, in_e[l] ) )
     810             :                 {
     811        2449 :                     max_e = in_e[l];
     812        2449 :                     move16();
     813             :                 }
     814             :             }
     815             : 
     816     1153200 :             FOR( l = 0; l < L_FRAME48k; l++ )
     817             :             {
     818     1152000 :                 data_out_f_fx[j][l] = L_shr( data_out_f_fx[j][l], sub( max_e, in_e[l] ) ); // exponent: max_e, Q: ( 15 - max_e )
     819     1152000 :                 move32();
     820             :             }
     821        1200 :             data_e[j] = max_e;
     822        1200 :             move16();
     823             : 
     824        1200 :             prev_gains_fx[i][j] = L_deposit_h( gains_fx[j] ); // Q31
     825        1200 :             move32();
     826             :         }
     827             :     }
     828             : 
     829         150 :     max_e = data_e[0];
     830         150 :     move16();
     831         300 :     FOR( i = 1; i < nchan_transport; i++ )
     832             :     {
     833         150 :         if ( LT_16( max_e, data_e[i] ) )
     834             :         {
     835          50 :             max_e = data_e[i];
     836          50 :             move16();
     837             :         }
     838             :     }
     839             : 
     840         450 :     FOR( i = 0; i < nchan_transport; i++ )
     841             :     {
     842      288300 :         FOR( j = 0; j < input_frame; j++ )
     843             :         {
     844      288000 :             data_out_f_fx[i][j] = L_shr( data_out_f_fx[i][j], sub( max_e, data_e[i] ) ); // exponent: max_e, Q: ( 15 - max_e )
     845      288000 :             move32();
     846             :         }
     847             :     }
     848             : 
     849         450 :     FOR( i = 0; i < nchan_transport; i++ )
     850             :     {
     851         300 :         Copy32( data_out_f_fx[i], data_in_f_fx[i], input_frame );
     852         300 :         *data_in_q = sub( 31, max_e );
     853         300 :         move16();
     854             :     }
     855             : 
     856         150 :     return;
     857             : }
     858             : 
     859             : /* Compute downmix */
     860             : 
     861             : 
     862             : /*--------------------------------------------------------------------------*
     863             :  * computeIntensityVector_ana()
     864             :  *
     865             :  *
     866             :  *--------------------------------------------------------------------------*/
     867             : 
     868        9600 : void computeIntensityVector_ana_fx(
     869             :     const Word16 *band_grouping,                                  /* i  : Band grouping for estimation   */
     870             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal   Qx */
     871             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input sig      Qx */
     872             :     const Word16 num_frequency_bands,                             /* i  : Number of frequency bands      */
     873             :     Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]   /* o  : Intensity           2 * Qx -31 */
     874             : )
     875             : {
     876             :     /* Reminder
     877             :      * X = a + ib; Y = c + id
     878             :      * X*Y = ac - bd + i(ad +bc)
     879             :      */
     880             :     Word16 i, j;
     881             :     Word32 real, img;
     882             :     Word16 brange[2];
     883             : 
     884      240000 :     FOR( i = 0; i < num_frequency_bands; i++ )
     885             :     {
     886      230400 :         brange[0] = band_grouping[i];
     887      230400 :         move16();
     888      230400 :         brange[1] = band_grouping[i + 1];
     889      230400 :         move16();
     890             : 
     891      230400 :         intensity_real[0][i] = 0;
     892      230400 :         move32();
     893      230400 :         intensity_real[1][i] = 0;
     894      230400 :         move32();
     895      230400 :         intensity_real[2][i] = 0;
     896      230400 :         move32();
     897             : 
     898      806400 :         FOR( j = brange[0]; j < brange[1]; j++ )
     899             :         {
     900      576000 :             real = Cldfb_RealBuffer[0][j]; // Qx
     901      576000 :             img = Cldfb_ImagBuffer[0][j];  // Qx
     902             :             /* Intensity is XYZ order, audio is WYZX order. */
     903      576000 :             intensity_real[0][i] = L_add( intensity_real[0][i], L_add( Mpy_32_32( Cldfb_RealBuffer[3][j], real ), Mpy_32_32( Cldfb_ImagBuffer[3][j], img ) ) ); // output Q = 2 * Qx -31
     904      576000 :             move32();
     905      576000 :             intensity_real[1][i] = L_add( intensity_real[1][i], L_add( Mpy_32_32( Cldfb_RealBuffer[1][j], real ), Mpy_32_32( Cldfb_ImagBuffer[1][j], img ) ) ); // output Q = 2 * Qx -31
     906      576000 :             move32();
     907      576000 :             intensity_real[2][i] = L_add( intensity_real[2][i], L_add( Mpy_32_32( Cldfb_RealBuffer[2][j], real ), Mpy_32_32( Cldfb_ImagBuffer[2][j], img ) ) ); // output Q = 2 * Qx -31
     908      576000 :             move32();
     909             :         }
     910             :     }
     911             : 
     912        9600 :     return;
     913             : }
     914             : /*--------------------------------------------------------------------------*
     915             :  * computeIntensityVector_ana()
     916             :  *
     917             :  *
     918             :  *--------------------------------------------------------------------------*/
     919             : 
     920             : 
     921             : /*--------------------------------------------------------------------------*
     922             :  * computeReferencePower_ana()
     923             :  *
     924             :  *
     925             :  *--------------------------------------------------------------------------*/
     926             : 
     927        7200 : void computeReferencePower_ana_fx(
     928             :     const Word16 *band_grouping,                                  /* i  : Band grouping for estimation                  */
     929             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal    input_q          */
     930             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal    input_q          */
     931             :     Word32 *reference_power,                                      /* o  : Estimated power              2 * inputq - 31  */
     932             :     const Word16 num_freq_bands                                   /* i  : Number of frequency bands                     */
     933             : )
     934             : {
     935             :     Word16 brange[2];
     936             :     Word16 ch_idx, i, j;
     937             : 
     938      180000 :     FOR( i = 0; i < num_freq_bands; i++ )
     939             :     {
     940      172800 :         brange[0] = band_grouping[i];
     941      172800 :         move16();
     942      172800 :         brange[1] = band_grouping[i + 1];
     943      172800 :         move16();
     944      172800 :         reference_power[i] = 0;
     945      172800 :         move32();
     946             : 
     947      864000 :         FOR( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
     948             :         {
     949             :             /* abs()^2 */
     950     2419200 :             FOR( j = brange[0]; j < brange[1]; j++ )
     951             :             {
     952             :                 // Q = 2*inputq - 31
     953     1728000 :                 reference_power[i] = L_add( L_add( Mpy_32_32( Cldfb_RealBuffer[ch_idx][j], Cldfb_RealBuffer[ch_idx][j] ), Mpy_32_32( Cldfb_ImagBuffer[ch_idx][j], Cldfb_ImagBuffer[ch_idx][j] ) ), reference_power[i] );
     954     1728000 :                 move32();
     955             :             }
     956             :         }
     957             :     }
     958             : 
     959             :     // v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
     960             : 
     961             :     /* Bypassing the v_multc ,so output q = 2*inputq - 30*/
     962        7200 :     return;
     963             : }
     964             : 
     965             : /*--------------------------------------------------------------------------*
     966             :  * computeReferencePower_ana()
     967             :  *
     968             :  *
     969             :  *--------------------------------------------------------------------------*/

Generated by: LCOV version 1.14