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 @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 332 342 97.1 %
Date: 2025-06-27 02:59:36 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             :  * Local function prototypes
      46             :  *------------------------------------------------------------------------*/
      47             : 
      48             : 
      49             : static void ivas_omasa_dmx_fx(
      50             :     Word32 data_in_f_fx[][L_FRAME48k],
      51             :     Word16 *data_in_q,
      52             :     const Word16 input_frame,
      53             :     const Word16 nchan_transport,
      54             :     const Word16 nchan_ism,
      55             :     const Word32 ism_azimuth_fx[MAX_NUM_OBJECTS],
      56             :     const Word32 ism_elevation_fx[MAX_NUM_OBJECTS],
      57             :     Word32 prev_gains_fx[][MASA_MAX_TRANSPORT_CHANNELS],
      58             :     const Word16 interpolator_fx[L_FRAME48k] );
      59             : 
      60             : 
      61             : static void ivas_omasa_param_est_ana_fx(
      62             :     OMASA_ANA_HANDLE hOMasa,
      63             :     Word32 data_f_fx[][L_FRAME48k],
      64             :     Word16 data_f_q,
      65             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
      66             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   // Q22
      67             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
      68             :     Word16 *energyRatio_q,
      69             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
      70             :     Word16 *spreadCoherence_q,
      71             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
      72             :     Word16 *surroundingCoherence_q,
      73             :     const Word16 input_frame,
      74             :     const Word16 nchan_ism );
      75             : 
      76             : /*--------------------------------------------------------------------------*
      77             :  * ivas_omasa_ana_open()
      78             :  *
      79             :  * Allocate and initialize OMASA handle
      80             :  *--------------------------------------------------------------------------*/
      81             : 
      82           1 : ivas_error ivas_omasa_ana_open(
      83             :     OMASA_ANA_HANDLE *hOMasaPtr, /* i/o: OMASA data handle pointer */
      84             :     Word32 input_Fs,             /* i  : Sampling frequency        */
      85             :     UWord16 total_num_objects    /* i  : Number of objects         */
      86             : )
      87             : {
      88             :     Word16 i, j;
      89             :     OMASA_ANA_HANDLE hOMasa;
      90             :     Word16 numAnalysisChannels;
      91             :     Word16 maxBin, input_frame;
      92             :     ivas_error error;
      93             :     Word16 scale;
      94             : 
      95           1 :     error = IVAS_ERR_OK;
      96           1 :     move32();
      97             : 
      98           1 :     IF( ( hOMasa = (OMASA_ANA_HANDLE) malloc( sizeof( OMASA_ANA_DATA ) ) ) == NULL )
      99             :     {
     100           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA\n" ) );
     101             :     }
     102             : 
     103           1 :     numAnalysisChannels = (Word16) total_num_objects;
     104           1 :     move16();
     105             : 
     106             :     /* Determine the number of bands */
     107           1 :     hOMasa->nbands = MASA_FREQUENCY_BANDS;
     108           1 :     move16();
     109             : 
     110             :     /* Determine band grouping */
     111           1 :     Copy( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
     112             : 
     113             :     /* maxBin = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); */
     114           1 :     maxBin = extract_l( Mpy_32_32( input_Fs, 2684355 /* INV_CLDFB_BANDWIDTH in Q31 */ ) ); // Q: ( ( Q0 + Q31 ) - Q31 ) -> Q0
     115             : 
     116          24 :     FOR( i = 1; i < hOMasa->nbands + 1; i++ )
     117             :     {
     118          24 :         IF( GE_16( hOMasa->band_grouping[i], maxBin ) )
     119             :         {
     120           1 :             hOMasa->band_grouping[i] = maxBin;
     121           1 :             move16();
     122           1 :             hOMasa->nbands = i;
     123           1 :             move16();
     124           1 :             BREAK;
     125             :         }
     126             :     }
     127             : 
     128             :     /* Determine block grouping */
     129           1 :     Copy( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
     130             : 
     131             :     /* open/initialize CLDFB */
     132           1 :     hOMasa->num_Cldfb_instances = numAnalysisChannels;
     133           5 :     FOR( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
     134             :     {
     135           4 :         IF( NE_32( ( error = openCldfb_ivas_fx( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, input_Fs, CLDFB_PROTOTYPE_5_00MS, DEC ) ), IVAS_ERR_OK ) )
     136             :         {
     137           0 :             return error;
     138             :         }
     139             :     }
     140             : 
     141           1 :     FOR( ; i < MAX_NUM_OBJECTS; i++ )
     142             :     {
     143           0 :         hOMasa->cldfbAnaEnc[i] = NULL;
     144             :     }
     145             : 
     146           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     147             :     {
     148           3 :         IF( ( hOMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ) ) == NULL )
     149             :         {
     150           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     151             :         }
     152             : 
     153          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     154             :         {
     155          12 :             IF( ( hOMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     156             :             {
     157           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     158             :             }
     159          12 :             set_zero_fx( hOMasa->direction_vector_m_fx[i][j], MASA_FREQUENCY_BANDS );
     160             :         }
     161           3 :         IF( ( hOMasa->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) ) ) == NULL )
     162             :         {
     163           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     164             :         }
     165             : 
     166          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     167             :         {
     168          12 :             IF( ( hOMasa->direction_vector_e[i][j] = (Word16 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word16 ) ) ) == NULL )
     169             :             {
     170           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     171             :             }
     172          12 :             set16_fx( hOMasa->direction_vector_e[i][j], 0, MASA_FREQUENCY_BANDS );
     173             :         }
     174             :     }
     175             : 
     176           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     177             :     {
     178          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     179             :         {
     180          96 :             IF( ( hOMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL )
     181             :             {
     182           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) );
     183             :             }
     184          96 :             set_zero_fx( hOMasa->buffer_intensity_real_fx[i][j], MASA_FREQUENCY_BANDS );
     185             :         }
     186             :     }
     187           1 :     set16_fx( hOMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF );
     188           1 :     set16_fx( hOMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF );
     189           1 :     set_zero_fx( hOMasa->buffer_energy_fx, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
     190             : 
     191           5 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
     192             :     {
     193           4 :         set32_fx( hOMasa->prev_object_dm_gains_fx[i], INV_SQRT_2_Q31, MASA_MAX_TRANSPORT_CHANNELS );
     194             :     }
     195             : 
     196             :     /* input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); */
     197           1 :     input_frame = extract_l( Mpy_32_32( input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     198         961 :     FOR( i = 0; i < input_frame; i++ )
     199             :     {
     200         960 :         hOMasa->interpolator_fx[i] = BASOP_Util_Divide1616_Scale( i, input_frame, &scale );
     201         960 :         move16();
     202         960 :         hOMasa->interpolator_fx[i] = shl( hOMasa->interpolator_fx[i], scale ); // Q15
     203         960 :         move16();
     204             :     }
     205             : 
     206           1 :     hOMasa->index_buffer_intensity = 0;
     207           1 :     move16();
     208             : 
     209           1 :     IF( ( hOMasa->hMasaOut = (MASA_DECODER_EXT_OUT_META_HANDLE) malloc( sizeof( MASA_DECODER_EXT_OUT_META ) ) ) == NULL )
     210             :     {
     211           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     212             :     }
     213             : 
     214           1 :     IF( ( hOMasa->sph_grid16 = (SPHERICAL_GRID_DATA *) malloc( sizeof( SPHERICAL_GRID_DATA ) ) ) == NULL )
     215             :     {
     216           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
     217             :     }
     218             : 
     219           1 :     generate_gridEq_fx( hOMasa->sph_grid16 );
     220             : 
     221           5 :     FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
     222             :     {
     223           4 :         set_zero_fx( hOMasa->energy_fx[i], MASA_FREQUENCY_BANDS );
     224             :     }
     225             : 
     226           1 :     set_zero_fx( hOMasa->ism_azimuth_fx, MAX_NUM_OBJECTS );
     227           1 :     set_zero_fx( hOMasa->ism_elevation_fx, MAX_NUM_OBJECTS );
     228             : 
     229           1 :     ( *hOMasaPtr ) = hOMasa;
     230             : 
     231           1 :     return error;
     232             : }
     233             : 
     234             : /*--------------------------------------------------------------------------*
     235             :  * ivas_omasa_ana_close()
     236             :  *
     237             :  * Close OMASA handle
     238             :  *--------------------------------------------------------------------------*/
     239             : 
     240        2664 : void ivas_omasa_ana_close(
     241             :     OMASA_ANA_HANDLE *hOMasa /* i/o: analysis OMASA handle */
     242             : )
     243             : {
     244             :     Word16 i, j;
     245             : 
     246        2664 :     test();
     247        2664 :     IF( hOMasa == NULL || *hOMasa == NULL )
     248             :     {
     249        2663 :         return;
     250             :     }
     251             : 
     252           5 :     FOR( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
     253             :     {
     254           4 :         deleteCldfb_ivas_fx( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
     255             :     }
     256             : 
     257           4 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     258             :     {
     259          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     260             :         {
     261          12 :             free( ( *hOMasa )->direction_vector_m_fx[i][j] );
     262          12 :             ( *hOMasa )->direction_vector_m_fx[i][j] = NULL;
     263             :         }
     264             : 
     265          15 :         FOR( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
     266             :         {
     267          12 :             free( ( *hOMasa )->direction_vector_e[i][j] );
     268          12 :             ( *hOMasa )->direction_vector_e[i][j] = NULL;
     269             :         }
     270             : 
     271          99 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     272             :         {
     273          96 :             free( ( *hOMasa )->buffer_intensity_real_fx[i][j] );
     274          96 :             ( *hOMasa )->buffer_intensity_real_fx[i][j] = NULL;
     275             :         }
     276             : 
     277           3 :         free( ( *hOMasa )->direction_vector_m_fx[i] );
     278           3 :         ( *hOMasa )->direction_vector_m_fx[i] = NULL;
     279             : 
     280           3 :         free( ( *hOMasa )->direction_vector_e[i] );
     281           3 :         ( *hOMasa )->direction_vector_e[i] = NULL;
     282             :     }
     283             : 
     284           1 :     free( ( *hOMasa )->hMasaOut );
     285           1 :     ( *hOMasa )->hMasaOut = NULL;
     286           1 :     free( ( *hOMasa )->sph_grid16 );
     287           1 :     ( *hOMasa )->sph_grid16 = NULL;
     288             : 
     289           1 :     free( ( *hOMasa ) );
     290           1 :     ( *hOMasa ) = NULL;
     291             : 
     292           1 :     return;
     293             : }
     294             : 
     295             : /*--------------------------------------------------------------------------*
     296             :  * ivas_omasa_ana()
     297             :  *
     298             :  * OMASA analysis function
     299             :  *--------------------------------------------------------------------------*/
     300             : 
     301             : 
     302         150 : void ivas_omasa_ana_fx(
     303             :     OMASA_ANA_HANDLE hOMasa,           /* i/o: OMASA analysis handle                       */
     304             :     Word32 data_in_f_fx[][L_FRAME48k], /* i/o: Input / transport audio signals             */
     305             :     Word16 *data_in_q,
     306             :     const Word16 input_frame,     /* i  : Input frame size                            */
     307             :     const Word16 nchan_transport, /* i  : Number of transport channels                */
     308             :     const Word16 nchan_ism        /* i  : Number of objects for parameter analysis    */
     309             : )
     310             : {
     311             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     312             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     313             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     314             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     315             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
     316             :     Word16 spreadCoherence_q, sorroundingCoherence_q, energyRatio_q;
     317             : 
     318             :     /* Estimate MASA parameters from the objects */
     319         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 );
     320             : 
     321             :     /* Create MASA metadata buffer from the estimated values */
     322         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, Q31, Q31, Q31 );
     323             : 
     324             :     /* Downmix */
     325         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 );
     326             : 
     327         150 :     return;
     328             : }
     329             : 
     330             : 
     331             : /*--------------------------------------------------------------------------*
     332             :  * Local functions
     333             :  *--------------------------------------------------------------------------*/
     334             : 
     335             : /* Estimate MASA parameters from the objects */
     336             : 
     337             : 
     338         150 : static void ivas_omasa_param_est_ana_fx(
     339             :     OMASA_ANA_HANDLE hOMasa,
     340             :     Word32 data_f_fx[][L_FRAME48k],
     341             :     Word16 data_f_q,
     342             :     Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q22
     343             :     Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],   // Q22
     344             :     Word32 energyRatio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     345             :     Word16 *energyRatio_q,
     346             :     Word32 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     347             :     Word16 *spreadCoherence_q,
     348             :     Word32 surroundingCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
     349             :     Word16 *surroundingCoherence_q,
     350             :     const Word16 input_frame,
     351             :     const Word16 nchan_ism )
     352             : {
     353             :     Word16 ts, i, d, j;
     354             :     Word16 num_freq_bins, num_freq_bands, index;
     355             :     Word16 l_ts;
     356             : 
     357             :     Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
     358             :     Word32 Chnl_RealBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
     359             :     Word16 Chnl_RealBuffer_q[MAX_NUM_OBJECTS];
     360             :     Word16 Chnl_ImagBuffer_q[MAX_NUM_OBJECTS];
     361             :     Word32 Chnl_ImagBuffer_fx[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
     362             :     Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     363             :     Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
     364             :     Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     365             :     Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
     366             :     Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS];
     367         150 :     Word16 diffuseness_q = 0;
     368         150 :     move16();
     369             :     Word16 diffuseness_e[MASA_FREQUENCY_BANDS];
     370             :     Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS];
     371             : 
     372             :     Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS];
     373             :     Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS];
     374             :     Word32 norm_tmp_fx;
     375             : 
     376             :     Word32 dir_v_fx[DIRAC_NUM_DIMS] /*, L_tmp1, L_tmp2*/;
     377             :     Word16 dir_v_q /*, norm_tmp_q*/;
     378             :     Word16 band_m_idx, block_m_idx;
     379             : 
     380             :     Word16 mrange[2];
     381             :     Word16 brange[2];
     382             : 
     383         150 :     num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
     384         150 :     move16();
     385         150 :     num_freq_bands = hOMasa->nbands;
     386         150 :     move16();
     387         150 :     l_ts = shr( input_frame, 4 );
     388             : 
     389             :     Word16 intensity_q;
     390             :     Word16 reference_power_q;
     391             : 
     392         150 :     set16_zero_fx( Chnl_RealBuffer_q, MAX_NUM_OBJECTS );
     393         150 :     set16_zero_fx( Chnl_ImagBuffer_q, MAX_NUM_OBJECTS );
     394             : 
     395             :     /* Compute ISM to FOA matrices */
     396         750 :     FOR( i = 0; i < nchan_ism; i++ )
     397             :     {
     398         600 :         hOMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31;
     399         600 :         move32();
     400         600 :         hOMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( extract_l( Mpy_32_32( hOMasa->ism_azimuth_fx[i], 46603 /*32767/360*/ ) /*Q22+Q24-31=>Q15*/ ) ), getCosWord16R2( extract_l( Mpy_32_32( hOMasa->ism_elevation_fx[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
     401         600 :         move32();
     402         600 :         hOMasa->chnlToFoaMtx_fx[2][i] = L_shl( getSineWord16R2( extract_l( Mpy_32_32( hOMasa->ism_elevation_fx[i], 46603 /*2^24/360*/ ) ) ), 16 ); // Q31
     403         600 :         move32();
     404         600 :         hOMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( extract_l( Mpy_32_32( hOMasa->ism_azimuth_fx[i], 46603 /*2^24/360*/ ) ) ), getCosWord16R2( extract_l( Mpy_32_32( hOMasa->ism_elevation_fx[i], 46603 /*2^24/360*/ ) ) ) ); // Q31
     405         600 :         move32();
     406             :     }
     407             : 
     408             :     /* do processing over all CLDFB time slots */
     409         750 :     FOR( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ )
     410             :     {
     411         600 :         mrange[0] = hOMasa->block_grouping[block_m_idx];
     412         600 :         move16();
     413         600 :         mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
     414         600 :         move16();
     415             : 
     416       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     417             :         {
     418       14400 :             hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0;
     419       14400 :             move32();
     420       14400 :             hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0;
     421       14400 :             move32();
     422       14400 :             hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0;
     423       14400 :             move32();
     424             : 
     425       14400 :             hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] = 0;
     426       14400 :             move16();
     427       14400 :             hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] = 0;
     428       14400 :             move16();
     429       14400 :             hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] = 0;
     430       14400 :             move16();
     431             :         }
     432             : 
     433             :         /* Need to initialize renormalization_factors, and variables to be normalized */
     434             : 
     435         600 :         set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands );
     436         600 :         set16_fx( renormalization_factor_diff_e, 0, hOMasa->nbands );
     437         600 :         set_zero_fx( diffuseness_m_fx, hOMasa->nbands );
     438         600 :         set16_fx( diffuseness_e, 0, hOMasa->nbands );
     439         600 :         set_zero_fx( hOMasa->energy_fx[block_m_idx], MASA_FREQUENCY_BANDS );
     440         600 :         set16_fx( hOMasa->energy_e[block_m_idx], 0, MASA_FREQUENCY_BANDS );
     441             : 
     442        3000 :         FOR( ts = mrange[0]; ts < mrange[1]; ts++ )
     443             :         {
     444        2400 :             Word16 cr_q = MAX_16, ci_q = MAX_16, sf, c_e;
     445        2400 :             move16();
     446        2400 :             move16();
     447        2400 :             Word16 inp_q = data_f_q;
     448        2400 :             move16();
     449       12000 :             FOR( i = 0; i < nchan_ism; i++ )
     450             :             {
     451        9600 :                 inp_q = data_f_q;
     452        9600 :                 cldfbAnalysis_ts_fx_var_q( &( data_f_fx[i][i_mult( l_ts, ts )] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &inp_q );
     453             : 
     454        9600 :                 cr_q = s_min( cr_q, L_norm_arr( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX ) );
     455        9600 :                 ci_q = s_min( ci_q, L_norm_arr( Chnl_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX ) );
     456             :             }
     457        2400 :             sf = sub( s_min( cr_q, ci_q ), 4 );
     458       12000 :             FOR( i = 0; i < nchan_ism; i++ )
     459             :             {
     460        9600 :                 scale_sig32( Chnl_RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf
     461        9600 :                 scale_sig32( Chnl_ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sf ); // Q-> inp_q + sf
     462             :             }
     463        2400 :             inp_q = add( inp_q, sf );
     464        2400 :             c_e = sub( 31, inp_q );
     465             : 
     466             :             /* Compute channel-based energy for metadata processing */
     467       60000 :             FOR( band_m_idx = 0; band_m_idx < num_freq_bands; band_m_idx++ )
     468             :             {
     469       57600 :                 brange[0] = hOMasa->band_grouping[band_m_idx];
     470       57600 :                 move16();
     471       57600 :                 brange[1] = hOMasa->band_grouping[band_m_idx + 1];
     472       57600 :                 move16();
     473      201600 :                 FOR( j = brange[0]; j < brange[1]; j++ )
     474             :                 {
     475      720000 :                     FOR( i = 0; i < nchan_ism; i++ )
     476             :                     {
     477      576000 :                         Word32 temp = L_add( Mult_32_32( Chnl_RealBuffer_fx[i][j], Chnl_RealBuffer_fx[i][j] ), Mult_32_32( Chnl_ImagBuffer_fx[i][j], Chnl_ImagBuffer_fx[i][j] ) ); // Q-> 2*inp_q - 31, e = 31 - (2*inp_q - 31) = 62 - 2*inp_q = 2*(31 - inp_q) = 2*c_e
     478      576000 :                         hOMasa->energy_fx[block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->energy_fx[block_m_idx][band_m_idx], hOMasa->energy_e[block_m_idx][band_m_idx], temp, shl( c_e, 1 ), &hOMasa->energy_e[block_m_idx][band_m_idx] );
     479      576000 :                         move32();
     480             :                     }
     481             :                 }
     482             :             }
     483             : 
     484             :             /* Compute FOA */
     485             :             /* W */
     486             : 
     487        2400 :             Copy32( Chnl_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); // inp_q
     488        2400 :             Copy32( Chnl_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); // inp_q
     489             : 
     490        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     491             :             {
     492        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
     493        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
     494             :             }
     495             : 
     496             :             /* Y */
     497             : 
     498        2400 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); // Q: Chnl_RealBuffer_q
     499        2400 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     500             : 
     501        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     502             :             {
     503        7200 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); // Q: Chnl_RealBuffer_q
     504        7200 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     505             :             }
     506             : 
     507             :             /* Z */
     508             : 
     509        2400 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
     510        2400 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     511             : 
     512        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     513             :             {
     514        7200 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); // Q: Chnl_RealBuffer_q
     515        7200 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     516             :             }
     517             : 
     518        2400 :             v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); // Q: Chnl_RealBuffer_q
     519        2400 :             v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     520             : 
     521        9600 :             FOR( i = 1; i < nchan_ism; i++ )
     522             :             {
     523        7200 :                 v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); // Q: Chnl_RealBuffer_q
     524        7200 :                 v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); // Q: Chnl_ImagBuffer_q
     525             :             }
     526        2400 :             computeIntensityVector_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx ); /* Q intensity_real_fx = 2*inp_q-31, e = 31 - 2*inp_q + 31 = 62 - 2*inp_q = 2*(31-inp_q)=2*c_e */
     527        2400 :             intensity_q = sub( 31, shl( c_e, 1 ) );
     528             : 
     529        2400 :             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], shl( c_e, 1 ), NULL ); /* Q direction_vector_fx = Q30*/
     530             :             /* Power estimation for diffuseness */
     531             : 
     532        2400 :             computeReferencePower_ana_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], num_freq_bands ); // 2 * inputq - 30
     533        2400 :             reference_power_q = sub( shl( inp_q, 1 ), 30 );
     534             : 
     535             :             /* Fill buffers of length "averaging_length" time slots for intensity and energy */
     536        2400 :             hOMasa->index_buffer_intensity = add( ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */
     537        2400 :             move16();
     538        2400 :             index = hOMasa->index_buffer_intensity;
     539        2400 :             move16();
     540             : 
     541        9600 :             FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     542             :             {
     543             :                 /* only real part needed */
     544        7200 :                 Copy32( intensity_real_fx[i], &( hOMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); // intensity_q
     545             :             }
     546        2400 :             hOMasa->buffer_intensity_real_q[index - 1] = intensity_q;
     547        2400 :             move16();
     548        2400 :             Copy32( reference_power_fx[ts], &( hOMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands );
     549        2400 :             hOMasa->buffer_energy_q[index - 1] = reference_power_q;
     550        2400 :             move16();
     551             : 
     552        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 ); // diffuseness_q=Q30
     553             : 
     554       60000 :             FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     555             :             {
     556       57600 :                 norm_tmp_fx = L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], L_sub( ONE_IN_Q30, diffuseness_vector_fx[band_m_idx] ) ), 1 ); /*2*inp_q-30*/
     557       57600 :                 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], Mult_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), shl( c_e, 1 ), &hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] );
     558       57600 :                 move32();
     559       57600 :                 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], Mult_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), shl( c_e, 1 ), &hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] );
     560       57600 :                 move32();
     561       57600 :                 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], Mult_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), shl( c_e, 1 ), &hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] );
     562       57600 :                 move32();
     563             : 
     564       57600 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], L_shl( Mult_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), 1 ), sub( shl( c_e, 1 ), 1 ), &diffuseness_e[band_m_idx] );
     565       57600 :                 move32();
     566       57600 :                 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( shl( c_e, 1 ), 1 ), &renormalization_factor_diff_e[band_m_idx] );
     567       57600 :                 move32();
     568             :             }
     569             :         }
     570             : 
     571       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     572             :         {
     573       14400 :             Word16 max_e = MIN_16;
     574       14400 :             move16();
     575       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     576             :             {
     577       43200 :                 max_e = s_max( max_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] );
     578             :             }
     579       14400 :             max_e = add( max_e, 1 ); /*1 as guard bit to prevent overflow*/
     580       57600 :             FOR( d = 0; d < DIRAC_NUM_DIMS; d++ )
     581             :             {
     582       43200 :                 dir_v_fx[d] = L_shr( hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( max_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) );
     583       43200 :                 move32();
     584             :             }
     585       14400 :             dir_v_q = sub( 31, max_e );
     586             : 
     587       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] );
     588             :         }
     589             : 
     590             :         /* Determine energy ratios */
     591       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     592             :         {
     593             :             Word16 diffuseness_m_e;
     594       14400 :             IF( GT_32( renormalization_factor_diff_fx[band_m_idx], EPSILON_FX ) )
     595             :             {
     596       14396 :                 diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &diffuseness_m_e );
     597       14396 :                 move32();
     598       14396 :                 diffuseness_m_e = add( diffuseness_m_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) );
     599       14396 :                 diffuseness_m_fx[band_m_idx] = L_shl_sat( diffuseness_m_fx[band_m_idx], add( 16, diffuseness_m_e ) ); // Q31
     600       14396 :                 move32();
     601             :             }
     602             :             ELSE
     603             :             {
     604           4 :                 diffuseness_m_fx[band_m_idx] = 0;
     605           4 :                 move32();
     606             :             }
     607       14400 :             energyRatio_fx[block_m_idx][band_m_idx] = L_sub( ONE_IN_Q31, diffuseness_m_fx[band_m_idx] );
     608       14400 :             move32();
     609             :         }
     610             : 
     611             :         /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
     612       15000 :         FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
     613             :         {
     614       14400 :             spreadCoherence_fx[block_m_idx][band_m_idx] = 0;
     615       14400 :             move32();
     616       14400 :             surroundingCoherence_fx[block_m_idx][band_m_idx] = 0;
     617       14400 :             move32();
     618             :         }
     619             :     }
     620         150 :     *energyRatio_q = Q31;
     621         150 :     *spreadCoherence_q = Q31;
     622         150 :     *surroundingCoherence_q = Q31;
     623         150 :     move16();
     624         150 :     move16();
     625         150 :     move16();
     626         150 :     return;
     627             : }
     628             : 
     629             : 
     630             : /* Compute downmix */
     631         150 : static void ivas_omasa_dmx_fx(
     632             :     Word32 data_in_f_fx[][L_FRAME48k],
     633             :     Word16 *data_in_q,
     634             :     const Word16 input_frame,
     635             :     const Word16 nchan_transport,
     636             :     const Word16 nchan_ism,
     637             :     const Word32 ism_azimuth_fx[MAX_NUM_OBJECTS],
     638             :     const Word32 ism_elevation_fx[MAX_NUM_OBJECTS],
     639             :     Word32 prev_gains_fx[][MASA_MAX_TRANSPORT_CHANNELS],
     640             :     const Word16 interpolator_fx[L_FRAME48k] )
     641             : {
     642             :     Word16 i, j, k, l, tmp1, tmp2;
     643             : 
     644             :     Word16 azimuth_fx, elevation_fx;
     645             :     Word16 gains_fx[MASA_MAX_TRANSPORT_CHANNELS];
     646             :     Word16 g1_fx, g2_fx, scale;
     647             :     Word32 data_out_f_fx[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k], L_tmp;
     648             :     Word16 max_e, tmp_e;
     649             :     Word16 in_e[960];
     650             :     Word16 data_e[4];
     651             : 
     652         450 :     FOR( i = 0; i < nchan_transport; i++ )
     653             :     {
     654         300 :         set_zero_fx( data_out_f_fx[i], input_frame );
     655             :     }
     656         150 :     set16_fx( data_e, 0, 4 );
     657         150 :     set16_fx( in_e, 0, 960 );
     658             : 
     659         750 :     FOR( i = 0; i < nchan_ism; i++ )
     660             :     {
     661             : 
     662         600 :         azimuth_fx = extract_l( L_shr( ism_azimuth_fx[i], Q22 ) );     // Q0
     663         600 :         elevation_fx = extract_l( L_shr( ism_elevation_fx[i], Q22 ) ); // Q0
     664             : 
     665         600 :         ivas_ism_get_stereo_gains_fx( azimuth_fx, elevation_fx, &gains_fx[0], &gains_fx[1] );
     666             : 
     667             :         /* Downmix using the panning gains */
     668        1800 :         FOR( j = 0; j < nchan_transport; j++ )
     669             :         {
     670        1200 :             test();
     671        1200 :             IF( abs_s( gains_fx[j] ) > 0 || L_abs( prev_gains_fx[i][j] ) > 0 )
     672             :             {
     673     1060944 :                 FOR( k = 0; k < input_frame; k++ )
     674             :                 {
     675             : 
     676     1059840 :                     g1_fx = interpolator_fx[k]; // Q15
     677     1059840 :                     move16();
     678     1059840 :                     scale = BASOP_Util_Add_MantExp( 16384, 1, negate( g1_fx ), 0, &g2_fx );
     679             : 
     680     1059840 :                     tmp1 = mult( g1_fx, gains_fx[j] );
     681     1059840 :                     tmp2 = mult( g2_fx, (Word16) L_shr( prev_gains_fx[i][j], 16 ) ); // Q: ( ( ( 15 - scale ) + ( Q31 - Q16 ) ) - Q15 ) -> ( 15 - scale )
     682     1059840 :                     scale = BASOP_Util_Add_MantExp( tmp1, 0, tmp2, scale, &tmp1 );
     683             : 
     684     1059840 :                     L_tmp = data_in_f_fx[i][k]; // data_in_q
     685     1059840 :                     move32();
     686     1059840 :                     tmp_e = sub( 31, *data_in_q );
     687     1059840 :                     move16();
     688             : 
     689     1059840 :                     L_tmp = Mpy_32_16_1( L_tmp, tmp1 );
     690     1059840 :                     scale = add( scale, tmp_e );
     691             : 
     692     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] );
     693     1059840 :                     move32();
     694             :                 }
     695        1104 :                 max_e = in_e[0];
     696        1104 :                 move16();
     697     1059840 :                 FOR( l = 1; l < L_FRAME48k; l++ )
     698             :                 {
     699     1058736 :                     IF( LT_16( max_e, in_e[l] ) )
     700             :                     {
     701        2363 :                         max_e = in_e[l];
     702        2363 :                         move16();
     703             :                     }
     704             :                 }
     705             : 
     706     1060944 :                 FOR( l = 0; l < L_FRAME48k; l++ )
     707             :                 {
     708     1059840 :                     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 )
     709     1059840 :                     move32();
     710             :                 }
     711        1104 :                 data_e[j] = max_e;
     712        1104 :                 move16();
     713             :             }
     714             : 
     715        1200 :             prev_gains_fx[i][j] = L_deposit_h( gains_fx[j] ); // Q31
     716        1200 :             move32();
     717             :         }
     718             :     }
     719             : 
     720         150 :     max_e = data_e[0];
     721         150 :     move16();
     722         300 :     FOR( i = 1; i < nchan_transport; i++ )
     723             :     {
     724         150 :         if ( LT_16( max_e, data_e[i] ) )
     725             :         {
     726          50 :             max_e = data_e[i];
     727          50 :             move16();
     728             :         }
     729             :     }
     730             : 
     731         450 :     FOR( i = 0; i < nchan_transport; i++ )
     732             :     {
     733      288300 :         FOR( j = 0; j < input_frame; j++ )
     734             :         {
     735      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 )
     736      288000 :             move32();
     737             :         }
     738             :     }
     739             : 
     740         450 :     FOR( i = 0; i < nchan_transport; i++ )
     741             :     {
     742         300 :         Copy32( data_out_f_fx[i], data_in_f_fx[i], input_frame );
     743         300 :         *data_in_q = sub( 31, max_e );
     744         300 :         move16();
     745             :     }
     746             : 
     747         150 :     return;
     748             : }
     749             : 
     750             : /* Compute downmix */
     751             : 
     752             : 
     753             : /*--------------------------------------------------------------------------*
     754             :  * computeIntensityVector_ana()
     755             :  *
     756             :  *
     757             :  *--------------------------------------------------------------------------*/
     758             : 
     759        9600 : void computeIntensityVector_ana_fx(
     760             :     const Word16 *band_grouping,                                  /* i  : Band grouping for estimation   */
     761             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal   Qx */
     762             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input sig      Qx */
     763             :     const Word16 num_frequency_bands,                             /* i  : Number of frequency bands      */
     764             :     Word32 intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]   /* o  : Intensity           2 * Qx -31 */
     765             : )
     766             : {
     767             :     /* Reminder
     768             :      * X = a + ib; Y = c + id
     769             :      * X*Y = ac - bd + i(ad +bc)
     770             :      */
     771             :     Word16 i, j;
     772             :     Word32 real, img;
     773             :     Word16 brange[2];
     774             : 
     775      240000 :     FOR( i = 0; i < num_frequency_bands; i++ )
     776             :     {
     777      230400 :         brange[0] = band_grouping[i];
     778      230400 :         move16();
     779      230400 :         brange[1] = band_grouping[i + 1];
     780      230400 :         move16();
     781             : 
     782      230400 :         intensity_real[0][i] = 0;
     783      230400 :         move32();
     784      230400 :         intensity_real[1][i] = 0;
     785      230400 :         move32();
     786      230400 :         intensity_real[2][i] = 0;
     787      230400 :         move32();
     788             : 
     789      806400 :         FOR( j = brange[0]; j < brange[1]; j++ )
     790             :         {
     791      576000 :             real = Cldfb_RealBuffer[0][j]; // Qx
     792      576000 :             img = Cldfb_ImagBuffer[0][j];  // Qx
     793             :             /* Intensity is XYZ order, audio is WYZX order. */
     794      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
     795      576000 :             move32();
     796      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
     797      576000 :             move32();
     798      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
     799      576000 :             move32();
     800             :         }
     801             :     }
     802             : 
     803        9600 :     return;
     804             : }
     805             : /*--------------------------------------------------------------------------*
     806             :  * computeIntensityVector_ana()
     807             :  *
     808             :  *
     809             :  *--------------------------------------------------------------------------*/
     810             : 
     811             : 
     812             : /*--------------------------------------------------------------------------*
     813             :  * computeReferencePower_ana()
     814             :  *
     815             :  *
     816             :  *--------------------------------------------------------------------------*/
     817             : 
     818        7200 : void computeReferencePower_ana_fx(
     819             :     const Word16 *band_grouping,                                  /* i  : Band grouping for estimation                  */
     820             :     Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Real part of input signal    input_q          */
     821             :     Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i  : Imag part of input signal    input_q          */
     822             :     Word32 *reference_power,                                      /* o  : Estimated power              2 * inputq - 31  */
     823             :     const Word16 num_freq_bands                                   /* i  : Number of frequency bands                     */
     824             : )
     825             : {
     826             :     Word16 brange[2];
     827             :     Word16 ch_idx, i, j;
     828             : 
     829      180000 :     FOR( i = 0; i < num_freq_bands; i++ )
     830             :     {
     831      172800 :         brange[0] = band_grouping[i];
     832      172800 :         move16();
     833      172800 :         brange[1] = band_grouping[i + 1];
     834      172800 :         move16();
     835      172800 :         reference_power[i] = 0;
     836      172800 :         move32();
     837             : 
     838      864000 :         FOR( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
     839             :         {
     840             :             /* abs()^2 */
     841     2419200 :             FOR( j = brange[0]; j < brange[1]; j++ )
     842             :             {
     843             :                 // Q = 2*inputq - 31
     844     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] );
     845     1728000 :                 move32();
     846             :             }
     847             :         }
     848             :     }
     849             : 
     850             :     // v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
     851             : 
     852             :     /* Bypassing the v_multc ,so output q = 2*inputq - 30*/
     853        7200 :     return;
     854             : }
     855             : 
     856             : /*--------------------------------------------------------------------------*
     857             :  * computeReferencePower_ana()
     858             :  *
     859             :  *
     860             :  *--------------------------------------------------------------------------*/

Generated by: LCOV version 1.14