LCOV - code coverage report
Current view: top level - lib_rend - ivas_dirac_output_synthesis_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 2136 2244 95.2 %
Date: 2025-05-03 01:55:50 Functions: 20 20 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 <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "cnst.h"
      38             : #include "prot_fx.h"
      39             : #include "ivas_prot_rend_fx.h"
      40             : #include "ivas_stat_dec.h"
      41             : #include "ivas_cnst.h"
      42             : #include "ivas_rom_com.h"
      43             : #include "ivas_rom_dec.h"
      44             : #include "wmc_auto.h"
      45             : #include "ivas_prot_fx.h"
      46             : #include "ivas_rom_com_fx.h"
      47             : 
      48             : /*-------------------------------------------------------------------------
      49             :  * Local constants
      50             :  *------------------------------------------------------------------------*/
      51             : 
      52             : #define DIRAC_AVG_LENGTH_SYNTH_MS      20   /*averaging length in ms for DirAC synthesis*/
      53             : #define DIRAC_ALPHA_MAX_Q15            3276 /*0.1f q15*/
      54             : #define DIRAC_AVG_LENGTH_SYNTH_MS_FAST 10
      55             : #define DIRAC_ALPHA_MAX_FAST_Q15       3932         /*0.12f q15*/
      56             : #define DIRECTION_SMOOTHNESS_ALPHA_Q31 ( 21474836 ) /*0.01f q31*/
      57             : 
      58             : #define POINT_3679_Q31 790059234 /*.3679 q31*/
      59             : #define POINT_1175_Q31 252329329 /*.1175 q31*/
      60             : 
      61             : /*-------------------------------------------------------------------------
      62             :  * Local function prototypes
      63             :  *------------------------------------------------------------------------*/
      64             : 
      65             : static void computeTargetPSDs_direct_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word32 *direct_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *direct_responses, const Word32 *direct_responses_square, Word32 *cy_auto_dir_smooth, Word16 *q_cy_auto_dir_smooth, Word32 *cy_cross_dir_smooth, Word16 *q_cy_cross_dir_smooth );
      66             : 
      67             : static void computeTargetPSDs_direct_subframe_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word32 *direct_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *direct_responses, const Word32 *direct_responses_square, Word32 *cy_auto_dir_smooth, Word16 *q_cy_auto_dir_smooth, Word32 *cy_cross_dir_smooth, Word16 *q_cy_cross_dir_smooth );
      68             : 
      69             : static void computeTargetPSDs_diffuse_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word16 start_band, const Word32 *diffuse_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *diffuse_responses_square, Word32 *cy_auto_diff_smooth, Word16 *q_cy_auto_diff_smooth );
      70             : 
      71             : static void computeTargetPSDs_diffuse_subframe_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word16 start_band, const Word32 *diffuse_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *diffuse_responses_square, Word32 *cy_auto_diff_smooth, Word16 *q_cy_auto_diff_smooth );
      72             : 
      73             : static void computeTargetPSDs_diffuse_with_onsets_fx( const Word16 num_channels, const Word16 num_freq_bands, const Word16 num_decorr_freq_bands, const Word16 *proto_frame_diff_index, const Word32 *diffuse_power_factor, const Word32 *reference_power, const Word16 *q_reference_power, const Word32 *diffuse_responses_square, const Word32 *onset_filter, Word32 *cy_auto_diff_smooth, Word16 *q_cy_auto_diff_smooth );
      74             : 
      75             : static void computeAlphaSynthesis_fx( Word16 *alpha_synthesis_fx /*q15*/, const Word16 averaging_length_ms, const Word16 maxAlpha_fx /*q15*/, Word16 *numAlphas, const Word16 slot_size, const Word16 num_freq_bands, Word16 *frequency_axis_fx /*q0*/, const Word32 output_Fs );
      76             : 
      77             : static void spreadCoherencePanningHoa_fx( const Word16 azimuth, const Word16 elevation, const Word16 spreadCoh_fx, Word32 *direct_response_fx, Word16 *Q_direct_response_hoa, const Word16 num_channels_dir, const Word16 ambisonics_order );
      78             : 
      79             : static void spreadCoherencePanningVbap_fx( const Word16 azimuth, const Word16 elevation, const Word16 spreadCoh_fx, Word32 *direct_response_fx, Word16 *Q_direct_response, const Word16 num_channels_dir, const VBAP_HANDLE hVBAPdata );
      80             : 
      81             : static void normalizePanningGains_fx( Word32 *direct_response_fx, Word16 *q_direct_res, const Word16 num_channels_dir );
      82             : 
      83             : 
      84             : /*-------------------------------------------------------------------------
      85             :  * ivas_dirac_dec_output_synthesis_open()
      86             :  *
      87             :  *
      88             :  *------------------------------------------------------------------------*/
      89             : 
      90        2153 : ivas_error ivas_dirac_dec_output_synthesis_open_fx(
      91             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle   */
      92             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                 */
      93             :     RENDERER_TYPE renderer_type,                          /* i  : renderer type                         */
      94             :     const Word16 nchan_transport,                         /* i  : number of transport channels          */
      95             :     const Word32 output_Fs,                               /* i  : output sampling rate                  */
      96             :     const Word16 hodirac_flag                             /* i  : flag to indicate HO-DirAC mode        */
      97             : )
      98             : {
      99             :     Word16 idx, ch_idx;
     100             :     Word16 size;
     101             :     UWord16 num_diffuse_responses;
     102             :     Word16 tmp_fx, tmp16;
     103             :     Word16 temp_alpha_synthesis_fx[CLDFB_NO_CHANNELS_MAX];
     104        2153 :     Word16 interpolator_tbl[JBM_CLDFB_SLOTS_IN_SUBFRAME] = { 8192, 16384, 24576, MAX16B }; /* idx / JBM_CLDFB_SLOTS_IN_SUBFRAME Q15 */
     105        2153 :     move16();
     106        2153 :     move16();
     107        2153 :     move16();
     108        2153 :     move16();
     109             : 
     110             :     /* pointers to structs for allocation */
     111        2153 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     112        2153 :     DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     113             : 
     114             :     /* check / set input parameters */
     115        2153 :     assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
     116        2153 :     assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
     117        2153 :     assert( hDirACRend->num_outputs_diff > 0 );
     118        2153 :     assert( hSpatParamRendCom->slot_size > 0 );
     119        2153 :     assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
     120        2153 :     assert( hDirACRend->diffuse_response_function_fx != NULL );
     121             : 
     122        2153 :     IF( hDirACRend->proto_signal_decorr_on )
     123             :     {
     124        1995 :         dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
     125        1995 :         move16();
     126             :     }
     127             :     ELSE
     128             :     {
     129         158 :         dirac_output_synthesis_params->max_band_decorr = 0;
     130         158 :         move16();
     131             :     }
     132             : 
     133             :     /*-----------------------------------------------------------------*
     134             :      * memory allocation
     135             :      *-----------------------------------------------------------------*/
     136             : 
     137        2153 :     dirac_output_synthesis_state->diffuse_responses_square_fx = NULL;
     138             : 
     139        2153 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
     140             :     {
     141         111 :         IF( ( dirac_output_synthesis_state->diffuse_responses_square_fx = (Word32 *) malloc( 2 * sizeof( Word32 ) ) ) == NULL )
     142             :         {
     143           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     144             :         }
     145             :     }
     146        2042 :     ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     147             :     {
     148        1247 :         IF( ( dirac_output_synthesis_state->diffuse_responses_square_fx = (Word32 *) malloc( hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( Word32 ) ) ) == NULL )
     149             :         {
     150           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     151             :         }
     152             :     }
     153             : 
     154             :     /* prototype power buffers */
     155        2153 :     dirac_output_synthesis_state->proto_power_smooth_prev_fx = NULL;
     156             : 
     157        2153 :     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     158             :     {
     159        1358 :         IF( ( dirac_output_synthesis_state->proto_power_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir * sizeof( Word32 ) ) ) == NULL )
     160             :         {
     161           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     162             :         }
     163        1358 :         dirac_output_synthesis_state->proto_power_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir );
     164        1358 :         move16();
     165             :     }
     166        2153 :     test();
     167        2153 :     test();
     168        2153 :     IF( dirac_output_synthesis_params->max_band_decorr > 0 && ( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_LS ) || EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) ) )
     169             :     {
     170        1200 :         IF( ( dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx = (Word32 *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( Word32 ) ) ) == NULL )
     171             :         {
     172           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     173             :         }
     174        1200 :         dirac_output_synthesis_state->proto_power_diff_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE );
     175        1200 :         move16();
     176             :     }
     177             :     ELSE
     178             :     {
     179         953 :         dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx = NULL;
     180             :     }
     181             : 
     182             :     /* buffer length and interpolator */
     183        2153 :     IF( ( dirac_output_synthesis_params->interpolator_fx = (Word16 *) malloc( JBM_CLDFB_SLOTS_IN_SUBFRAME * sizeof( Word16 ) ) ) == NULL )
     184             :     {
     185           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     186             :     }
     187             : 
     188             :     /* target PSD buffers */
     189        2153 :     IF( hodirac_flag )
     190             :     {
     191         112 :         size = imult1616( imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), DIRAC_HO_NUMSECTORS );
     192             :     }
     193             :     ELSE
     194             :     {
     195        2041 :         size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     196             :     }
     197        2153 :     IF( ( dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx = (Word32 *) malloc( size * sizeof( Word32 ) ) ) == NULL )
     198             :     {
     199           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     200             :     }
     201        2153 :     dirac_output_synthesis_state->cy_cross_dir_smooth_prev_len = size;
     202        2153 :     move16();
     203        2153 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     204             :     {
     205         795 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx = NULL;
     206         795 :         IF( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx = (Word32 *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
     207             :         {
     208           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     209             :         }
     210         795 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
     211         795 :         move16();
     212             :     }
     213             :     ELSE
     214             :     {
     215        1358 :         IF( ( dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
     216             :         {
     217           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     218             :         }
     219        1358 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     220        1358 :         move16();
     221             : 
     222        1358 :         IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
     223             :         {
     224         412 :             IF( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
     225             :             {
     226           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     227             :             }
     228         412 :             dirac_output_synthesis_state->cy_auto_diff_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     229         412 :             move16();
     230             :         }
     231             :         ELSE
     232             :         {
     233         946 :             IF( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
     234             :             {
     235           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     236             :             }
     237         946 :             dirac_output_synthesis_state->cy_auto_diff_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
     238         946 :             move16();
     239             :         }
     240             :     }
     241             : 
     242             :     /* direct and diffuse gain buffers */
     243        2153 :     IF( ( dirac_output_synthesis_state->gains_dir_prev_fx = (Word32 *) malloc( size * sizeof( Word32 ) ) ) == NULL )
     244             :     {
     245           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     246             :     }
     247        2153 :     dirac_output_synthesis_state->gains_dir_prev_len = size;
     248        2153 :     move16();
     249        2153 :     test();
     250        2153 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     251             :     {
     252         795 :         IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
     253             :         {
     254           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     255             :         }
     256         795 :         dirac_output_synthesis_state->gains_diff_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
     257         795 :         move16();
     258             :     }
     259        1358 :     ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) && NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
     260             :     {
     261         835 :         IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
     262             :         {
     263           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     264             :         }
     265         835 :         dirac_output_synthesis_state->gains_diff_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
     266         835 :         move16();
     267             :     }
     268             :     ELSE
     269             :     {
     270         523 :         IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
     271             :         {
     272           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     273             :         }
     274         523 :         dirac_output_synthesis_state->gains_diff_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     275         523 :         move16();
     276             :     }
     277             : 
     278             :     /*-----------------------------------------------------------------*
     279             :      * prepare processing parameters
     280             :      *-----------------------------------------------------------------*/
     281             : 
     282             :     /* compute alpha */
     283        2153 :     test();
     284        2153 :     test();
     285        2153 :     IF( !( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) )
     286             :     {
     287        1358 :         computeAlphaSynthesis_fx( temp_alpha_synthesis_fx, DIRAC_AVG_LENGTH_SYNTH_MS, DIRAC_ALPHA_MAX_Q15, &dirac_output_synthesis_params->numAlphas, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis_fx, output_Fs );
     288             : 
     289        1358 :         IF( ( dirac_output_synthesis_params->alpha_synthesis_fx = (Word16 *) malloc( dirac_output_synthesis_params->numAlphas * sizeof( Word16 ) ) ) == NULL )
     290             :         {
     291           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     292             :         }
     293        1358 :         Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fx, dirac_output_synthesis_params->numAlphas ); /*q15*/
     294             : 
     295        1358 :         computeAlphaSynthesis_fx( temp_alpha_synthesis_fx, DIRAC_AVG_LENGTH_SYNTH_MS_FAST, DIRAC_ALPHA_MAX_FAST_Q15, &dirac_output_synthesis_params->numAlphasFast, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis_fx, output_Fs );
     296             : 
     297        1358 :         IF( ( dirac_output_synthesis_params->alpha_synthesis_fast_fx = (Word16 *) malloc( dirac_output_synthesis_params->numAlphasFast * sizeof( Word16 ) ) ) == NULL )
     298             :         {
     299           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     300             :         }
     301        1358 :         Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fast_fx, dirac_output_synthesis_params->numAlphasFast ); /*q15*/
     302             : 
     303        1358 :         IF( ( dirac_output_synthesis_state->reference_power_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     304             :         {
     305           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     306             :         }
     307        1358 :         set32_fx( dirac_output_synthesis_state->reference_power_smooth_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
     308             : #ifdef FIX_867_CLDFB_NRG_SCALE
     309        1358 :         dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = Q31;
     310        1358 :         dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = Q31;
     311        1358 :         move16();
     312        1358 :         move16();
     313             : #else
     314             :         dirac_output_synthesis_state->reference_power_smooth_prev_q = Q31;
     315             :         move16();
     316             : #endif
     317             : 
     318        1358 :         IF( ( dirac_output_synthesis_state->direction_smoothness_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     319             :         {
     320           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     321             :         }
     322        1358 :         set32_fx( dirac_output_synthesis_state->direction_smoothness_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
     323             :     }
     324             :     ELSE
     325             :     {
     326         795 :         dirac_output_synthesis_params->alpha_synthesis_fx = NULL;
     327         795 :         dirac_output_synthesis_params->alpha_synthesis_fast_fx = NULL;
     328         795 :         dirac_output_synthesis_state->reference_power_smooth_prev_fx = NULL;
     329         795 :         dirac_output_synthesis_state->direction_smoothness_prev_fx = NULL;
     330             :     }
     331             : 
     332             :     /* compute interpolator */
     333       10765 :     FOR( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
     334             :     {
     335        8612 :         dirac_output_synthesis_params->interpolator_fx[idx - 1] = interpolator_tbl[idx - 1]; /* Q15 */
     336        8612 :         move16();
     337             :     }
     338             : 
     339             :     /* prepare diffuse response function */
     340        2153 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
     341             :     {
     342         111 :         num_diffuse_responses = 2;
     343         111 :         move16();
     344             :     }
     345             :     ELSE
     346             :     {
     347        2042 :         num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
     348        2042 :         move16();
     349             :     }
     350             : 
     351        2153 :     IF( dirac_output_synthesis_state->diffuse_responses_square_fx != NULL )
     352             :     {
     353       12406 :         FOR( ch_idx = 0; ch_idx < num_diffuse_responses; ++ch_idx )
     354             :         {
     355             :             /*dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = pow(dirac_output_synthesis_params->diffuse_response_function[ch_idx]/max_response, 2.0f);*/
     356       11048 :             tmp_fx = hDirACRend->diffuse_response_function_fx[ch_idx]; /*q15*/
     357       11048 :             move16();
     358             : 
     359       11048 :             dirac_output_synthesis_state->diffuse_responses_square_fx[ch_idx] = L_mult( tmp_fx, tmp_fx ); /* Q15 + Q15 + 1 -> Q31 */
     360       11048 :             move32();
     361             :         }
     362             :     }
     363             : 
     364             : 
     365        2153 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     366             :     {
     367             :         Word16 diff_compensation_order;
     368             :         Word32 diff_nrg_total_fx, diff_nrg_fx, diff_nrg_trans_fx, diff_nrg_decorr_fx;
     369             : 
     370             :         /* compensate missing diffuseness modelling up order 2, except for HR*/
     371         795 :         IF( GE_16( nchan_transport, 3 ) )
     372             :         {
     373         786 :             diff_compensation_order = 3;
     374         786 :             move16();
     375             :         }
     376             :         ELSE
     377             :         {
     378           9 :             diff_compensation_order = 2;
     379           9 :             move16();
     380             :         }
     381         795 :         diff_compensation_order = s_min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
     382             : 
     383         795 :         diff_nrg_total_fx = 0;
     384         795 :         move32();
     385         795 :         diff_nrg_trans_fx = 0;
     386         795 :         move32();
     387         795 :         diff_nrg_decorr_fx = 0;
     388         795 :         move32();
     389             : 
     390         795 :         Word16 gaurd_bits = find_guarded_bits_fx( imult1616( add( diff_compensation_order, 1 ), add( diff_compensation_order, 1 ) ) );
     391         795 :         tmp16 = add( diff_compensation_order, 1 );
     392         795 :         tmp16 = imult1616( tmp16, tmp16 );
     393       13404 :         FOR( ch_idx = 0; ch_idx < tmp16; ch_idx++ )
     394             :         {
     395       12609 :             diff_nrg_fx = L_shr( L_mult0( hDirACRend->diffuse_response_function_fx[ch_idx], hDirACRend->diffuse_response_function_fx[ch_idx] ), gaurd_bits ); // Q30 - gaurd_bits
     396             : 
     397       12609 :             diff_nrg_total_fx = L_add( diff_nrg_total_fx, diff_nrg_fx ); // Q30 - gaurd_bits
     398             : 
     399             :             /* is it a transport channel?*/
     400       12609 :             test();
     401       12609 :             if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
     402             :             {
     403        3882 :                 diff_nrg_trans_fx = L_add( diff_nrg_trans_fx, diff_nrg_fx ); // Q30 - gaurd_bits
     404             :             }
     405             :             /* is it a decorrelated or transport channel?*/
     406       12609 :             if ( LT_16( ch_idx, hDirACRend->num_outputs_diff ) )
     407             :             {
     408        3180 :                 diff_nrg_decorr_fx = L_add( diff_nrg_decorr_fx, diff_nrg_fx ); // Q30 - gaurd_bits
     409             :             }
     410             :         }
     411         795 :         Word16 exp_1 = 0, exp_2 = 0, tmp;
     412         795 :         move16();
     413         795 :         move16();
     414         795 :         tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_trans_fx, &exp_1 );                              // Q(15 - exp_1)
     415         795 :         dirac_output_synthesis_params->diffuse_compensation_factor_fx = L_shl( L_deposit_l( tmp ), add( Q12, exp_1 ) ); // Q27
     416         795 :         move32();
     417             : 
     418         795 :         tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_decorr_fx, &exp_2 );                                    // (Q15 - exp_2)
     419         795 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = L_shl( L_deposit_l( tmp ), add( Q14, exp_2 ) ); // Q29
     420         795 :         move32();
     421             :     }
     422             :     ELSE
     423             :     {
     424        1358 :         dirac_output_synthesis_params->diffuse_compensation_factor_fx = 0;
     425        1358 :         move32();
     426        1358 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = 0;
     427        1358 :         move32();
     428             :     }
     429             : 
     430        2153 :     return IVAS_ERR_OK;
     431             : }
     432             : 
     433             : 
     434             : /*-------------------------------------------------------------------------
     435             :  * ivas_dirac_dec_output_synthesis_init()
     436             :  *
     437             :  *
     438             :  *------------------------------------------------------------------------*/
     439             : 
     440        2171 : void ivas_dirac_dec_output_synthesis_init_fx(
     441             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle         */
     442             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                       */
     443             :     const Word16 nchan_out_woLFE,                         /* i  : number of output audio channels without LFE */
     444             :     const Word16 hodirac_flag                             /* i  : flag to indicate HO-DirAC mode              */
     445             : )
     446             : {
     447             :     Word16 size;
     448             : 
     449             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
     450             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
     451             : 
     452        2171 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     453        2171 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     454             : 
     455             :     /*-----------------------------------------------------------------*
     456             :      * init outputSynthesisPSD_Init
     457             :      *-----------------------------------------------------------------*/
     458             : 
     459             :     /* initialize buffers */
     460        2171 :     IF( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx != NULL )
     461             :     {
     462        1358 :         set32_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
     463             :     }
     464        2171 :     h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev = 0;
     465        2171 :     move16();
     466             : 
     467        2171 :     IF( hodirac_flag )
     468             :     {
     469         112 :         size = imult1616( imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), DIRAC_HO_NUMSECTORS );
     470             :     }
     471             :     ELSE
     472             :     {
     473        2059 :         size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     474             :     }
     475        2171 :     set32_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx, 0, size );
     476        2171 :     h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = 0;
     477        2171 :     move16();
     478             : 
     479        2171 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     480             :     {
     481         813 :         set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( h_dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff ) );
     482             :     }
     483        1358 :     ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
     484             :     {
     485         946 :         set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) );
     486             :     }
     487             :     ELSE
     488             :     {
     489         412 :         set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
     490             :     }
     491        2171 :     h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = 0;
     492        2171 :     move16();
     493             : 
     494        2171 :     IF( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx != NULL )
     495             :     {
     496        1358 :         set32_fx( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ) );
     497             : #ifdef FIX_867_CLDFB_NRG_SCALE
     498        1358 :         h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = Q31;
     499        1358 :         h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = Q31;
     500        1358 :         move16();
     501        1358 :         move16();
     502             : #else
     503             :         h_dirac_output_synthesis_state->proto_power_smooth_prev_q = Q31;
     504             :         move16();
     505             : #endif
     506             :     }
     507        2171 :     set32_fx( h_dirac_output_synthesis_state->gains_dir_prev_fx, 0, size );
     508        2171 :     h_dirac_output_synthesis_state->gains_dir_prev_q = 0;
     509        2171 :     move16();
     510             : 
     511        2171 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     512             :     {
     513         813 :         set32_fx( h_dirac_output_synthesis_state->gains_diff_prev_fx, 0, imult1616( h_dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff ) );
     514             :     }
     515             :     ELSE
     516             :     {
     517        1358 :         set32_fx( h_dirac_output_synthesis_state->gains_diff_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
     518             :     }
     519        2171 :     h_dirac_output_synthesis_state->gains_diff_prev_q = 0;
     520        2171 :     move16();
     521             : 
     522        2171 :     IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx != NULL )
     523             :     {
     524        1200 :         set32_fx( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx, 0, imult1616( h_dirac_output_synthesis_params->max_band_decorr, nchan_out_woLFE ) );
     525             :     }
     526        2171 :     h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_q = Q31;
     527        2171 :     move16();
     528             : 
     529        2171 :     return;
     530             : }
     531             : 
     532             : 
     533             : /*-------------------------------------------------------------------------
     534             :  * ivas_dirac_dec_output_synthesis_close()
     535             :  *
     536             :  * Memory deallocation of Output synthesis sub-module
     537             :  *------------------------------------------------------------------------*/
     538             : 
     539        2153 : void ivas_dirac_dec_output_synthesis_close_fx(
     540             :     DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle                    */
     541             : )
     542             : {
     543             :     /* pointers to structs for allocation */
     544        2153 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     545        2153 :     DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     546             : 
     547             :     /*-----------------------------------------------------------------*
     548             :      * memory deallocation
     549             :      *-----------------------------------------------------------------*/
     550             : 
     551             :     /* free interpolator */
     552        2153 :     IF( ( dirac_output_synthesis_params )->interpolator_fx != NULL )
     553             :     {
     554        2153 :         free( ( dirac_output_synthesis_params )->interpolator_fx );
     555        2153 :         ( dirac_output_synthesis_params )->interpolator_fx = NULL;
     556             :     }
     557             : 
     558             :     /* free alpha */
     559        2153 :     IF( ( dirac_output_synthesis_params )->alpha_synthesis_fx != NULL )
     560             :     {
     561        1358 :         free( ( dirac_output_synthesis_params )->alpha_synthesis_fx );
     562        1358 :         ( dirac_output_synthesis_params )->alpha_synthesis_fx = NULL;
     563             :     }
     564        2153 :     IF( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx != NULL )
     565             :     {
     566        1358 :         free( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx );
     567        1358 :         ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx = NULL;
     568             :     }
     569             : 
     570        2153 :     IF( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx != NULL )
     571             :     {
     572        1358 :         free( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx );
     573        1358 :         ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx = NULL;
     574             :     }
     575             : 
     576        2153 :     IF( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx != NULL )
     577             :     {
     578        1358 :         free( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx );
     579        1358 :         ( dirac_output_synthesis_state )->direction_smoothness_prev_fx = NULL;
     580             :     }
     581             : 
     582        2153 :     IF( ( dirac_output_synthesis_state )->diffuse_responses_square_fx != NULL )
     583             :     {
     584        1358 :         free( ( dirac_output_synthesis_state )->diffuse_responses_square_fx );
     585        1358 :         ( dirac_output_synthesis_state )->diffuse_responses_square_fx = NULL;
     586             :     }
     587             : 
     588             :     /* free power buffers */
     589        2153 :     IF( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx != NULL )
     590             :     {
     591        1358 :         free( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx );
     592        1358 :         ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx = NULL;
     593             :     }
     594             : 
     595        2153 :     IF( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx != NULL )
     596             :     {
     597        1200 :         free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx );
     598        1200 :         ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx = NULL;
     599             :     }
     600             : 
     601             :     /* free target power buffers */
     602        2153 :     IF( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx != NULL )
     603             :     {
     604        1358 :         free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx );
     605        1358 :         ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx = NULL;
     606             :     }
     607        2153 :     IF( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx != NULL )
     608             :     {
     609        2153 :         free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx );
     610        2153 :         ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx = NULL;
     611             :     }
     612        2153 :     IF( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx != NULL )
     613             :     {
     614        2153 :         free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx );
     615        2153 :         ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx = NULL;
     616             :     }
     617             : 
     618             :     /* free gain buffers */
     619        2153 :     IF( ( dirac_output_synthesis_state )->gains_dir_prev_fx != NULL )
     620             :     {
     621        2153 :         free( ( dirac_output_synthesis_state )->gains_dir_prev_fx );
     622        2153 :         ( dirac_output_synthesis_state )->gains_dir_prev_fx = NULL;
     623             :     }
     624        2153 :     IF( ( dirac_output_synthesis_state )->gains_diff_prev_fx != NULL )
     625             :     {
     626        2153 :         free( ( dirac_output_synthesis_state )->gains_diff_prev_fx );
     627        2153 :         ( dirac_output_synthesis_state )->gains_diff_prev_fx = NULL;
     628             :     }
     629        2153 :     return;
     630             : }
     631             : 
     632             : 
     633             : /*-------------------------------------------------------------------------
     634             :  * ivas_dirac_dec_output_synthesis_process_slot()
     635             :  *
     636             :  *
     637             :  *------------------------------------------------------------------------*/
     638             : 
     639     1265265 : void ivas_dirac_dec_output_synthesis_process_slot_fx(
     640             :     const Word32 *reference_power, /* i  : Estimated power             Q(q_reference_power)*/
     641             : #ifdef FIX_867_CLDFB_NRG_SCALE
     642             :     const Word16 *q_reference_power, /* i  : Estimated power Q            */
     643             : #else
     644             :     const Word16 q_reference_power, /* i  : Estimated power Q            */
     645             : #endif
     646             :     const Word32 *onset, /* i  : onset filter                Q31*/
     647             :     const Word16 *azimuth,
     648             :     const Word16 *elevation,
     649             :     const Word32 *diffuseness, /* Q(q_diffuseness)*/
     650             :     Word16 q_diffuseness,
     651             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle         */
     652             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                       */
     653             :     const Word16 sh_rot_max_order,
     654             :     const Word32 *p_Rmat,              /* i  : rotation matrix             Q30*/
     655             :     const VBAP_HANDLE hVBAPdata,       /* i  : VBAP structure              */
     656             :     const IVAS_OUTPUT_SETUP hOutSetup, /* i  : output setup structure      */
     657             :     const Word16 nchan_transport,      /* i  : number of transport channels*/
     658             :     const Word16 md_idx,
     659             :     const Word16 hodirac_flag, /* i  : flag to indicate HO-DirAC mode   */
     660             :     const Word16 dec_param_estim )
     661             : {
     662             :     Word16 num_freq_bands, num_channels_dir;
     663             :     Word16 num_freq_bands_diff, num_channels_diff;
     664             :     Word16 ch_idx;
     665             :     Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
     666             :     Word16 diff_start_band, tmp16;
     667             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
     668             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
     669             : 
     670     1265265 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     671     1265265 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     672             : 
     673     1265265 :     h_dirac_output_synthesis_state->onset_filter_fx = onset; /*Q31*/
     674             : 
     675             :     /*-----------------------------------------------------------------*
     676             :      * processing
     677             :      *-----------------------------------------------------------------*/
     678             : 
     679             :     /* collect some often used parameters */
     680     1265265 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
     681     1265265 :     move16();
     682     1265265 :     num_channels_dir = hDirACRend->num_outputs_dir;
     683     1265265 :     move16();
     684     1265265 :     num_channels_diff = hDirACRend->num_outputs_diff;
     685     1265265 :     move16();
     686     1265265 :     num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
     687     1265265 :     move16();
     688             : 
     689     1265265 :     IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_LS ) )
     690             :     {
     691      281936 :         num_channels_dir = hOutSetup.nchan_out_woLFE;
     692      281936 :         move16();
     693             :     }
     694             : 
     695     1265265 :     test();
     696     1265265 :     IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) && hodirac_flag )
     697             :     {
     698      212624 :         ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
     699             :                                                          hDirACRend,
     700             :                                                          hVBAPdata,
     701             :                                                          NULL,
     702             :                                                          NULL,
     703             :                                                          azimuth,
     704             :                                                          elevation,
     705             :                                                          md_idx,
     706             :                                                          NULL,
     707             :                                                          0,
     708             :                                                          2,
     709             :                                                          p_Rmat,
     710             :                                                          hodirac_flag );
     711             :         {
     712             : 
     713      212624 :             IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
     714             :             {
     715           0 :                 Scale_sig32( h_dirac_output_synthesis_state->direct_responses_square_fx, imult1616( num_channels_dir, num_freq_bands ), sub( 31, h_dirac_output_synthesis_state->direct_responses_square_q ) ); /* h_dirac_output_synthesis_state->direct_responses_square_q->Q31*/
     716           0 :                 h_dirac_output_synthesis_state->direct_responses_square_q = 31;
     717           0 :                 move16();
     718             :             }
     719      212624 :             Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_fx, i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
     720      212624 :             IF( hodirac_flag )
     721             :             {
     722      212624 :                 Scale_sig32( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir], i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
     723             :             }
     724      212624 :             h_dirac_output_synthesis_state->direct_responses_q = 31;
     725      212624 :             move16();
     726             :         }
     727             :     }
     728             : 
     729     1265265 :     test();
     730     1265265 :     IF( dec_param_estim == FALSE && hodirac_flag )
     731             :     {
     732      212624 :         IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     733             :         {
     734      212624 :             v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */
     735      212624 :             v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands );                                    /*30*/
     736      212624 :             Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx],
     737             :                     h_dirac_output_synthesis_state->direct_power_factor_fx,
     738             :                     num_freq_bands ); /*Q30*/
     739      212624 :             Copy32( aux_buf,
     740             :                     h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     741             :                     num_freq_bands ); /*Q30*/
     742             : 
     743      212624 :             v_multc_fixed( hSpatParamRendCom->energy_ratio2_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /*30+31-31->30*/
     744      212624 :             v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands );                                    /*30*/
     745      212624 :             Copy32( hSpatParamRendCom->energy_ratio2_fx[md_idx],
     746      212624 :                     &h_dirac_output_synthesis_state->direct_power_factor_fx[hSpatParamRendCom->num_freq_bands],
     747             :                     num_freq_bands ); /*Q30*/
     748      212624 :             Copy32( aux_buf,
     749      212624 :                     &h_dirac_output_synthesis_state->diffuse_power_factor_fx[hSpatParamRendCom->num_freq_bands],
     750             :                     num_freq_bands ); /*Q30*/
     751             : 
     752      212624 :             h_dirac_output_synthesis_state->diffuse_power_factor_q = 30;
     753      212624 :             move16();
     754      212624 :             h_dirac_output_synthesis_state->direct_power_factor_q = 30;
     755      212624 :             move16();
     756             :         }
     757             :         ELSE
     758             :         {
     759           0 :             ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
     760           0 :                                                     hSpatParamRendCom->diffuseness_vector_fx[md_idx],
     761             :                                                     h_dirac_output_synthesis_state->direct_power_factor_fx,
     762             :                                                     h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     763             :                                                     &h_dirac_output_synthesis_state->direct_power_factor_q,
     764             :                                                     &h_dirac_output_synthesis_state->diffuse_power_factor_q );
     765             :         }
     766             :     }
     767     1052641 :     ELSE IF( EQ_16( dec_param_estim, TRUE ) )
     768             :     {
     769             :         /* compute direct responses */
     770      694820 :         ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
     771             :                                                          hDirACRend,
     772             :                                                          hVBAPdata,
     773             :                                                          NULL,
     774             :                                                          NULL,
     775             :                                                          azimuth,
     776             :                                                          elevation,
     777             :                                                          md_idx,
     778             :                                                          NULL,
     779             :                                                          0,
     780             :                                                          sh_rot_max_order,
     781             :                                                          p_Rmat,
     782             :                                                          hodirac_flag );
     783             : 
     784             :         {
     785      694820 :             IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
     786             :             {
     787       72000 :                 Scale_sig32( h_dirac_output_synthesis_state->direct_responses_square_fx, imult1616( num_channels_dir, num_freq_bands ), sub( 31, h_dirac_output_synthesis_state->direct_responses_square_q ) ); /*h_dirac_output_synthesis_state->direct_responses_square_q->Q31*/
     788       72000 :                 h_dirac_output_synthesis_state->direct_responses_square_q = 31;
     789       72000 :                 move16();
     790             :             }
     791      694820 :             Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_fx, i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
     792      694820 :             IF( hodirac_flag )
     793             :             {
     794           0 :                 Scale_sig32( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir], i_mult( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); /*h_dirac_output_synthesis_state->direct_responses_q->Q31*/
     795             :             }
     796      694820 :             h_dirac_output_synthesis_state->direct_responses_q = 31;
     797      694820 :             move16();
     798             :         }
     799             : 
     800      694820 :         IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     801             :         {
     802      622820 :             ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
     803             :                                                     diffuseness,
     804             :                                                     h_dirac_output_synthesis_state->direct_power_factor_fx,
     805             :                                                     h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     806             :                                                     &h_dirac_output_synthesis_state->direct_power_factor_q,
     807             :                                                     &h_dirac_output_synthesis_state->diffuse_power_factor_q );
     808      622820 :             h_dirac_output_synthesis_state->direct_power_factor_q = sub( 31, h_dirac_output_synthesis_state->direct_power_factor_q );
     809      622820 :             h_dirac_output_synthesis_state->diffuse_power_factor_q = sub( 31, h_dirac_output_synthesis_state->diffuse_power_factor_q );
     810             : 
     811      622820 :             v_multc_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx,
     812             :                            ONE_IN_Q29 /*0.25f Q31*/,
     813             :                            h_dirac_output_synthesis_state->direct_power_factor_fx,
     814             :                            num_freq_bands ); /*h_dirac_output_synthesis_state->direct_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->direct_power_factor_q*/
     815      622820 :             v_multc_fixed( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     816             :                            ONE_IN_Q29 /*0.25f Q31*/,
     817             :                            h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     818             :                            num_freq_bands ); /*h_dirac_output_synthesis_state->diffuse_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->diffuse_power_factor_q*/
     819             : 
     820             :             /*Direct gain*/
     821             : 
     822      622820 :             Word16 *Q_temp_cy_cross_dir_smooth_fx = (Word16 *) malloc( num_freq_bands * num_channels_dir * sizeof( Word16 ) );
     823             : 
     824      622820 :             tmp16 = imult1616( num_freq_bands, num_channels_dir );
     825   483283940 :             FOR( Word16 kk = 0; kk < tmp16; kk++ )
     826             :             {
     827   482661120 :                 Q_temp_cy_cross_dir_smooth_fx[kk] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
     828   482661120 :                 move16();
     829             :             }
     830             : 
     831     3114100 :             FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ )
     832             :             {
     833             :                 Word16 k;
     834     2491280 :                 IF( ch_idx != 0 )
     835             :                 {
     836             :                     Word32 a, c;
     837             :                     Word16 b, b_exp, sqr_exp, q_diff_aab, q_diff_c;
     838             :                     Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab;
     839             :                     Word32 sqr_inp, sqr;
     840             : 
     841             :                     /*Directonal sound gain nrg compensation*/
     842     1868460 :                     c = L_add( ONE_IN_Q29 /*1 Q29*/, Mpy_32_16_1( L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ), 5461 /*1.0 / 6.0 Q15*/ ) ); /*Diffuseness modellling nrg compensation*/ /*Q29*/
     843    11210760 :                     FOR( k = 0; k < num_freq_bands_diff; k++ )
     844             :                     {
     845     9342300 :                         a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
     846     9342300 :                         move32();
     847     9342300 :                         IF( reference_power[k + num_freq_bands] == 0 )
     848             :                         {
     849       20370 :                             b = 0;
     850       20370 :                             move16();
     851       20370 :                             b_exp = 0;
     852       20370 :                             move16();
     853             :                         }
     854             :                         ELSE
     855             :                         {
     856     9321930 :                             IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
     857             :                             {
     858      493668 :                                 b = MAX_16;
     859      493668 :                                 move16();
     860      493668 :                                 b_exp = 0;
     861      493668 :                                 move16();
     862             :                             }
     863             :                             ELSE
     864             :                             {
     865     8828262 :                                 b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*Q(15-b_exp)*/
     866             :                             }
     867             :                         }
     868             : 
     869     9342300 :                         mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) );                                           // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
     870     9342300 :                         mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q(q_diff_aab) = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
     871     9342300 :                         mpy_diff_c = Mpy_32_32( diffuseness[k], c );                                               // Q(q_diff_c) = q_diffuseness - 2
     872             : 
     873     9342300 :                         q_diff_aab = add( sub( add( h_dirac_output_synthesis_state->direct_responses_q, sub( 15, b_exp ) ), 15 ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) );
     874     9342300 :                         q_diff_c = sub( q_diffuseness, 2 );
     875             : 
     876     9342300 :                         test();
     877     9342300 :                         IF( mpy_diff_c != 0 && mpy_diff_aab != 0 )
     878             :                         {
     879     7920520 :                             sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*Q(31-sqr_exp)*/
     880             :                         }
     881             :                         ELSE
     882             :                         {
     883     1421780 :                             IF( mpy_diff_c == 0 )
     884             :                             {
     885      604527 :                                 sqr_inp = mpy_diff_aab; /*Q(q_diff_aab)*/
     886      604527 :                                 move32();
     887      604527 :                                 sqr_exp = sub( 31, q_diff_aab );
     888             :                             }
     889             :                             ELSE
     890             :                             {
     891      817253 :                                 sqr_inp = mpy_diff_c; /*Q(q_diff_c)*/
     892      817253 :                                 move32();
     893      817253 :                                 sqr_exp = sub( 31, q_diff_c );
     894             :                             }
     895             :                         }
     896     9342300 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
     897     9342300 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
     898     9342300 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
     899             :                         {
     900     6965947 :                             IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
     901             :                             {
     902       33535 :                                 h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth-> (31-sqr_exp) */
     903       33535 :                                 move32();
     904       33535 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
     905       33535 :                                 move16();
     906             :                             }
     907             :                             ELSE
     908             :                             {
     909     6932412 :                                 sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*( 31- sqr_exp )-> h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
     910     6932412 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
     911     6932412 :                                 move16();
     912             :                             }
     913     6965947 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx*/
     914     6965947 :                             move32();
     915             :                         }
     916             :                         ELSE
     917             :                         {
     918     2376353 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*31-sqr_exp*/
     919     2376353 :                             move32();
     920     2376353 :                             Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
     921     2376353 :                             move16();
     922             :                         }
     923             :                     }
     924     1868460 :                     c = Madd_32_16( ONE_IN_Q27 /*1 Q27*/, L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ ), 5461 ); /*Diffuseness modellling nrg compensation*/ /* 1.0 / 6.0  = 5461 in Q15*/ /*Q27*/
     925             : #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_output_synthesis_process_slot
     926    85545120 :                     FOR( ; k < num_freq_bands; k++ )
     927             :                     {
     928    83676660 :                         a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
     929    83676660 :                         move32();
     930    83676660 :                         IF( reference_power[k + num_freq_bands] == 0 )
     931             :                         {
     932    14036874 :                             sqr_inp = Mpy_32_32( diffuseness[k], c );
     933    14036874 :                             sqr_exp = sub( 31 + 4, q_diffuseness );
     934             :                         }
     935             :                         ELSE
     936             :                         {
     937             :                             Word16 diff_c_exp;
     938             :                             Word16 diff_aab_exp;
     939    69639786 :                             IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
     940             :                             {
     941    12248610 :                                 mpy_a_a_b = Mpy_32_32( a, a );                                                             // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
     942    12248610 :                                 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
     943    12248610 :                                 mpy_diff_c = Mpy_32_32( diffuseness[k], c );                                               // Q = q_diffuseness - 4
     944    12248610 :                                 diff_aab_exp = sub( 31 + 62, add( h_dirac_output_synthesis_state->direct_responses_q, add( h_dirac_output_synthesis_state->direct_responses_q, q_diffuseness ) ) );
     945    12248610 :                                 diff_c_exp = sub( 31 + 4, q_diffuseness );
     946             : 
     947    12248610 :                                 sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/
     948             :                             }
     949             :                             ELSE
     950             :                             {
     951    57391176 :                                 b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/
     952             : 
     953    57391176 :                                 mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) );                                           // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
     954    57391176 :                                 mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
     955    57391176 :                                 mpy_diff_c = Mpy_32_32( diffuseness[k], c );                                               // Q = q_diffuseness - 4
     956    57391176 :                                 diff_aab_exp = sub( sub( add( sub( 31 + 62, h_dirac_output_synthesis_state->direct_responses_q ), b_exp ), h_dirac_output_synthesis_state->direct_responses_q ), q_diffuseness );
     957    57391176 :                                 diff_c_exp = sub( 31 + 4, q_diffuseness );
     958             : 
     959    57391176 :                                 sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, diff_c_exp, mpy_diff_aab, diff_aab_exp, &sqr_exp ); /*q(31-sqr_exp)*/
     960             :                             }
     961             :                         }
     962    83676660 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
     963    83676660 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
     964             : 
     965             : 
     966    83676660 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
     967             :                         {
     968    60215437 :                             IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
     969             :                             {
     970      106401 :                                 h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/
     971      106401 :                                 move32();
     972      106401 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
     973      106401 :                                 move16();
     974             :                             }
     975             :                             ELSE
     976             :                             {
     977    60109036 :                                 sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
     978    60109036 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
     979    60109036 :                                 move16();
     980             :                             }
     981    60215437 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
     982    60215437 :                             move32();
     983             :                         }
     984             :                         ELSE
     985             :                         {
     986    23461223 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/
     987    23461223 :                             move32();
     988    23461223 :                             Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
     989    23461223 :                             move16();
     990             :                         }
     991             :                     }
     992             : #else
     993             :                     FOR( ; k < num_freq_bands; k++ )
     994             :                     {
     995             :                         a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
     996             :                         move32();
     997             :                         IF( reference_power[k + num_freq_bands] == 0 )
     998             :                         {
     999             :                             b = 0;
    1000             :                             move16();
    1001             :                             b_exp = 0;
    1002             :                             move16();
    1003             :                         }
    1004             :                         ELSE
    1005             :                         {
    1006             :                             IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
    1007             :                             {
    1008             :                                 b = MAX_16;
    1009             :                                 move16();
    1010             :                                 b_exp = 0;
    1011             :                                 move16();
    1012             :                             }
    1013             :                             ELSE
    1014             :                             {
    1015             :                                 b = BASOP_Util_Divide3232_Scale( reference_power[k + num_freq_bands], reference_power[k + ( ch_idx + 1 ) * num_freq_bands], &b_exp ); /*q(15-b_exp)*/
    1016             :                             }
    1017             :                         }
    1018             : 
    1019             :                         mpy_a_a_b = Mpy_32_32( a, Mpy_32_16_1( a, b ) );                                           // Q = (h_dirac_output_synthesis_state->q_direct_responses + (15 - b_exp) - 15) + (h_dirac_output_synthesis_state->q_direct_responses) - 31
    1020             :                         mpy_diff_aab = Mpy_32_32( L_sub( L_shl( 1, q_diffuseness ), diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
    1021             :                         mpy_diff_c = Mpy_32_32( diffuseness[k], c );                                               // Q = q_diffuseness - 4
    1022             : 
    1023             :                         q_diff_aab = add( add( h_dirac_output_synthesis_state->direct_responses_q, sub( sub( 15, b_exp ), 15 ) ), add( sub( h_dirac_output_synthesis_state->direct_responses_q, 31 ), sub( q_diffuseness, 31 ) ) );
    1024             :                         q_diff_c = sub( q_diffuseness, 4 );
    1025             : 
    1026             :                         test();
    1027             :                         IF( mpy_diff_c != 0 && mpy_diff_aab != 0 )
    1028             :                         {
    1029             :                             sqr_inp = BASOP_Util_Add_Mant32Exp( mpy_diff_c, sub( 31, q_diff_c ), mpy_diff_aab, sub( 31, q_diff_aab ), &sqr_exp ); /*q(31-sqr_exp)*/
    1030             :                         }
    1031             :                         ELSE
    1032             :                         {
    1033             :                             IF( mpy_diff_c == 0 )
    1034             :                             {
    1035             :                                 sqr_inp = mpy_diff_aab; /*q_diff_aab*/
    1036             :                                 move32();
    1037             :                                 sqr_exp = sub( 31, q_diff_aab );
    1038             :                             }
    1039             :                             ELSE
    1040             :                             {
    1041             :                                 sqr_inp = mpy_diff_c;
    1042             :                                 move32();
    1043             :                                 sqr_exp = sub( 31, q_diff_c ); /*q_diff_c*/
    1044             :                             }
    1045             :                         }
    1046             :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
    1047             :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
    1048             :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
    1049             :                         {
    1050             :                             IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
    1051             :                             {
    1052             :                                 h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/
    1053             :                                 move32();
    1054             :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
    1055             :                                 move16();
    1056             :                             }
    1057             :                             ELSE
    1058             :                             {
    1059             :                                 sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
    1060             :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
    1061             :                                 move16();
    1062             :                             }
    1063             :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
    1064             :                             move32();
    1065             :                         }
    1066             :                         ELSE
    1067             :                         {
    1068             :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31- sqr_exp)*/
    1069             :                             move32();
    1070             :                             Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
    1071             :                             move16();
    1072             :                         }
    1073             :                     }
    1074             : #endif
    1075             :                 }
    1076             :                 ELSE
    1077             :                 {
    1078             :                     Word32 sqr_inp, mpy_diff, sqr;
    1079             :                     Word16 sqr_exp;
    1080             :                     /*Diffuseness modellling nrg compensation*/
    1081     3736920 :                     FOR( k = 0; k < num_freq_bands_diff; k++ )
    1082             :                     {
    1083             :                         /*diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) )*/
    1084     3114100 :                         mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx /*q29=0.5 * q30*/, ONE_IN_Q29 /*0.5 Q30*/ ) /*q30*/ ); // Q = q_diffuseness - 1
    1085     3114100 :                         sqr_inp = L_add( L_shl( 1, sub( q_diffuseness, 1 ) ), mpy_diff );                                                                                                          // Q = q_diffuseness - 1
    1086     3114100 :                         sqr_exp = sub( 31, sub( q_diffuseness, 1 ) );
    1087     3114100 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
    1088     3114100 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
    1089     3114100 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
    1090             :                         {
    1091     2329020 :                             IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
    1092             :                             {
    1093           0 :                                 h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q(31- sqr_exp)*/
    1094           0 :                                 move32();
    1095           0 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
    1096           0 :                                 move16();
    1097             :                             }
    1098             :                             ELSE
    1099             :                             {
    1100     2329020 :                                 sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q(31-sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
    1101     2329020 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
    1102     2329020 :                                 move16();
    1103             :                             }
    1104     2329020 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
    1105     2329020 :                             move32();
    1106             :                         }
    1107             :                         ELSE
    1108             :                         {
    1109      785080 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31-sqr_exp)*/
    1110      785080 :                             move32();
    1111      785080 :                             Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
    1112      785080 :                             move16();
    1113             :                         }
    1114             :                     }
    1115    28515040 :                     FOR( ; k < num_freq_bands; k++ )
    1116             :                     {
    1117    27892220 :                         mpy_diff = Mpy_32_32( diffuseness[k], L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx, ONE_IN_Q29 /*1 Q29*/ ) ); // Q = q_diffuseness - 1
    1118    27892220 :                         sqr_inp = L_add( L_shl( 1, sub( q_diffuseness, 1 ) ), mpy_diff );                                                                              // Q = q_diffuseness - 1
    1119    27892220 :                         sqr_exp = sub( 31, sub( q_diffuseness, 1 ) );
    1120    27892220 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
    1121    27892220 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
    1122    27892220 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
    1123             :                         {
    1124    20865680 :                             IF( LT_16( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
    1125             :                             {
    1126           0 :                                 h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_shr( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, sub( 31, sqr_exp ) ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, Q( 31- sqr_exp )*/
    1127           0 :                                 move32();
    1128           0 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
    1129           0 :                                 move16();
    1130             :                             }
    1131             :                             ELSE
    1132             :                             {
    1133    20865680 :                                 sqr = L_shr( sqr, sub( sub( 31, sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) ); /*Q( 31- sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
    1134    20865680 :                                 Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
    1135    20865680 :                                 move16();
    1136             :                             }
    1137    20865680 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
    1138    20865680 :                             move32();
    1139             :                         }
    1140             :                         ELSE
    1141             :                         {
    1142     7026540 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*Q(31-sqr_exp)*/
    1143     7026540 :                             move32();
    1144     7026540 :                             Q_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sub( 31, sqr_exp );
    1145     7026540 :                             move16();
    1146             :                         }
    1147             :                     }
    1148             :                 }
    1149             :             }
    1150      622820 :             Word16 temp = MAX_16; /*q0*/
    1151      622820 :             move16();
    1152      622820 :             tmp16 = imult1616( num_freq_bands, num_channels_dir );
    1153   483283940 :             FOR( Word16 kk = 0; kk < tmp16; kk++ )
    1154             :             {
    1155   482661120 :                 temp = s_min( Q_temp_cy_cross_dir_smooth_fx[kk], temp );
    1156             :             }
    1157      622820 :             h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp;
    1158      622820 :             move16();
    1159   483283940 :             FOR( Word16 kk = 0; kk < tmp16; kk++ )
    1160             :             {
    1161   482661120 :                 h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], sub( temp, Q_temp_cy_cross_dir_smooth_fx[kk] ) ); /*Q_temp_cy_cross_dir_smooth_fx[kk]->temp*/
    1162   482661120 :                 move32();
    1163             :             }
    1164      622820 :             free( Q_temp_cy_cross_dir_smooth_fx );
    1165             :             /*Directional gain (panning)*/
    1166      622820 :             Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 );
    1167      622820 :             IF( LT_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
    1168             :             {
    1169           0 :                 Word16 temp_q1 = sub( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
    1170           0 :                 FOR( Word16 kk = 0; kk < tmp16; kk++ )
    1171             :                 {
    1172           0 :                     h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk] = L_shl( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[kk], temp_q1 ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/
    1173           0 :                     move32();
    1174             :                 }
    1175           0 :                 h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q;
    1176           0 :                 move16();
    1177             :             }
    1178      622820 :             Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q );
    1179     7872660 :             FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
    1180             :             {
    1181     7249840 :                 IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
    1182             :                 {
    1183             :                     Word16 i;
    1184             :                     Word32 aux;
    1185     7105517 :                     IF( temp_q1 < 0 )
    1186             :                     {
    1187     7105517 :                         Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 );
    1188   358685897 :                         FOR( i = 0; i < num_freq_bands; i++ )
    1189             :                         {
    1190   351580380 :                             aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] );
    1191   351580380 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux, temp_q1_equiv );
    1192   351580380 :                             move32();
    1193             :                         }
    1194             :                     }
    1195             :                     ELSE
    1196             :                     {
    1197           0 :                         FOR( i = 0; i < num_freq_bands; i++ )
    1198             :                         {
    1199           0 :                             aux = Mpy_32_32( h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] );
    1200           0 :                             aux = L_shl( aux, temp_q1 );
    1201           0 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], aux );
    1202           0 :                             move32();
    1203             :                         }
    1204             :                     }
    1205             :                 }
    1206             :                 ELSE
    1207             :                 {
    1208             :                     Word16 i;
    1209     7199783 :                     FOR( i = 0; i < num_freq_bands; i++ )
    1210             :                     {
    1211     7055460 :                         h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i] = Madd_32_32( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + i], h_dirac_output_synthesis_state->direct_power_factor_fx[i], h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + i] );
    1212     7055460 :                         move32();
    1213             :                     }
    1214             :                 }
    1215             :             }
    1216             : 
    1217             : 
    1218             :             /*Diffuse gain*/
    1219      622820 :             FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
    1220             :             {
    1221           0 :                 v_multc_fixed_16( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
    1222           0 :                                   hDirACRend->diffuse_response_function_fx[ch_idx],
    1223             :                                   aux_buf,
    1224             :                                   num_freq_bands_diff ); /* h_dirac_output_synthesis_state->diffuse_power_factor_q+15-15*/
    1225           0 :                 temp_q = h_dirac_output_synthesis_state->diffuse_power_factor_q;
    1226           0 :                 IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) )
    1227             :                 {
    1228           0 :                     Scale_sig32( aux_buf, num_freq_bands, sub( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth, temp_q ) ); /*temp_q->(h_dirac_output_synthesis_state->q_cy_auto_diff_smooth)*/
    1229             :                 }
    1230             : #ifdef VEC_ARITH_OPT_v1
    1231           0 :                 v_add_fixed_no_hdrm( aux_buf,
    1232           0 :                                      &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1233           0 :                                      &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1234             :                                      num_freq_bands_diff ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/
    1235             : #else                                                       /* VEC_ARITH_OPT_v1 */
    1236             :                 v_add_fixed( aux_buf,
    1237             :                              &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1238             :                              &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1239             :                              num_freq_bands_diff, 0 ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/
    1240             : #endif                                                      /* VEC_ARITH_OPT_v1 */
    1241             :             }
    1242             : 
    1243      622820 :             return;
    1244             :         }
    1245             :         ELSE
    1246             :         {
    1247             :             /* compute reference and diffuse power factor for this frame */
    1248       72000 :             ivas_dirac_dec_compute_power_factors_fx( num_freq_bands,
    1249             :                                                      diffuseness,
    1250       72000 :                                                      h_dirac_output_synthesis_params->max_band_decorr,
    1251             :                                                      h_dirac_output_synthesis_state->direct_power_factor_fx,
    1252             :                                                      h_dirac_output_synthesis_state->diffuse_power_factor_fx );
    1253             : 
    1254       72000 :             Scale_sig32( h_dirac_output_synthesis_state->direct_power_factor_fx, num_freq_bands, 2 );  /*q29->q31*/
    1255       72000 :             Scale_sig32( h_dirac_output_synthesis_state->diffuse_power_factor_fx, num_freq_bands, 2 ); /*q29->q31*/
    1256       72000 :             h_dirac_output_synthesis_state->diffuse_power_factor_q = 31;
    1257       72000 :             move16();
    1258       72000 :             h_dirac_output_synthesis_state->direct_power_factor_q = 31;
    1259       72000 :             move16();
    1260             :         }
    1261             :     }
    1262             : 
    1263      642445 :     diff_start_band = 0;
    1264      642445 :     move16();
    1265      642445 :     IF( h_dirac_output_synthesis_params->use_onset_filters )
    1266             :     {
    1267      209936 :         computeTargetPSDs_diffuse_with_onsets_fx( num_channels_dir,
    1268      209936 :                                                   num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
    1269      209936 :                                                   hDirACRend->proto_index_diff,
    1270      209936 :                                                   h_dirac_output_synthesis_state->diffuse_power_factor_fx,
    1271             :                                                   reference_power,
    1272             : #ifdef FIX_867_CLDFB_NRG_SCALE
    1273             :                                                   q_reference_power,
    1274             : #else
    1275             :                                                   &q_reference_power,
    1276             : #endif
    1277      209936 :                                                   h_dirac_output_synthesis_state->diffuse_responses_square_fx,
    1278             :                                                   onset,
    1279             :                                                   h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
    1280             :                                                   &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    1281             : 
    1282      209936 :         diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
    1283      209936 :         move16();
    1284             :     }
    1285             : 
    1286             :     /* process other PSDs only slot wise for 4 transport channels */
    1287      642445 :     IF( EQ_16( dec_param_estim, TRUE ) )
    1288             :     {
    1289             : #ifdef FIX_867_CLDFB_NRG_SCALE
    1290       72000 :         computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
    1291             : 
    1292       72000 :         computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    1293             : #else
    1294             :         computeTargetPSDs_direct_fx( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->direct_responses_fx, h_dirac_output_synthesis_state->direct_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
    1295             : 
    1296             :         computeTargetPSDs_diffuse_fx( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor_fx, reference_power, &q_reference_power, h_dirac_output_synthesis_state->diffuse_responses_square_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    1297             : #endif
    1298             :     }
    1299             : 
    1300      642445 :     return;
    1301             : }
    1302             : 
    1303             : 
    1304             : /*-------------------------------------------------------------------------
    1305             :  * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
    1306             :  *
    1307             :  *
    1308             :  *------------------------------------------------------------------------*/
    1309             : 
    1310      222420 : void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx(
    1311             :     Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
    1312             :     Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
    1313             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,                    /* i/o: common spatial renderer data handle         */
    1314             :     DIRAC_REND_HANDLE hDirACRend,                                            /* i/o: DirAC renderer handle                       */
    1315             :     const Word16 nchan_transport,                                            /* i  : number of transport channels                */
    1316             :     const Word16 nbslots,                                                    /* i  : number of slots to process                  */
    1317             :     const Word32 *onset_filter,                                              /* Q31 */
    1318             :     Word32 *diffuseness,                                                     // Q30
    1319             :     const Word16 hodirac_flag,                                               /* i  : flag to indicate HO-DirAC mode */
    1320             :     const Word16 dec_param_estim,
    1321             :     Word16 *q_cy_cross_dir_smooth_prev,
    1322             :     Word16 *q_cy_auto_diff_smooth_prev )
    1323             : {
    1324             :     Word16 buf_idx, ch_idx, i, l;
    1325             :     Word16 num_freq_bands, num_freq_bands_diff;
    1326             :     Word16 num_channels_dir, num_channels_diff;
    1327             :     Word32 g, g1[MAX_FREQUENCY_BANDS], g2;
    1328             :     Word32 *p_gains_dir, *p_gains_diff;
    1329             :     Word32 *p_gains_dir_prev, *p_gains_diff_prev;
    1330             :     Word32 *p_cy_cross_dir_smooth;
    1331             :     Word32 *p_cy_auto_diff_smooth;
    1332             :     Word32 *p_proto, *p_out_real, *p_out_imag;
    1333             :     Word32 *p_proto_diff;
    1334             :     Word16 *proto_direct_index, num_protos_dir;
    1335             :     Word32 output_real[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1336             :     Word32 output_imag[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1337             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS h_dirac_output_synthesis_params;
    1338             :     DIRAC_OUTPUT_SYNTHESIS_STATE h_dirac_output_synthesis_state;
    1339             :     Word16 nchan_transport_foa;
    1340             :     Word16 ch_idx_diff;
    1341             :     Word32 cmp1, cmp2;
    1342             :     Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
    1343             :     Word32 ratio_float[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX];
    1344      222420 :     Word16 q_com = 0;
    1345      222420 :     move16();
    1346      222420 :     Word16 exp = 0;
    1347      222420 :     move16();
    1348             :     Word16 q_shift;
    1349             : 
    1350             :     /* collect some often used parameters */
    1351      222420 :     h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
    1352      222420 :     h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
    1353      222420 :     proto_direct_index = hDirACRend->proto_index_dir;
    1354             : 
    1355      222420 :     num_protos_dir = hDirACRend->num_protos_dir;
    1356      222420 :     move16();
    1357      222420 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
    1358      222420 :     move16();
    1359      222420 :     num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
    1360      222420 :     move16();
    1361      222420 :     num_channels_dir = hDirACRend->num_outputs_dir;
    1362      222420 :     move16();
    1363      222420 :     num_channels_diff = hDirACRend->num_outputs_diff;
    1364      222420 :     move16();
    1365      222420 :     nchan_transport_foa = s_min( 4, nchan_transport );
    1366      222420 :     move16();
    1367             : 
    1368      222420 :     Word16 prod = imult1616( num_freq_bands, num_channels_dir );
    1369             :     /*-----------------------------------------------------------------*
    1370             :      * comput target Gains
    1371             :      *-----------------------------------------------------------------*/
    1372             : 
    1373      222420 :     IF( hodirac_flag )
    1374             :     {
    1375             :         /*Direct gain*/
    1376      265780 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1377             :         {
    1378      212624 :             v_multc_fixed( diffuseness,                                                                     // Q30
    1379             :                            ONE_IN_Q31,                                                                      // Q31
    1380      212624 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q30
    1381             :                            num_freq_bands );
    1382      212624 :             v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],     // Q30
    1383             :                            L_sub( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, ONE_IN_Q27 ), // Q27
    1384      212624 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],     // Q26
    1385             :                            num_freq_bands );
    1386             : 
    1387    12861264 :             FOR( l = 0; l < num_freq_bands; l++ )
    1388             :             {
    1389    12648640 :                 exp = Q31 - Q26;
    1390    25297280 :                 h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
    1391    12648640 :                     Sqrt32( L_add( ONE_IN_Q26 /*1 in Q26*/, h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] ),
    1392             :                             &exp ); // (Q31 - exp)
    1393    12648640 :                 move32();
    1394             :             }
    1395             : 
    1396             :             // Scale to bring in common Q-factor
    1397      212624 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
    1398      212624 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1399             :                          num_freq_bands,
    1400      212624 :                          sub( q_com, sub( Q31, exp ) ) ); /*Q( Q31- exp)->q_com*/
    1401      212624 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1402             :                          num_freq_bands,
    1403      212624 :                          sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
    1404             :         }
    1405             : 
    1406     3215316 :         FOR( l = 0; l < num_freq_bands; l++ )
    1407             :         {
    1408     3162160 :             aux_buf[l] = L_sub( ONE_IN_Q30, diffuseness[l] ); // Q30
    1409     3162160 :             move32();
    1410     3162160 :             ratio_float[l] = L_sub( ONE_IN_Q31, h_dirac_output_synthesis_state.direct_power_factor_fx[num_freq_bands + l] ); // Q31
    1411     3162160 :             move32();
    1412     3162160 :             ratio_float[l + num_freq_bands] = L_sub( ONE_IN_Q31, ratio_float[l] ); // Q31
    1413     3162160 :             move32();
    1414             :         }
    1415             : 
    1416       53156 :         v_mult_fixed( aux_buf, ratio_float, ratio_float, num_freq_bands );                                   //(Q30, Q31) -> Q30
    1417       53156 :         v_mult_fixed( aux_buf, &ratio_float[num_freq_bands], &ratio_float[num_freq_bands], num_freq_bands ); //(Q30, Q31) -> Q30
    1418             : 
    1419             :         /*Directional gain*/
    1420      635028 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1421             :         {
    1422      581872 :             v_mult_fixed( ratio_float,                                                                     // Q30
    1423      581872 :                           &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands],    // Q31
    1424      581872 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], //(Q30, Q31) -> Q30
    1425             :                           num_freq_bands );
    1426      581872 :             v_mult_fixed( &ratio_float[num_freq_bands],                                                                                        // Q30
    1427      581872 :                           &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],    // Q31
    1428      581872 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], //(Q30, Q31) -> Q30
    1429             :                           num_freq_bands );
    1430             : 
    1431             :             // Scale to bring in common Q-factor
    1432      581872 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q30 );
    1433      581872 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1434             :                          num_freq_bands,
    1435      581872 :                          sub( q_com, Q30 ) ); /*Q30->q_com*/
    1436      581872 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
    1437             :                          num_freq_bands,
    1438      581872 :                          sub( q_com, Q30 ) ); /*Q30->q_com*/
    1439      581872 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1440             :                          num_freq_bands,
    1441      581872 :                          sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
    1442      581872 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
    1443             :                          num_freq_bands,
    1444      581872 :                          sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
    1445             :         }
    1446             : 
    1447       53156 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
    1448       53156 :         move16();
    1449       53156 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
    1450       53156 :         move16();
    1451             : 
    1452             :         /*Diffuse gain*/
    1453       53156 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1454             :         {
    1455           0 :             v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx,                               // Q31
    1456           0 :                               hDirACRend->diffuse_response_function_fx[ch_idx],                                     // Q15
    1457           0 :                               &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
    1458             :                               num_freq_bands_diff );
    1459             : 
    1460             :             // Scale to bring in common Q-factor
    1461           0 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
    1462           0 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1463             :                          num_freq_bands_diff,
    1464           0 :                          sub( q_com, Q31 ) ); /*q31->q_com*/
    1465           0 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
    1466             :                          num_freq_bands_diff,
    1467           0 :                          sub( q_com, h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev ) ); /* h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev->q_com*/
    1468             :         }
    1469             : 
    1470       53156 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
    1471       53156 :         move16();
    1472       53156 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
    1473       53156 :         move16();
    1474             :     }
    1475      169264 :     ELSE IF( EQ_16( dec_param_estim, FALSE ) )
    1476             :     {
    1477             :         /*Direct gain*/
    1478       24496 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1479             :         {
    1480       12248 :             v_mult_fixed( h_dirac_output_synthesis_state.diffuse_power_factor_fx,                          // Q31
    1481       12248 :                           h_dirac_output_synthesis_state.diffuse_power_factor_fx,                          // Q31
    1482       12248 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
    1483             :                           num_freq_bands );
    1484       12248 :             v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],                         // Q31
    1485             :                            L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr_fx, Q3 ), ONE_IN_Q26 ), // Q26
    1486       12248 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],                         // Q26
    1487             :                            num_freq_bands_diff );
    1488       12248 :             v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q31
    1489             :                            L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, Q1 ), ONE_IN_Q26 ),      // Q26
    1490       12248 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q26
    1491       12248 :                            num_freq_bands - num_freq_bands_diff );
    1492             : 
    1493      747128 :             FOR( l = 0; l < num_freq_bands; l++ )
    1494             :             {
    1495      734880 :                 exp = Q31 - Q26;
    1496     1469760 :                 h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
    1497      734880 :                     Sqrt32( L_add( ONE_IN_Q26, h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] ),
    1498             :                             &exp ); // (Q31 - exp)
    1499      734880 :                 move32();
    1500             :             }
    1501             : 
    1502             :             // Scale to bring in common Q-factor
    1503       12248 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
    1504       12248 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1505             :                          num_freq_bands,
    1506       12248 :                          sub( q_com, sub( Q31, exp ) ) ); /*( Q31- exp )->q_com*/
    1507       12248 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1508             :                          num_freq_bands,
    1509       12248 :                          sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
    1510             :         }
    1511             : 
    1512             :         /*Directional gain*/
    1513       76592 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1514             :         {
    1515       64344 :             v_mult_fixed( h_dirac_output_synthesis_state.direct_power_factor_fx,                           // Q31
    1516       64344 :                           &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands],    // Q31
    1517       64344 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
    1518             :                           num_freq_bands );
    1519             : 
    1520             :             // Scale to bring in common Q-factor
    1521       64344 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q31 );
    1522       64344 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1523             :                          num_freq_bands,
    1524       64344 :                          sub( q_com, Q31 ) ); /*q31->q_com*/
    1525       64344 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1526             :                          num_freq_bands,
    1527       64344 :                          sub( q_com, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev->q_com*/
    1528             :         }
    1529             : 
    1530       12248 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
    1531       12248 :         move16();
    1532       12248 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
    1533       12248 :         move16();
    1534             : 
    1535             :         /*Diffuse gain*/
    1536       12248 :         q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
    1537       48992 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1538             :         {
    1539       36744 :             v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx,                               // Q31
    1540       36744 :                               hDirACRend->diffuse_response_function_fx[ch_idx],                                     // Q15
    1541       36744 :                               &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
    1542             :                               num_freq_bands_diff );
    1543             : 
    1544             :             // Scale to bring in common Q-factor
    1545       36744 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1546             :                          num_freq_bands_diff,
    1547       36744 :                          sub( q_com, Q31 ) ); /*q31->q_com*/
    1548       36744 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
    1549             :                          num_freq_bands_diff,
    1550       36744 :                          sub( q_com, h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev ) ); /*h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev->q_com*/
    1551             :         }
    1552             : 
    1553       12248 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
    1554       12248 :         move16();
    1555       12248 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
    1556       12248 :         move16();
    1557             :     }
    1558             : 
    1559             :     /*-----------------------------------------------------------------*
    1560             :      * compute gains
    1561             :      *-----------------------------------------------------------------*/
    1562             : 
    1563      222420 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx;
    1564      222420 :     p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx;
    1565             : 
    1566    11931080 :     FOR( l = 0; l < num_freq_bands; l++ )
    1567             :     {
    1568    11708660 :         g1[l] = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31
    1569    11708660 :         move32();
    1570             :     }
    1571             : 
    1572      222420 :     q_shift = sub( 26, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev );
    1573      222420 :     move16();
    1574             : 
    1575             :     /* Direct gains */
    1576      222420 :     IF( hodirac_flag )
    1577             :     {
    1578       53156 :         cmp1 = L_shr( 66437775 /* 0.99f in Q26 */, q_shift );
    1579       53156 :         cmp2 = L_shr( ONE_IN_Q27 /* 2.0f in Q26 */, q_shift );
    1580      265780 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1581             :         {
    1582    12861264 :             FOR( l = 0; l < num_freq_bands; l++ )
    1583             :             {
    1584    12648640 :                 g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1585    12648640 :                 g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
    1586    12648640 :                 g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1587    12648640 :                 g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1588    12648640 :                 *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1589    12648640 :                 move32();
    1590             :             }
    1591             :         }
    1592             :     }
    1593             :     ELSE
    1594             :     {
    1595      169264 :         cmp1 = L_shr( 57042534 /* 0.85f in Q26 */, q_shift );
    1596      169264 :         cmp2 = L_shr( 77175193 /* 1.15f in Q26 */, q_shift );
    1597      809576 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1598             :         {
    1599    32621672 :             FOR( l = 0; l < num_freq_bands; l++ )
    1600             :             {
    1601    31981360 :                 g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1602    31981360 :                 g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
    1603    31981360 :                 g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1604    31981360 :                 g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1605    31981360 :                 *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1606    31981360 :                 move32();
    1607             :             }
    1608             :         }
    1609             :     }
    1610             : 
    1611             :     /*Directional gains*/
    1612      222420 :     cmp1 = L_shr( -DIRAC_GAIN_LIMIT_Q26, q_shift );
    1613      222420 :     cmp2 = L_negate( cmp1 );
    1614     2696828 :     FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1615             :     {
    1616   131300408 :         FOR( l = 0; l < num_freq_bands; l++ )
    1617             :         {
    1618   128826000 :             g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1619   128826000 :             g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
    1620   128826000 :             g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1621   128826000 :             g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1622   128826000 :             *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1623   128826000 :             move32();
    1624             :         }
    1625             :     }
    1626             : 
    1627      222420 :     IF( hodirac_flag )
    1628             :     {
    1629       53156 :         p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx + prod;
    1630       53156 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx + prod;
    1631             : 
    1632             :         /*Direct gains*/
    1633      265780 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1634             :         {
    1635    12861264 :             FOR( l = 0; l < num_freq_bands; l++ )
    1636             :             {
    1637    12648640 :                 p_cy_cross_dir_smooth++;
    1638    12648640 :                 p_gains_dir++;
    1639             :             }
    1640             :         }
    1641             : 
    1642             :         /*Directional gains*/
    1643      635028 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1644             :         {
    1645    35167792 :             FOR( l = 0; l < num_freq_bands; l++ )
    1646             :             {
    1647    34585920 :                 g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1648    34585920 :                 g2 = L_add_sat( g2, Mpy_32_32( g1[l], ( *( p_cy_cross_dir_smooth++ ) ) ) ); // (p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
    1649    34585920 :                 g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1650    34585920 :                 g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1651    34585920 :                 *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1652    34585920 :                 move32();
    1653             :             }
    1654             :         }
    1655             :     }
    1656             : 
    1657             :     /*Diffuse gains*/
    1658      222420 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
    1659      222420 :     p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
    1660      222420 :     g1[0] = POINT_1175_Q31; // Q31
    1661      222420 :     move32();
    1662      259164 :     FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1663             :     {
    1664      845112 :         FOR( l = 0; l < num_freq_bands_diff; l++ )
    1665             :         {
    1666      808368 :             move32();
    1667      808368 :             g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[0] ), *( p_gains_diff ) );            // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1668      808368 :             g2 = L_add_sat( g2, Mpy_32_32( g1[0], ( *( p_cy_auto_diff_smooth++ ) ) ) ); // p_gains_diff_q, (Q31, p_gains_diff_q) -> p_gains_diff_q
    1669      808368 :             g2 = L_max( g2, 0 );                                                        // p_gains_diff_q
    1670      808368 :             g2 = L_min( g2, cmp2 );                                                     // p_gains_diff_q
    1671      808368 :             *( p_gains_diff++ ) = g2;                                                   // p_gains_diff_q
    1672      808368 :             move32();
    1673             :         }
    1674             :     }
    1675             : 
    1676             :     /*-----------------------------------------------------------------*
    1677             :      * gain interpolation and output streams
    1678             :      *-----------------------------------------------------------------*/
    1679             : 
    1680     1106856 :     FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    1681             :     {
    1682      884436 :         g1[0] = L_deposit_h( h_dirac_output_synthesis_params.interpolator_fx[buf_idx] ); // Q31
    1683      884436 :         move32();
    1684      884436 :         g2 = L_sub( ONE_IN_Q31, g1[0] ); // Q31
    1685             : 
    1686             :         /*Direct input->output*/
    1687      884436 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx; // (p_gains_dir_q)
    1688      884436 :         p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev_fx;
    1689    14109908 :         FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
    1690             :         {
    1691    13225472 :             Scale_sig32( &h_dirac_output_synthesis_state.gains_dir_prev_fx[ch_idx * num_freq_bands],
    1692             :                          num_freq_bands,
    1693    13225472 :                          sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev_q ) ); /*h_dirac_output_synthesis_state.gains_dir_prev_q->h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
    1694             :         }
    1695      884436 :         h_dirac_output_synthesis_state.gains_dir_prev_q = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
    1696      884436 :         move16();
    1697             : 
    1698     4275204 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1699             :         {
    1700     6781536 :             p_proto_diff = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
    1701     3390768 :                            shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
    1702     3390768 :                            shl( ch_idx * num_freq_bands, Q1 );
    1703   180950128 :             FOR( l = 0; l < num_freq_bands; l++ )
    1704             :             {
    1705   177559360 :                 g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
    1706             : 
    1707   177559360 :                 output_real[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto_diff++ ) ) ); // (p_gains_dir_q, p_proto_diff_q) -> (p_gains_dir_q + p_proto_diff_q - 31)
    1708   177559360 :                 move32();
    1709   177559360 :                 output_imag[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto_diff++ ) ) ); // (p_gains_dir_q, p_proto_diff_q) -> (p_gains_dir_q + p_proto_diff_q - 31)
    1710   177559360 :                 move32();
    1711             :             }
    1712             :         }
    1713             : 
    1714             :         /*Directional stream*/
    1715      884436 :         Word16 offset = shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 );
    1716    10719140 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1717             :         {
    1718     9834704 :             IF( hodirac_flag )
    1719             :             {
    1720     2327488 :                 IF( proto_direct_index[ch_idx] == 0 )
    1721             :                 {
    1722             :                     Word32 *p_proto2;
    1723             :                     Word32 gs1, gs2;
    1724     2305024 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1725     1152512 :                               shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    1726     1152512 :                               shl( i_mult( proto_direct_index[0], num_freq_bands ), Q1 );
    1727     2305024 :                     p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1728     1152512 :                                shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    1729     1152512 :                                shl( i_mult( proto_direct_index[1], num_freq_bands ), Q1 );
    1730    69458432 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1731             :                     {
    1732             : 
    1733             :                         Word32 temp1, temp2;
    1734    68305920 :                         gs1 = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir ) ) ), g2, ( *( p_gains_dir_prev ) ) );               // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
    1735    68305920 :                         gs2 = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir + prod ) ) ), g2, ( *( p_gains_dir_prev + prod ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
    1736    68305920 :                         p_gains_dir++;
    1737    68305920 :                         p_gains_dir_prev++;
    1738             : 
    1739    68305920 :                         temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
    1740    68305920 :                         temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
    1741             :                         // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
    1742   136611840 :                         output_real[l * num_channels_dir + ch_idx] =
    1743    68305920 :                             Madd_32_32(
    1744             :                                 Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ), /* s1 */
    1745             :                                 gs2, L_sub( temp1, temp2 ) );                /* s2 */
    1746    68305920 :                         move32();
    1747    68305920 :                         p_proto++;
    1748    68305920 :                         p_proto2++;
    1749             : 
    1750    68305920 :                         temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
    1751    68305920 :                         temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
    1752             :                         // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
    1753   136611840 :                         output_imag[l * num_channels_dir + ch_idx] =
    1754    68305920 :                             Madd_32_32(
    1755             :                                 Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ),
    1756             :                                 gs2, L_sub( temp1, temp2 ) );
    1757    68305920 :                         move32();
    1758    68305920 :                         p_proto++;
    1759    68305920 :                         p_proto2++;
    1760             :                     }
    1761             :                 }
    1762             :                 ELSE
    1763             :                 {
    1764     2349952 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1765     1174976 :                               shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    1766     1174976 :                               shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
    1767     1174976 :                     Word16 diff = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
    1768    71212736 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1769             :                     {
    1770    70037760 :                         p_gains_dir++;
    1771    70037760 :                         p_gains_dir_prev++;
    1772             : 
    1773    70037760 :                         output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), diff ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
    1774    70037760 :                         move32();
    1775    70037760 :                         output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), diff ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
    1776    70037760 :                         move32();
    1777             :                     }
    1778             :                 }
    1779             :             }
    1780             :             ELSE
    1781             :             {
    1782    15014432 :                 p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1783    15014432 :                           offset +
    1784     7507216 :                           shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
    1785     7507216 :                 IF( EQ_16( proto_direct_index[ch_idx], 0 ) )
    1786             :                 {
    1787   367849064 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1788             :                     {
    1789   360589280 :                         g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_dir++ ) ) ), g2, ( *( p_gains_dir_prev++ ) ) ); // (Q31, p_gains_dir_q) -> (p_gains_dir_q)
    1790             : 
    1791   360589280 :                         output_real[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto++ ) ) ); // (p_gains_dir_q, p_proto_dir_q) -> (p_gains_dir_q + p_proto_dir_q - 31)
    1792   360589280 :                         move32();
    1793   360589280 :                         output_imag[l * num_channels_dir + ch_idx] = Mpy_32_32( g, ( *( p_proto++ ) ) ); // (p_gains_dir_q, p_proto_dir_q) -> (p_gains_dir_q + p_proto_dir_q - 31)
    1794   360589280 :                         move32();
    1795             :                     }
    1796             :                 }
    1797             :                 ELSE
    1798             :                 {
    1799      247432 :                     Word16 shift_q = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
    1800    13736552 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1801             :                     {
    1802    13489120 :                         p_gains_dir++;
    1803    13489120 :                         p_gains_dir_prev++;
    1804             : 
    1805    13489120 :                         output_real[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), shift_q ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
    1806    13489120 :                         move32();
    1807    13489120 :                         output_imag[l * num_channels_dir + ch_idx] = L_shl( *( p_proto++ ), shift_q ); // p_proto_dir_q -> (p_gains_dir_q + p_proto_dir_q - 31)
    1808    13489120 :                         move32();
    1809             :                     }
    1810             :                 }
    1811             :             }
    1812             :         }
    1813             : 
    1814             :         /*Diffuse stream*/
    1815      884436 :         p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
    1816      884436 :         p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
    1817     1031412 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1818             :         {
    1819      146976 :             Scale_sig32( &h_dirac_output_synthesis_state.gains_diff_prev_fx[ch_idx * num_freq_bands_diff],
    1820             :                          num_freq_bands_diff,
    1821      146976 :                          sub( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state.gains_diff_prev_q ) ); /*h_dirac_output_synthesis_state.gains_diff_prev_q->h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev*/
    1822             :         }
    1823      884436 :         h_dirac_output_synthesis_state.gains_diff_prev_q = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
    1824      884436 :         move16();
    1825             : 
    1826      884436 :         ch_idx_diff = nchan_transport_foa;
    1827      884436 :         move16();
    1828     1031412 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1829             :         {
    1830      146976 :             IF( proto_direct_index[ch_idx] == 0 )
    1831             :             {
    1832      293952 :                 p_proto = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
    1833      146976 :                           shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
    1834      146976 :                           shl( i_mult( ch_idx_diff, num_freq_bands ), Q1 );
    1835      146976 :                 ch_idx_diff = add( ch_idx_diff, 1 );
    1836     3380448 :                 FOR( l = 0; l < num_freq_bands_diff; l++ )
    1837             :                 {
    1838     3233472 :                     g = Madd_32_32( Mpy_32_32( g1[0], ( *( p_gains_diff++ ) ) ), g2, ( *( p_gains_diff_prev++ ) ) ); // (Q31, p_gains_diff_q) -> p_gains_diff_q
    1839             : 
    1840             :                     // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
    1841     6466944 :                     output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
    1842     3233472 :                         Madd_32_32( output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
    1843     3233472 :                                     g, ( *( p_proto++ ) ) );
    1844     3233472 :                     move32();
    1845             : 
    1846             :                     // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
    1847     6466944 :                     output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
    1848     3233472 :                         Madd_32_32( output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
    1849     3233472 :                                     g, ( *( p_proto++ ) ) );
    1850     3233472 :                     move32();
    1851             :                 }
    1852             :             }
    1853             :             ELSE
    1854             :             {
    1855           0 :                 p_gains_diff += num_freq_bands_diff;
    1856           0 :                 p_gains_diff_prev += num_freq_bands_diff;
    1857             :             }
    1858             :         }
    1859             : 
    1860             :         /*-----------------------------------------------------------------*
    1861             :          * Copy output or HOA decoder
    1862             :          *-----------------------------------------------------------------*/
    1863             : 
    1864      884436 :         test();
    1865             :         /*q=(p_gains_dir_q + p_proto_dir_q - 31)*/
    1866      884436 :         IF( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
    1867      156000 :         {
    1868             :             Word32 *p_real, *p_imag;
    1869             :             const Word32 *hoa_decoder;
    1870             : 
    1871      156000 :             hoa_decoder = hDirACRend->hoa_decoder;
    1872             : 
    1873     1592000 :             FOR( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
    1874             :             {
    1875     1436000 :                 p_real = RealBuffer[ch_idx][buf_idx]; /*q - Q2*/
    1876     1436000 :                 p_imag = ImagBuffer[ch_idx][buf_idx]; /*q - Q2*/
    1877             : 
    1878    80556000 :                 FOR( l = 0; l < num_freq_bands; l++ )
    1879             :                 {
    1880    79120000 :                     p_out_real = output_real + i_mult( l, num_channels_dir );
    1881    79120000 :                     p_out_imag = output_imag + i_mult( l, num_channels_dir );
    1882    79120000 :                     p_real[l] = Mpy_32_32( *( p_out_real++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
    1883    79120000 :                     move32();
    1884    79120000 :                     p_imag[l] = Mpy_32_32( *( p_out_imag++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
    1885    79120000 :                     move32();
    1886  1265920000 :                     FOR( i = 1; i < num_channels_dir; i++ )
    1887             :                     {
    1888  1186800000 :                         p_real[l] = Madd_32_32( p_real[l], *( p_out_real++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
    1889  1186800000 :                         move32();
    1890  1186800000 :                         p_imag[l] = Madd_32_32( p_imag[l], *( p_out_imag++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
    1891  1186800000 :                         move32();
    1892             :                     }
    1893             :                 }
    1894     1436000 :                 hoa_decoder += 16;
    1895             :             }
    1896             :         }
    1897             :         ELSE
    1898             :         {
    1899    11457908 :             FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
    1900             :             {
    1901   561190912 :                 FOR( l = 0; l < num_freq_bands; l++ )
    1902             :                 {
    1903   550461440 :                     RealBuffer[ch_idx][buf_idx][l] = L_shr( output_real[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
    1904   550461440 :                     move32();
    1905   550461440 :                     ImagBuffer[ch_idx][buf_idx][l] = L_shr( output_imag[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
    1906   550461440 :                     move32();
    1907             :                 }
    1908             :             }
    1909             :         }
    1910             :     }
    1911             : 
    1912             :     /*-----------------------------------------------------------------*
    1913             :      * update buffers
    1914             :      *-----------------------------------------------------------------*/
    1915             : 
    1916             :     /* store estimates for next synthesis block */
    1917      222420 :     IF( hodirac_flag )
    1918             :     {
    1919       53156 :         Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, prod * DIRAC_HO_NUMSECTORS ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
    1920             :     }
    1921             :     ELSE
    1922             :     {
    1923      169264 :         Copy32( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx, h_dirac_output_synthesis_state.gains_dir_prev_fx, prod ); /*h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
    1924             :     }
    1925      222420 :     *q_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
    1926      222420 :     move16();
    1927             : 
    1928      222420 :     Copy32( h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx, h_dirac_output_synthesis_state.gains_diff_prev_fx, imult1616( num_freq_bands_diff, num_channels_diff ) ); /* h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev*/
    1929      222420 :     *q_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
    1930      222420 :     move16();
    1931             : 
    1932             :     /* reset values */
    1933      222420 :     IF( hodirac_flag )
    1934             :     {
    1935       53156 :         set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod * DIRAC_HO_NUMSECTORS );
    1936             :     }
    1937             :     ELSE
    1938             :     {
    1939      169264 :         set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod );
    1940             :     }
    1941             : 
    1942      222420 :     set_zero_fx( h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx, imult1616( num_freq_bands_diff, num_channels_diff ) );
    1943             : 
    1944      222420 :     return;
    1945             : }
    1946             : 
    1947             : 
    1948             : /*-------------------------------------------------------------------------
    1949             :  * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
    1950             :  *
    1951             :  *
    1952             :  *------------------------------------------------------------------------*/
    1953       95963 : void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
    1954             :     Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                        Q(q_Cldfb)*/
    1955             :     Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                        Q(q_Cldfb)*/
    1956             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,                    /* i/o: common spatial renderer data handle         */
    1957             :     DIRAC_REND_HANDLE hDirACRend,                                            /* i/o: DirAC renderer handle                       */
    1958             :     const Word16 nbslots,                                                    /* i  : number of slots to process                  */
    1959             :     Word32 *diffuseness_vector,                                              /* i  : diffuseness (needed for direction smoothing) Q(31)*/
    1960             :     Word32 *reference_power_smooth,                                          /*Q(q_reference_power_smooth)*/
    1961             :     Word16 *q_reference_power_smooth,
    1962             :     Word32 qualityBasedSmFactor, /*Q(31)*/
    1963             :     const Word16 enc_param_start_band,
    1964             :     Word16 *q_Cldfb )
    1965             : {
    1966             :     Word16 buf_idx, num_freq_bands;
    1967             :     Word16 diff_start_band;
    1968             :     Word16 k, l;
    1969             :     Word16 nchan_out_woLFE;
    1970             :     Word32 *p_power_smooth_prev, *p_power_diff_smooth_prev;
    1971             :     Word32 *p_gain_1, *p_gain_2;
    1972             :     Word32 *p_power_smooth_diff, *p_power_smooth;
    1973             :     Word32 *p_gains_dir, *p_gains_diff;
    1974             :     Word32 g, g1, g2;
    1975             :     Word32 *p_cy_auto_dir_smooth, *p_cy_auto_dir_smooth_prev;
    1976             :     Word16 q_cy_auto_dir_smooth_local[MAX_OUTPUT_CHANNELS], q_cy_auto_dir_smooth_prev_local[MAX_OUTPUT_CHANNELS];
    1977             :     Word32 *p_cy_cross_dir_smooth, *p_cy_cross_dir_smooth_prev;
    1978             :     Word32 *p_cy_auto_diff_smooth, *p_cy_auto_diff_smooth_prev;
    1979             :     Word32 gains_dir[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1980             :     Word32 gains_diff[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1981             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
    1982             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
    1983             :     Word16 *proto_direct_index, num_protos_dir;
    1984             :     Word32 target_power_y, target_power_y1;
    1985             :     Word16 q_target_power_y, q_target_power_y1;
    1986             :     Word32 subtract_power_y;
    1987             :     Word32 subtract_target_ratio;
    1988             :     Word32 subtract_target_ratio_db;
    1989             :     Word32 a, b;
    1990             :     UWord16 nchan_target_psds;
    1991             :     Word32 alpha[CLDFB_NO_CHANNELS_MAX];
    1992             :     Word16 *alpha_synthesis;
    1993             :     Word16 *alpha_synthesis_fast;
    1994             :     Word16 alphaMaxBin;
    1995             :     Word16 alphaMaxBinFast;
    1996             :     Word32 L_tmp;
    1997             :     Word16 exp_arr[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1998       95963 :     Word16 exp = 0, exp1, tmp, q_com, q_tmp, min_exp;
    1999             :     Word32 tmp32;
    2000       95963 :     move16();
    2001             : 
    2002             :     Word64 Cldfb_RealBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    2003             :     Word64 Cldfb_ImagBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    2004       95963 :     Word64 W_temp = 0;
    2005       95963 :     move64();
    2006       95963 :     push_wmops( "dirac_out_synth_sfr" );
    2007             : 
    2008       95963 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
    2009       95963 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
    2010             : 
    2011             :     /* collect some often used parameters */
    2012       95963 :     proto_direct_index = hDirACRend->proto_index_dir;
    2013       95963 :     move16();
    2014       95963 :     num_protos_dir = hDirACRend->num_protos_dir;
    2015       95963 :     move16();
    2016       95963 :     nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
    2017       95963 :     move16();
    2018       95963 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
    2019       95963 :     move16();
    2020       95963 :     set16_fx( q_cy_auto_dir_smooth_local, h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, nchan_out_woLFE );
    2021             : 
    2022             :     /*-----------------------------------------------------------------*
    2023             :      * compute target PSDs
    2024             :      *-----------------------------------------------------------------*/
    2025       95963 :     IF( enc_param_start_band == 0 )
    2026             :     {
    2027       77963 :         IF( EQ_16( h_dirac_output_synthesis_params->use_onset_filters, 1 ) )
    2028             :         {
    2029       52517 :             diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
    2030       52517 :             move16();
    2031             :         }
    2032             :         ELSE
    2033             :         {
    2034       25446 :             diff_start_band = 0;
    2035       25446 :             move16();
    2036             :         }
    2037             : 
    2038       77963 :         IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
    2039             :         {
    2040        9414 :             nchan_target_psds = 2;
    2041        9414 :             move16();
    2042             :         }
    2043             :         ELSE
    2044             :         {
    2045       68549 :             nchan_target_psds = nchan_out_woLFE;
    2046       68549 :             move16();
    2047             :         }
    2048             : 
    2049       77963 :         computeTargetPSDs_direct_subframe_fx( nchan_target_psds, num_freq_bands,
    2050       77963 :                                               h_dirac_output_synthesis_state->direct_power_factor_fx,
    2051             :                                               reference_power_smooth,
    2052             :                                               q_reference_power_smooth,
    2053       77963 :                                               h_dirac_output_synthesis_state->direct_responses_fx,
    2054       77963 :                                               h_dirac_output_synthesis_state->direct_responses_square_fx,
    2055             :                                               h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx,
    2056             :                                               q_cy_auto_dir_smooth_local,
    2057             :                                               h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx,
    2058             :                                               &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
    2059             : 
    2060             : #ifndef FIX_867_CLDFB_NRG_SCALE
    2061             :         // Scale cy_auto_diff_smooth_fx if required
    2062             :         IF( diff_start_band != 0 )
    2063             :         {
    2064             :             q_com = s_min( *q_reference_power_smooth, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    2065             :             scale_sig32( reference_power_smooth, num_freq_bands, sub( q_com, *q_reference_power_smooth ) );                                         /**q_reference_power_smooth->q_com*/
    2066             :             scale_sig32( h_dirac_output_synthesis_state->reference_power_smooth_prev_fx, num_freq_bands, sub( q_com, *q_reference_power_smooth ) ); /**q_reference_power_smooth->q_com*/
    2067             :             scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
    2068             :                          i_mult( num_freq_bands, nchan_target_psds ),
    2069             :                          sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/
    2070             :             *q_reference_power_smooth = q_com;
    2071             :             move16();
    2072             :             h_dirac_output_synthesis_state->reference_power_smooth_prev_q = q_com;
    2073             :             move16();
    2074             : 
    2075             :             h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = q_com;
    2076             :             move16();
    2077             :         }
    2078             : #endif
    2079             : 
    2080       77963 :         computeTargetPSDs_diffuse_subframe_fx( nchan_target_psds, num_freq_bands, diff_start_band,
    2081       77963 :                                                h_dirac_output_synthesis_state->diffuse_power_factor_fx,
    2082             :                                                reference_power_smooth,
    2083             :                                                q_reference_power_smooth,
    2084       77963 :                                                h_dirac_output_synthesis_state->diffuse_responses_square_fx,
    2085             :                                                h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
    2086             :                                                &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    2087             :     }
    2088             : 
    2089             :     /*-----------------------------------------------------------------*
    2090             :      * compute variables for stereo transport signal type detection
    2091             :      *-----------------------------------------------------------------*/
    2092             : 
    2093       95963 :     IF( hDirACRend->masa_stereo_type_detect != NULL )
    2094             :     {
    2095       16206 :         MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
    2096             : 
    2097       16206 :         p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx;   // q_cy_auto_dir_smooth
    2098       16206 :         p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx; // q_cy_auto_diff_smooth
    2099       16206 :         q_com = s_min( q_cy_auto_dir_smooth_local[1], h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    2100             : 
    2101       16206 :         IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
    2102             :         {
    2103        9414 :             exp = Q31 - Q31;
    2104        9414 :             move16();
    2105        9414 :             exp1 = 0;
    2106        9414 :             move16();
    2107        9414 :             tmp32 = BASOP_Util_Divide3232_Scale_newton( L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ),
    2108        9414 :                                                         ( L_add( Sqrt32( h_dirac_output_synthesis_state->direct_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
    2109             :                                                         &exp1 );
    2110        9414 :             target_power_y = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
    2111        9414 :             q_target_power_y = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
    2112        9414 :             q_target_power_y = sub( q_target_power_y, 1 );
    2113             : 
    2114        9414 :             exp = Q31 - Q31;
    2115        9414 :             move16();
    2116        9414 :             exp1 = 0;
    2117        9414 :             move16();
    2118        9414 :             tmp32 = BASOP_Util_Divide3232_Scale_newton( L_shl( p_cy_auto_diff_smooth[num_freq_bands], sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ),
    2119        9414 :                                                         ( L_add( Sqrt32( h_dirac_output_synthesis_state->diffuse_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
    2120             :                                                         &exp1 );
    2121        9414 :             target_power_y1 = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
    2122        9414 :             q_target_power_y1 = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
    2123        9414 :             q_target_power_y1 = sub( q_target_power_y1, 1 );
    2124             : 
    2125        9414 :             target_power_y = L_add( L_shl( target_power_y, sub( s_min( q_target_power_y1, q_target_power_y ), q_target_power_y ) ), L_shl( target_power_y1, sub( s_min( q_target_power_y1, q_target_power_y ), q_target_power_y1 ) ) ); /*min(q_target_power_y1, q_target_power_y )*/
    2126        9414 :             exp = s_min( q_target_power_y1, q_target_power_y );
    2127             :         }
    2128             :         ELSE
    2129             :         {
    2130        6792 :             target_power_y = L_add(
    2131        6792 :                 L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ),
    2132        6792 :                 L_shl( p_cy_auto_diff_smooth[num_freq_bands], sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) ) ); // q_com
    2133        6792 :             exp = q_com;
    2134        6792 :             move16();
    2135             :         }
    2136             : 
    2137       16206 :         a = 858993; /* ( 0.0004f in Q31 ); Temporal smoothing coefficient */
    2138       16206 :         move32();
    2139       16206 :         b = L_sub( ONE_IN_Q31, a ); /* Temporal smoothing coefficient */
    2140             : 
    2141       16206 :         q_com = s_min( exp, masa_stereo_type_detect->q_target_power_y_smooth );
    2142       16206 :         target_power_y = L_shl( target_power_y, sub( q_com, exp ) );
    2143       16206 :         masa_stereo_type_detect->target_power_y_smooth_fx = L_shl( masa_stereo_type_detect->target_power_y_smooth_fx,
    2144       16206 :                                                                    sub( q_com, masa_stereo_type_detect->q_target_power_y_smooth ) );
    2145       16206 :         move32();
    2146       16206 :         masa_stereo_type_detect->target_power_y_smooth_fx =
    2147       16206 :             L_add( Mpy_32_32( a, target_power_y ),
    2148             :                    Mpy_32_32( b, masa_stereo_type_detect->target_power_y_smooth_fx ) ); //(Q31, q_com) -> q_com
    2149       16206 :         move32();
    2150       16206 :         masa_stereo_type_detect->q_target_power_y_smooth = q_com;
    2151       16206 :         move16();
    2152             : 
    2153       16206 :         IF( NE_16( masa_stereo_type_detect->q_subtract_power_y, masa_stereo_type_detect->q_subtract_power_y_smooth ) )
    2154             :         {
    2155           0 :             exp = s_min( add( masa_stereo_type_detect->q_subtract_power_y, norm_l( masa_stereo_type_detect->subtract_power_y_fx ) ), add( masa_stereo_type_detect->q_subtract_power_y_smooth, norm_l( masa_stereo_type_detect->subtract_power_y_smooth_fx ) ) );
    2156           0 :             masa_stereo_type_detect->subtract_power_y_fx = L_shl( masa_stereo_type_detect->subtract_power_y_fx, sub( exp, masa_stereo_type_detect->q_subtract_power_y ) );
    2157           0 :             move32();
    2158           0 :             masa_stereo_type_detect->subtract_power_y_smooth_fx = L_shl( masa_stereo_type_detect->subtract_power_y_smooth_fx, sub( exp, masa_stereo_type_detect->q_subtract_power_y_smooth ) );
    2159           0 :             move32();
    2160           0 :             masa_stereo_type_detect->q_subtract_power_y = exp;
    2161           0 :             move16();
    2162           0 :             masa_stereo_type_detect->q_subtract_power_y_smooth = exp;
    2163           0 :             move16();
    2164             :         }
    2165       16206 :         subtract_power_y = masa_stereo_type_detect->subtract_power_y_fx; // q_subtract_power_y
    2166       16206 :         move32();
    2167             : 
    2168       16206 :         W_temp = W_add( W_mult0_32_32( a, subtract_power_y ), W_mult0_32_32( b, masa_stereo_type_detect->subtract_power_y_smooth_fx ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth
    2169       16206 :         IF( W_temp )
    2170             :         {
    2171       16193 :             exp = W_norm( W_temp );
    2172       16193 :             masa_stereo_type_detect->subtract_power_y_smooth_fx = W_extract_h( W_shl( W_temp, exp ) ); // Q31 + masa_stereo_type_detect->q_subtract_power_y_smooth + exp - 32
    2173       16193 :             move32();
    2174       16193 :             masa_stereo_type_detect->q_subtract_power_y_smooth = sub( add( masa_stereo_type_detect->q_subtract_power_y_smooth, exp ), 1 );
    2175       16193 :             move16();
    2176             :         }
    2177             :         ELSE
    2178             :         {
    2179          13 :             masa_stereo_type_detect->subtract_power_y_smooth_fx = 0; // Q31
    2180          13 :             move32();
    2181          13 :             masa_stereo_type_detect->q_subtract_power_y_smooth = Q31;
    2182          13 :             move16();
    2183             :         }
    2184       16206 :         exp = 0;
    2185       16206 :         move16();
    2186       16206 :         test();
    2187       16206 :         IF( masa_stereo_type_detect->target_power_y_smooth_fx && masa_stereo_type_detect->subtract_power_y_smooth_fx )
    2188             :         {
    2189       16190 :             subtract_target_ratio = L_sub( BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ),
    2190             :                                            BASOP_Util_Log2( masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q25
    2191       16190 :             exp = sub( masa_stereo_type_detect->q_subtract_power_y_smooth, q_com );
    2192       16190 :             L_tmp = Mpy_32_32( L_sub( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ); // Q25
    2193             :         }
    2194             :         ELSE
    2195             :         {
    2196          16 :             subtract_target_ratio = BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ); // Q25
    2197          16 :             exp = sub( 31, masa_stereo_type_detect->q_subtract_power_y_smooth );
    2198          16 :             L_tmp = L_sub( Mpy_32_32( L_add( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ), -503316480 /* L_shl( -15, 25 ) */ /*log(EPSILON)*/ ); // Q25
    2199             :         }
    2200       16206 :         subtract_target_ratio_db = Mpy_32_32( 1342177280 /* 10.0f * in Q27*/, L_tmp ); // (Q27, (Q25, Q31)) -> (Q27, Q25) -> Q21
    2201             : 
    2202       16206 :         masa_stereo_type_detect->subtract_target_ratio_db_fx = subtract_target_ratio_db; // Q21
    2203       16206 :         move32();
    2204       16206 :         masa_stereo_type_detect->subtract_power_y_fx = 0;
    2205       16206 :         move32();
    2206       16206 :         masa_stereo_type_detect->q_subtract_power_y = Q31;
    2207       16206 :         move16();
    2208             :     }
    2209             : 
    2210             :     /*-----------------------------------------------------------------*
    2211             :      * compute smoothing coefficients
    2212             :      *-----------------------------------------------------------------*/
    2213             : 
    2214       95963 :     alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis_fx;           // Q15
    2215       95963 :     alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast_fx; // Q15
    2216       95963 :     alphaMaxBin = sub( h_dirac_output_synthesis_params->numAlphas, 1 );
    2217       95963 :     alphaMaxBinFast = sub( h_dirac_output_synthesis_params->numAlphasFast, 1 );
    2218             : 
    2219     5600663 :     FOR( l = 0; l < num_freq_bands; l++ )
    2220             :     {
    2221             :         Word32 instDirectionSmoothness, weightedDirectionSmoothness, smoothedDirectionSmoothness;
    2222             :         Word32 currWeight, prevWeight, sumWeight;
    2223             :         Word16 indexFast, indexSlow;
    2224     5504700 :         Word32 alpha_quality_based = 42949672; /* 0.02f in Q31 */
    2225     5504700 :         move32();
    2226             : 
    2227     5504700 :         indexSlow = s_min( l, alphaMaxBin );
    2228     5504700 :         indexFast = s_min( l, alphaMaxBinFast );
    2229             : 
    2230             :         /* Estimate the smoothness of the directions based on the diffuseness parameter */
    2231     5504700 :         instDirectionSmoothness = L_sub( ONE_IN_Q31, diffuseness_vector[l] );               // Q31
    2232     5504700 :         instDirectionSmoothness = L_min( L_max( instDirectionSmoothness, 0 ), ONE_IN_Q31 ); // Q31
    2233             : 
    2234             :         /* Average the direction smoothness parameter over time */
    2235     5504700 :         currWeight = Mpy_32_32( DIRECTION_SMOOTHNESS_ALPHA_Q31,
    2236     5504700 :                                 reference_power_smooth[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
    2237     5504700 :         prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ),
    2238     5504700 :                                 h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
    2239             : 
    2240             : #ifdef FIX_867_CLDFB_NRG_SCALE
    2241     5504700 :         assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] );
    2242     5504700 :         assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] );
    2243             : #else
    2244             :         assert( *q_reference_power_smooth == h_dirac_output_synthesis_state->reference_power_smooth_prev_q );
    2245             : #endif
    2246             :         weightedDirectionSmoothness =
    2247     5504700 :             L_add( Mpy_32_32( currWeight, instDirectionSmoothness ),
    2248     5504700 :                    Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth
    2249     5504700 :         sumWeight = L_add( currWeight, prevWeight );                                                           // q_reference_power_smooth
    2250             : 
    2251     5504700 :         exp = 0;
    2252     5504700 :         move16();
    2253             : 
    2254     5504700 :         tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/
    2255     5504700 :         smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) );             // Q31
    2256             : 
    2257     5504700 :         h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] = smoothedDirectionSmoothness; // Q31
    2258     5504700 :         move32();
    2259     5504700 :         h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] = sumWeight; // q_reference_power_smooth
    2260     5504700 :         move32();
    2261             : 
    2262             :         /* Determine smoothing parameter for rendering. The smoother the directions, the less smoothing is required (i.e., faster smoothing can be used). */
    2263    11009400 :         alpha[l] =
    2264     5504700 :             L_add( Mpy_32_16_1( smoothedDirectionSmoothness, alpha_synthesis_fast[indexFast] ),
    2265     5504700 :                    Mpy_32_16_1( L_sub( ONE_IN_Q31, smoothedDirectionSmoothness ), alpha_synthesis[indexSlow] ) ); //(Q31, Q15) -> Q31
    2266     5504700 :         move32();
    2267             : 
    2268             :         /* Adjust smoothing parameter based on encoding quality */
    2269    11009400 :         alpha[l] =
    2270     5504700 :             L_add( Mpy_32_32( qualityBasedSmFactor, alpha[l] ),
    2271             :                    Mpy_32_32( L_sub( ONE_IN_Q31, qualityBasedSmFactor ), alpha_quality_based ) ); //(Q31, Q31) -> Q31
    2272     5504700 :         move32();
    2273             :     }
    2274             : 
    2275             :     /*-----------------------------------------------------------------*
    2276             :      * compute gains
    2277             :      *-----------------------------------------------------------------*/
    2278             : 
    2279             :     /*Direct normalization gains on reduced number of protos*/
    2280       95963 :     p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx;
    2281       95963 :     p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
    2282       95963 :     set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) );
    2283             : 
    2284      419919 :     FOR( k = 0; k < num_protos_dir; k++ )
    2285             :     {
    2286    19311796 :         FOR( l = 0; l < num_freq_bands; l++ )
    2287             :         {
    2288    18987840 :             g1 = alpha[l]; // Q31
    2289    18987840 :             move32();
    2290    18987840 :             g2 = L_sub( ONE_IN_Q31, g1 );                                                          // Q31
    2291    18987840 :             *p_power_smooth_prev = L_add( EPSILON_FX, Mpy_32_32( g2, ( *p_power_smooth_prev ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth
    2292    18987840 :             move32();
    2293    18987840 :             *( p_power_smooth_prev ) = L_add( *( p_power_smooth_prev ), Mpy_32_32( g1, ( *p_power_smooth ) ) ); //(Q31, q_proto_power_smooth) -> q_proto_power_smooth
    2294    18987840 :             move32();
    2295             : 
    2296             : #ifdef FIX_867_CLDFB_NRG_SCALE
    2297    18987840 :             assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] == h_dirac_output_synthesis_state->proto_power_smooth_q[0] );
    2298    18987840 :             assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] == h_dirac_output_synthesis_state->proto_power_smooth_q[1] );
    2299             : #else
    2300             :             assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q == h_dirac_output_synthesis_state->proto_power_smooth_q );
    2301             : #endif
    2302    18987840 :             IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) )
    2303             :             {
    2304       12353 :                 p_power_smooth_prev++;
    2305       12353 :                 L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2306       12353 :                 exp_arr[k * num_freq_bands + l] = exp;
    2307       12353 :                 move16();
    2308             : 
    2309       12353 :                 *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2310       12353 :                 move32();
    2311             :             }
    2312             :             ELSE
    2313             :             {
    2314    18975487 :                 L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2315    18975487 :                 exp_arr[k * num_freq_bands + l] = exp;
    2316    18975487 :                 move16();
    2317             : 
    2318    18975487 :                 *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2319    18975487 :                 move32();
    2320             :             }
    2321             :         }
    2322             :     }
    2323             : 
    2324             :     // Move proto_power_smooth_fx to common Q-factor
    2325             : 
    2326             : #ifdef FIX_867_CLDFB_NRG_SCALE
    2327       95963 :     Word16 min_exp2 = -64;
    2328       95963 :     min_exp = MIN_16;
    2329       95963 :     move16();
    2330       95963 :     move16();
    2331       95963 :     Word16 q_tmp2 = Q31;
    2332       95963 :     q_tmp = Q31;
    2333       95963 :     move16();
    2334       95963 :     move16();
    2335             : 
    2336      419919 :     FOR( k = 0; k < num_protos_dir; k++ )
    2337             :     {
    2338    10000636 :         FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
    2339             :         {
    2340     9676680 :             min_exp = s_max( min_exp, exp_arr[k * num_freq_bands + l] );
    2341             :         }
    2342     9635116 :         FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2343             :         {
    2344     9311160 :             min_exp2 = s_max( min_exp2, exp_arr[k * num_freq_bands + l] );
    2345             :         }
    2346             :     }
    2347             : 
    2348       95963 :     p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
    2349             : 
    2350      419919 :     FOR( k = 0; k < num_protos_dir; k++ )
    2351             :     {
    2352    10000636 :         FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
    2353             :         {
    2354     9676680 :             *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/
    2355     9676680 :             move32();
    2356     9676680 :             p_power_smooth++;
    2357             :         }
    2358     9635116 :         FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2359             :         {
    2360     9311160 :             *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp2, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/
    2361     9311160 :             move32();
    2362     9311160 :             p_power_smooth++;
    2363             :         }
    2364             :     }
    2365             : 
    2366             :     // Update the Q-factor
    2367       95963 :     h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[0], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] );
    2368       95963 :     h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = s_min( h_dirac_output_synthesis_state->proto_power_smooth_q[1], h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] );
    2369       95963 :     move16();
    2370       95963 :     move16();
    2371             : 
    2372       95963 :     q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) );
    2373       95963 :     q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) );
    2374             : 
    2375       95963 :     h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp;
    2376       95963 :     h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2;
    2377       95963 :     move16();
    2378       95963 :     move16();
    2379             : #else
    2380             :     min_exp = MIN_16;
    2381             :     move16();
    2382             :     q_tmp = Q31;
    2383             :     move16();
    2384             : 
    2385             :     FOR( k = 0; k < num_protos_dir; k++ )
    2386             :     {
    2387             :         FOR( l = 0; l < num_freq_bands; l++ )
    2388             :         {
    2389             :             IF( GT_16( exp_arr[k * num_freq_bands + l], min_exp ) )
    2390             :             {
    2391             :                 min_exp = exp_arr[k * num_freq_bands + l];
    2392             :                 move16();
    2393             :             }
    2394             :         }
    2395             :     }
    2396             : 
    2397             :     p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx;
    2398             :     p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
    2399             : 
    2400             :     FOR( k = 0; k < num_protos_dir; k++ )
    2401             :     {
    2402             :         FOR( l = 0; l < num_freq_bands; l++ )
    2403             :         {
    2404             :             *p_power_smooth = L_shr( *p_power_smooth, sub( min_exp, exp_arr[k * num_freq_bands + l] ) ); /*(31-(exp-(31-q_proto_power_smooth)))->(31-(min_exp-(31-q_proto_power_smooth)))*/
    2405             :             move32();
    2406             :             p_power_smooth++;
    2407             :             q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_q ) );
    2408             :         }
    2409             :     }
    2410             : 
    2411             :     // Update the Q-factor
    2412             :     h_dirac_output_synthesis_state->proto_power_smooth_prev_q = h_dirac_output_synthesis_state->proto_power_smooth_q;
    2413             :     move16();
    2414             :     h_dirac_output_synthesis_state->proto_power_smooth_q = q_tmp;
    2415             :     move16();
    2416             : #endif
    2417             : 
    2418             :     /*Direct gains and diffuse gains on number of output channels*/
    2419       95963 :     p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx;
    2420       95963 :     p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth_fx;
    2421             : 
    2422       95963 :     p_gains_diff = gains_diff;
    2423       95963 :     p_gains_dir = gains_dir;
    2424             : 
    2425       95963 :     p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx;
    2426       95963 :     p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx;
    2427      782400 :     FOR( k = 0; k < nchan_out_woLFE; k++ )
    2428             :     {
    2429      686437 :         q_cy_auto_dir_smooth_prev_local[k] = getScaleFactor32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands );
    2430      686437 :         move16();
    2431      686437 :         scale_sig32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands, q_cy_auto_dir_smooth_prev_local[k] ); /*q_cy_auto_dir_smooth_prev_local[k]+h_dirac_output_synthesis_state -> q_cy_auto_dir_smooth_prev*/
    2432      686437 :         q_cy_auto_dir_smooth_prev_local[k] = add( q_cy_auto_dir_smooth_prev_local[k], h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev );
    2433      686437 :         move16();
    2434      686437 :         q_com = s_min( q_cy_auto_dir_smooth_local[k], q_cy_auto_dir_smooth_prev_local[k] );
    2435      686437 :         scale_sig32( p_cy_auto_dir_smooth + imult1616( k, num_freq_bands ), num_freq_bands, sub( q_com, q_cy_auto_dir_smooth_local[k] ) );           /*q_cy_auto_dir_smooth_local -> q_com*/
    2436      686437 :         scale_sig32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands, sub( q_com, q_cy_auto_dir_smooth_prev_local[k] ) ); /*q_cy_auto_dir_smooth_prev_local -> q_com*/
    2437      686437 :         q_cy_auto_dir_smooth_local[k] = q_cy_auto_dir_smooth_prev_local[k] = q_com;
    2438      686437 :         move16();
    2439      686437 :         move16();
    2440             :     }
    2441             : 
    2442             : 
    2443       95963 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx;
    2444       95963 :     p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx;
    2445       95963 :     q_com = s_min( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev );
    2446       95963 :     scale_sig32( p_cy_cross_dir_smooth, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) );           /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth -> q_com*/
    2447       95963 :     scale_sig32( p_cy_cross_dir_smooth_prev, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev -> q_com*/
    2448       95963 :     h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = q_com;
    2449       95963 :     move16();
    2450       95963 :     move16();
    2451             : 
    2452       95963 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx;
    2453       95963 :     p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx;
    2454       95963 :     q_com = s_min( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev );
    2455       95963 :     scale_sig32( p_cy_auto_diff_smooth, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) );           /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth -> q_com*/
    2456       95963 :     scale_sig32( p_cy_auto_diff_smooth_prev, imult1616( nchan_out_woLFE, num_freq_bands ), sub( q_com, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ) ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev -> q_com*/
    2457       95963 :     h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = q_com;
    2458       95963 :     move16();
    2459       95963 :     move16();
    2460             : 
    2461      782400 :     FOR( k = 0; k < nchan_out_woLFE; k++ )
    2462             :     {
    2463             :         Word32 power_smooth_temp;
    2464             : #ifdef FIX_867_CLDFB_NRG_SCALE
    2465             :         Word16 qidx;
    2466             : #endif
    2467      686437 :         p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx + i_mult( proto_direct_index[k], num_freq_bands ); // q_proto_power_smooth
    2468     8171782 :         FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    2469             :         {
    2470             :             /*Direct*/
    2471     7485345 :             g1 = alpha[l]; // Q31
    2472     7485345 :             move32();
    2473     7485345 :             g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
    2474     7485345 :             assert( q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k] );
    2475     7485345 :             *( p_cy_auto_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
    2476             :                                                     Mpy_32_32( g2, ( *( p_cy_auto_dir_smooth_prev ) ) ) ); // (Q31, q_cy_auto_dir_smooth_prev_local) -> q_cy_auto_dir_smooth_prev_local
    2477     7485345 :             move32();
    2478     7485345 :             assert( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev );
    2479     7485345 :             *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ),
    2480             :                                                      Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
    2481     7485345 :             move32();
    2482             : 
    2483     7485345 :             power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );      // proto_power_smooth_q + norm_l( *p_power_smooth )
    2484     7485345 :             L_tmp = Mpy_32_32( power_smooth_temp, ( *( p_cy_auto_dir_smooth_prev++ ) ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31
    2485             : #ifdef FIX_867_CLDFB_NRG_SCALE
    2486     7485345 :             qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    2487     7485345 :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
    2488     7485345 :                                       q_cy_auto_dir_smooth_prev_local[k] ),
    2489             :                                  Q31 ) );
    2490             : 
    2491             : #else
    2492             :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ),
    2493             :                                       q_cy_auto_dir_smooth_prev_local[k] ),
    2494             :                                  Q31 ) );
    2495             : #endif
    2496     7485345 :             p_power_smooth++;
    2497             : 
    2498     7485345 :             *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
    2499     7485345 :             move32();
    2500     7485345 :             *( p_gains_dir ) = L_shl_sat( *( p_gains_dir ), sub( h_dirac_output_synthesis_state->gains_dir_prev_q, sub( Q31, exp ) ) ); // gains_dir_prev_q
    2501     7485345 :             move32();
    2502             : 
    2503     7485345 :             IF( *( p_gains_dir ) < 0 )
    2504             :             {
    2505           0 :                 *( p_gains_dir ) = 0;
    2506           0 :                 move32();
    2507             :             }
    2508     7485345 :             ELSE IF( GT_32( *( p_gains_dir ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ) ) )
    2509             :             {
    2510       18332 :                 *( p_gains_dir ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ); /*26 + h_dirac_output_synthesis_state->gains_dir_prev_q + 1 + 5 - 32 -> h_dirac_output_synthesis_state->gains_dir_prev_q*/
    2511       18332 :                 move32();
    2512             :             }
    2513             : 
    2514     7485345 :             IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    2515             :             {
    2516      884551 :                 *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*h_dirac_output_synthesis_state->gains_dir_prev_q*/
    2517      884551 :                 move32();
    2518             :             }
    2519     7485345 :             p_gains_dir++;
    2520             : 
    2521             :             /*diffuse*/
    2522     7485345 :             *p_power_diff_smooth_prev = L_add( L_add( Mpy_32_32( g1, ( *( p_power_smooth_diff++ ) ) ),
    2523             :                                                       Mpy_32_32( g2, ( *( p_power_diff_smooth_prev ) ) ) ),
    2524             :                                                EPSILLON_FX ); // (Q31, q_power_diff_smooth_prev) -> q_power_diff_smooth_prev
    2525     7485345 :             move32();
    2526     7485345 :             *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth++ ) ) ),
    2527             :                                                      Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
    2528     7485345 :             move32();
    2529             : 
    2530     7485345 :             exp = 0;
    2531     7485345 :             move16();
    2532     7485345 :             L_tmp = BASOP_Util_Divide3232_Scale_newton( *( p_cy_auto_diff_smooth_prev++ ), ( *( p_power_diff_smooth_prev++ ) ), &exp ); // (Q31 - exp) + (q_a - q_b)
    2533     7485345 :             exp = sub( Q31, add( sub( Q31, exp ), sub( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state->proto_power_diff_smooth_q ) ) );
    2534             : 
    2535     7485345 :             *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); // (31 - exp)
    2536     7485345 :             move32();
    2537     7485345 :             *( p_gains_diff ) = L_shl_sat( *( p_gains_diff ), sub( h_dirac_output_synthesis_state->gains_diff_prev_q, sub( Q31, exp ) ) ); // gains_diff_prev_q
    2538     7485345 :             move32();
    2539             : 
    2540     7485345 :             IF( *( p_gains_diff ) < 0 )
    2541             :             {
    2542           0 :                 *( p_gains_diff ) = 0;
    2543           0 :                 move32();
    2544             :             }
    2545     7485345 :             ELSE IF( GT_32( *( p_gains_diff ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ) ) ) /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
    2546             :             {
    2547      144111 :                 *( p_gains_diff ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ); /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
    2548      144111 :                 move32();
    2549             :             }
    2550     7485345 :             p_gains_diff++;
    2551             :         }
    2552             : 
    2553             :         /*Only direct prototype*/
    2554    33115672 :         FOR( ; l < num_freq_bands; l++ )
    2555             :         {
    2556             :             /*Direct*/
    2557    32429235 :             g1 = alpha[l]; // Q31
    2558    32429235 :             move32();
    2559    32429235 :             g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
    2560    32429235 :             W_temp = W_add( W_mult_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
    2561             :                             W_mult_32_32( g2, ( *( p_cy_auto_dir_smooth_prev ) ) ) ); /*32+q_cy_auto_dir_smooth_prev_local*/
    2562    32429235 :             q_tmp = W_norm( W_temp );
    2563    32429235 :             L_tmp = W_extract_h( W_shl( W_temp, q_tmp ) );              // q_cy_auto_dir_smooth_prev_local + q_tmp
    2564    32429235 :             *( p_cy_auto_dir_smooth_prev++ ) = L_shr_r( L_tmp, q_tmp ); // q_cy_auto_dir_smooth_prev_local
    2565             : 
    2566    32429235 :             move32();
    2567    32429235 :             *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth ) ) ),
    2568             :                                                      Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
    2569    32429235 :             move32();
    2570    32429235 :             test();
    2571    32429235 :             if ( *( p_cy_cross_dir_smooth_prev ) == 0 && ( *( p_cy_cross_dir_smooth ) != 0 ) )
    2572             :             {
    2573      812890 :                 *( p_cy_cross_dir_smooth_prev ) = 1;
    2574      812890 :                 move32();
    2575             :             }
    2576    32429235 :             ( p_cy_cross_dir_smooth++ );
    2577    32429235 :             power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );
    2578    32429235 :             L_tmp = Mpy_32_32( power_smooth_temp, L_tmp ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_dir_smooth_prev_local - 31
    2579             : #ifdef FIX_867_CLDFB_NRG_SCALE
    2580    32429235 :             qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    2581    32429235 :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
    2582    32429235 :                                       add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ),
    2583             :                                  Q31 ) );
    2584             : #else
    2585             :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ),
    2586             :                                       add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ),
    2587             :                                  Q31 ) );
    2588             : #endif
    2589             : 
    2590    32429235 :             *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
    2591    32429235 :             move32();
    2592    32429235 :             *( p_gains_dir ) = L_shl_sat( *( p_gains_dir ), sub( h_dirac_output_synthesis_state->gains_dir_prev_q, sub( Q31, exp ) ) ); // gains_dir_prev_q
    2593    32429235 :             move32();
    2594             : 
    2595    32429235 :             IF( *( p_gains_dir ) < 0 )
    2596             :             {
    2597           0 :                 *( p_gains_dir ) = 0;
    2598           0 :                 move32();
    2599             :             }
    2600    32429235 :             ELSE IF( GT_32( *( p_gains_dir ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ) ) ) /*gains_dir_prev_q*/
    2601             :             {
    2602       24927 :                 *( p_gains_dir ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_dir_prev_q ) ), Q5 ) ); /*gains_dir_prev_q*/
    2603       24927 :                 move32();
    2604             :             }
    2605             : 
    2606    32429235 :             IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    2607             :             {
    2608     2838346 :                 *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*gains_dir_prev_q*/
    2609     2838346 :                 move32();
    2610             :             }
    2611    32429235 :             p_gains_dir++;
    2612             : 
    2613             :             /*diffuse*/
    2614    32429235 :             *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth ) ) ),
    2615             :                                                      Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
    2616             : 
    2617    32429235 :             test();
    2618    32429235 :             if ( *( p_cy_auto_diff_smooth_prev ) == 0 && ( *( p_cy_auto_diff_smooth ) != 0 ) )
    2619             :             {
    2620     1918152 :                 *( p_cy_auto_diff_smooth_prev ) = 1;
    2621     1918152 :                 move32();
    2622             :             }
    2623    32429235 :             ( p_cy_auto_diff_smooth++ );
    2624    32429235 :             move32();
    2625             : 
    2626    32429235 :             power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );     // proto_power_smooth_q + norm_l( *p_power_smooth )
    2627    32429235 :             L_tmp = Mpy_32_32( power_smooth_temp, ( *( p_cy_auto_diff_smooth_prev ) ) ); // proto_power_smooth_q + norm_l( *p_power_smooth ) ) + q_cy_auto_diff_smooth_prev - 31
    2628             : 
    2629    32429235 :             test();
    2630    32429235 :             test();
    2631    32429235 :             if ( L_tmp == 0 && ( power_smooth_temp != 0 && *( p_cy_auto_diff_smooth_prev ) != 0 ) )
    2632             :             {
    2633     2382876 :                 L_tmp = 1;
    2634     2382876 :                 move32();
    2635             :             }
    2636    32429235 :             ( p_cy_auto_diff_smooth_prev++ );
    2637             : #ifdef FIX_867_CLDFB_NRG_SCALE
    2638    32429235 :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
    2639    32429235 :                                       h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ),
    2640             :                                  Q31 ) );
    2641             : #else
    2642             :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q, norm_l( *p_power_smooth ) ),
    2643             :                                       h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ),
    2644             :                                  Q31 ) );
    2645             : #endif
    2646    32429235 :             p_power_smooth++;
    2647             : 
    2648    32429235 :             *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); /*31-exp*/
    2649    32429235 :             move32();
    2650    32429235 :             *( p_gains_diff ) = L_shl_sat( *( p_gains_diff ), sub( h_dirac_output_synthesis_state->gains_diff_prev_q, sub( Q31, exp ) ) ); // gains_diff_prev_q
    2651    32429235 :             move32();
    2652             : 
    2653    32429235 :             IF( *( p_gains_diff ) < 0 )
    2654             :             {
    2655           0 :                 *( p_gains_diff ) = 0;
    2656           0 :                 move32();
    2657             :             }
    2658    32429235 :             ELSE IF( GT_32( *( p_gains_diff ), W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ) ) ) // gains_diff_prev_q
    2659             :             {
    2660       17063 :                 *( p_gains_diff ) = W_extract_h( W_shl( W_mult_32_32( DIRAC_GAIN_LIMIT_Q26, L_shl( 1, h_dirac_output_synthesis_state->gains_diff_prev_q ) ), Q5 ) ); // gains_diff_prev_q
    2661       17063 :                 move32();
    2662             :             }
    2663    32429235 :             p_gains_diff++;
    2664             :         }
    2665             :     }
    2666             : 
    2667             :     /*-----------------------------------------------------------------*
    2668             :      * gain interpolation and output streams
    2669             :      *-----------------------------------------------------------------*/
    2670       95963 :     Word16 q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_power_diff_smooth_q );
    2671       95963 :     if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
    2672             :     {
    2673       68549 :         q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q );
    2674             :     }
    2675             : 
    2676      476792 :     FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    2677             :     {
    2678      380829 :         g1 = L_deposit_h( h_dirac_output_synthesis_params->interpolator_fx[buf_idx] ); // Q15 -> Q31
    2679      380829 :         g2 = L_sub( ONE_IN_Q31, g1 );                                                  // Q31
    2680             : 
    2681             :         /*Direct stream*/
    2682      380829 :         p_gain_1 = gains_dir;
    2683      380829 :         p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev_fx; // gains_dir_prev_q
    2684     3122762 :         FOR( k = 0; k < nchan_out_woLFE; k++ )
    2685             :         {
    2686     5483866 :             p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
    2687     2741933 :                              shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    2688     2741933 :                              shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 );
    2689   162229173 :             FOR( l = 0; l < num_freq_bands; l++ )
    2690             :             {
    2691   159487240 :                 g = L_add( Mpy_32_32( g1, *( p_gain_1++ ) ), Mpy_32_32( g2, *( p_gain_2++ ) ) ); // (Q31, gains_dir_prev_q) -> gains_dir_prev_q
    2692             : 
    2693   159487240 :                 Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ); // (gains_dir_prev_q, q_proto_direct_buffer) -> gains_dir_prev_q + q_proto_direct_buffer
    2694   159487240 :                 move64();
    2695             : 
    2696   159487240 :                 Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ); // (gains_dir_prev_q, q_proto_direct_buffer) -> gains_dir_prev_q + q_proto_direct_buffer
    2697   159487240 :                 move64();
    2698             :             }
    2699             :         }
    2700             : 
    2701             :         /*Diffuse stream*/
    2702      380829 :         IF( h_dirac_output_synthesis_params->max_band_decorr != 0 )
    2703             :         {
    2704      548128 :             p_power_smooth_diff = h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx +
    2705      274064 :                                   shl( i_mult( buf_idx, i_mult( h_dirac_output_synthesis_params->max_band_decorr, nchan_out_woLFE ) ), Q1 );
    2706             :         }
    2707      380829 :         p_gain_1 = gains_diff;
    2708      380829 :         p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev_fx; // gains_diff_prev_q
    2709     3122762 :         FOR( k = 0; k < nchan_out_woLFE; k++ )
    2710             :         {
    2711    32669453 :             FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    2712             :             {
    2713    29927520 :                 g = L_add( Mpy_32_32( g1, *( p_gain_1++ ) ), Mpy_32_32( g2, *( p_gain_2++ ) ) ); // (Q31, gains_diff_prev_q) -> gains_diff_prev_q
    2714    29927520 :                 Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
    2715    29927520 :                                                               W_shr( W_mult0_32_32( g, ( *( p_power_smooth_diff++ ) ) ), negate( q_align ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
    2716    29927520 :                 move64();
    2717             : 
    2718    29927520 :                 if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
    2719             :                 {
    2720      208132 :                     W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
    2721             :                 }
    2722             : 
    2723    29927520 :                 Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
    2724    29927520 :                                                               W_shr( W_mult0_32_32( g, ( *( p_power_smooth_diff++ ) ) ), negate( q_align ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
    2725    29927520 :                 move64();
    2726             : 
    2727    29927520 :                 if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
    2728             :                 {
    2729      116796 :                     W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] );
    2730             :                 }
    2731             :             }
    2732             : 
    2733             :             /*Direct proto*/
    2734     5483866 :             p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
    2735     2741933 :                              shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    2736     2741933 :                              shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 ) +
    2737     2741933 :                              shl( h_dirac_output_synthesis_params->max_band_decorr, Q1 );
    2738   132301653 :             FOR( ; l < num_freq_bands; l++ )
    2739             :             {
    2740   129559720 :                 g = L_add( Mpy_32_32( g1, *( p_gain_1++ ) ), Mpy_32_32( g2, *( p_gain_2++ ) ) ); // (Q31, gains_diff_prev_q) -> gains_diff_prev_q
    2741   129559720 :                 Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
    2742   129559720 :                                                               W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
    2743   129559720 :                 move64();
    2744             : 
    2745   129559720 :                 if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
    2746             :                 {
    2747       85621 :                     W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
    2748             :                 }
    2749             : 
    2750   129559720 :                 Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
    2751   129559720 :                                                               W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
    2752   129559720 :                 move64();
    2753             : 
    2754   129559720 :                 if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
    2755             :                 {
    2756       49668 :                     W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ); // gains_diff_prev_q + q_proto_direct_buffer
    2757             :                 }
    2758             :             }
    2759             :         }
    2760             :     }
    2761       95963 :     q_align = W_norm( W_temp );
    2762      476792 :     FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    2763             :     {
    2764     3122762 :         FOR( k = 0; k < nchan_out_woLFE; k++ )
    2765             :         {
    2766   162229173 :             FOR( l = 0; l < num_freq_bands; l++ )
    2767             :             {
    2768   159487240 :                 RealBuffer[k][buf_idx][l] = W_extract_h( W_shl( Cldfb_RealBuffer64_fx[k][buf_idx][l], q_align ) ); /*( ( ( h_dirac_output_synthesis_state->proto_direct_buffer_f_q+h_dirac_output_synthesis_state->gains_dir_prev_q )+ q_align )- 32 )*/
    2769   159487240 :                 move32();
    2770   159487240 :                 ImagBuffer[k][buf_idx][l] = W_extract_h( W_shl( Cldfb_ImagBuffer64_fx[k][buf_idx][l], q_align ) ); /*( ( ( h_dirac_output_synthesis_state->proto_direct_buffer_f_q+h_dirac_output_synthesis_state->gains_dir_prev_q )+ q_align )- 32 )*/
    2771   159487240 :                 move32();
    2772             :             }
    2773             :         }
    2774             :     }
    2775             : 
    2776       95963 :     *q_Cldfb = sub( add( add( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->gains_dir_prev_q ), q_align ), 32 );
    2777       95963 :     move16();
    2778             : 
    2779             :     /*-----------------------------------------------------------------*
    2780             :      * update buffers
    2781             :      *-----------------------------------------------------------------*/
    2782             : 
    2783             :     /* store estimates for next synthesis block */
    2784       95963 :     Copy32( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );   /*gains_dir_prev_q*/
    2785       95963 :     Copy32( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) ); /*gains_diff_prev_q*/
    2786             : 
    2787             :     /* reset values */
    2788       95963 :     set_zero_fx( h_dirac_output_synthesis_state->proto_power_smooth_fx, imult1616( num_freq_bands, num_protos_dir ) );
    2789       95963 :     IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx != NULL )
    2790             :     {
    2791       95963 :         set_zero_fx( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
    2792             :     }
    2793             : 
    2794       95963 :     minimum_fx( q_cy_auto_dir_smooth_prev_local, nchan_out_woLFE, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev );
    2795      782400 :     FOR( k = 0; k < nchan_out_woLFE; k++ )
    2796             :     {
    2797      686437 :         scale_sig32( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx + ( k * num_freq_bands ), num_freq_bands, sub( h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev, q_cy_auto_dir_smooth_prev_local[k] ) ); /*q_cy_auto_dir_smooth_prev_local[k] -> h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev*/
    2798             :     }
    2799             : 
    2800       95963 :     set_zero_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
    2801       95963 :     h_dirac_output_synthesis_state->q_cy_auto_dir_smooth = 0;
    2802       95963 :     move16();
    2803       95963 :     set_zero_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
    2804       95963 :     h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = 0;
    2805       95963 :     move16();
    2806       95963 :     set_zero_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
    2807       95963 :     h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = 0;
    2808       95963 :     move16();
    2809             : 
    2810       95963 :     pop_wmops();
    2811             : 
    2812       95963 :     return;
    2813             : }
    2814             : 
    2815             : 
    2816             : /*-------------------------------------------------------------------------
    2817             :  * ivas_dirac_dec_get_response_split_order()
    2818             :  *
    2819             :  * calculate reponse, 1 degree resolution
    2820             :  *------------------------------------------------------------------------*/
    2821             : 
    2822      144000 : static void ivas_dirac_dec_get_response_split_order_fx(
    2823             :     const Word16 azimuth,   /*q0*/
    2824             :     const Word16 elevation, /*q0*/
    2825             :     Word32 *response,       /*q_response*/
    2826             :     const Word16 shd_rot_max_order,
    2827             :     const Word32 *p_Rmat /* Q30 */,
    2828             :     Word16 *q_response )
    2829             : {
    2830             :     Word16 index_azimuth, index_elevation;
    2831             :     Word16 el, e, az;
    2832             :     Word32 cos_1, cos_2, sin_1, cos_az[3];
    2833             :     Word32 sin_az[3];
    2834             :     Word32 f, c;
    2835             :     Word16 l, m;
    2836             :     Word16 b, b1, b_2, b1_2, a;
    2837             :     Word32 dv_0, dv_1, dv_2, dv_r_0, dv_r_1, dv_r_2;
    2838             :     Word32 w;
    2839             :     Word16 tmp;
    2840             :     Word32 temp;
    2841             :     Word16 exp;
    2842             : 
    2843      144000 :     push_wmops( "ivas_dirac_dec_get_response_split_order" );
    2844             : 
    2845             :     /* Corner case for handling crash in idiv1616 when numerator is 0 */
    2846      144000 :     IF( EQ_16( azimuth, -180 ) )
    2847             :     {
    2848           0 :         tmp = 0;
    2849           0 :         move16();
    2850             :     }
    2851             :     ELSE
    2852             :     {
    2853      144000 :         tmp = idiv1616( add( azimuth, 180 ), 360 );
    2854             :     }
    2855      144000 :     index_azimuth = sub( add( azimuth, 180 ), i_mult( tmp, 360 ) ); // index_azimuth = (azimuth + 180) % 360
    2856      144000 :     index_elevation = add( elevation, 90 );
    2857             : 
    2858      144000 :     IF( GT_16( index_elevation, 90 ) )
    2859             :     {
    2860       22893 :         e = -ONE_IN_Q14; /*-1 in Q14*/
    2861       22893 :         move16();
    2862       22893 :         el = sub( 180, index_elevation );
    2863             :     }
    2864             :     ELSE
    2865             :     {
    2866      121107 :         e = ONE_IN_Q14; /*1 in Q14*/
    2867      121107 :         move16();
    2868      121107 :         el = index_elevation;
    2869      121107 :         move16();
    2870             :     }
    2871             : 
    2872      144000 :     IF( GT_16( index_azimuth, 180 ) )
    2873             :     {
    2874       57389 :         az = sub( 360, index_azimuth );
    2875       57389 :         f = -ONE_IN_Q30; /*-1 Q30*/
    2876       57389 :         move32();
    2877             :     }
    2878             :     ELSE
    2879             :     {
    2880       86611 :         az = index_azimuth;
    2881       86611 :         move16();
    2882       86611 :         f = ONE_IN_Q30; /*1 Q30*/
    2883       86611 :         move32();
    2884             :     }
    2885             : 
    2886             :     // dirac_gains_trg_term_int Q30
    2887      144000 :     cos_1 = L_shr( dirac_gains_trg_term_int[az][0], 1 );     // Q29
    2888      144000 :     cos_2 = L_shl( Mpy_32_32( cos_1, cos_1 ), 2 );           // Q29
    2889      144000 :     sin_1 = Mpy_32_32( f, dirac_gains_trg_term_int[az][1] ); // Q29
    2890             : 
    2891      144000 :     cos_az[0] = cos_1; // Q29
    2892      144000 :     move32();
    2893      144000 :     cos_az[1] = L_shl( L_sub( Mpy_32_32( TWO_IN_Q29, cos_2 ), ONE_IN_Q27 ), 2 ); // Q29
    2894      144000 :     move32();
    2895      144000 :     cos_az[2] = L_sub( L_shl( Mpy_32_32( Mpy_32_32( TWO_IN_Q29, cos_1 ), cos_az[1] ), 4 ), cos_az[0] ); // Q29
    2896      144000 :     move32();
    2897             : 
    2898      144000 :     sin_az[0] = sin_1; // Q29
    2899      144000 :     move32();
    2900      144000 :     sin_az[1] = L_shl( Mpy_32_32( Mpy_32_32( sin_1, TWO_IN_Q29 ), cos_1 ), 4 ); // Q29
    2901      144000 :     move32();
    2902      144000 :     sin_az[2] = L_shl( Mpy_32_32( sin_1, L_sub( Mpy_32_32( FOUR_IN_Q28, cos_2 ), ONE_IN_Q26 ) ), 5 ); // Q29
    2903      144000 :     move32();
    2904             : 
    2905      144000 :     response[0] = ONE_IN_Q29;
    2906      144000 :     move32();
    2907             : 
    2908      480000 :     FOR( l = 1; l <= shd_rot_max_order; l++ )
    2909             :     {
    2910      336000 :         b_2 = i_mult( l, l );
    2911      336000 :         b1_2 = add( b_2, i_mult( 2, l ) );
    2912      720000 :         FOR( m = 0; m < l; m += 2 )
    2913             :         {
    2914      384000 :             b = add( b_2, m );
    2915      384000 :             a = dirac_gains_P_idx[b];
    2916      384000 :             move16();
    2917             : 
    2918      384000 :             c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
    2919             : 
    2920      384000 :             response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 6 ); // Q29
    2921      384000 :             move32();
    2922             : 
    2923      384000 :             b1 = sub( b1_2, m );
    2924      384000 :             response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 6 ); // Q29
    2925      384000 :             move32();
    2926             :         }
    2927             : 
    2928      528000 :         FOR( m = 1; m < l; m += 2 )
    2929             :         {
    2930      192000 :             b = add( b_2, m );
    2931      192000 :             a = dirac_gains_P_idx[b];
    2932      192000 :             move16();
    2933             : 
    2934      192000 :             c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
    2935      192000 :             c = Mpy_32_16_1( c, e );                                                                             // Q24
    2936             : 
    2937      192000 :             response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 7 ); // Q29
    2938      192000 :             move32();
    2939             : 
    2940      192000 :             b1 = sub( b1_2, m );
    2941      192000 :             response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 7 ); // Q29
    2942      192000 :             move32();
    2943             :         }
    2944             : 
    2945      336000 :         b = add( b_2, l );
    2946      336000 :         a = dirac_gains_P_idx[b];
    2947      336000 :         move16();
    2948             : 
    2949      336000 :         c = L_shl( Mpy_32_32( dirac_gains_norm_term_int[a], dirac_gains_Pnm_int[el][a] ), 3 ); // Q29
    2950      336000 :         IF( EQ_16( l % 2, 1 ) )
    2951             :         {
    2952      192000 :             c = L_shl( Mpy_32_16_1( c, e ), 1 ); // Q29
    2953             :         }
    2954             : 
    2955      336000 :         response[b] = c; // Q29
    2956      336000 :         move32();
    2957             :     }
    2958             : 
    2959             :     /*Conversion spherical to cartesian coordinates*/
    2960      144000 :     w = L_negate( dirac_gains_trg_term_int[el][1] );                      // Q30
    2961      144000 :     dv_0 = Mpy_32_32( w, cos_1 );                                         // Q28
    2962      144000 :     dv_1 = Mpy_32_32( w, sin_1 );                                         // Q28
    2963      144000 :     dv_2 = L_shr( Mpy_32_16_1( dirac_gains_trg_term_int[el][0], e ), 1 ); // Q28
    2964             : 
    2965             :     /*Rotation mtx multiplication*/
    2966      144000 :     dv_r_0 = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat[0], Q1 ), dv_0 ), L_shr( p_Rmat[1], Q1 ), dv_1 ), L_shr( p_Rmat[2], Q1 ), dv_2 ); // Q26
    2967      144000 :     dv_r_1 = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat[3], Q1 ), dv_0 ), L_shr( p_Rmat[4], Q1 ), dv_1 ), L_shr( p_Rmat[5], Q1 ), dv_2 ); // Q26
    2968      144000 :     dv_r_2 = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat[6], Q1 ), dv_0 ), L_shr( p_Rmat[7], Q1 ), dv_1 ), L_shr( p_Rmat[8], Q1 ), dv_2 ); // Q26
    2969             : 
    2970      144000 :     tmp = BASOP_util_atan2( dv_r_1, dv_r_0, 0 );            // Q13
    2971      144000 :     index_azimuth = shr( mult( tmp, _180_OVER_PI_Q9 ), 7 ); // Q0;
    2972      144000 :     IF( EQ_16( index_azimuth, -180 ) )
    2973             :     {
    2974        6462 :         tmp = 0;
    2975        6462 :         move16();
    2976             :     }
    2977             :     ELSE
    2978             :     {
    2979      137538 :         tmp = idiv1616( add( index_azimuth, 180 ), 360 );
    2980             :     }
    2981      144000 :     index_azimuth = sub( add( index_azimuth, 180 ), i_mult( tmp, 360 ) ); // index_azimuth = (index_azimuth + 180) % 360
    2982             : 
    2983      144000 :     temp = L_add( Mpy_32_32( dv_r_0, dv_r_0 ), Mpy_32_32( dv_r_1, dv_r_1 ) ); // Q21
    2984      144000 :     exp = sub( 31, Q21 );
    2985      144000 :     temp = Sqrt32( temp, &exp );
    2986             : 
    2987      144000 :     tmp = BASOP_util_atan2( dv_r_2, temp, sub( sub( 31, Q26 ), exp ) ); // Q13
    2988      144000 :     index_elevation = shr( mult( tmp, _180_OVER_PI_Q9 ), Q7 );          // Q0
    2989      144000 :     index_elevation = add( index_elevation, 90 );
    2990             : 
    2991      144000 :     IF( GT_16( index_elevation, 90 ) )
    2992             :     {
    2993       22893 :         e = -ONE_IN_Q14; /*-1 Q14*/
    2994       22893 :         move16();
    2995       22893 :         el = sub( 180, index_elevation );
    2996             :     }
    2997             :     ELSE
    2998             :     {
    2999      121107 :         e = ONE_IN_Q14; /*1 Q14*/
    3000      121107 :         move16();
    3001      121107 :         el = index_elevation;
    3002      121107 :         move16();
    3003             :     }
    3004             : 
    3005      144000 :     IF( GT_16( index_azimuth, 180 ) )
    3006             :     {
    3007      110941 :         az = sub( 360, index_azimuth );
    3008      110941 :         f = -ONE_IN_Q30; /*-1 Q30*/
    3009      110941 :         move32();
    3010             :     }
    3011             :     ELSE
    3012             :     {
    3013       33059 :         az = index_azimuth;
    3014       33059 :         move16();
    3015       33059 :         f = ONE_IN_Q30; /*1 Q30*/
    3016       33059 :         move32();
    3017             :     }
    3018             : 
    3019             :     // dirac_gains_trg_term_int Q30
    3020      144000 :     cos_1 = L_shr( dirac_gains_trg_term_int[az][0], 1 );     // Q29
    3021      144000 :     cos_2 = L_shl( Mpy_32_32( cos_1, cos_1 ), 2 );           // Q29
    3022      144000 :     sin_1 = Mpy_32_32( f, dirac_gains_trg_term_int[az][1] ); // Q29
    3023             : 
    3024      144000 :     cos_az[0] = cos_1; // Q29
    3025      144000 :     move32();
    3026      144000 :     cos_az[1] = L_shl( L_sub( Mpy_32_32( TWO_IN_Q29, cos_2 ), ONE_IN_Q27 ), 2 ); // Q29
    3027      144000 :     move32();
    3028      144000 :     cos_az[2] = L_sub( L_shl( Mpy_32_32( Mpy_32_32( TWO_IN_Q29, cos_1 ), cos_az[1] ), 4 ), cos_az[0] ); // Q29
    3029      144000 :     move32();
    3030             : 
    3031      144000 :     sin_az[0] = sin_1; // Q29
    3032      144000 :     move32();
    3033      144000 :     sin_az[1] = L_shl( Mpy_32_32( Mpy_32_32( sin_1, TWO_IN_Q29 ), cos_1 ), 4 ); // Q29
    3034      144000 :     move32();
    3035      144000 :     sin_az[2] = L_shl( Mpy_32_32( sin_1, L_sub( Mpy_32_32( FOUR_IN_Q28, cos_2 ), ONE_IN_Q26 ) ), 5 ); // Q29
    3036      144000 :     move32();
    3037             : 
    3038      240000 :     FOR( l = shd_rot_max_order + 1; l <= 3; l++ )
    3039             :     {
    3040       96000 :         b_2 = i_mult( l, l );
    3041       96000 :         b1_2 = add( b_2, i_mult( 2, l ) );
    3042             : 
    3043      288000 :         FOR( m = 0; m < l; m += 2 )
    3044             :         {
    3045      192000 :             b = add( b_2, m );
    3046      192000 :             a = dirac_gains_P_idx[b];
    3047      192000 :             move16();
    3048             : 
    3049      192000 :             c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
    3050             : 
    3051      192000 :             response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 6 ); // Q29
    3052      192000 :             move32();
    3053             : 
    3054      192000 :             b1 = sub( b1_2, m );
    3055      192000 :             response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 6 ); // Q29
    3056      192000 :             move32();
    3057             :         }
    3058             : 
    3059      192000 :         FOR( m = 1; m < l; m += 2 )
    3060             :         {
    3061       96000 :             b = add( b_2, m );
    3062       96000 :             a = dirac_gains_P_idx[b];
    3063       96000 :             move16();
    3064             : 
    3065       96000 :             c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25
    3066       96000 :             c = Mpy_32_16_1( c, e );                                                                             // Q24
    3067             : 
    3068       96000 :             response[b] = L_shl( Mpy_32_32( c, sin_az[l - m - 1] ), 7 ); // Q29
    3069       96000 :             move32();
    3070             : 
    3071       96000 :             b1 = sub( b1_2, m );
    3072       96000 :             response[b1] = L_shl( Mpy_32_32( c, cos_az[l - m - 1] ), 7 ); // Q29
    3073       96000 :             move32();
    3074             :         }
    3075             : 
    3076       96000 :         b = add( b_2, l );
    3077       96000 :         a = dirac_gains_P_idx[b];
    3078       96000 :         move16();
    3079             : 
    3080       96000 :         c = L_shl( Mpy_32_32( dirac_gains_norm_term_int[a], dirac_gains_Pnm_int[el][a] ), 3 ); // Q29
    3081             : 
    3082       96000 :         IF( EQ_16( l % 2, 1 ) )
    3083             :         {
    3084       96000 :             c = L_shl( Mpy_32_16_1( c, e ), 1 ); // Q29
    3085             :         }
    3086             : 
    3087       96000 :         response[b] = c; // Q29
    3088       96000 :         move32();
    3089             :     }
    3090             : 
    3091      144000 :     *q_response = Q29;
    3092      144000 :     move16();
    3093             : 
    3094      144000 :     pop_wmops();
    3095             : 
    3096      144000 :     return;
    3097             : }
    3098             : 
    3099             : /*-------------------------------------------------------------------------
    3100             :  * ivas_dirac_dec_compute_directional_responses()
    3101             :  *
    3102             :  *
    3103             :  *------------------------------------------------------------------------*/
    3104             : 
    3105     1050811 : void ivas_dirac_dec_compute_directional_responses_fx(
    3106             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle                            */
    3107             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                                          */
    3108             :     const VBAP_HANDLE hVBAPdata,                          /* i  : VBAP structure                                                 */
    3109             :     const Word16 *masa_band_mapping,                      /* i  : Band mapping for MASA, NULL assumes not using MASA in any form */
    3110             :     MASA_ISM_DATA_HANDLE hMasaIsm,                        /* i  : MASA_ISM data structure                                        */
    3111             :     const Word16 *azimuth,
    3112             :     const Word16 *elevation,
    3113             :     const Word16 md_idx,
    3114             :     const Word32 *surCohRatio_fx, /*i:Q_surCohRatio*/
    3115             :     Word16 Q_surCohRatio,
    3116             :     const Word16 shd_rot_max_order, /* i  : split-order rotation method    */
    3117             :     const Word32 *p_Rmat,           /* i  : rotation matrix             Q30*/
    3118             :     const Word16 hodirac_flag       /* i  : flag to indicate HO-DirAC mode */
    3119             : )
    3120             : {
    3121             :     Word16 k, l, i;
    3122             :     Word16 num_channels_dir;
    3123             :     const Word16 *azimuth2, *elevation2;
    3124             : 
    3125             :     Word32 direct_response_hoa_fx[MAX_OUTPUT_CHANNELS]; /*  number of output channels (HOA 3rd order) -> 16 */
    3126             :     Word32 direct_response_ls_fx[MAX_OUTPUT_CHANNELS];
    3127             :     Word32 direct_response_square_fx[MAX_OUTPUT_CHANNELS];
    3128             :     Word32 direct_response_dir2_fx[MAX_OUTPUT_CHANNELS];
    3129             :     Word32 directRatio_fx[MASA_MAXIMUM_DIRECTIONS];
    3130             :     Word16 Q_direct_response_ls, exp_direct_response_ls;
    3131             :     Word16 Q_direct_response_dir2, exp_direct_response_dir2;
    3132             :     Word16 Q_direct_response_hoa, exp_direct_response_hoa;
    3133             :     Word16 direct_response_square_q, direct_response_q;
    3134     1050811 :     Word16 exp_surCohRatio = sub( 31, Q_surCohRatio );
    3135             :     Word32 totalDirect_fx;
    3136             :     Word32 *direct_response_fx;
    3137             :     Word16 codingBand;
    3138             :     Word16 dipole_freq_range[2];
    3139             :     MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type;
    3140             : 
    3141     1050811 :     Q_direct_response_ls = Q31;
    3142     1050811 :     move16();
    3143     1050811 :     exp_direct_response_ls = 0;
    3144     1050811 :     move16();
    3145     1050811 :     Q_direct_response_dir2 = Q31;
    3146     1050811 :     move16();
    3147     1050811 :     exp_direct_response_dir2 = 0;
    3148     1050811 :     move16();
    3149     1050811 :     Q_direct_response_hoa = Q31;
    3150     1050811 :     move16();
    3151     1050811 :     exp_direct_response_hoa = 0;
    3152     1050811 :     move16();
    3153     1050811 :     direct_response_square_q = Q31;
    3154     1050811 :     move16();
    3155     1050811 :     direct_response_q = Q29;
    3156     1050811 :     move16();
    3157             : 
    3158     1050811 :     azimuth2 = NULL;
    3159     1050811 :     elevation2 = NULL;
    3160     1050811 :     transport_signal_type = MASA_STEREO_NOT_DEFINED;
    3161     1050811 :     move32();
    3162             : 
    3163     1050811 :     IF( hDirACRend->masa_stereo_type_detect != NULL )
    3164             :     {
    3165       16206 :         dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
    3166       16206 :         move16();
    3167       16206 :         dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
    3168       16206 :         move16();
    3169       16206 :         transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
    3170       16206 :         move16();
    3171             :     }
    3172             : 
    3173     1050811 :     num_channels_dir = hDirACRend->num_outputs_dir;
    3174     1050811 :     move16();
    3175     1050811 :     IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    3176             :     {
    3177      280616 :         azimuth2 = hSpatParamRendCom->azimuth2[md_idx]; /*q0*/
    3178      280616 :         move16();
    3179      280616 :         elevation2 = hSpatParamRendCom->elevation2[md_idx]; /*q0*/
    3180      280616 :         move16();
    3181             :     }
    3182             : 
    3183     1050811 :     codingBand = -1;
    3184             : 
    3185     1050811 :     assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
    3186             : 
    3187    57347511 :     FOR( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
    3188             :     {
    3189    56296700 :         test();
    3190    56296700 :         if ( masa_band_mapping != NULL && EQ_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) )
    3191             :         {
    3192     1027115 :             codingBand = add( codingBand, 1 );
    3193             :         }
    3194             : 
    3195    56296700 :         test();
    3196    56296700 :         test();
    3197    56296700 :         test();
    3198    56296700 :         IF( masa_band_mapping != NULL && GT_16( k, MASA_band_grouping_24[masa_band_mapping[codingBand]] ) &&
    3199             :             LT_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) &&
    3200             :             NE_16( k, hDirACRend->h_output_synthesis_psd_params.max_band_decorr ) )
    3201             :         {
    3202             :             /* Panning gains have to be computed only for the first bin of the coding band in MASA, for other bins the previous values can be used */
    3203     4116660 :             IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    3204             :             {
    3205     3526317 :                 mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k - 1],
    3206     3526317 :                                  hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k],
    3207     3526317 :                                  hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
    3208             :             }
    3209     4116660 :             mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k - 1],
    3210     4116660 :                              hSpatParamRendCom->num_freq_bands,
    3211     4116660 :                              &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k],
    3212     4116660 :                              hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/
    3213             :         }
    3214             :         ELSE
    3215             :         {
    3216             :             /* HOA3 PANNING */
    3217    52180040 :             IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_HOA3 ) )
    3218             :             {
    3219    47265169 :                 set32_fx( direct_response_hoa_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS );  /*q29*/
    3220    47265169 :                 set32_fx( direct_response_dir2_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/
    3221             : 
    3222    47265169 :                 Q_direct_response_hoa = Q29;
    3223    47265169 :                 move16();
    3224    47265169 :                 Q_direct_response_dir2 = Q29;
    3225    47265169 :                 move16();
    3226    47265169 :                 exp_direct_response_hoa = 0;
    3227    47265169 :                 move16();
    3228    47265169 :                 exp_direct_response_dir2 = 0;
    3229    47265169 :                 move16();
    3230             : 
    3231    47265169 :                 IF( p_Rmat != 0 )
    3232             :                 {
    3233       96000 :                     ivas_dirac_dec_get_response_split_order_fx( azimuth[k], elevation[k], direct_response_hoa_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_hoa );
    3234             : 
    3235       96000 :                     IF( hodirac_flag )
    3236             :                     {
    3237       48000 :                         ivas_dirac_dec_get_response_split_order_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, shd_rot_max_order, p_Rmat, &Q_direct_response_dir2 );
    3238             :                     }
    3239             :                 }
    3240             :                 ELSE
    3241             :                 {
    3242             : #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx
    3243    47169169 :                     ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order );
    3244             : #else
    3245             :                     ivas_dirac_dec_get_response_fx( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_hoa );
    3246             : #endif
    3247             : 
    3248    47169169 :                     IF( hodirac_flag )
    3249             :                     {
    3250             : #ifdef FIX_1310_SPEEDUP_ivas_dirac_dec_get_response_fx
    3251    15762800 :                         ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order );
    3252             : #else
    3253             :                         ivas_dirac_dec_get_response_fx( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order, Q_direct_response_dir2 );
    3254             : #endif
    3255             :                     }
    3256             :                 }
    3257             : 
    3258    47265169 :                 test();
    3259    47265169 :                 test();
    3260    47265169 :                 test();
    3261    47265169 :                 test();
    3262    47265169 :                 IF( masa_band_mapping == NULL && EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    3263             :                 {
    3264    46817120 :                     mvr2r_inc_fixed( direct_response_hoa_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_hoa*/
    3265             : 
    3266    46817120 :                     IF( hodirac_flag )
    3267             :                     {
    3268    15810800 :                         mvr2r_inc_fixed( direct_response_dir2_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*Q_direct_response_dir2*/
    3269             :                     }
    3270             :                 }
    3271      448049 :                 ELSE IF( ( ( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) && ( masa_band_mapping != NULL ) ) ||
    3272             :                          EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
    3273             :                 {
    3274             :                     /* Synthesize the first direction */
    3275      448049 :                     IF( GT_16( Q_direct_response_hoa, Q29 ) )
    3276             :                     {
    3277           0 :                         Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_hoa, Q29 ) ); /*Q_direct_response_hoa->q29*/
    3278           0 :                         Q_direct_response_hoa = Q29;
    3279           0 :                         move16();
    3280           0 :                         exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    3281             :                     }
    3282      448049 :                     spreadCoherencePanningHoa_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
    3283      448049 :                                                   direct_response_hoa_fx, &Q_direct_response_hoa, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
    3284             : 
    3285      448049 :                     exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    3286             :                     /* Synthesize the second direction and combine the gains */
    3287      448049 :                     IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    3288             :                     {
    3289      118200 :                         IF( GT_16( Q_direct_response_dir2, Q29 ) )
    3290             :                         {
    3291           0 :                             Scale_sig32( direct_response_dir2_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_dir2, Q29 ) ); /*Q_direct_response_dir2->q29*/
    3292           0 :                             Q_direct_response_dir2 = Q29;
    3293           0 :                             move16();
    3294           0 :                             exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
    3295             :                         }
    3296      118200 :                         spreadCoherencePanningHoa_fx( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2_fx[md_idx][k],
    3297      118200 :                                                       direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
    3298             : 
    3299      118200 :                         exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    3300             :                         /* Combine gains from the two directions */
    3301      118200 :                         totalDirect_fx = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
    3302      118200 :                         IF( totalDirect_fx == 0 )
    3303             :                         {
    3304          10 :                             totalDirect_fx = EPSILON_FIX;
    3305          10 :                             move32();
    3306             :                         }
    3307             : 
    3308             :                         Word16 var_a, var_b, exp_1, exp_2;
    3309      118200 :                         var_a = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); /*15-exp_1*/
    3310      118200 :                         var_b = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); /*15-exp_2*/
    3311             : 
    3312      118200 :                         directRatio_fx[0] = L_deposit_h( var_a ); /*15-exp_1+16*/
    3313      118200 :                         move32();
    3314      118200 :                         directRatio_fx[1] = L_deposit_h( var_b ); /*15-exp_2+16*/
    3315      118200 :                         move32();
    3316             : 
    3317             :                         Word32 temp_a;
    3318             :                         Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_a, final_exp;
    3319      118200 :                         set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
    3320      118200 :                         exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    3321             : 
    3322     1023000 :                         FOR( l = 0; l < num_channels_dir; l++ )
    3323             :                         {
    3324      904800 :                             direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], directRatio_fx[0] ); /*Q(Q_direct_response_hoa+31-exp_1-31)*/
    3325      904800 :                             move32();
    3326      904800 :                             exp_arr[l] = add( exp_1, sub( 31, Q_direct_response_hoa ) );
    3327      904800 :                             move16();
    3328      904800 :                             temp_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); /*Q(Q_direct_response_dir2+31-exp_2-31)*/
    3329      904800 :                             exp_temp_a = add( exp_2, sub( 31, Q_direct_response_dir2 ) );
    3330      904800 :                             direct_response_hoa_fx[l] = BASOP_Util_Add_Mant32Exp( direct_response_hoa_fx[l], exp_arr[l], temp_a, exp_temp_a, &final_exp ); /*Q(31-final_exp)*/
    3331      904800 :                             move32();
    3332      904800 :                             exp_arr[l] = final_exp;
    3333      904800 :                             move16();
    3334             :                         }
    3335             : 
    3336      118200 :                         Word16 max_exp = MIN16B;
    3337      118200 :                         move16();
    3338      118200 :                         maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
    3339     2009400 :                         FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
    3340             :                         {
    3341     1891200 :                             direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31-exp_arr[l])->Q(31-max_exp)*/
    3342     1891200 :                             move32();
    3343             :                         }
    3344      118200 :                         exp_direct_response_hoa = max_exp;
    3345      118200 :                         move16();
    3346      118200 :                         Q_direct_response_hoa = sub( 31, max_exp );
    3347             :                     }
    3348             : 
    3349      448049 :                     IF( hSpatParamRendCom->numIsmDirections > 0 )
    3350             :                     {
    3351             :                         Word16 dir;
    3352             :                         Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
    3353             :                         Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
    3354        8152 :                         Word16 exp_direct_response_ism = 0, exp_direct_response_temp;
    3355             :                         Word32 masaDirect_fx;
    3356             :                         Word32 ismDirect_fx;
    3357        8152 :                         move16();
    3358             : 
    3359        8152 :                         set32_fx( direct_response_ism_fx, 0, num_channels_dir );
    3360             : 
    3361       40760 :                         FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    3362             :                         {
    3363       32608 :                             IF( hMasaIsm->ism_is_edited[dir] )
    3364             :                             {
    3365           0 :                                 ivas_dirac_dec_get_response_fx( hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], direct_response_temp_fx, hDirACRend->hOutSetup.ambisonics_order, Q29 );
    3366             :                             }
    3367             :                             ELSE
    3368             :                             {
    3369       32608 :                                 ivas_dirac_dec_get_response_fx( hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], direct_response_temp_fx, hDirACRend->hOutSetup.ambisonics_order, Q29 );
    3370             :                             }
    3371       32608 :                             exp_direct_response_temp = 2;
    3372       32608 :                             move16();
    3373             : 
    3374       32608 :                             Word32 temp_1 = 0;
    3375       32608 :                             Word16 exp_temp = 0, exp_arr[MAX_OUTPUT_CHANNELS];
    3376       32608 :                             move16();
    3377       32608 :                             move16();
    3378       32608 :                             set16_fx( exp_arr, 0, MAX_OUTPUT_CHANNELS );
    3379      348992 :                             FOR( l = 0; l < num_channels_dir; l++ )
    3380             :                             {
    3381      316384 :                                 temp_1 = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] );                                                                   // Q28
    3382      316384 :                                 direct_response_ism_fx[l] = BASOP_Util_Add_Mant32Exp( direct_response_ism_fx[l], exp_direct_response_ism, temp_1, add( exp_direct_response_temp, 1 ), &exp_temp ); //(31-exp_temp)
    3383      316384 :                                 move32();
    3384      316384 :                                 exp_arr[l] = exp_temp;
    3385      316384 :                                 move16();
    3386             :                             }
    3387       32608 :                             Word16 max_exp = MIN16B;
    3388       32608 :                             move16();
    3389       32608 :                             maximum_fx( exp_arr, num_channels_dir, &max_exp );
    3390      348992 :                             FOR( l = 0; l < num_channels_dir; l++ )
    3391             :                             {
    3392      316384 :                                 direct_response_ism_fx[l] = L_shr( direct_response_ism_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31- exp_arr[l])->Q(31-max_exp)*/
    3393      316384 :                                 move32();
    3394             :                             }
    3395       32608 :                             exp_direct_response_ism = max_exp;
    3396       32608 :                             move16();
    3397             :                         }
    3398             :                         Word16 exp_1, exp_2;
    3399        8152 :                         masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; /*q30*/
    3400        8152 :                         move32();
    3401        8152 :                         if ( masaDirect_fx == 0 )
    3402             :                         {
    3403          92 :                             masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); /*q30*/
    3404             :                         }
    3405        8152 :                         if ( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    3406             :                         {
    3407           0 :                             masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
    3408             :                         }
    3409             : 
    3410        8152 :                         ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; /*q30*/
    3411        8152 :                         move32();
    3412       32608 :                         FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    3413             :                         {
    3414       24456 :                             ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); /*q30*/
    3415             :                         }
    3416             : 
    3417        8152 :                         totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); /*q30*/ // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
    3418        8152 :                         Word16 var_a = 0, var_b = 0;
    3419        8152 :                         var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); /*Q(15-exp_1)*/
    3420        8152 :                         var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 );  /*q(15-exp_2)*/
    3421        8152 :                         directRatio_fx[0] = L_deposit_h( var_a );                                     // Q(31-exp_1)
    3422        8152 :                         move32();
    3423        8152 :                         directRatio_fx[1] = L_deposit_h( var_b ); // Q(31-exp_2)
    3424        8152 :                         move32();
    3425             : 
    3426             :                         Word32 temp_2, temp_3;
    3427             :                         Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
    3428        8152 :                         set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
    3429       87248 :                         FOR( l = 0; l < num_channels_dir; l++ )
    3430             :                         {
    3431       79096 :                             direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], directRatio_fx[0] ); /*31-exp_direct_response_hoa+31-exp_1-31*/
    3432       79096 :                             move32();
    3433       79096 :                             exp_arr[l] = add( exp_direct_response_hoa, exp_1 );
    3434       79096 :                             move16();
    3435       79096 :                             temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] );                                                                     /*31-exp_direct_response_ism+31-exp_2-31*/
    3436       79096 :                             temp_3 = BASOP_Util_Add_Mant32Exp( direct_response_hoa_fx[l], exp_arr[l], temp_2, add( exp_2, exp_direct_response_ism ), &exp_temp_3 ); /*31-exp_temp_3*/
    3437             : 
    3438       79096 :                             direct_response_hoa_fx[l] = temp_3; /*31-exp_temp_3*/
    3439       79096 :                             move32();
    3440       79096 :                             exp_arr[l] = exp_temp_3;
    3441       79096 :                             move16();
    3442             :                         }
    3443             : 
    3444        8152 :                         Word16 max_exp = MIN16B;
    3445        8152 :                         move16();
    3446        8152 :                         maximum_fx( exp_arr, num_channels_dir, &max_exp );
    3447       87248 :                         FOR( l = 0; l < num_channels_dir; l++ )
    3448             :                         {
    3449       79096 :                             direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
    3450       79096 :                             move32();
    3451             :                         }
    3452        8152 :                         Q_direct_response_hoa = sub( 31, max_exp );
    3453        8152 :                         exp_direct_response_hoa = max_exp;
    3454        8152 :                         move16();
    3455             :                     }
    3456             : 
    3457             :                     /* Synthesize surrounding coherence */
    3458      448049 :                     IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
    3459             :                     {
    3460             :                         Word32 var_a, var_b;
    3461             :                         Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp;
    3462      279197 :                         set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
    3463             : 
    3464     1864349 :                         FOR( l = 1; l < num_channels_dir; l++ )
    3465             :                         {
    3466     1585152 :                             exp = 0;
    3467     1585152 :                             move16();
    3468     1585152 :                             var_a = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp ); /*q(31-exp)*/
    3469     1585152 :                             var_b = Sqrt32( var_a, &exp );                                                                                     /*31-exp*/
    3470     1585152 :                             direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], var_b );                                         /*Q_direct_response_hoa+31-exp-31*/
    3471     1585152 :                             move32();
    3472     1585152 :                             exp_arr[l] = add( sub( 31, Q_direct_response_hoa ), exp );
    3473     1585152 :                             move16();
    3474             :                         }
    3475      279197 :                         Word16 max_exp = MIN_16;
    3476      279197 :                         move16();
    3477      279197 :                         maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
    3478     4746349 :                         FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
    3479             :                         {
    3480     4467152 :                             direct_response_hoa_fx[l] = L_shr( direct_response_hoa_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
    3481     4467152 :                             move32();
    3482             :                         }
    3483      279197 :                         Q_direct_response_hoa = sub( 31, max_exp );
    3484      279197 :                         exp_direct_response_hoa = max_exp;
    3485      279197 :                         move16();
    3486             :                     }
    3487             : 
    3488      448049 :                     Q_direct_response_hoa = sub( Q31, exp_direct_response_hoa );
    3489             : 
    3490      448049 :                     Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_hoa ) ); /*Q_direct_response_hoa->q29*/
    3491      448049 :                     direct_response_q = Q29;
    3492      448049 :                     move16();
    3493             : 
    3494      448049 :                     direct_response_fx = direct_response_hoa_fx;
    3495      448049 :                     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    3496             :                     {
    3497      303512 :                         v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*Q(2*direct_response_q-31)*/
    3498      303512 :                         direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
    3499             : 
    3500      303512 :                         mvr2r_inc_fixed( direct_response_square_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
    3501             : 
    3502      303512 :                         IF( EQ_16( transport_signal_type, MASA_STEREO_SPACED_MICS ) )
    3503             :                         {
    3504       30683 :                             direct_response_fx[0] = ONE_IN_Q29; /*q29*/
    3505       30683 :                             move32();
    3506       30683 :                             test();
    3507       30683 :                             IF( GE_16( k, dipole_freq_range[0] ) && LT_16( k, dipole_freq_range[1] ) )
    3508             :                             {
    3509        3897 :                                 direct_response_fx[1] = ONE_IN_Q29; /*q29*/
    3510        3897 :                                 move32();
    3511             :                             }
    3512             :                         }
    3513             :                         ELSE
    3514             :                         {
    3515      272829 :                             set32_fx( direct_response_fx, ONE_IN_Q29, hDirACRend->num_protos_ambi ); /*q29*/
    3516             :                         }
    3517             :                     }
    3518             : 
    3519      448049 :                     mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*q29*/
    3520             :                 }
    3521             :                 ELSE
    3522             :                 {
    3523           0 :                     assert( 0 && "Not supported synthesis method!" );
    3524             :                 }
    3525             :             }
    3526     4914871 :             ELSE IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_VBAP ) ) /*VBAP*/
    3527             :             {
    3528             :                 /* Synthesize the first direction */
    3529     4914871 :                 spreadCoherencePanningVbap_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
    3530             :                                                direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir, hVBAPdata );
    3531     4914871 :                 normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3532     4914871 :                 exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3533             : 
    3534             :                 /* Synthesize the second direction and combine the gains */
    3535     4914871 :                 IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    3536             :                 {
    3537      204188 :                     spreadCoherencePanningVbap_fx( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2_fx[md_idx][k], direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir, hVBAPdata );
    3538      204188 :                     normalizePanningGains_fx( direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir );
    3539             : 
    3540             :                     /* Combine gains from the two directions */
    3541      204188 :                     Word32 test = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
    3542             : 
    3543      204188 :                     IF( test == 0 )
    3544             :                     {
    3545        1337 :                         totalDirect_fx = L_add( test, EPSILON_FIX ); // Q30
    3546             :                     }
    3547             :                     ELSE
    3548             :                     {
    3549      202851 :                         totalDirect_fx = test; // q30
    3550      202851 :                         move32();
    3551             :                     }
    3552             :                     Word16 var_1, var_2, exp_1, exp_2;
    3553      204188 :                     var_1 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); // 15-exp_1
    3554      204188 :                     var_2 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); // 15-exp_2
    3555             : 
    3556      204188 :                     directRatio_fx[0] = L_deposit_h( var_1 ); // 31-exp_1
    3557      204188 :                     move32();
    3558      204188 :                     directRatio_fx[1] = L_deposit_h( var_2 ); // 31-exp_2
    3559      204188 :                     move32();
    3560             : 
    3561             :                     Word32 var_a;
    3562             :                     Word16 exp_tmp;
    3563      204188 :                     Word16 exp_max = MIN16B, exp_table[MAX_OUTPUT_CHANNELS];
    3564      204188 :                     move16();
    3565      204188 :                     set16_fx( exp_table, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
    3566             : 
    3567      204188 :                     exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3568      204188 :                     exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
    3569             : 
    3570      204188 :                     Word32 temp = 0;
    3571      204188 :                     move32();
    3572     1855504 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3573             :                     {
    3574     1651316 :                         temp = Mpy_32_32( direct_response_ls_fx[l], directRatio_fx[0] );    // exp_direct_response_ls + exp_1
    3575     1651316 :                         var_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); // exp_direct_response_dir2 + exp_2
    3576     1651316 :                         exp_tmp = 0;
    3577     1651316 :                         move16();
    3578     1651316 :                         direct_response_ls_fx[l] = BASOP_Util_Add_Mant32Exp( temp, add( exp_direct_response_ls, exp_1 ), var_a, add( exp_direct_response_dir2, exp_2 ), &exp_tmp ); // q(31-exp_tmp)
    3579     1651316 :                         move32();
    3580     1651316 :                         exp_table[l] = exp_tmp;
    3581     1651316 :                         move16();
    3582             :                     }
    3583             : 
    3584      204188 :                     maximum_fx( exp_table, MAX_OUTPUT_CHANNELS, &exp_max );
    3585             : 
    3586     3471196 :                     FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
    3587             :                     {
    3588     3267008 :                         direct_response_ls_fx[i] = L_shr( direct_response_ls_fx[i], sub( exp_max, exp_table[i] ) ); /*(q(31-exp_table[i])->q(31-exp_max))*/
    3589     3267008 :                         move32();
    3590             :                     }
    3591      204188 :                     Q_direct_response_ls = sub( 31, exp_max );
    3592      204188 :                     exp_direct_response_ls = exp_max;
    3593      204188 :                     move16();
    3594             : 
    3595      204188 :                     normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3596      204188 :                     exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3597             :                 }
    3598             : 
    3599     4914871 :                 IF( hSpatParamRendCom->numIsmDirections > 0 )
    3600             :                 {
    3601             :                     Word16 dir;
    3602             : 
    3603             :                     Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
    3604        9195 :                     set32_fx( direct_response_temp_fx, 0, MAX_OUTPUT_CHANNELS );
    3605        9195 :                     Word16 Q_direct_response_temp = Q31;
    3606        9195 :                     move16();
    3607             :                     Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
    3608        9195 :                     set32_fx( direct_response_ism_fx, 0, num_channels_dir );
    3609             :                     Word32 masaDirect_fx;
    3610             :                     Word32 ismDirect_fx;
    3611             : 
    3612       35695 :                     FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    3613             :                     {
    3614       26500 :                         IF( hMasaIsm->ism_is_edited[dir] )
    3615             :                         {
    3616           0 :                             vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 );
    3617             :                         }
    3618             :                         ELSE
    3619             :                         {
    3620       26500 :                             vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
    3621             :                         }
    3622       26500 :                         Word32 tmp = 0;
    3623       26500 :                         move32();
    3624             :                         Word16 Q_arr[MAX_OUTPUT_CHANNELS], exp_tmp;
    3625      245264 :                         FOR( l = 0; l < num_channels_dir; l++ )
    3626             :                         {
    3627      218764 :                             tmp = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] );                          // Q30 * 2 - 31
    3628      218764 :                             direct_response_ism_fx[l] = BASOP_Util_Add_Mant32Exp( direct_response_ism_fx[l], 0, tmp, 31 - ( 60 - 31 ), &exp_tmp ); // q(31-exp_tmp)
    3629      218764 :                             move32();
    3630      218764 :                             Q_arr[l] = sub( 31, exp_tmp );
    3631      218764 :                             move16();
    3632             :                         }
    3633       26500 :                         Word16 Q_min = MAX16B;
    3634       26500 :                         move32();
    3635       26500 :                         minimum_fx( Q_arr, num_channels_dir, &Q_min );
    3636      245264 :                         FOR( i = 0; i < num_channels_dir; i++ )
    3637             :                         {
    3638      218764 :                             direct_response_ism_fx[i] = L_shr( direct_response_ism_fx[i], sub( Q_arr[i], Q_min ) ); // Q_arr[i]->Q_min
    3639      218764 :                             move32();
    3640             :                         }
    3641       26500 :                         Q_direct_response_temp = Q_min;
    3642       26500 :                         move16();
    3643       26500 :                         normalizePanningGains_fx( direct_response_ism_fx, &Q_direct_response_temp, num_channels_dir );
    3644             :                     }
    3645             : 
    3646             :                     Word16 exp_1, exp_2;
    3647        9195 :                     masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; // q30
    3648        9195 :                     move32();
    3649        9195 :                     IF( masaDirect_fx == 0 )
    3650             :                     {
    3651          39 :                         masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); // q30
    3652             :                     }
    3653        9195 :                     IF( EQ_32( hSpatParamRendCom->numParametricDirections, 2 ) )
    3654             :                     {
    3655        3000 :                         masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); // q30
    3656             :                     }
    3657             : 
    3658        9195 :                     ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; // q30
    3659        9195 :                     move32();
    3660       26500 :                     FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    3661             :                     {
    3662       17305 :                         ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // q30
    3663             :                     }
    3664             : 
    3665        9195 :                     totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); // q30 // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
    3666             :                     Word16 var_a, var_b;
    3667        9195 :                     var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); // 15-exp_1
    3668        9195 :                     var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 );  // 15- exp_2
    3669        9195 :                     directRatio_fx[0] = L_deposit_h( var_a );                                     // 31- exp_1
    3670        9195 :                     move32();
    3671        9195 :                     directRatio_fx[1] = L_deposit_h( var_b ); // 31 - exp_2
    3672        9195 :                     move32();
    3673             : 
    3674             :                     Word32 temp_2, temp_3;
    3675             :                     Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
    3676        9195 :                     set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
    3677       84648 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3678             :                     {
    3679       75453 :                         direct_response_ls_fx[l] = Mpy_32_32( direct_response_ls_fx[l], directRatio_fx[0] ); // q(31-exp_direct_response_ls+31-exp_1-31)
    3680       75453 :                         move32();
    3681       75453 :                         exp_arr[l] = add( exp_direct_response_ls, exp_1 );
    3682       75453 :                         move16();
    3683       75453 :                         temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] );                                                                              // q(Q_direct_response_temp+31-exp_2-31)
    3684       75453 :                         temp_3 = BASOP_Util_Add_Mant32Exp( direct_response_ls_fx[l], exp_arr[l], temp_2, add( exp_2, sub( 31, Q_direct_response_temp ) ), &exp_temp_3 ); // 31-exp_temp_3
    3685             : 
    3686       75453 :                         direct_response_ls_fx[l] = temp_3; // 31-exp_temp_3
    3687       75453 :                         move32();
    3688       75453 :                         exp_arr[l] = exp_temp_3;
    3689       75453 :                         move16();
    3690             :                     }
    3691             : 
    3692        9195 :                     Word16 max_exp = MIN16B;
    3693        9195 :                     move16();
    3694        9195 :                     maximum_fx( exp_arr, num_channels_dir, &max_exp );
    3695       84648 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3696             :                     {
    3697       75453 :                         direct_response_ls_fx[l] = L_shr( direct_response_ls_fx[l], sub( max_exp, exp_arr[l] ) ); /*q(31-exp_arr[l])->q(31-max_exp)*/
    3698       75453 :                         move16();
    3699             :                     }
    3700        9195 :                     Q_direct_response_ls = sub( 31, max_exp );
    3701        9195 :                     exp_direct_response_ls = max_exp;
    3702        9195 :                     move16();
    3703             : 
    3704        9195 :                     normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3705        9195 :                     exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3706             :                 }
    3707             : 
    3708             :                 /* Synthesize surrounding coherence */
    3709     4914871 :                 test();
    3710     4914871 :                 IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
    3711             :                 {
    3712             :                     Word16 num_channels_surrCoh;
    3713             : 
    3714      349421 :                     num_channels_surrCoh = num_channels_dir;
    3715      349421 :                     move16();
    3716      349421 :                     num_channels_surrCoh = sub( num_channels_surrCoh, hDirACRend->num_ele_spk_no_diffuse_rendering );
    3717             : 
    3718             :                     Word32 temp, final;
    3719             :                     Word16 exp_temp, exp_temp_a, temp_a, final_exp;
    3720      349421 :                     Word16 exp_arr[MAX_OUTPUT_CHANNELS], max_exp = MIN16B;
    3721      349421 :                     move16();
    3722      349421 :                     set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
    3723     2981906 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3724             :                     {
    3725     2632485 :                         exp_temp = 0;
    3726     2632485 :                         move16();
    3727     2632485 :                         temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp_temp ); // q(31-exp_temp)
    3728     2632485 :                         temp = Sqrt32( temp, &exp_temp );                                                                                      // q(31-exp_temp)
    3729     2632485 :                         direct_response_ls_fx[l] = Mpy_32_32( direct_response_ls_fx[l], temp );                                                // Q31-(exp_direct_response_ls + exp_temp)
    3730     2632485 :                         move32();
    3731             : 
    3732     2632485 :                         exp_arr[l] = add( exp_direct_response_ls, exp_temp );
    3733     2632485 :                         move16();
    3734     2632485 :                         IF( hDirACRend->diffuse_response_function_fx[l] > 0 )
    3735             :                         {
    3736     2621285 :                             exp_temp_a = 0;
    3737     2621285 :                             move16();
    3738     2621285 :                             temp_a = BASOP_Util_Divide3216_Scale( surCohRatio_fx[k], num_channels_surrCoh, &exp_temp_a ); /*15-(exp_temp_a+exp_surCohRatio-15)*/
    3739     2621285 :                             exp_temp_a = add( exp_temp_a, sub( exp_surCohRatio, 15 ) );
    3740     2621285 :                             temp_a = Sqrt16( temp_a, &exp_temp_a ); /*15-temp_a*/
    3741     2621285 :                             final_exp = 0;
    3742     2621285 :                             move16();
    3743     2621285 :                             final = BASOP_Util_Add_Mant32Exp( direct_response_ls_fx[l], exp_arr[l], L_deposit_h( temp_a ), exp_temp_a, &final_exp ); /*31-final_exp*/
    3744     2621285 :                             direct_response_ls_fx[l] = final;                                                                                        /*31-final_exp*/
    3745     2621285 :                             move32();
    3746     2621285 :                             exp_arr[l] = final_exp;
    3747     2621285 :                             move16();
    3748             :                         }
    3749             :                     }
    3750             : 
    3751      349421 :                     max_exp = MIN16B; /*Q0*/
    3752      349421 :                     move16();
    3753      349421 :                     maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
    3754     5940157 :                     FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
    3755             :                     {
    3756     5590736 :                         direct_response_ls_fx[l] = L_shr( direct_response_ls_fx[l], sub( max_exp, exp_arr[l] ) ); /*Q(31-exp_arr[l])->Q(31-max_exp)*/
    3757     5590736 :                         move32();
    3758             :                     }
    3759             : 
    3760      349421 :                     Q_direct_response_ls = sub( 31, max_exp );
    3761      349421 :                     exp_direct_response_ls = max_exp;
    3762      349421 :                     move16();
    3763             :                 }
    3764             : 
    3765     4914871 :                 normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3766     4914871 :                 exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3767             : 
    3768     4914871 :                 Scale_sig32( direct_response_ls_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_ls ) ); /*Q_direct_response_ls->Q29*/
    3769     4914871 :                 direct_response_q = Q29;
    3770     4914871 :                 move16();
    3771             : 
    3772             :                 /* Set computed gains */
    3773     4914871 :                 direct_response_fx = direct_response_ls_fx;
    3774     4914871 :                 v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*2*direct_response_q-31*/
    3775     4914871 :                 direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
    3776             : 
    3777     4914871 :                 mvr2r_inc_fixed( direct_response_square_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
    3778     4914871 :                 mvr2r_inc_fixed( direct_response_fx, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );               /*direct_response_q*/
    3779             :             }
    3780             :             ELSE
    3781             :             {
    3782           0 :                 assert( 0 && "Not supported panning method!" );
    3783             :             }
    3784             :         }
    3785             :     }
    3786             : 
    3787     1050811 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_q = direct_response_q;
    3788     1050811 :     move16();
    3789     1050811 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = direct_response_square_q;
    3790     1050811 :     move16();
    3791             : 
    3792     1050811 :     return;
    3793             : }
    3794             : 
    3795             : 
    3796             : /*-------------------------------------------------------------------------
    3797             :  * ivas_dirac_dec_compute_gain_factors()
    3798             :  *
    3799             :  *
    3800             :  *------------------------------------------------------------------------*/
    3801             : 
    3802      688224 : void ivas_dirac_dec_compute_gain_factors_fx(
    3803             :     const Word16 num_freq_bands,
    3804             :     const Word32 *diffuseness_fx, /*i:q30*/
    3805             :     Word32 *direct_gain_factor,   /*o:exponent is max_exp_direct*/
    3806             :     Word32 *diffuse_gain_factor,  /*o:exponent is max_exp_diffusion*/
    3807             :     Word16 *max_exp_direct_fx,
    3808             :     Word16 *max_exp_diffusion )
    3809             : {
    3810             :     Word16 i;
    3811             :     Word16 exp1, exp2;
    3812             :     Word16 exp_diffuse_gain_factor[60], exp_direct_gain_factor[60]; /*exp buffers*/
    3813             : 
    3814    35591584 :     FOR( i = 0; i < num_freq_bands; i++ )
    3815             :     {
    3816    34903360 :         exp1 = 1;
    3817    34903360 :         move16();
    3818    34903360 :         exp2 = 1;
    3819    34903360 :         move16();
    3820    34903360 :         direct_gain_factor[i] = Sqrt32( L_sub( ONE_IN_Q30 /*1 Q30*/, diffuseness_fx[i] ), &exp1 ); /*31-exp1*/
    3821    34903360 :         move32();
    3822    34903360 :         diffuse_gain_factor[i] = Sqrt32( diffuseness_fx[i], &exp2 ); /*31-exp2*/
    3823    34903360 :         move32();
    3824    34903360 :         exp_direct_gain_factor[i] = exp1;
    3825    34903360 :         move16();
    3826    34903360 :         exp_diffuse_gain_factor[i] = exp2;
    3827    34903360 :         move16();
    3828             :     }
    3829             : 
    3830             :     /*make common exp for both buffers*/
    3831      688224 :     Word16 max_exp_direct = MIN16B; /*Q0*/
    3832      688224 :     move16();
    3833      688224 :     Word16 max_exp_diffuse = MIN16B; /*Q0*/
    3834      688224 :     move16();
    3835    35591584 :     FOR( i = 0; i < num_freq_bands; i++ )
    3836             :     {
    3837    34903360 :         max_exp_direct = s_max( max_exp_direct, exp_direct_gain_factor[i] );
    3838    34903360 :         max_exp_diffuse = s_max( max_exp_diffuse, exp_diffuse_gain_factor[i] );
    3839             :     }
    3840             : 
    3841      688224 :     *max_exp_direct_fx = max_exp_direct;
    3842      688224 :     move16();
    3843      688224 :     *max_exp_diffusion = max_exp_diffuse;
    3844      688224 :     move16();
    3845             : 
    3846    35591584 :     FOR( i = 0; i < num_freq_bands; i++ )
    3847             :     {
    3848    34903360 :         direct_gain_factor[i] = L_shr( direct_gain_factor[i], sub( max_exp_direct, exp_direct_gain_factor[i] ) ); /*Q(31-max_exp_direct)*/
    3849    34903360 :         move32();
    3850    34903360 :         diffuse_gain_factor[i] = L_shr( diffuse_gain_factor[i], sub( max_exp_diffuse, exp_diffuse_gain_factor[i] ) ); /*Q(31-max_exp_diffuse)*/
    3851    34903360 :         move32();
    3852             :     }
    3853             : 
    3854             : 
    3855      688224 :     return;
    3856             : }
    3857             : 
    3858             : 
    3859             : /*-------------------------------------------------------------------------
    3860             :  * ivas_dirac_dec_compute_power_factors()
    3861             :  *
    3862             :  *
    3863             :  *------------------------------------------------------------------------*/
    3864             : 
    3865      149963 : void ivas_dirac_dec_compute_power_factors_fx(
    3866             :     const Word16 num_freq_bands,
    3867             :     const Word32 *diffuseness_fx, // Q3O
    3868             :     const Word16 max_band_decorr,
    3869             :     Word32 *direct_power_factor, /*input is q30 and ouput is q29*/
    3870             :     Word32 *diffuse_power_factor /*input is q30 and ouput is q29*/ )
    3871             : {
    3872             :     Word16 i;
    3873             : 
    3874      149963 :     v_multc_fixed( diffuseness_fx, L_negate( ( ONE_IN_Q31 ) ), direct_power_factor, num_freq_bands ); // Q30
    3875             : 
    3876      149963 :     v_addc_fixed( direct_power_factor, ONE_IN_Q30, direct_power_factor, num_freq_bands ); // Q30
    3877             : 
    3878      149963 :     Copy32( diffuseness_fx, diffuse_power_factor, num_freq_bands ); // Q30
    3879             : 
    3880      149963 :     v_mult_fixed( &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], num_freq_bands - max_band_decorr ); // Q29
    3881             : 
    3882      149963 :     v_mult_fixed( &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], num_freq_bands - max_band_decorr ); // Q29
    3883             : 
    3884             : 
    3885     1178198 :     FOR( i = 0; i < max_band_decorr; i++ )
    3886             :     {
    3887     1028235 :         direct_power_factor[i] = L_shr( direct_power_factor[i], 1 ); // Q29
    3888     1028235 :         move32();
    3889     1028235 :         diffuse_power_factor[i] = L_shr( diffuse_power_factor[i], 1 ); // Q29
    3890     1028235 :         move32();
    3891             :     }
    3892      149963 :     return;
    3893             : }
    3894             : 
    3895             : 
    3896             : /*-------------------------------------------------------------------------
    3897             :  * ivas_lfe_synth_with_filters()
    3898             :  *
    3899             :  *
    3900             :  *------------------------------------------------------------------------*/
    3901         150 : void ivas_lfe_synth_with_filters_fx(
    3902             :     MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: LFE synthesis structure for McMASA  */
    3903             :     Word32 *data_fx[],                          /* o  : output signals (Q11)             */
    3904             :     const Word16 output_frame,                  /* i  : output frame length per channel     */
    3905             :     const Word16 separateChannelIndex,          /* i  : separate channel index              */
    3906             :     const Word16 lfeChannelIndex                /* i  : LFE channel index                   */
    3907             : )
    3908             : {
    3909             :     Word16 lowpassCoef_fx;
    3910             :     Word16 lowpassCoef_fx_exp;
    3911             :     Word16 i, j;
    3912             :     Word32 lowPassSignal_fx[L_FRAME48k];
    3913             :     Word32 highPassSignal_fx[L_FRAME48k];
    3914             :     Word16 slot_index;
    3915             :     Word16 subframe_index;
    3916             :     Word16 slotSize;
    3917             :     Word32 transportEne_fx, targetEneLfe_fx, targetEneTrans_fx;
    3918             :     Word16 mrange[2];
    3919             :     Word16 lfeGain_fx;
    3920             :     Word16 lfeGain_fx_exp;
    3921             :     Word16 transportGain_fx;
    3922             :     Word16 transportGain_fx_exp;
    3923             :     Word16 delay;
    3924             : 
    3925             :     /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */
    3926         150 :     delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
    3927         150 :     move16();
    3928         150 :     delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/
    3929             : 
    3930             :     /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */
    3931         150 :     lowpassCoef_fx_exp = 15;
    3932         150 :     move16();
    3933         150 :     lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize, &lowpassCoef_fx_exp ); /*15-lowpassCoef_fx_exp*/
    3934      144150 :     FOR( i = 0; i < output_frame; i++ )
    3935             :     {
    3936      144000 :         hMasaLfeSynth->lowpassSum_fx = L_add( hMasaLfeSynth->lowpassSum_fx, L_shl( Mpy_32_16_1( L_sub( data_fx[separateChannelIndex][i], hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferLoPointer] ), lowpassCoef_fx ), lowpassCoef_fx_exp ) ); // Q11
    3937      144000 :         lowPassSignal_fx[i] = hMasaLfeSynth->lowpassSum_fx;                                                                                                                                                                                                    // Q11
    3938      144000 :         move32();
    3939      144000 :         highPassSignal_fx[i] = L_sub( hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferHiPointer], lowPassSignal_fx[i] ); // Q11
    3940      144000 :         move32();
    3941      144000 :         hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferLoPointer] = data_fx[separateChannelIndex][i]; // Q11
    3942      144000 :         move32();
    3943             : 
    3944      144000 :         hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferLoPointer, 1 );
    3945      144000 :         move16();
    3946      144000 :         IF( hMasaLfeSynth->ringBufferLoPointer < 0 )
    3947             :         {
    3948         600 :             hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
    3949         600 :             move16();
    3950             :         }
    3951             : 
    3952      144000 :         hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferHiPointer, 1 );
    3953      144000 :         move16();
    3954      144000 :         IF( hMasaLfeSynth->ringBufferHiPointer < 0 )
    3955             :         {
    3956         600 :             hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
    3957         600 :             move16();
    3958             :         }
    3959             :     }
    3960             : 
    3961             :     /* Synthesize the LFE signal */
    3962         150 :     slotSize = shr_r( output_frame, 4 ); // output_frame / CLDFB_NO_COL_MAX
    3963        2550 :     FOR( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
    3964             :     {
    3965        2400 :         subframe_index = shr( slot_index, 4 );
    3966             : 
    3967        2400 :         mrange[0] = i_mult( slot_index, slotSize );
    3968        2400 :         move16();
    3969        2400 :         mrange[1] = i_mult( add( slot_index, 1 ), slotSize );
    3970        2400 :         move16();
    3971             : 
    3972        2400 :         transportEne_fx = 0;
    3973        2400 :         move32();
    3974        2400 :         Word64 W_tmp = 0;
    3975        2400 :         move64();
    3976      146400 :         FOR( i = mrange[0]; i < mrange[1]; i++ )
    3977             :         {
    3978      144000 :             W_tmp = W_add( W_tmp, W_mult0_32_32( lowPassSignal_fx[i], lowPassSignal_fx[i] ) ); // Q22
    3979             :         }
    3980             : 
    3981        2400 :         Word16 tmp_shift = W_norm( W_tmp );
    3982             : 
    3983        2400 :         W_tmp = W_shl( W_tmp, tmp_shift ); /*Q22+tmp_shift*/
    3984             : 
    3985        2400 :         Word16 tmp_q = sub( add( Q22, tmp_shift ), 32 );
    3986             :         Word16 tmp_exp;
    3987             : 
    3988        2400 :         transportEne_fx = W_extract_h( W_tmp );                                                                                                                                      /* Q22 + tmp_shift - 32 */
    3989        2400 :         targetEneLfe_fx = W_extract_l( W_shr( W_mult0_32_32( transportEne_fx, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ), Q14 ) );                                    /* Q22 + tmp_shift - 32 */
    3990        2400 :         targetEneTrans_fx = W_extract_l( W_shr( W_mult0_32_32( transportEne_fx, s_max( sub( ONE_IN_Q14, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ), 168 ) ), Q14 ) ); /* Q22 + tmp_shift - 32 */
    3991             : 
    3992        2400 :         hMasaLfeSynth->transportEneSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->transportEneSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* transportEneSmooth_q */
    3993        2400 :         move32();
    3994        2400 :         hMasaLfeSynth->targetEneLfeSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneLfeSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneLfeSmooth_q */
    3995        2400 :         move32();
    3996        2400 :         hMasaLfeSynth->targetEneTransSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneTransSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneTransSmooth_q */
    3997        2400 :         move32();
    3998             : 
    3999        2400 :         hMasaLfeSynth->transportEneSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->transportEneSmooth_fx, sub( Q31, hMasaLfeSynth->transportEneSmooth_q ), transportEne_fx, sub( Q31, tmp_q ), &tmp_exp ); /* Q31 - tmp_exp */
    4000        2400 :         move32();
    4001        2400 :         hMasaLfeSynth->transportEneSmooth_q = sub( Q31, tmp_exp );
    4002        2400 :         move16();
    4003        2400 :         hMasaLfeSynth->targetEneLfeSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->targetEneLfeSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneLfeSmooth_q ), targetEneLfe_fx, sub( Q31, tmp_q ), &tmp_exp ); /* Q31 - tmp_exp */
    4004        2400 :         move32();
    4005        2400 :         hMasaLfeSynth->targetEneLfeSmooth_q = sub( Q31, tmp_exp );
    4006        2400 :         move16();
    4007        2400 :         hMasaLfeSynth->targetEneTransSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->targetEneTransSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneTransSmooth_q ), targetEneTrans_fx, sub( Q31, tmp_q ), &tmp_exp ); /* Q31 - tmp_exp */
    4008        2400 :         move32();
    4009        2400 :         hMasaLfeSynth->targetEneTransSmooth_q = sub( Q31, tmp_exp );
    4010        2400 :         move16();
    4011             : 
    4012        2400 :         IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( hMasaLfeSynth->targetEneLfeSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneLfeSmooth_q ), /*EPSILON + */ hMasaLfeSynth->transportEneSmooth_fx, sub( Q31, hMasaLfeSynth->transportEneSmooth_q ) ), 1 ) )
    4013             :         {
    4014           0 :             lfeGain_fx = MAX_16; /* 1.0 in q15*/
    4015           0 :             move16();
    4016             :         }
    4017             :         ELSE
    4018             :         {
    4019        2400 :             lfeGain_fx = extract_h( BASOP_Util_Divide3232_Scale_newton( hMasaLfeSynth->targetEneLfeSmooth_fx, L_add( EPSILON_FX, hMasaLfeSynth->transportEneSmooth_fx ), &lfeGain_fx_exp ) ); /*Q(31-(lfeGain_fx_exp+hMasaLfeSynth->transportEneSmooth_q-hMasaLfeSynth->targetEneLfeSmooth_q))-16*/
    4020        2400 :             lfeGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneLfeSmooth_q ), lfeGain_fx_exp );
    4021        2400 :             lfeGain_fx = Sqrt16( lfeGain_fx, &lfeGain_fx_exp ); // Q15-lfeGain_fx_exp
    4022        2400 :             lfeGain_fx = shl_r( lfeGain_fx, lfeGain_fx_exp );   // Q15
    4023             :         }
    4024        2400 :         IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( hMasaLfeSynth->targetEneTransSmooth_fx, sub( Q31, hMasaLfeSynth->targetEneTransSmooth_q ), /*EPSILON + */ hMasaLfeSynth->transportEneSmooth_fx, sub( Q31, hMasaLfeSynth->transportEneSmooth_q ) ), 1 ) )
    4025             :         {
    4026           0 :             transportGain_fx = MAX_16; // q15
    4027           0 :             move16();
    4028             :         }
    4029             :         ELSE
    4030             :         {
    4031             :             Flag overFlow;
    4032        2400 :             transportGain_fx = BASOP_Util_Divide3232_Scale( hMasaLfeSynth->targetEneTransSmooth_fx, /*EPSILON + */ hMasaLfeSynth->transportEneSmooth_fx, &transportGain_fx_exp ); /*Q=15-(transportGain_fx_exp+hMasaLfeSynth->transportEneSmooth_q-hMasaLfeSynth->targetEneTransSmooth_q)*/
    4033        2400 :             transportGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneTransSmooth_q ), transportGain_fx_exp );
    4034        2400 :             transportGain_fx = Sqrt16( transportGain_fx, &transportGain_fx_exp );           // q15-transportGain_fx_exp
    4035        2400 :             transportGain_fx = shl_ro( transportGain_fx, transportGain_fx_exp, &overFlow ); // Q15
    4036             :         }
    4037        2400 :         j = 0;
    4038        2400 :         move16();
    4039      146400 :         FOR( i = mrange[0]; i < mrange[1]; i++ )
    4040             :         {
    4041      144000 :             Word32 L_tmp1 = L_mult( transportGain_fx, hMasaLfeSynth->interpolator_fx[j] );                                               // Q31
    4042      144000 :             Word32 L_tmp2 = L_mult( hMasaLfeSynth->transportGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) );             // Q31
    4043      144000 :             data_fx[separateChannelIndex][i] = L_add( Mpy_32_32( L_add( L_tmp1, L_tmp2 ), lowPassSignal_fx[i] ), highPassSignal_fx[i] ); /*q31+q11-q31->q11*/
    4044      144000 :             move32();
    4045      144000 :             Word32 L_tmp3 = L_mult( lfeGain_fx, hMasaLfeSynth->interpolator_fx[j] );                                   // Q31
    4046      144000 :             Word32 L_tmp4 = L_mult( hMasaLfeSynth->lfeGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) ); /*q31*/
    4047      144000 :             data_fx[lfeChannelIndex][i] = Mpy_32_32( L_add( L_tmp3, L_tmp4 ), lowPassSignal_fx[i] );                   /*q31+q11-q31->q11*/
    4048      144000 :             move32();
    4049      144000 :             j = add( j, 1 );
    4050             :         }
    4051             : 
    4052        2400 :         hMasaLfeSynth->lfeGainPrev_fx = lfeGain_fx; /*q15*/
    4053        2400 :         move16();
    4054        2400 :         hMasaLfeSynth->transportGainPrev_fx = transportGain_fx; /*q15*/
    4055        2400 :         move16();
    4056             :     }
    4057             : 
    4058             :     /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
    4059         150 :     lowpassCoef_fx_exp = 15;
    4060         150 :     move16();
    4061         150 :     lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize2, &lowpassCoef_fx_exp ); // q15-lowpassCoef_fx_exp
    4062      144150 :     FOR( i = 0; i < output_frame; i++ )
    4063             :     {
    4064      144000 :         hMasaLfeSynth->lowpassSum2_fx = L_add( hMasaLfeSynth->lowpassSum2_fx,
    4065      144000 :                                                L_shl_r( L_sub( Mpy_32_16_1( data_fx[lfeChannelIndex][i], lowpassCoef_fx ),
    4066      144000 :                                                                Mpy_32_16_1( hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2], lowpassCoef_fx ) ),
    4067             :                                                         lowpassCoef_fx_exp ) ); /*q11+15-lowpassCoef_fx_exp-15+lowpassCoef_fx_exp->q11*/
    4068      144000 :         move32();
    4069      144000 :         hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2] = data_fx[lfeChannelIndex][i]; /*q11*/
    4070      144000 :         move32();
    4071             : 
    4072      144000 :         hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferLoPointer2, 1 );
    4073      144000 :         move16();
    4074      144000 :         IF( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
    4075             :         {
    4076        1200 :             hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferSize2, 1 );
    4077        1200 :             move16();
    4078             :         }
    4079             : 
    4080      144000 :         data_fx[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2_fx; /*q11*/
    4081      144000 :         move32();
    4082             :     }
    4083             : 
    4084             :     /* Delay the separated channel to match the delay of the lowpass filter */
    4085         150 :     delay = hMasaLfeSynth->delayBuffer_syncLp_size;
    4086         150 :     move16();
    4087         150 :     delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/
    4088             : 
    4089         150 :     return;
    4090             : }
    4091             : 
    4092             : /*-------------------------------------------------------------------------
    4093             :  * Local functions
    4094             :  *------------------------------------------------------------------------*/
    4095             : 
    4096       72000 : static void computeTargetPSDs_direct_fx(
    4097             :     const Word16 num_channels,
    4098             :     const Word16 num_freq_bands,
    4099             :     const Word32 *direct_power_factor, /*q31*/
    4100             :     const Word32 *reference_power,     /*q_reference_power*/
    4101             :     const Word16 *q_reference_power,
    4102             :     const Word32 *direct_responses,        /*q31*/
    4103             :     const Word32 *direct_responses_square, /*q31*/
    4104             :     Word32 *cy_auto_dir_smooth,            /*q_cy_auto_dir_smooth*/
    4105             :     Word16 *q_cy_auto_dir_smooth,
    4106             :     Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
    4107             :     Word16 *q_cy_cross_dir_smooth )
    4108             : {
    4109             :     Word16 ch_idx, cur_idx;
    4110             : 
    4111             :     /* segment auxiliary buffer */
    4112             :     Word32 direct_power[CLDFB_NO_CHANNELS_MAX];   /* size: num_freq_bands. */
    4113             :     Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    4114             : 
    4115             :     /* estimate direct and diffuse power */
    4116       72000 :     v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
    4117             : 
    4118             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4119       72000 :     Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
    4120       72000 :     Word16 common2_q = s_min( *q_cy_cross_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
    4121             : #else
    4122             :     Word16 common1_q = s_min( *q_cy_auto_dir_smooth, *q_reference_power );
    4123             :     Word16 common2_q = s_min( *q_cy_cross_dir_smooth, *q_reference_power );
    4124             : #endif
    4125             : 
    4126             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    4127      784000 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    4128             :     {
    4129      712000 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    4130             : 
    4131      712000 :         v_mult_fixed( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
    4132             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4133      712000 :         scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) );                                    /* Q(common1_q) */
    4134      712000 :         scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common1_q, q_reference_power[1] ) ); /* Q(common1_q) */
    4135             : #else
    4136             :         scale_sig32( aux_buffer_res, num_freq_bands, sub( common1_q, *q_reference_power ) ); /* Q(common1_q) */
    4137             : #endif
    4138      712000 :         scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) );          /* Q(common1_q) */
    4139      712000 :         v_add_fixed( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common1_q) - Q1 */
    4140             : 
    4141      712000 :         v_mult_fixed( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
    4142             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4143      712000 :         scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) );                                    /* Q(common2_q) */
    4144      712000 :         scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( common2_q, q_reference_power[1] ) ); /* Q(common2_q) */
    4145             : #else
    4146             :         scale_sig32( aux_buffer_res, num_freq_bands, sub( common2_q, *q_reference_power ) ); /* Q(common2_q) */
    4147             : #endif
    4148      712000 :         scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) );          /* Q(common2_q) */
    4149      712000 :         v_add_fixed( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands, Q1 ); /* Q(common2_q) - Q1 */
    4150             :     }
    4151             : 
    4152             :     /* Q adjustment */
    4153       72000 :     *q_cy_auto_dir_smooth = sub( common1_q, Q1 );
    4154       72000 :     move16();
    4155       72000 :     *q_cy_cross_dir_smooth = sub( common2_q, Q1 );
    4156       72000 :     move16();
    4157             : 
    4158       72000 :     return;
    4159             : }
    4160             : 
    4161             : 
    4162       77963 : static void computeTargetPSDs_direct_subframe_fx(
    4163             :     const Word16 num_channels,
    4164             :     const Word16 num_freq_bands,
    4165             :     const Word32 *direct_power_factor, /*q31*/
    4166             :     const Word32 *reference_power,     /*q_reference_power*/
    4167             :     const Word16 *q_reference_power,
    4168             :     const Word32 *direct_responses,        /*q31*/
    4169             :     const Word32 *direct_responses_square, /*q31*/
    4170             :     Word32 *cy_auto_dir_smooth,            /*q_cy_auto_dir_smooth*/
    4171             :     Word16 *q_cy_auto_dir_smooth,
    4172             :     Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
    4173             :     Word16 *q_cy_cross_dir_smooth )
    4174             : {
    4175             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4176             :     Word16 ch_idx, cur_idx, q_tmp;
    4177             :     Word32 L_tmp[CLDFB_NO_CHANNELS_MAX];
    4178             :     Word16 q_cy_auto_dir_smooth_local[2];
    4179             : #else
    4180             :     Word16 ch_idx, cur_idx, i, q_tmp;
    4181             :     Word64 W_tmp[CLDFB_NO_CHANNELS_MAX], W_max;
    4182             :     set64_fx( W_tmp, 0, CLDFB_NO_CHANNELS_MAX );
    4183             : #endif
    4184             : 
    4185             :     /* segment auxiliary buffer */
    4186             :     Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    4187             : 
    4188             :     /* estimate direct and diffuse power */
    4189             : #ifndef FIX_867_CLDFB_NRG_SCALE
    4190             :     FOR( i = 0; i < num_freq_bands; i++ )
    4191             :     {
    4192             :         direct_power[i] = Mpy_32_32( direct_power_factor[i], reference_power[i] );
    4193             :         move32();
    4194             :         test();
    4195             :         if ( direct_power[i] == 0 && ( direct_power_factor[i] != 0 && reference_power[i] != 0 ) )
    4196             :         {
    4197             :             direct_power[i] = 1;
    4198             :             move32();
    4199             :         }
    4200             :     }
    4201             : #else
    4202       77963 :     v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands );
    4203             : #endif
    4204             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    4205      595814 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    4206             :     {
    4207      517851 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    4208             : 
    4209             : #ifndef FIX_867_CLDFB_NRG_SCALE
    4210             :         W_max = 0;
    4211             :         move64();
    4212             :         FOR( i = 0; i < num_freq_bands; i++ )
    4213             :         {
    4214             :             W_tmp[i] = W_mult_32_32( direct_power[i], direct_responses_square[cur_idx + i] ); // q_reference_power + Q31 + 1
    4215             :             move64();
    4216             :             IF( LT_64( W_max, W_abs( W_tmp[i] ) ) )
    4217             :             {
    4218             :                 W_max = W_abs( W_tmp[i] );
    4219             :             }
    4220             :         }
    4221             :         q_tmp = W_norm( W_max );
    4222             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4223             :         FOR( i = 0; i < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); i++ )
    4224             :         {
    4225             :             cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power[0]+q_tmp*/
    4226             :             move32();
    4227             :         }
    4228             :         Word16 q_tmp2 = sub( q_tmp, sub( q_reference_power[1], q_reference_power[0] ) );
    4229             :         FOR( i = CLDFB_NO_CHANNELS_HALF; i < num_freq_bands; i++ )
    4230             :         {
    4231             :             cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp2 ) ); /*q_reference_power[1]+q_tmp*/
    4232             :             move32();
    4233             :         }
    4234             :         q_cy_auto_dir_smooth[ch_idx] = add( q_reference_power[0], q_tmp );
    4235             :         move16();
    4236             : #else
    4237             :         FOR( i = 0; i < num_freq_bands; i++ )
    4238             :         {
    4239             :             cy_auto_dir_smooth[cur_idx + i] = W_extract_h( W_shl( W_tmp[i], q_tmp ) ); /*q_reference_power+q_tmp*/
    4240             :             move32();
    4241             :         }
    4242             :         q_cy_auto_dir_smooth[ch_idx] = add( *q_reference_power, q_tmp );
    4243             :         move16();
    4244             : #endif
    4245             : #else
    4246      517851 :         q_tmp = L_norm_arr( &direct_responses_square[cur_idx], num_freq_bands );
    4247      517851 :         Copy_Scale_sig32( &direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp );
    4248      517851 :         v_mult_fixed( direct_power, L_tmp, &cy_auto_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, q_tmp) -> q_reference_power + q_tmp
    4249             : 
    4250      517851 :         q_cy_auto_dir_smooth_local[0] = add( add( q_reference_power[0], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    4251      517851 :         q_cy_auto_dir_smooth_local[1] = add( add( q_reference_power[1], q_tmp ), L_norm_arr( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ) ) );
    4252      517851 :         q_cy_auto_dir_smooth[ch_idx] = s_min( q_cy_auto_dir_smooth_local[0], q_cy_auto_dir_smooth_local[1] );
    4253      517851 :         move16();
    4254             : 
    4255      517851 :         Scale_sig32( cy_auto_dir_smooth + cur_idx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[0], q_tmp ) ) );
    4256      517851 :         Scale_sig32( cy_auto_dir_smooth + cur_idx + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_cy_auto_dir_smooth[ch_idx], add( q_reference_power[1], q_tmp ) ) );
    4257             : 
    4258             : #endif
    4259      517851 :         v_mult_fixed( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands ); // (q_reference_power, Q31) -> q_reference_power
    4260             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4261      517851 :         Scale_sig32( &cy_cross_dir_smooth[cur_idx] + CLDFB_NO_CHANNELS_HALF, s_max( sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), 0 ), sub( q_reference_power[0], q_reference_power[1] ) );
    4262             : #endif
    4263             :     }
    4264             : 
    4265             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4266       77963 :     *q_cy_cross_dir_smooth = q_reference_power[0];
    4267       77963 :     move16();
    4268             : #else
    4269             :     *q_cy_cross_dir_smooth = *q_reference_power;
    4270             :     move16();
    4271             : #endif
    4272             : 
    4273       77963 :     return;
    4274             : }
    4275             : 
    4276             : 
    4277       72000 : static void computeTargetPSDs_diffuse_fx(
    4278             :     const Word16 num_channels,
    4279             :     const Word16 num_freq_bands,
    4280             :     const Word16 start_band,
    4281             :     const Word32 *diffuse_power_factor, /*q31*/
    4282             :     const Word32 *reference_power,      /*q_reference_power*/
    4283             :     const Word16 *q_reference_power,
    4284             :     const Word32 *diffuse_responses_square, /*Q31*/
    4285             :     Word32 *cy_auto_diff_smooth,            /*q_cy_auto_diff_smooth*/
    4286             :     Word16 *q_cy_auto_diff_smooth )
    4287             : {
    4288             :     Word16 ch_idx, cur_idx;
    4289             : 
    4290             :     /* segment auxiliary buffer */
    4291             :     Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX];  /* size: num_freq_bands. */
    4292             :     Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    4293             : 
    4294             :     /* estimate direct and diffuse power */
    4295       72000 :     v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
    4296             : 
    4297             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4298       72000 :     Word16 common_q = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
    4299             : #else
    4300             :     Word16 common_q = s_min( *q_cy_auto_diff_smooth, *q_reference_power );
    4301             : #endif
    4302             : 
    4303             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    4304      784000 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    4305             :     {
    4306      712000 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    4307             : 
    4308      712000 :         v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, sub( num_freq_bands, start_band ) ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
    4309             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4310      712000 :         scale_sig32( aux_buffer_res, s_min( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ), sub( common_q, q_reference_power[0] ) );                                    /* Q(common_q) */
    4311      712000 :         scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( sub( num_freq_bands, start_band ), CLDFB_NO_CHANNELS_HALF ) ), sub( common_q, q_reference_power[1] ) ); /* Q(common_q) */
    4312             : #else
    4313             :         scale_sig32( aux_buffer_res, sub( num_freq_bands, start_band ), sub( common_q, *q_reference_power ) ); /* Q(common_q) */
    4314             : #endif
    4315      712000 :         scale_sig32( &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), sub( common_q, *q_cy_auto_diff_smooth ) );                        /* Q(common_q) */
    4316      712000 :         v_add_fixed( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ), Q1 ); /* Q(common_q) - Q1 */
    4317             :     }
    4318             : 
    4319             :     /* Q adjustment */
    4320       72000 :     *q_cy_auto_diff_smooth = sub( common_q, Q1 );
    4321       72000 :     move16();
    4322             : 
    4323       72000 :     return;
    4324             : }
    4325             : 
    4326             : 
    4327       77963 : static void computeTargetPSDs_diffuse_subframe_fx(
    4328             :     const Word16 num_channels,
    4329             :     const Word16 num_freq_bands,
    4330             :     const Word16 start_band,
    4331             :     const Word32 *diffuse_power_factor, /*q31*/
    4332             :     const Word32 *reference_power,      /*q_reference_power*/
    4333             :     const Word16 *q_reference_power,
    4334             :     const Word32 *diffuse_responses_square, /*q31*/
    4335             :     Word32 *cy_auto_diff_smooth,            /*q_cy_auto_diff_smooth*/
    4336             :     Word16 *q_cy_auto_diff_smooth )
    4337             : {
    4338             :     Word16 ch_idx, cur_idx;
    4339             :     Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */
    4340             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4341             :     Word16 q_cy_auto_diff_smooth_new, q_diffuse_power;
    4342             : #endif
    4343             : 
    4344             :     /* estimate direct and diffuse power */
    4345       77963 :     v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
    4346             : 
    4347             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4348       77963 :     q_diffuse_power = s_min( q_reference_power[0], q_reference_power[1] );
    4349       77963 :     Scale_sig32( diffuse_power, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_diffuse_power, q_reference_power[0] ) );
    4350       77963 :     Scale_sig32( diffuse_power + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_diffuse_power, q_reference_power[1] ) );
    4351       77963 :     q_cy_auto_diff_smooth_new = q_diffuse_power;
    4352       77963 :     IF( LT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
    4353             :     {
    4354        3966 :         Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_cy_auto_diff_smooth_new ) );
    4355        3966 :         q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth;
    4356        3966 :         move16();
    4357             :     }
    4358             : #endif
    4359             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    4360      595814 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    4361             :     {
    4362      517851 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    4363             : 
    4364             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4365      517851 :         IF( GT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
    4366             :         {
    4367      460751 :             Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_diffuse_power, *q_cy_auto_diff_smooth ) );
    4368             :         }
    4369             : #endif
    4370      517851 :         v_multc_fixed( &diffuse_power[start_band], diffuse_responses_square[ch_idx], &cy_auto_diff_smooth[cur_idx + start_band], sub( num_freq_bands, start_band ) ); // (q_reference_power, Q31) -> q_reference_power
    4371             :     }
    4372             : 
    4373             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4374       77963 :     *q_cy_auto_diff_smooth = q_cy_auto_diff_smooth_new;
    4375       77963 :     move16();
    4376             : #else
    4377             :     *q_cy_auto_diff_smooth = *q_reference_power;
    4378             :     move16();
    4379             : #endif
    4380             : 
    4381       77963 :     return;
    4382             : }
    4383             : 
    4384             : 
    4385      209936 : static void computeTargetPSDs_diffuse_with_onsets_fx(
    4386             :     const Word16 num_channels,
    4387             :     const Word16 num_freq_bands,
    4388             :     const Word16 num_decorr_freq_bands,
    4389             :     const Word16 *proto_frame_diff_index,
    4390             :     const Word32 *diffuse_power_factor, /*q31*/
    4391             :     const Word32 *reference_power,      /* q_reference_power */
    4392             :     const Word16 *q_reference_power,
    4393             :     const Word32 *diffuse_responses_square, /*q31*/
    4394             :     const Word32 *onset_filter,             /*q31*/
    4395             :     Word32 *cy_auto_diff_smooth,            /*q_cy_auto_diff_smooth*/
    4396             :     Word16 *q_cy_auto_diff_smooth )
    4397             : {
    4398             :     Word16 ch_idx, cur_idx, diff_idx;
    4399             :     Word32 diffuse_response_p4, aux_buffer_res1[CLDFB_NO_CHANNELS_MAX];
    4400             :     /* segment auxiliary buffer */
    4401             :     Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX];  /* size: num_freq_bands. */
    4402             :     Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    4403             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4404             :     Word16 q_common, q_reference_power_min_one[2];
    4405             : 
    4406      209936 :     q_reference_power_min_one[0] = sub( q_reference_power[0], Q1 );
    4407      209936 :     q_reference_power_min_one[1] = sub( q_reference_power[1], Q1 );
    4408             : #else
    4409             :     Word16 q_common, q_reference_power_min_one;
    4410             : 
    4411             :     q_reference_power_min_one = sub( *q_reference_power, Q1 );
    4412             : #endif
    4413             : 
    4414             :     /* estimate direct and diffuse power */
    4415      209936 :     v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
    4416             : 
    4417             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4418      209936 :     q_common = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power_min_one[0], q_reference_power_min_one[1] ) );
    4419             : #else
    4420             :     IF( GT_16( *q_cy_auto_diff_smooth, q_reference_power_min_one ) )
    4421             :     {
    4422             :         q_common = q_reference_power_min_one;
    4423             :         move16();
    4424             :     }
    4425             :     ELSE
    4426             :     {
    4427             :         q_common = *q_cy_auto_diff_smooth;
    4428             :         move16();
    4429             :     }
    4430             : #endif
    4431             : 
    4432             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    4433     1682192 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    4434             :     {
    4435     1472256 :         diffuse_response_p4 = Mpy_32_32( diffuse_responses_square[ch_idx], diffuse_responses_square[ch_idx] ); // (Q31, Q31) -> Q31
    4436             : 
    4437     1472256 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    4438     1472256 :         diff_idx = imult1616( proto_frame_diff_index[ch_idx], num_freq_bands );
    4439             : 
    4440     1472256 :         v_multc_fixed( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
    4441     1472256 :         v_multc_fixed( &onset_filter[diff_idx], INT_MIN, aux_buffer_res, num_decorr_freq_bands );                           // (Q31, Q31) -> Q31
    4442     1472256 :         v_addc_fixed( aux_buffer_res, ONE_IN_Q31, aux_buffer_res, num_decorr_freq_bands );                                  // Q31
    4443     1472256 :         v_multc_fixed( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands );                        // (Q31, Q31) -> Q31
    4444     1472256 :         v_add_fixed( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands, Q1 );                          // Q30
    4445     1472256 :         v_mult_fixed( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands );                               // (Q30, q_reference_power) -> q_reference_power - Q1
    4446             : 
    4447             : #ifdef FIX_867_CLDFB_NRG_SCALE
    4448     1472256 :         IF( NE_16( q_common, q_reference_power_min_one[0] ) )
    4449             :         {
    4450       17631 :             scale_sig32( aux_buffer_res, s_min( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_common, q_reference_power_min_one[0] ) ); // q_common
    4451             :         }
    4452     1472256 :         IF( NE_16( q_common, q_reference_power_min_one[1] ) )
    4453             :         {
    4454      686647 :             scale_sig32( aux_buffer_res + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_decorr_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_common, q_reference_power_min_one[1] ) ); // q_common
    4455             :         }
    4456     1472256 :         IF( NE_16( q_common, *q_cy_auto_diff_smooth ) )
    4457             :         {
    4458     1168005 :             scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common
    4459             :         }
    4460     1472256 :         v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 );                                                 // (q_common - Q1)
    4461     1472256 :         scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1)
    4462             : #else
    4463             :         IF( NE_16( q_common, q_reference_power_min_one ) )
    4464             :         {
    4465             :             scale_sig32( aux_buffer_res, num_decorr_freq_bands, sub( q_common, q_reference_power_min_one ) ); // q_common
    4466             :         }
    4467             :         IF( NE_16( q_common, *q_cy_auto_diff_smooth ) )
    4468             :         {
    4469             :             scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common
    4470             :         }
    4471             :         v_add_fixed( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, Q1 );                                                 // (q_common - Q1)
    4472             :         scale_sig32( &cy_auto_diff_smooth[cur_idx + num_decorr_freq_bands], sub( num_freq_bands, num_decorr_freq_bands ), sub( sub( q_common, Q1 ), *q_cy_auto_diff_smooth ) ); // (q_common - Q1)
    4473             : #endif
    4474             :     }
    4475             : 
    4476             :     /* Q adjustment */
    4477      209936 :     *q_cy_auto_diff_smooth = sub( q_common, Q1 );
    4478      209936 :     move16();
    4479             : 
    4480      209936 :     return;
    4481             : }
    4482             : 
    4483             : 
    4484        2716 : static void computeAlphaSynthesis_fx( Word16 *alpha_synthesis_fx /*q15*/, const Word16 averaging_length_ms, const Word16 maxAlpha_fx /*q15*/, Word16 *numAlphas, const Word16 slot_size, const Word16 num_freq_bands, Word16 *frequency_axis_fx /*q0*/, const Word32 output_Fs )
    4485             : {
    4486             :     Word16 k;
    4487             :     Word16 avg_length_f_ms_fx;
    4488             : 
    4489             :     /* check input pointer */
    4490        2716 :     IF( alpha_synthesis_fx == NULL )
    4491             :     {
    4492           0 :         return;
    4493             :     }
    4494             : 
    4495        2716 :     IF( averaging_length_ms == 0 )
    4496             :     {
    4497           0 :         set16_fx( alpha_synthesis_fx, MAX16B, num_freq_bands ); /*q15*/
    4498             :     }
    4499             :     ELSE
    4500             :     {
    4501       10864 :         FOR( k = 0; k < num_freq_bands; k++ )
    4502             :         {
    4503       10864 :             Word16 faxis_idx = s_max( k, 1 );
    4504             : 
    4505             :             // avg_length_f_ms = 1000.f * (float)averaging_length_ms / fabsf(frequency_axis[faxis_idx]);
    4506       10864 :             Word16 tmp_exp = 0;
    4507       10864 :             Word16 tmp_1 = BASOP_Util_Divide1616_Scale( averaging_length_ms, frequency_axis_fx[faxis_idx], &tmp_exp ); /*Q(15-(tmp_exp+15-15))*/
    4508       10864 :             Word16 tmp_2 = mult( tmp_1, 1000 );                                                                        // 15 - tmp_exp + 0 -15 = -tmp_exp (Q-fac)
    4509       10864 :             avg_length_f_ms_fx = tmp_2;                                                                                // Q(-tmp_exp)
    4510       10864 :             move16();
    4511       10864 :             move16();
    4512             : 
    4513             :             /*            alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );*/
    4514       10864 :             Word32 tmp_3 = Mpy_32_16_1( output_Fs, avg_length_f_ms_fx ); // 0 - tmp_exp - 15 (Q-fac)
    4515             :             Word16 tmp_exp_3;
    4516       10864 :             Word16 tmp_4 = BASOP_Util_Divide3232_Scale( tmp_3, 1000, &tmp_exp_3 ); /*tmp_exp_4 stores resultant exponent*/
    4517       10864 :             Word16 tmp_exp_4 = sub( add( tmp_exp_3, add( add( 31, tmp_exp ), 15 ) ), 31 );
    4518             :             Word16 tmp_exp_5;
    4519       10864 :             Word16 tmp_5 = BASOP_Util_Divide1616_Scale( slot_size, tmp_4, &tmp_exp_5 ); /*res_exp stores resultant exponent*/
    4520       10864 :             Word16 res_exp = sub( add( tmp_exp_5, 15 ), tmp_exp_4 );
    4521             : 
    4522       10864 :             Word16 flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( tmp_5 ), res_exp, 1, 31 );
    4523       10864 :             IF( EQ_16( flag, -1 ) )
    4524             :             {
    4525       10864 :                 alpha_synthesis_fx[k] = shr( tmp_5, negate( res_exp ) ); // q15
    4526       10864 :                 move16();
    4527             :             }
    4528             :             ELSE
    4529             :             {
    4530           0 :                 alpha_synthesis_fx[k] = MAX16B; /*q15*/
    4531           0 :                 move16();
    4532             :             }
    4533             : 
    4534       10864 :             Word16 flag2 = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( alpha_synthesis_fx[k] ), 0, L_deposit_h( maxAlpha_fx ), 0 );
    4535       10864 :             test();
    4536       10864 :             IF( flag2 == 0 || EQ_16( flag2, 1 ) )
    4537             :             {
    4538        2716 :                 alpha_synthesis_fx[k] = maxAlpha_fx; /*q15*/
    4539        2716 :                 move16();
    4540        2716 :                 *numAlphas = add( k, 1 );
    4541        2716 :                 move16();
    4542        2716 :                 BREAK;
    4543             :             }
    4544             :         }
    4545             :     }
    4546             : 
    4547        2716 :     return;
    4548             : }
    4549             : 
    4550             : 
    4551      566249 : static void spreadCoherencePanningHoa_fx(
    4552             :     const Word16 azimuth,
    4553             :     const Word16 elevation,
    4554             :     const Word16 spreadCoh_fx,  /*i:Q15*/
    4555             :     Word32 *direct_response_fx, /*i/o:Q_direct_response*/
    4556             :     Word16 *Q_direct_response,  /*i/o:stores q for direct_response_fx*/
    4557             :     const Word16 num_channels_dir,
    4558             :     const Word16 ambisonics_order )
    4559             : {
    4560             :     Word16 i;
    4561             : 
    4562             :     Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
    4563             :     Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
    4564             :     Word32 gainCenter_fx;
    4565             :     Word32 gainSide_fx;
    4566             : 
    4567      566249 :     ivas_dirac_dec_get_response_fx( azimuth, elevation, direct_response_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
    4568             : 
    4569             :     Word16 exp_Gain_side, exp_Gain_center;
    4570      566249 :     IF( spreadCoh_fx > 0 )
    4571             :     {
    4572      322745 :         ivas_dirac_dec_get_response_fx( add( azimuth, 30 ), elevation, direct_response_left_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
    4573      322745 :         ivas_dirac_dec_get_response_fx( add( azimuth, 330 ), elevation, direct_response_right_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
    4574             : 
    4575             : 
    4576             :         Word16 var_a, var_b, exp_a;
    4577             : 
    4578      322745 :         IF( LT_16( spreadCoh_fx, ONE_IN_Q14 /*0.5 q15*/ ) )
    4579             :         {
    4580             :             /*gainCenter  = (3 - 4*spreadCoh )/3*/
    4581      317873 :             var_a = sub( 24576 /*3 in Q13*/, spreadCoh_fx ); // Q13
    4582      317873 :             var_a = mult( var_a, ONE_BY_THREE_Q15 );         // Q13
    4583             : 
    4584      317873 :             gainCenter_fx = L_deposit_h( shr( var_a, 2 ) );                      // Q11 + 16 = Q27
    4585      317873 :             gainSide_fx = L_deposit_h( mult( spreadCoh_fx, ONE_BY_THREE_Q15 ) ); // Q14 + 16 (reduce Q by 1 to *2) = Q30
    4586      317873 :             exp_Gain_side = 31 - Q30;
    4587      317873 :             move16();
    4588      317873 :             exp_Gain_center = 31 - Q27;
    4589      317873 :             move16();
    4590             :         }
    4591             :         ELSE
    4592             :         {
    4593        4872 :             var_a = shl( sub( 16384 /*2 in Q13*/, shr( spreadCoh_fx, 2 ) ), 1 ); // q13
    4594        4872 :             exp_a = 15 - Q13;
    4595        4872 :             move16();
    4596        4872 :             var_a = Inv16( var_a, &exp_a );     // 15-exp_a
    4597        4872 :             gainSide_fx = L_deposit_h( var_a ); // 15-exp_a + 16 = Q31 -exp_a
    4598        4872 :             exp_Gain_side = exp_a;
    4599        4872 :             move16();
    4600             : 
    4601        4872 :             var_b = sub( 8192 /*2 in Q12*/, shr( spreadCoh_fx, 2 ) /*Q14*/ ); // exp => 3
    4602        4872 :             gainCenter_fx = L_deposit_h( mult( var_b, var_a ) );              // 15-exp_a + 12-15+16=>28-exp_a =  // 3 + exp_a
    4603        4872 :             exp_Gain_center = add( 3, exp_a );
    4604             :         }
    4605             : 
    4606             : 
    4607             :         Word32 mpy1, mpy2;
    4608             :         Word16 exp_arr[16], exp;
    4609      322745 :         set16_fx( exp_arr, sub( 31, *Q_direct_response ), 16 );
    4610     2589658 :         FOR( i = 0; i < num_channels_dir; i++ )
    4611             :         {
    4612     2266913 :             mpy1 = Mpy_32_32( L_add( direct_response_left_fx[i], direct_response_right_fx[i] ), gainSide_fx ); // 31 - Q_direct_response + exp_Gain_Side
    4613     2266913 :             mpy2 = Mpy_32_32( direct_response_fx[i], gainCenter_fx );                                          // 31 - Q_direct_response + exp_Gain_Center
    4614     2266913 :             exp = 0;
    4615     2266913 :             move16();
    4616     2266913 :             direct_response_fx[i] = BASOP_Util_Add_Mant32Exp( mpy1, add( sub( 31, *Q_direct_response ), exp_Gain_side ), mpy2, add( sub( 31, *Q_direct_response ), exp_Gain_center ), &exp ); // 31-exp
    4617     2266913 :             move32();
    4618     2266913 :             exp_arr[i] = exp;
    4619     2266913 :             move16();
    4620             :         }
    4621      322745 :         Word16 max_val = MIN_16;
    4622      322745 :         move16();
    4623     5486665 :         FOR( i = 0; i < 16; i++ )
    4624             :         {
    4625     5163920 :             max_val = s_max( max_val, exp_arr[i] );
    4626             :         }
    4627     5486665 :         FOR( i = 0; i < 16; i++ )
    4628             :         {
    4629     5163920 :             direct_response_fx[i] = L_shr( direct_response_fx[i], sub( max_val, exp_arr[i] ) ); // Q(31-exp_arr[i])->q(31-max_val)
    4630     5163920 :             move32();
    4631             :         }
    4632      322745 :         *Q_direct_response = sub( 31, max_val );
    4633      322745 :         move16();
    4634             :     }
    4635             : 
    4636      566249 :     return;
    4637             : }
    4638             : 
    4639             : 
    4640     5119059 : static void spreadCoherencePanningVbap_fx(
    4641             :     const Word16 azimuth,       /*i:q0*/
    4642             :     const Word16 elevation,     /*i:q0*/
    4643             :     const Word16 spreadCoh_fx,  /*i:q15*/
    4644             :     Word32 *direct_response_fx, /*i/o:Q_direct_response*/
    4645             :     Word16 *Q_direct_response,  /*o: stores q for direct_response_fx*/
    4646             :     const Word16 num_channels_dir,
    4647             :     const VBAP_HANDLE hVBAPdata )
    4648             : {
    4649             :     Word16 i;
    4650             :     Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
    4651             :     Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
    4652     5119059 :     set32_fx( direct_response_left_fx, 0, MAX_OUTPUT_CHANNELS );
    4653     5119059 :     set32_fx( direct_response_right_fx, 0, MAX_OUTPUT_CHANNELS );
    4654             :     Word32 gainCenter_fx;
    4655             :     Word32 gainSide_fx;
    4656             : 
    4657     5119059 :     IF( hVBAPdata == NULL )
    4658             :     {
    4659             :         /* Distribute signal to all channels if VBAP is not properly initialized. */
    4660           0 :         Word16 exp_tmp = 0;
    4661           0 :         move16();
    4662           0 :         Word16 var_temp = ISqrt16( num_channels_dir, &exp_tmp );
    4663           0 :         set32_fx( direct_response_fx, var_temp, num_channels_dir );
    4664           0 :         *Q_direct_response = sub( 31, exp_tmp );
    4665           0 :         move16();
    4666             : 
    4667           0 :         return;
    4668             :     }
    4669             : 
    4670     5119059 :     set32_fx( direct_response_fx, 0, MAX_OUTPUT_CHANNELS );
    4671     5119059 :     vbap_determine_gains_fx( hVBAPdata, direct_response_fx /*q29*/, azimuth, elevation, 0 );
    4672     5119059 :     *Q_direct_response = Q29;
    4673     5119059 :     move16();
    4674             : 
    4675     5119059 :     IF( spreadCoh_fx > 0 )
    4676             :     {
    4677      459977 :         vbap_determine_gains_fx( hVBAPdata, direct_response_left_fx /*q29*/, add( azimuth, 30 ), elevation, 0 );
    4678      459977 :         vbap_determine_gains_fx( hVBAPdata, direct_response_right_fx /*q29*/, sub( azimuth, 30 ), elevation, 0 );
    4679             : 
    4680      459977 :         Word32 var1 = 0;
    4681      459977 :         move32();
    4682      459977 :         Word32 var2 = 0;
    4683      459977 :         move32();
    4684      459977 :         Word16 var_a = 0;
    4685      459977 :         move16();
    4686      459977 :         Word16 var_b = 0;
    4687      459977 :         move16();
    4688      459977 :         IF( LT_16( spreadCoh_fx, 16384 ) ) // 16384 = 0.5 in Q15
    4689             :         {
    4690      449157 :             var_a = mult( spreadCoh_fx, INV_SQRT3_FX );         // Q14
    4691      449157 :             var_b = sub( ONE_IN_Q14, spreadCoh_fx );            // Q14
    4692      449157 :             gainCenter_fx = L_deposit_h( add( var_a, var_b ) ); // Q30
    4693      449157 :             gainSide_fx = L_deposit_h( var_a );                 // Q30
    4694             :         }
    4695             :         ELSE
    4696             :         {
    4697       10820 :             var_a = sub( ONE_IN_Q14, shr( spreadCoh_fx, 1 ) ); // Q13
    4698       10820 :             gainCenter_fx = L_shl( L_deposit_h( var_a ), 1 );  // Q30
    4699       10820 :             gainSide_fx = ONE_IN_Q30;
    4700       10820 :             move32();
    4701             :         }
    4702             : 
    4703      459977 :         Word32 var3 = 0;
    4704      459977 :         move32();
    4705      459977 :         *Q_direct_response = Q28;
    4706      459977 :         move16();
    4707     3988489 :         FOR( i = 0; i < num_channels_dir; i++ )
    4708             :         {
    4709     3528512 :             var1 = L_add( direct_response_left_fx[i], direct_response_right_fx[i] ); // Q29
    4710     3528512 :             var2 = Mpy_32_32( var1, gainSide_fx );                                   // Q28
    4711     3528512 :             var3 = Mpy_32_32( direct_response_fx[i], gainCenter_fx );                // Q28
    4712     3528512 :             direct_response_fx[i] = L_add( var3, var2 );                             // Q28
    4713     3528512 :             move32();
    4714             :         }
    4715             :     }
    4716             : 
    4717     5119059 :     return;
    4718             : }
    4719             : 
    4720             : 
    4721    10273813 : static void normalizePanningGains_fx(
    4722             :     Word32 *direct_response_fx, /*i/o:resultant q is q_direct_res*/
    4723             :     Word16 *q_direct_res,       /*i/o: stores q for direct_response_fx*/
    4724             :     const Word16 num_channels_dir )
    4725             : {
    4726             :     Word32 energySum_fx;
    4727    10273813 :     Word16 exp_energySum = 0;
    4728             :     Word32 normVal_fx;
    4729             :     Word16 i;
    4730    10273813 :     move16();
    4731             : 
    4732    10273813 :     Word16 gb = find_guarded_bits_fx( num_channels_dir );
    4733    10273813 :     energySum_fx = sum2_f_32_fx( direct_response_fx, num_channels_dir, gb ); // exp_energySum stores resultant exponent
    4734    10273813 :     IF( GT_16( *q_direct_res, Q31 ) )
    4735             :     {
    4736        1691 :         exp_energySum = add( shl( sub( Q31, *q_direct_res ), 1 ), gb );
    4737             :     }
    4738    10273813 :     exp_energySum = sub( Q31, sub( sub( shl( *q_direct_res, 1 ), Q31 ), gb ) );
    4739             : 
    4740    10273813 :     IF( energySum_fx > 0 )
    4741             :     {
    4742    10260101 :         normVal_fx = ISqrt32( energySum_fx, &exp_energySum ); // 31-exp_energySum
    4743             :     }
    4744             :     ELSE
    4745             :     {
    4746       13712 :         energySum_fx = BASOP_Util_Add_Mant32Exp( energySum_fx, exp_energySum, ONE_IN_Q30, 1, &exp_energySum ); // 31-exp_energySum
    4747       13712 :         normVal_fx = ISqrt32( energySum_fx, &exp_energySum );                                                  // 31-exp_energySum
    4748             :     }
    4749             : 
    4750   108107232 :     FOR( i = 0; i < num_channels_dir; i++ )
    4751             :     {
    4752    97833419 :         direct_response_fx[i] = Mpy_32_32( direct_response_fx[i], normVal_fx ); // q_direct_res stores resultant q for the same
    4753    97833419 :         move32();
    4754             :     }
    4755    10273813 :     Word16 exp = add( sub( Q31, *q_direct_res ), exp_energySum );
    4756    10273813 :     *q_direct_res = sub( Q31, exp );
    4757             : 
    4758    10273813 :     return;
    4759             : }

Generated by: LCOV version 1.14