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 -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 1976 2082 94.9 %
Date: 2025-08-23 01:22:27 Functions: 19 19 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        2254 : 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        2254 :     Word16 interpolator_tbl[JBM_CLDFB_SLOTS_IN_SUBFRAME] = { 8192, 16384, 24576, MAX16B }; /* idx / JBM_CLDFB_SLOTS_IN_SUBFRAME Q15 */
     105        2254 :     move16();
     106        2254 :     move16();
     107        2254 :     move16();
     108        2254 :     move16();
     109             : 
     110             :     /* pointers to structs for allocation */
     111        2254 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     112        2254 :     DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     113             : 
     114             :     /* check / set input parameters */
     115        2254 :     assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
     116        2254 :     assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
     117        2254 :     assert( hDirACRend->num_outputs_diff > 0 );
     118        2254 :     assert( hSpatParamRendCom->slot_size > 0 );
     119        2254 :     assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
     120        2254 :     assert( hDirACRend->diffuse_response_function_fx != NULL );
     121             : 
     122        2254 :     IF( hDirACRend->proto_signal_decorr_on )
     123             :     {
     124        2097 :         dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
     125        2097 :         move16();
     126             :     }
     127             :     ELSE
     128             :     {
     129         157 :         dirac_output_synthesis_params->max_band_decorr = 0;
     130         157 :         move16();
     131             :     }
     132             : 
     133             :     /*-----------------------------------------------------------------*
     134             :      * memory allocation
     135             :      *-----------------------------------------------------------------*/
     136             : 
     137        2254 :     dirac_output_synthesis_state->diffuse_responses_square_fx = NULL;
     138             : 
     139        2254 :     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        2143 :     ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     147             :     {
     148        1308 :         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        2254 :     dirac_output_synthesis_state->proto_power_smooth_prev_fx = NULL;
     156             : 
     157        2254 :     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     158             :     {
     159        1419 :         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        1419 :         dirac_output_synthesis_state->proto_power_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir );
     164        1419 :         move16();
     165             :     }
     166        2254 :     test();
     167        2254 :     test();
     168        2254 :     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        1262 :         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        1262 :         dirac_output_synthesis_state->proto_power_diff_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->hOutSetup.nchan_out_woLFE );
     175        1262 :         move16();
     176             :     }
     177             :     ELSE
     178             :     {
     179         992 :         dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx = NULL;
     180             :     }
     181             : 
     182             :     /* buffer length and interpolator */
     183        2254 :     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        2254 :     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        2142 :         size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     196             :     }
     197        2254 :     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        2254 :     dirac_output_synthesis_state->cy_cross_dir_smooth_prev_len = size;
     202        2254 :     move16();
     203             : 
     204        2254 :     IF( ( dirac_output_synthesis_state->Q_temp_cy_cross_dir_smooth_fx = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
     205             :     {
     206           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     207             :     }
     208             : 
     209        2254 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     210             :     {
     211         835 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx = NULL;
     212         835 :         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 )
     213             :         {
     214           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     215             :         }
     216         835 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
     217         835 :         move16();
     218             :     }
     219             :     ELSE
     220             :     {
     221        1419 :         IF( ( dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
     222             :         {
     223           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     224             :         }
     225        1419 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     226        1419 :         move16();
     227             : 
     228        1419 :         IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
     229             :         {
     230         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 )
     231             :             {
     232           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     233             :             }
     234         412 :             dirac_output_synthesis_state->cy_auto_diff_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     235         412 :             move16();
     236             :         }
     237             :         ELSE
     238             :         {
     239        1007 :             IF( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
     240             :             {
     241           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     242             :             }
     243        1007 :             dirac_output_synthesis_state->cy_auto_diff_smooth_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
     244        1007 :             move16();
     245             :         }
     246             :     }
     247             : 
     248             :     /* direct and diffuse gain buffers */
     249        2254 :     IF( ( dirac_output_synthesis_state->gains_dir_prev_fx = (Word32 *) malloc( size * sizeof( Word32 ) ) ) == NULL )
     250             :     {
     251           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     252             :     }
     253        2254 :     dirac_output_synthesis_state->gains_dir_prev_len = size;
     254        2254 :     move16();
     255        2254 :     test();
     256        2254 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     257             :     {
     258         835 :         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 )
     259             :         {
     260           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     261             :         }
     262         835 :         dirac_output_synthesis_state->gains_diff_prev_len = imult1616( dirac_output_synthesis_params->max_band_decorr, hDirACRend->num_outputs_diff );
     263         835 :         move16();
     264             :     }
     265        1419 :     ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) && NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
     266             :     {
     267         896 :         IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( Word32 ) ) ) == NULL )
     268             :         {
     269           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     270             :         }
     271         896 :         dirac_output_synthesis_state->gains_diff_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff );
     272         896 :         move16();
     273             :     }
     274             :     ELSE
     275             :     {
     276         523 :         IF( ( dirac_output_synthesis_state->gains_diff_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( Word32 ) ) ) == NULL )
     277             :         {
     278           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     279             :         }
     280         523 :         dirac_output_synthesis_state->gains_diff_prev_len = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     281         523 :         move16();
     282             :     }
     283             : 
     284             :     /*-----------------------------------------------------------------*
     285             :      * prepare processing parameters
     286             :      *-----------------------------------------------------------------*/
     287             : 
     288             :     /* compute alpha */
     289        2254 :     test();
     290        2254 :     test();
     291        2254 :     IF( !( EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) )
     292             :     {
     293        1419 :         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 );
     294             : 
     295        1419 :         IF( ( dirac_output_synthesis_params->alpha_synthesis_fx = (Word16 *) malloc( dirac_output_synthesis_params->numAlphas * sizeof( Word16 ) ) ) == NULL )
     296             :         {
     297           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     298             :         }
     299        1419 :         Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fx, dirac_output_synthesis_params->numAlphas ); /*q15*/
     300             : 
     301        1419 :         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 );
     302             : 
     303        1419 :         IF( ( dirac_output_synthesis_params->alpha_synthesis_fast_fx = (Word16 *) malloc( dirac_output_synthesis_params->numAlphasFast * sizeof( Word16 ) ) ) == NULL )
     304             :         {
     305           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     306             :         }
     307        1419 :         Copy( temp_alpha_synthesis_fx, dirac_output_synthesis_params->alpha_synthesis_fast_fx, dirac_output_synthesis_params->numAlphasFast ); /*q15*/
     308             : 
     309        1419 :         IF( ( dirac_output_synthesis_state->reference_power_smooth_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     310             :         {
     311           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     312             :         }
     313        1419 :         set32_fx( dirac_output_synthesis_state->reference_power_smooth_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
     314        1419 :         dirac_output_synthesis_state->reference_power_smooth_prev_q[0] = Q31;
     315        1419 :         dirac_output_synthesis_state->reference_power_smooth_prev_q[1] = Q31;
     316        1419 :         move16();
     317        1419 :         move16();
     318             : 
     319        1419 :         IF( ( dirac_output_synthesis_state->direction_smoothness_prev_fx = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     320             :         {
     321           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     322             :         }
     323        1419 :         set32_fx( dirac_output_synthesis_state->direction_smoothness_prev_fx, 0, hSpatParamRendCom->num_freq_bands );
     324             :     }
     325             :     ELSE
     326             :     {
     327         835 :         dirac_output_synthesis_params->alpha_synthesis_fx = NULL;
     328         835 :         dirac_output_synthesis_params->alpha_synthesis_fast_fx = NULL;
     329         835 :         dirac_output_synthesis_state->reference_power_smooth_prev_fx = NULL;
     330         835 :         dirac_output_synthesis_state->direction_smoothness_prev_fx = NULL;
     331             :     }
     332             : 
     333             :     /* compute interpolator */
     334       11270 :     FOR( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
     335             :     {
     336        9016 :         dirac_output_synthesis_params->interpolator_fx[idx - 1] = interpolator_tbl[idx - 1]; /* Q15 */
     337        9016 :         move16();
     338             :     }
     339             : 
     340             :     /* prepare diffuse response function */
     341        2254 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
     342             :     {
     343         111 :         num_diffuse_responses = 2;
     344         111 :         move16();
     345             :     }
     346             :     ELSE
     347             :     {
     348        2143 :         num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
     349        2143 :         move16();
     350             :     }
     351             : 
     352        2254 :     IF( dirac_output_synthesis_state->diffuse_responses_square_fx != NULL )
     353             :     {
     354       13050 :         FOR( ch_idx = 0; ch_idx < num_diffuse_responses; ++ch_idx )
     355             :         {
     356             :             /*dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = pow(dirac_output_synthesis_params->diffuse_response_function[ch_idx]/max_response, 2.0f);*/
     357       11631 :             tmp_fx = hDirACRend->diffuse_response_function_fx[ch_idx]; /*q15*/
     358       11631 :             move16();
     359             : 
     360       11631 :             dirac_output_synthesis_state->diffuse_responses_square_fx[ch_idx] = L_mult( tmp_fx, tmp_fx ); /* Q15 + Q15 + 1 -> Q31 */
     361       11631 :             move32();
     362             :         }
     363             :     }
     364             : 
     365             : 
     366        2254 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     367             :     {
     368             :         Word16 diff_compensation_order;
     369             :         Word32 diff_nrg_total_fx, diff_nrg_fx, diff_nrg_trans_fx, diff_nrg_decorr_fx;
     370             : 
     371             :         /* compensate missing diffuseness modelling up order 2, except for HR*/
     372         835 :         IF( GE_16( nchan_transport, 3 ) )
     373             :         {
     374         826 :             diff_compensation_order = 3;
     375         826 :             move16();
     376             :         }
     377             :         ELSE
     378             :         {
     379           9 :             diff_compensation_order = 2;
     380           9 :             move16();
     381             :         }
     382         835 :         diff_compensation_order = s_min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
     383             : 
     384         835 :         diff_nrg_total_fx = 0;
     385         835 :         move32();
     386         835 :         diff_nrg_trans_fx = 0;
     387         835 :         move32();
     388         835 :         diff_nrg_decorr_fx = 0;
     389         835 :         move32();
     390             : 
     391         835 :         Word16 gaurd_bits = find_guarded_bits_fx( imult1616( add( diff_compensation_order, 1 ), add( diff_compensation_order, 1 ) ) );
     392         835 :         tmp16 = add( diff_compensation_order, 1 );
     393         835 :         tmp16 = imult1616( tmp16, tmp16 );
     394       12331 :         FOR( ch_idx = 0; ch_idx < tmp16; ch_idx++ )
     395             :         {
     396       11496 :             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
     397             : 
     398       11496 :             diff_nrg_total_fx = L_add( diff_nrg_total_fx, diff_nrg_fx ); // Q30 - gaurd_bits
     399             : 
     400             :             /* is it a transport channel?*/
     401       11496 :             test();
     402       11496 :             if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
     403             :             {
     404        4042 :                 diff_nrg_trans_fx = L_add( diff_nrg_trans_fx, diff_nrg_fx ); // Q30 - gaurd_bits
     405             :             }
     406             :             /* is it a decorrelated or transport channel?*/
     407       11496 :             if ( LT_16( ch_idx, hDirACRend->num_outputs_diff ) )
     408             :             {
     409        3340 :                 diff_nrg_decorr_fx = L_add( diff_nrg_decorr_fx, diff_nrg_fx ); // Q30 - gaurd_bits
     410             :             }
     411             :         }
     412         835 :         Word16 exp_1 = 0, exp_2 = 0, tmp;
     413         835 :         move16();
     414         835 :         move16();
     415         835 :         tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_trans_fx, &exp_1 );                              // Q(15 - exp_1)
     416         835 :         dirac_output_synthesis_params->diffuse_compensation_factor_fx = L_shl( L_deposit_l( tmp ), add( Q12, exp_1 ) ); // Q27
     417         835 :         move32();
     418             : 
     419         835 :         tmp = BASOP_Util_Divide3232_Scale( diff_nrg_total_fx, diff_nrg_decorr_fx, &exp_2 );                                    // (Q15 - exp_2)
     420         835 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = L_shl( L_deposit_l( tmp ), add( Q14, exp_2 ) ); // Q29
     421         835 :         move32();
     422             :     }
     423             :     ELSE
     424             :     {
     425        1419 :         dirac_output_synthesis_params->diffuse_compensation_factor_fx = 0;
     426        1419 :         move32();
     427        1419 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx = 0;
     428        1419 :         move32();
     429             :     }
     430             : 
     431        2254 :     return IVAS_ERR_OK;
     432             : }
     433             : 
     434             : 
     435             : /*-------------------------------------------------------------------------
     436             :  * ivas_dirac_dec_output_synthesis_init()
     437             :  *
     438             :  *
     439             :  *------------------------------------------------------------------------*/
     440             : 
     441        2277 : void ivas_dirac_dec_output_synthesis_init_fx(
     442             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle         */
     443             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                       */
     444             :     const Word16 nchan_out_woLFE,                         /* i  : number of output audio channels without LFE */
     445             :     const Word16 hodirac_flag                             /* i  : flag to indicate HO-DirAC mode              */
     446             : )
     447             : {
     448             :     Word16 size;
     449             : 
     450             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
     451             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
     452             : 
     453        2277 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     454        2277 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     455             : 
     456             :     /*-----------------------------------------------------------------*
     457             :      * init outputSynthesisPSD_Init
     458             :      *-----------------------------------------------------------------*/
     459             : 
     460             :     /* initialize buffers */
     461        2277 :     IF( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx != NULL )
     462             :     {
     463        1419 :         set32_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
     464             :     }
     465        2277 :     h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev = 0;
     466        2277 :     move16();
     467             : 
     468        2277 :     IF( hodirac_flag )
     469             :     {
     470         112 :         size = imult1616( imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ), DIRAC_HO_NUMSECTORS );
     471             :     }
     472             :     ELSE
     473             :     {
     474        2165 :         size = imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir );
     475             :     }
     476        2277 :     set32_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx, 0, size );
     477        2277 :     h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = 0;
     478        2277 :     move16();
     479             : 
     480        2277 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     481             :     {
     482         858 :         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 ) );
     483             :     }
     484        1419 :     ELSE IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
     485             :     {
     486        1007 :         set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff ) );
     487             :     }
     488             :     ELSE
     489             :     {
     490         412 :         set32_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
     491             :     }
     492        2277 :     h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = 0;
     493        2277 :     move16();
     494             : 
     495        2277 :     IF( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx != NULL )
     496             :     {
     497        1419 :         set32_fx( h_dirac_output_synthesis_state->proto_power_smooth_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_protos_dir ) );
     498        1419 :         h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] = Q31;
     499        1419 :         h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] = Q31;
     500        1419 :         move16();
     501        1419 :         move16();
     502             :     }
     503        2277 :     set32_fx( h_dirac_output_synthesis_state->gains_dir_prev_fx, 0, size );
     504        2277 :     h_dirac_output_synthesis_state->gains_dir_prev_q = 0;
     505        2277 :     move16();
     506             : 
     507        2277 :     IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     508             :     {
     509         858 :         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 ) );
     510             :     }
     511             :     ELSE
     512             :     {
     513        1419 :         set32_fx( h_dirac_output_synthesis_state->gains_diff_prev_fx, 0, imult1616( hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_dir ) );
     514             :     }
     515        2277 :     h_dirac_output_synthesis_state->gains_diff_prev_q = 0;
     516        2277 :     move16();
     517             : 
     518        2277 :     IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx != NULL )
     519             :     {
     520        1262 :         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 ) );
     521             :     }
     522        2277 :     h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_q = Q31;
     523        2277 :     move16();
     524             : 
     525        2277 :     return;
     526             : }
     527             : 
     528             : 
     529             : /*-------------------------------------------------------------------------
     530             :  * ivas_dirac_dec_output_synthesis_close()
     531             :  *
     532             :  * Memory deallocation of Output synthesis sub-module
     533             :  *------------------------------------------------------------------------*/
     534             : 
     535        2254 : void ivas_dirac_dec_output_synthesis_close_fx(
     536             :     DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle                    */
     537             : )
     538             : {
     539             :     /* pointers to structs for allocation */
     540        2254 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     541        2254 :     DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     542             : 
     543             :     /*-----------------------------------------------------------------*
     544             :      * memory deallocation
     545             :      *-----------------------------------------------------------------*/
     546             : 
     547             :     /* free interpolator */
     548        2254 :     IF( ( dirac_output_synthesis_params )->interpolator_fx != NULL )
     549             :     {
     550        2254 :         free( ( dirac_output_synthesis_params )->interpolator_fx );
     551        2254 :         ( dirac_output_synthesis_params )->interpolator_fx = NULL;
     552             :     }
     553             : 
     554             :     /* free alpha */
     555        2254 :     IF( ( dirac_output_synthesis_params )->alpha_synthesis_fx != NULL )
     556             :     {
     557        1419 :         free( ( dirac_output_synthesis_params )->alpha_synthesis_fx );
     558        1419 :         ( dirac_output_synthesis_params )->alpha_synthesis_fx = NULL;
     559             :     }
     560        2254 :     IF( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx != NULL )
     561             :     {
     562        1419 :         free( ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx );
     563        1419 :         ( dirac_output_synthesis_params )->alpha_synthesis_fast_fx = NULL;
     564             :     }
     565             : 
     566        2254 :     IF( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx != NULL )
     567             :     {
     568        1419 :         free( ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx );
     569        1419 :         ( dirac_output_synthesis_state )->reference_power_smooth_prev_fx = NULL;
     570             :     }
     571             : 
     572        2254 :     IF( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx != NULL )
     573             :     {
     574        1419 :         free( ( dirac_output_synthesis_state )->direction_smoothness_prev_fx );
     575        1419 :         ( dirac_output_synthesis_state )->direction_smoothness_prev_fx = NULL;
     576             :     }
     577             : 
     578        2254 :     IF( ( dirac_output_synthesis_state )->diffuse_responses_square_fx != NULL )
     579             :     {
     580        1419 :         free( ( dirac_output_synthesis_state )->diffuse_responses_square_fx );
     581        1419 :         ( dirac_output_synthesis_state )->diffuse_responses_square_fx = NULL;
     582             :     }
     583             : 
     584             :     /* free power buffers */
     585        2254 :     IF( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx != NULL )
     586             :     {
     587        1419 :         free( ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx );
     588        1419 :         ( dirac_output_synthesis_state )->proto_power_smooth_prev_fx = NULL;
     589             :     }
     590             : 
     591        2254 :     IF( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx != NULL )
     592             :     {
     593        1262 :         free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx );
     594        1262 :         ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev_fx = NULL;
     595             :     }
     596             : 
     597             :     /* free target power buffers */
     598        2254 :     IF( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx != NULL )
     599             :     {
     600        1419 :         free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx );
     601        1419 :         ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev_fx = NULL;
     602             :     }
     603        2254 :     IF( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx != NULL )
     604             :     {
     605        2254 :         free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx );
     606        2254 :         ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev_fx = NULL;
     607             :     }
     608        2254 :     IF( ( dirac_output_synthesis_state )->Q_temp_cy_cross_dir_smooth_fx != NULL )
     609             :     {
     610        2254 :         free( ( dirac_output_synthesis_state )->Q_temp_cy_cross_dir_smooth_fx );
     611        2254 :         ( dirac_output_synthesis_state )->Q_temp_cy_cross_dir_smooth_fx = NULL;
     612             :     }
     613        2254 :     IF( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx != NULL )
     614             :     {
     615        2254 :         free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx );
     616        2254 :         ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev_fx = NULL;
     617             :     }
     618             : 
     619             :     /* free gain buffers */
     620        2254 :     IF( ( dirac_output_synthesis_state )->gains_dir_prev_fx != NULL )
     621             :     {
     622        2254 :         free( ( dirac_output_synthesis_state )->gains_dir_prev_fx );
     623        2254 :         ( dirac_output_synthesis_state )->gains_dir_prev_fx = NULL;
     624             :     }
     625        2254 :     IF( ( dirac_output_synthesis_state )->gains_diff_prev_fx != NULL )
     626             :     {
     627        2254 :         free( ( dirac_output_synthesis_state )->gains_diff_prev_fx );
     628        2254 :         ( dirac_output_synthesis_state )->gains_diff_prev_fx = NULL;
     629             :     }
     630        2254 :     return;
     631             : }
     632             : 
     633             : 
     634             : /*-------------------------------------------------------------------------
     635             :  * ivas_dirac_dec_output_synthesis_process_slot()
     636             :  *
     637             :  *
     638             :  *------------------------------------------------------------------------*/
     639             : 
     640     1304655 : void ivas_dirac_dec_output_synthesis_process_slot_fx(
     641             :     const Word32 *reference_power,   /* i  : Estimated power             Q(q_reference_power)*/
     642             :     const Word16 *q_reference_power, /* i  : Estimated power Q            */
     643             :     const Word32 *onset,             /* i  : onset filter                Q31*/
     644             :     const Word16 *azimuth,
     645             :     const Word16 *elevation,
     646             :     const Word32 *diffuseness, /* Q(q_diffuseness)*/
     647             :     Word16 q_diffuseness,
     648             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle         */
     649             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                       */
     650             :     const VBAP_HANDLE hVBAPdata,                          /* i  : VBAP structure              */
     651             :     const IVAS_OUTPUT_SETUP hOutSetup,                    /* i  : output setup structure      */
     652             :     const Word16 nchan_transport,                         /* i  : number of transport channels*/
     653             :     const Word16 md_idx,
     654             :     const Word16 hodirac_flag, /* i  : flag to indicate HO-DirAC mode   */
     655             :     const Word16 dec_param_estim )
     656             : {
     657             :     Word16 num_freq_bands, num_channels_dir;
     658             :     Word16 num_freq_bands_diff, num_channels_diff;
     659             :     Word16 ch_idx;
     660             :     Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
     661             :     Word16 diff_start_band;
     662             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
     663             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
     664             : 
     665     1304655 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     666     1304655 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     667             : 
     668     1304655 :     h_dirac_output_synthesis_state->onset_filter_fx = onset; /*Q31*/
     669             : 
     670             :     /*-----------------------------------------------------------------*
     671             :      * processing
     672             :      *-----------------------------------------------------------------*/
     673             : 
     674             :     /* collect some often used parameters */
     675     1304655 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
     676     1304655 :     move16();
     677     1304655 :     num_channels_dir = hDirACRend->num_outputs_dir;
     678     1304655 :     move16();
     679     1304655 :     num_channels_diff = hDirACRend->num_outputs_diff;
     680     1304655 :     move16();
     681     1304655 :     num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
     682     1304655 :     move16();
     683             : 
     684     1304655 :     IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_LS ) )
     685             :     {
     686      269809 :         num_channels_dir = hOutSetup.nchan_out_woLFE;
     687      269809 :         move16();
     688             :     }
     689             : 
     690     1304655 :     test();
     691     1304655 :     IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) && hodirac_flag )
     692             :     {
     693      212624 :         ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
     694             :                                                          hDirACRend,
     695             :                                                          hVBAPdata,
     696             :                                                          NULL,
     697             :                                                          NULL,
     698             :                                                          azimuth,
     699             :                                                          elevation,
     700             :                                                          md_idx,
     701             :                                                          NULL,
     702             :                                                          0,
     703             :                                                          hodirac_flag );
     704             :         {
     705             : 
     706      212624 :             IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
     707             :             {
     708           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*/
     709           0 :                 h_dirac_output_synthesis_state->direct_responses_square_q = 31;
     710           0 :                 move16();
     711             :             }
     712      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*/
     713      212624 :             IF( hodirac_flag )
     714             :             {
     715      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*/
     716             :             }
     717      212624 :             h_dirac_output_synthesis_state->direct_responses_q = 31;
     718      212624 :             move16();
     719             :         }
     720             :     }
     721             : 
     722     1304655 :     test();
     723     1304655 :     IF( dec_param_estim == FALSE && hodirac_flag )
     724             :     {
     725      212624 :         IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     726             :         {
     727      212624 :             v_multc_fixed( hSpatParamRendCom->energy_ratio1_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /* 30 + 31 - 31 -> 30 */
     728      212624 :             v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands );                                    /*30*/
     729      212624 :             Copy32( hSpatParamRendCom->energy_ratio1_fx[md_idx],
     730             :                     h_dirac_output_synthesis_state->direct_power_factor_fx,
     731             :                     num_freq_bands ); /*Q30*/
     732      212624 :             Copy32( aux_buf,
     733             :                     h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     734             :                     num_freq_bands ); /*Q30*/
     735             : 
     736      212624 :             v_multc_fixed( hSpatParamRendCom->energy_ratio2_fx[md_idx], -MAX_32 /*-1 Q31*/, aux_buf, num_freq_bands ); /*30+31-31->30*/
     737      212624 :             v_addc_fixed( aux_buf, ONE_IN_Q30 /*1 Q30*/, aux_buf, num_freq_bands );                                    /*30*/
     738      212624 :             Copy32( hSpatParamRendCom->energy_ratio2_fx[md_idx],
     739      212624 :                     &h_dirac_output_synthesis_state->direct_power_factor_fx[hSpatParamRendCom->num_freq_bands],
     740             :                     num_freq_bands ); /*Q30*/
     741      212624 :             Copy32( aux_buf,
     742      212624 :                     &h_dirac_output_synthesis_state->diffuse_power_factor_fx[hSpatParamRendCom->num_freq_bands],
     743             :                     num_freq_bands ); /*Q30*/
     744             : 
     745      212624 :             h_dirac_output_synthesis_state->diffuse_power_factor_q = 30;
     746      212624 :             move16();
     747      212624 :             h_dirac_output_synthesis_state->direct_power_factor_q = 30;
     748      212624 :             move16();
     749             :         }
     750             :         ELSE
     751             :         {
     752           0 :             ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
     753           0 :                                                     hSpatParamRendCom->diffuseness_vector_fx[md_idx],
     754             :                                                     h_dirac_output_synthesis_state->direct_power_factor_fx,
     755             :                                                     h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     756             :                                                     &h_dirac_output_synthesis_state->direct_power_factor_q,
     757             :                                                     &h_dirac_output_synthesis_state->diffuse_power_factor_q );
     758             :         }
     759             :     }
     760     1092031 :     ELSE IF( EQ_16( dec_param_estim, TRUE ) )
     761             :     {
     762             :         /* compute direct responses */
     763      730303 :         ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
     764             :                                                          hDirACRend,
     765             :                                                          hVBAPdata,
     766             :                                                          NULL,
     767             :                                                          NULL,
     768             :                                                          azimuth,
     769             :                                                          elevation,
     770             :                                                          md_idx,
     771             :                                                          NULL,
     772             :                                                          0,
     773             :                                                          hodirac_flag );
     774             : 
     775             :         {
     776      730303 :             IF( h_dirac_output_synthesis_state->direct_responses_square_fx )
     777             :             {
     778       56000 :                 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*/
     779       56000 :                 h_dirac_output_synthesis_state->direct_responses_square_q = 31;
     780       56000 :                 move16();
     781             :             }
     782      730303 :             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*/
     783      730303 :             IF( hodirac_flag )
     784             :             {
     785           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*/
     786             :             }
     787      730303 :             h_dirac_output_synthesis_state->direct_responses_q = 31;
     788      730303 :             move16();
     789             :         }
     790             : 
     791      730303 :         IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     792             :         {
     793      674303 :             ivas_dirac_dec_compute_gain_factors_fx( num_freq_bands,
     794             :                                                     diffuseness,
     795             :                                                     h_dirac_output_synthesis_state->direct_power_factor_fx,
     796             :                                                     h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     797             :                                                     &h_dirac_output_synthesis_state->direct_power_factor_q,
     798             :                                                     &h_dirac_output_synthesis_state->diffuse_power_factor_q );
     799      674303 :             h_dirac_output_synthesis_state->direct_power_factor_q = sub( 31, h_dirac_output_synthesis_state->direct_power_factor_q );
     800      674303 :             h_dirac_output_synthesis_state->diffuse_power_factor_q = sub( 31, h_dirac_output_synthesis_state->diffuse_power_factor_q );
     801             : 
     802      674303 :             v_multc_fixed( h_dirac_output_synthesis_state->direct_power_factor_fx,
     803             :                            ONE_IN_Q29 /*0.25f Q31*/,
     804             :                            h_dirac_output_synthesis_state->direct_power_factor_fx,
     805             :                            num_freq_bands ); /*h_dirac_output_synthesis_state->direct_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->direct_power_factor_q*/
     806      674303 :             v_multc_fixed( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     807             :                            ONE_IN_Q29 /*0.25f Q31*/,
     808             :                            h_dirac_output_synthesis_state->diffuse_power_factor_fx,
     809             :                            num_freq_bands ); /*h_dirac_output_synthesis_state->diffuse_power_factor_q+Q31-Q31->h_dirac_output_synthesis_state->diffuse_power_factor_q*/
     810             :             /*Direct gain*/
     811             : 
     812      674303 :             Word16 *exp_temp_cy_cross_dir_smooth_fx = (Word16 *) malloc( num_freq_bands * num_channels_dir * sizeof( Word16 ) );
     813      674303 :             Word16 cy_cross_dir_smooth_e = sub( 31, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
     814             : 
     815   529513343 :             FOR( Word16 kk = 0; kk < ( num_freq_bands * num_channels_dir ); kk++ )
     816             :             {
     817   528839040 :                 exp_temp_cy_cross_dir_smooth_fx[kk] = cy_cross_dir_smooth_e; // h_dirac_output_synthesis_state->q_cy_cross_dir_smooth;
     818   528839040 :                 move16();
     819             :             }
     820             : 
     821      674303 :             Word16 q_temp = sub( add( shl( h_dirac_output_synthesis_state->direct_responses_q, 1 ), q_diffuseness ), 62 );
     822      674303 :             Word32 one_in_qdiff = L_shl( 1, q_diffuseness );
     823      674303 :             Word32 c1 = Madd_32_16( ONE_IN_Q29 /*1 Q29*/, 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*/
     824      674303 :             Word16 q_diff_c = sub( q_diffuseness, 2 );
     825             : 
     826     3371515 :             FOR( ch_idx = 0; ch_idx < s_min( 4, nchan_transport ); ch_idx++ )
     827             :             {
     828             :                 Word16 k;
     829     2697212 :                 IF( ch_idx != 0 )
     830             :                 {
     831             :                     Word32 a, c;
     832             :                     Word16 b, b_exp, sqr_exp, q_diff_aab; // , q_diff_c;
     833             :                     Word32 mpy_a_a_b, mpy_diff_c, mpy_diff_aab;
     834             :                     Word32 sqr_inp, sqr;
     835             : 
     836             :                     /*Directonal sound gain nrg compensation*/
     837    12137454 :                     FOR( k = 0; k < num_freq_bands_diff; k++ )
     838             :                     {
     839    10114545 :                         a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
     840    10114545 :                         move32();
     841             : 
     842             : 
     843    10114545 :                         b_exp = 0;
     844    10114545 :                         move16();
     845             : 
     846    10114545 :                         b = 0;
     847    10114545 :                         move16();
     848             : 
     849    10114545 :                         if ( 0 == reference_power[k + ( ch_idx + 1 ) * num_freq_bands] )
     850             :                         {
     851      582105 :                             b = MAX_16;
     852      582105 :                             move16();
     853             :                         }
     854             : 
     855    10114545 :                         test();
     856    10114545 :                         IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] && reference_power[k + num_freq_bands] )
     857             :                         {
     858     9523003 :                             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)*/
     859             :                         }
     860             : 
     861             : 
     862    10114545 :                         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
     863    10114545 :                         mpy_diff_aab = Mpy_32_32( L_sub( one_in_qdiff, 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
     864    10114545 :                         mpy_diff_c = Mpy_32_32( diffuseness[k], c1 );                                 // Q(q_diff_c) = q_diffuseness - 2
     865             : 
     866    10114545 :                         q_diff_aab = sub( q_temp, b_exp ); // 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 ) ) );
     867             : 
     868    10114545 :                         Word16 minq = sub( s_min( q_diff_aab, q_diff_c ), 1 );
     869    10114545 :                         Word32 op1 = L_shr( mpy_diff_aab, sub( q_diff_aab, minq ) );
     870    10114545 :                         Word32 op2 = L_shr( mpy_diff_c, sub( q_diff_c, minq ) );
     871    10114545 :                         sqr_inp = L_add( op1, op2 );
     872    10114545 :                         sqr_exp = sub( 31, minq );
     873    10114545 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
     874    10114545 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
     875    10114545 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
     876             :                         {
     877     7543388 :                             IF( GT_16( sqr_exp, cy_cross_dir_smooth_e ) )
     878             :                             {
     879       32625 :                                 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( sqr_exp, cy_cross_dir_smooth_e ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth-> (31-sqr_exp) */
     880       32625 :                                 move32();
     881       32625 :                                 exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
     882       32625 :                                 move16();
     883             :                             }
     884             :                             ELSE
     885             :                             {
     886     7510763 :                                 sqr = L_shr( sqr, sub( cy_cross_dir_smooth_e, sqr_exp ) ); /*( 31- sqr_exp )-> h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
     887             :                             }
     888     7543388 :                             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 ); /*exp_temp_cy_cross_dir_smooth_fx*/
     889     7543388 :                             move32();
     890             :                         }
     891             :                         ELSE
     892             :                         {
     893     2571157 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr; // L_add( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k], sqr ); /*31-sqr_exp*/
     894     2571157 :                             move32();
     895     2571157 :                             exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
     896     2571157 :                             move16();
     897             :                         }
     898             :                     }
     899     2022909 :                     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*/
     900     2022909 :                     Word16 diff_c_exp = sub( q_diffuseness, 4 );
     901    94492884 :                     FOR( ; k < num_freq_bands; k++ )
     902             :                     {
     903    92469975 :                         a = h_dirac_output_synthesis_state->direct_responses_fx[ch_idx * num_freq_bands + k]; // Q = h_dirac_output_synthesis_state->q_direct_responses
     904    92469975 :                         move32();
     905    92469975 :                         IF( reference_power[k + num_freq_bands] == 0 )
     906             :                         {
     907    18976818 :                             sqr_inp = Mpy_32_32( diffuseness[k], c );
     908    18976818 :                             sqr_exp = sub( 31 + 4, q_diffuseness );
     909             :                         }
     910             :                         ELSE
     911             :                         {
     912             :                             Word16 diff_aab_exp;
     913    73493157 :                             IF( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] == 0 )
     914             :                             {
     915    14620162 :                                 mpy_a_a_b = Mpy_32_32( a, a );                                                // Q = (h_dirac_output_synthesis_state->q_direct_responses + (h_dirac_output_synthesis_state->q_direct_responses) - 31
     916    14620162 :                                 mpy_diff_aab = Mpy_32_32( L_sub( one_in_qdiff, diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - 31 + q_diffuseness -31
     917    14620162 :                                 mpy_diff_c = Mpy_32_32( diffuseness[k], c );                                  // Q = q_diffuseness - 4
     918    14620162 :                                 diff_aab_exp = q_temp;
     919    14620162 :                                 move16();
     920             :                             }
     921             :                             ELSE
     922             :                             {
     923    58872995 :                                 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)*/
     924             : 
     925    58872995 :                                 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
     926    58872995 :                                 mpy_diff_aab = Mpy_32_32( L_sub( one_in_qdiff, diffuseness[k] ), mpy_a_a_b ); // Q = 2*(h_dirac_output_synthesis_state->q_direct_responses) - b_exp - 31 + q_diffuseness -31
     927    58872995 :                                 mpy_diff_c = Mpy_32_32( diffuseness[k], c );                                  // Q = q_diffuseness - 4
     928    58872995 :                                 diff_aab_exp = sub( q_temp, b_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);
     929             :                             }
     930    73493157 :                             Word16 minq = sub( s_min( diff_aab_exp, diff_c_exp ), 1 );
     931    73493157 :                             Word32 op1 = L_shr( mpy_diff_aab, sub( diff_aab_exp, minq ) );
     932    73493157 :                             Word32 op2 = L_shr( mpy_diff_c, sub( diff_c_exp, minq ) );
     933    73493157 :                             sqr_inp = L_add( op1, op2 );
     934    73493157 :                             sqr_exp = sub( 31, minq );
     935             :                         }
     936    92469975 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
     937    92469975 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
     938             : 
     939             : 
     940    92469975 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
     941             :                         {
     942    66463030 :                             IF( GT_16( sqr_exp, cy_cross_dir_smooth_e ) )
     943             :                             {
     944      109454 :                                 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( sqr_exp, cy_cross_dir_smooth_e ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q( 31- sqr_exp )*/
     945      109454 :                                 move32();
     946      109454 :                                 exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
     947      109454 :                                 move16();
     948             :                             }
     949             :                             ELSE
     950             :                             {
     951    66353576 :                                 sqr = L_shr( sqr, sub( cy_cross_dir_smooth_e, sqr_exp ) ); /*Q(31- sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
     952             :                             }
     953    66463030 :                             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 ); /*exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
     954    66463030 :                             move32();
     955             :                         }
     956             :                         ELSE
     957             :                         {
     958    26006945 :                             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)*/
     959    26006945 :                             move32();
     960    26006945 :                             exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp;
     961    26006945 :                             move16();
     962             :                         }
     963             :                     }
     964             :                 }
     965             :                 ELSE
     966             :                 {
     967             :                     Word32 sqr_inp, sqr;
     968             :                     Word16 sqr_exp;
     969      674303 :                     Word32 One_in_qdiff = L_shl( 1, sub( q_diffuseness, 1 ) );
     970      674303 :                     Word32 diff = L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr_fx /*q29=0.5 * q30*/, ONE_IN_Q29 /*0.5 Q30*/ ); // Q30
     971      674303 :                     Word16 sq_e = sub( 32, q_diffuseness );                                                                                                  // 31-(q_diffuseness-1)
     972             :                     /*Diffuseness modellling nrg compensation*/
     973     4045818 :                     FOR( k = 0; k < num_freq_bands_diff; k++ )
     974             :                     {
     975             :                         /*diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) )*/
     976     3371515 :                         sqr_inp = Madd_32_32( One_in_qdiff, diffuseness[k], diff ); // Q = q_diffuseness - 1
     977     3371515 :                         sqr_exp = sq_e;
     978     3371515 :                         move16();
     979     3371515 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
     980     3371515 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
     981     3371515 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
     982             :                         {
     983     2521530 :                             IF( LT_16( cy_cross_dir_smooth_e, sqr_exp ) )
     984             :                             {
     985           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( sqr_exp, cy_cross_dir_smooth_e ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth->Q(31- sqr_exp)*/
     986           0 :                                 move32();
     987           0 :                                 exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
     988           0 :                                 move16();
     989             :                             }
     990             :                             ELSE
     991             :                             {
     992     2521530 :                                 sqr = L_shr( sqr, sub( cy_cross_dir_smooth_e, sqr_exp ) ); /*Q(31-sqr_exp)->h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
     993             :                             }
     994     2521530 :                             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 ); /*exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
     995     2521530 :                             move32();
     996             :                         }
     997             :                         ELSE
     998             :                         {
     999      849985 :                             h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr; /*Q(31-sqr_exp)*/
    1000      849985 :                             move32();
    1001      849985 :                             exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
    1002      849985 :                             move16();
    1003             :                         }
    1004             :                     }
    1005      674303 :                     diff = L_sub( h_dirac_output_synthesis_params->diffuse_compensation_factor_fx, ONE_IN_Q27 /*1 Q27*/ );
    1006      674303 :                     diff = L_shl( diff, 2 ); // Q29
    1007    31497628 :                     FOR( ; k < num_freq_bands; k++ )
    1008             :                     {
    1009    30823325 :                         sqr_inp = Madd_32_32( One_in_qdiff, diffuseness[k], diff ); // Q = q_diffuseness - 1
    1010    30823325 :                         sqr_exp = sq_e;
    1011    30823325 :                         move16();
    1012    30823325 :                         sqr = Sqrt32( sqr_inp, &sqr_exp ); /*Q(31-sqr_exp)*/
    1013    30823325 :                         sqr = L_shr( sqr, 2 );             /*Q(31-sqr_exp)*/
    1014    30823325 :                         IF( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] != 0 )
    1015             :                         {
    1016    23057950 :                             IF( GT_16( sqr_exp, cy_cross_dir_smooth_e ) )
    1017             :                             {
    1018           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( sqr_exp, cy_cross_dir_smooth_e ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, Q( 31- sqr_exp )*/
    1019           0 :                                 move32();
    1020           0 :                                 exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp; // sub( 31, sqr_exp );
    1021           0 :                                 move16();
    1022             :                             }
    1023             :                             ELSE
    1024             :                             {
    1025    23057950 :                                 sqr = L_shr( sqr, sub( cy_cross_dir_smooth_e, sqr_exp ) ); /*Q( 31- sqr_exp ), h_dirac_output_synthesis_state->q_cy_cross_dir_smooth*/
    1026             :                             }
    1027    23057950 :                             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 ); /*exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k]*/
    1028    23057950 :                             move32();
    1029             :                         }
    1030             :                         ELSE
    1031             :                         {
    1032     7765375 :                             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)*/
    1033     7765375 :                             move32();
    1034     7765375 :                             exp_temp_cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + k] = sqr_exp;
    1035     7765375 :                             move16();
    1036             :                         }
    1037             :                     }
    1038             :                 }
    1039             :             }
    1040      674303 :             Word16 temp = exp_temp_cy_cross_dir_smooth_fx[0]; /*q0*/
    1041      674303 :             move16();
    1042   528839040 :             FOR( Word16 kk = 1; kk < ( num_freq_bands * num_channels_dir ); kk++ )
    1043             :             {
    1044   528164737 :                 temp = s_max( exp_temp_cy_cross_dir_smooth_fx[kk], temp );
    1045             :             }
    1046             : 
    1047             : 
    1048             :             /*Directional gain (panning)*/
    1049      674303 :             Word16 temp_q = sub( add( h_dirac_output_synthesis_state->direct_power_factor_q, h_dirac_output_synthesis_state->direct_responses_q ), 31 );
    1050      674303 :             Word16 temp_exp = sub( 31, temp_q );
    1051             : 
    1052      674303 :             IF( LT_16( temp, temp_exp ) )
    1053             :             {
    1054           0 :                 FOR( Word16 kk = 0; kk < ( num_freq_bands * num_channels_dir ); kk++ )
    1055             :                 {
    1056           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], sub( exp_temp_cy_cross_dir_smooth_fx[kk], temp_exp ) ); /*h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ->temp_q*/
    1057           0 :                     move32();
    1058             :                 }
    1059           0 :                 h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = temp_q;
    1060           0 :                 move16();
    1061             :             }
    1062             :             ELSE
    1063             :             {
    1064   529513343 :                 FOR( Word16 kk = 0; kk < ( num_freq_bands * num_channels_dir ); kk++ )
    1065             :                 {
    1066   528839040 :                     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( exp_temp_cy_cross_dir_smooth_fx[kk], temp ) ); /*exp_temp_cy_cross_dir_smooth_fx[kk]->temp*/
    1067   528839040 :                     move32();
    1068             :                 }
    1069      674303 :                 h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = sub( 31, temp );
    1070      674303 :                 move16();
    1071             :             }
    1072      674303 :             free( exp_temp_cy_cross_dir_smooth_fx );
    1073             : 
    1074      674303 :             Word16 temp_q1 = sub( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth, temp_q );
    1075     8420979 :             FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
    1076             :             {
    1077     7746676 :                 IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_cross_dir_smooth ) )
    1078             :                 {
    1079             :                     Word16 i;
    1080             :                     Word32 aux;
    1081     7727750 :                     IF( temp_q1 < 0 )
    1082             :                     {
    1083     7727750 :                         Word32 temp_q1_equiv = L_lshl( (Word32) 0x80000000, temp_q1 );
    1084   398850110 :                         FOR( i = 0; i < num_freq_bands; i++ )
    1085             :                         {
    1086   391122360 :                             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] );
    1087   391122360 :                             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 );
    1088   391122360 :                             move32();
    1089             :                         }
    1090             :                     }
    1091             :                     ELSE
    1092             :                     {
    1093           0 :                         FOR( i = 0; i < num_freq_bands; i++ )
    1094             :                         {
    1095           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] );
    1096           0 :                             aux = L_shl( aux, temp_q1 );
    1097           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 );
    1098           0 :                             move32();
    1099             :                         }
    1100             :                     }
    1101             :                 }
    1102             :                 ELSE
    1103             :                 {
    1104             :                     Word16 i;
    1105      956246 :                     FOR( i = 0; i < num_freq_bands; i++ )
    1106             :                     {
    1107      937320 :                         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] );
    1108      937320 :                         move32();
    1109             :                     }
    1110             :                 }
    1111             :             }
    1112             : 
    1113             : 
    1114             :             /*Diffuse gain*/
    1115      674303 :             FOR( ch_idx = s_min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
    1116             :             {
    1117           0 :                 v_multc_fixed_16( h_dirac_output_synthesis_state->diffuse_power_factor_fx,
    1118           0 :                                   hDirACRend->diffuse_response_function_fx[ch_idx],
    1119             :                                   aux_buf,
    1120             :                                   num_freq_bands_diff ); /* h_dirac_output_synthesis_state->diffuse_power_factor_q+15-15*/
    1121           0 :                 temp_q = h_dirac_output_synthesis_state->diffuse_power_factor_q;
    1122           0 :                 IF( NE_16( temp_q, h_dirac_output_synthesis_state->q_cy_auto_diff_smooth ) )
    1123             :                 {
    1124           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)*/
    1125             :                 }
    1126           0 :                 v_add_fixed_no_hdrm( aux_buf,
    1127           0 :                                      &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1128           0 :                                      &h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1129             :                                      num_freq_bands_diff ); /*h_dirac_output_synthesis_state->q_cy_auto_diff_smooth*/
    1130             :             }
    1131             : 
    1132      674303 :             return;
    1133             :         }
    1134             :         ELSE
    1135             :         {
    1136             :             /* compute reference and diffuse power factor for this frame */
    1137       56000 :             ivas_dirac_dec_compute_power_factors_fx( num_freq_bands,
    1138             :                                                      diffuseness,
    1139       56000 :                                                      h_dirac_output_synthesis_params->max_band_decorr,
    1140             :                                                      h_dirac_output_synthesis_state->direct_power_factor_fx,
    1141             :                                                      h_dirac_output_synthesis_state->diffuse_power_factor_fx );
    1142             : 
    1143       56000 :             Scale_sig32( h_dirac_output_synthesis_state->direct_power_factor_fx, num_freq_bands, 2 );  /*q29->q31*/
    1144       56000 :             Scale_sig32( h_dirac_output_synthesis_state->diffuse_power_factor_fx, num_freq_bands, 2 ); /*q29->q31*/
    1145       56000 :             h_dirac_output_synthesis_state->diffuse_power_factor_q = 31;
    1146       56000 :             move16();
    1147       56000 :             h_dirac_output_synthesis_state->direct_power_factor_q = 31;
    1148       56000 :             move16();
    1149             :         }
    1150             :     }
    1151             : 
    1152      630352 :     diff_start_band = 0;
    1153      630352 :     move16();
    1154      630352 :     IF( h_dirac_output_synthesis_params->use_onset_filters )
    1155             :     {
    1156      213809 :         computeTargetPSDs_diffuse_with_onsets_fx( num_channels_dir,
    1157      213809 :                                                   num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
    1158      213809 :                                                   hDirACRend->proto_index_diff,
    1159      213809 :                                                   h_dirac_output_synthesis_state->diffuse_power_factor_fx,
    1160             :                                                   reference_power,
    1161             :                                                   q_reference_power,
    1162      213809 :                                                   h_dirac_output_synthesis_state->diffuse_responses_square_fx,
    1163             :                                                   onset,
    1164             :                                                   h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
    1165             :                                                   &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    1166             : 
    1167      213809 :         diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
    1168      213809 :         move16();
    1169             :     }
    1170             : 
    1171             :     /* process other PSDs only slot wise for 4 transport channels */
    1172      630352 :     IF( EQ_16( dec_param_estim, TRUE ) )
    1173             :     {
    1174       56000 :         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 );
    1175             : 
    1176       56000 :         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 );
    1177             :     }
    1178             : 
    1179      630352 :     return;
    1180             : }
    1181             : 
    1182             : 
    1183             : /*-------------------------------------------------------------------------
    1184             :  * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
    1185             :  *
    1186             :  *
    1187             :  *------------------------------------------------------------------------*/
    1188             : 
    1189      235404 : void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx(
    1190             :     Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
    1191             :     Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
    1192             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,                    /* i/o: common spatial renderer data handle         */
    1193             :     DIRAC_REND_HANDLE hDirACRend,                                            /* i/o: DirAC renderer handle                       */
    1194             :     const Word16 nchan_transport,                                            /* i  : number of transport channels                */
    1195             :     const Word16 nbslots,                                                    /* i  : number of slots to process                  */
    1196             :     const Word32 *onset_filter,                                              /* Q31 */
    1197             :     Word32 *diffuseness,                                                     // Q30
    1198             :     const Word16 hodirac_flag,                                               /* i  : flag to indicate HO-DirAC mode */
    1199             :     const Word16 dec_param_estim,
    1200             :     Word16 *q_cy_cross_dir_smooth_prev,
    1201             :     Word16 *q_cy_auto_diff_smooth_prev )
    1202             : {
    1203             :     Word16 buf_idx, ch_idx, i, l;
    1204             :     Word16 num_freq_bands, num_freq_bands_diff;
    1205             :     Word16 num_channels_dir, num_channels_diff;
    1206             :     Word32 g, g1[MAX_FREQUENCY_BANDS], g2;
    1207             :     Word32 *p_gains_dir, *p_gains_diff;
    1208             :     Word32 *p_gains_dir_prev, *p_gains_diff_prev;
    1209             :     Word32 *p_cy_cross_dir_smooth;
    1210             :     Word32 *p_cy_auto_diff_smooth;
    1211             :     Word32 *p_proto, *p_out_real, *p_out_imag;
    1212             :     Word32 *p_proto_diff;
    1213             :     Word16 *proto_direct_index, num_protos_dir;
    1214             :     Word32 output_real[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1215             :     Word32 output_imag[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1216             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS h_dirac_output_synthesis_params;
    1217             :     DIRAC_OUTPUT_SYNTHESIS_STATE h_dirac_output_synthesis_state;
    1218             :     Word16 nchan_transport_foa;
    1219             :     Word16 ch_idx_diff;
    1220             :     Word32 cmp1, cmp2;
    1221             :     Word32 aux_buf[CLDFB_NO_CHANNELS_MAX];
    1222             :     Word32 ratio_float[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX];
    1223      235404 :     Word16 q_com = 0;
    1224      235404 :     move16();
    1225      235404 :     Word16 exp = 0;
    1226      235404 :     move16();
    1227             :     Word16 q_shift;
    1228             : 
    1229             :     /* collect some often used parameters */
    1230      235404 :     h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
    1231      235404 :     h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
    1232      235404 :     proto_direct_index = hDirACRend->proto_index_dir;
    1233             : 
    1234      235404 :     num_protos_dir = hDirACRend->num_protos_dir;
    1235      235404 :     move16();
    1236      235404 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
    1237      235404 :     move16();
    1238      235404 :     num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
    1239      235404 :     move16();
    1240      235404 :     num_channels_dir = hDirACRend->num_outputs_dir;
    1241      235404 :     move16();
    1242      235404 :     num_channels_diff = hDirACRend->num_outputs_diff;
    1243      235404 :     move16();
    1244      235404 :     nchan_transport_foa = s_min( 4, nchan_transport );
    1245      235404 :     move16();
    1246             : 
    1247      235404 :     Word16 prod = imult1616( num_freq_bands, num_channels_dir );
    1248             :     /*-----------------------------------------------------------------*
    1249             :      * comput target Gains
    1250             :      *-----------------------------------------------------------------*/
    1251             : 
    1252      235404 :     IF( hodirac_flag )
    1253             :     {
    1254             :         /*Direct gain*/
    1255      265780 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1256             :         {
    1257      212624 :             v_multc_fixed( diffuseness,                                                                     // Q30
    1258             :                            ONE_IN_Q31,                                                                      // Q31
    1259      212624 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q30
    1260             :                            num_freq_bands );
    1261      212624 :             v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],     // Q30
    1262             :                            L_sub( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, ONE_IN_Q27 ), // Q27
    1263      212624 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],     // Q26
    1264             :                            num_freq_bands );
    1265             : 
    1266    12861264 :             FOR( l = 0; l < num_freq_bands; l++ )
    1267             :             {
    1268    12648640 :                 exp = Q31 - Q26;
    1269    25297280 :                 h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
    1270    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] ),
    1271             :                             &exp ); // (Q31 - exp)
    1272    12648640 :                 move32();
    1273             :             }
    1274             : 
    1275             :             // Scale to bring in common Q-factor
    1276      212624 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
    1277      212624 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1278             :                          num_freq_bands,
    1279      212624 :                          sub( q_com, sub( Q31, exp ) ) ); /*Q( Q31- exp)->q_com*/
    1280      212624 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1281             :                          num_freq_bands,
    1282      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*/
    1283             :         }
    1284             : 
    1285     3215316 :         FOR( l = 0; l < num_freq_bands; l++ )
    1286             :         {
    1287     3162160 :             aux_buf[l] = L_sub( ONE_IN_Q30, diffuseness[l] ); // Q30
    1288     3162160 :             move32();
    1289     3162160 :             ratio_float[l] = L_sub( ONE_IN_Q31, h_dirac_output_synthesis_state.direct_power_factor_fx[num_freq_bands + l] ); // Q31
    1290     3162160 :             move32();
    1291     3162160 :             ratio_float[l + num_freq_bands] = L_sub( ONE_IN_Q31, ratio_float[l] ); // Q31
    1292     3162160 :             move32();
    1293             :         }
    1294             : 
    1295       53156 :         v_mult_fixed( aux_buf, ratio_float, ratio_float, num_freq_bands );                                   //(Q30, Q31) -> Q30
    1296       53156 :         v_mult_fixed( aux_buf, &ratio_float[num_freq_bands], &ratio_float[num_freq_bands], num_freq_bands ); //(Q30, Q31) -> Q30
    1297             : 
    1298             :         /*Directional gain*/
    1299      630268 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1300             :         {
    1301      577112 :             v_mult_fixed( ratio_float,                                                                     // Q30
    1302      577112 :                           &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands],    // Q31
    1303      577112 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], //(Q30, Q31) -> Q30
    1304             :                           num_freq_bands );
    1305      577112 :             v_mult_fixed( &ratio_float[num_freq_bands],                                                                                        // Q30
    1306      577112 :                           &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],    // Q31
    1307      577112 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir], //(Q30, Q31) -> Q30
    1308             :                           num_freq_bands );
    1309             : 
    1310             :             // Scale to bring in common Q-factor
    1311      577112 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q30 );
    1312      577112 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1313             :                          num_freq_bands,
    1314      577112 :                          sub( q_com, Q30 ) ); /*Q30->q_com*/
    1315      577112 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
    1316             :                          num_freq_bands,
    1317      577112 :                          sub( q_com, Q30 ) ); /*Q30->q_com*/
    1318      577112 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1319             :                          num_freq_bands,
    1320      577112 :                          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*/
    1321      577112 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
    1322             :                          num_freq_bands,
    1323      577112 :                          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*/
    1324             :         }
    1325             : 
    1326       53156 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
    1327       53156 :         move16();
    1328       53156 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
    1329       53156 :         move16();
    1330             : 
    1331             :         /*Diffuse gain*/
    1332       53156 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1333             :         {
    1334           0 :             v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx,                               // Q31
    1335           0 :                               hDirACRend->diffuse_response_function_fx[ch_idx],                                     // Q15
    1336           0 :                               &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
    1337             :                               num_freq_bands_diff );
    1338             : 
    1339             :             // Scale to bring in common Q-factor
    1340           0 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
    1341           0 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1342             :                          num_freq_bands_diff,
    1343           0 :                          sub( q_com, Q31 ) ); /*q31->q_com*/
    1344           0 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
    1345             :                          num_freq_bands_diff,
    1346           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*/
    1347             :         }
    1348             : 
    1349       53156 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
    1350       53156 :         move16();
    1351       53156 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
    1352       53156 :         move16();
    1353             :     }
    1354      182248 :     ELSE IF( EQ_16( dec_param_estim, FALSE ) )
    1355             :     {
    1356             :         /*Direct gain*/
    1357       24502 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1358             :         {
    1359       12251 :             v_mult_fixed( h_dirac_output_synthesis_state.diffuse_power_factor_fx,                          // Q31
    1360       12251 :                           h_dirac_output_synthesis_state.diffuse_power_factor_fx,                          // Q31
    1361       12251 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
    1362             :                           num_freq_bands );
    1363       12251 :             v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],                         // Q31
    1364             :                            L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr_fx, Q3 ), ONE_IN_Q26 ), // Q26
    1365       12251 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],                         // Q26
    1366             :                            num_freq_bands_diff );
    1367       12251 :             v_multc_fixed( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q31
    1368             :                            L_sub( L_shr( h_dirac_output_synthesis_params.diffuse_compensation_factor_fx, Q1 ), ONE_IN_Q26 ),      // Q26
    1369       12251 :                            &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + num_freq_bands_diff], // Q26
    1370       12251 :                            num_freq_bands - num_freq_bands_diff );
    1371             : 
    1372      747311 :             FOR( l = 0; l < num_freq_bands; l++ )
    1373             :             {
    1374      735060 :                 exp = Q31 - Q26;
    1375     1470120 :                 h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] =
    1376      735060 :                     Sqrt32( L_add( ONE_IN_Q26, h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands + l] ),
    1377             :                             &exp ); // (Q31 - exp)
    1378      735060 :                 move32();
    1379             :             }
    1380             : 
    1381             :             // Scale to bring in common Q-factor
    1382       12251 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, sub( Q31, exp ) );
    1383       12251 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1384             :                          num_freq_bands,
    1385       12251 :                          sub( q_com, sub( Q31, exp ) ) ); /*( Q31- exp )->q_com*/
    1386       12251 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1387             :                          num_freq_bands,
    1388       12251 :                          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*/
    1389             :         }
    1390             : 
    1391             :         /*Directional gain*/
    1392       76604 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1393             :         {
    1394       64353 :             v_mult_fixed( h_dirac_output_synthesis_state.direct_power_factor_fx,                           // Q31
    1395       64353 :                           &h_dirac_output_synthesis_state.direct_responses_fx[ch_idx * num_freq_bands],    // Q31
    1396       64353 :                           &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands], // Q31
    1397             :                           num_freq_bands );
    1398             : 
    1399             :             // Scale to bring in common Q-factor
    1400       64353 :             q_com = s_min( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, Q31 );
    1401       64353 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx[ch_idx * num_freq_bands],
    1402             :                          num_freq_bands,
    1403       64353 :                          sub( q_com, Q31 ) ); /*q31->q_com*/
    1404       64353 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx[ch_idx * num_freq_bands],
    1405             :                          num_freq_bands,
    1406       64353 :                          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*/
    1407             :         }
    1408             : 
    1409       12251 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth = q_com;
    1410       12251 :         move16();
    1411       12251 :         h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev = q_com;
    1412       12251 :         move16();
    1413             : 
    1414             :         /*Diffuse gain*/
    1415       12251 :         q_com = s_min( h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev, Q31 );
    1416       49004 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1417             :         {
    1418       36753 :             v_multc_fixed_16( h_dirac_output_synthesis_state.diffuse_power_factor_fx,                               // Q31
    1419       36753 :                               hDirACRend->diffuse_response_function_fx[ch_idx],                                     // Q15
    1420       36753 :                               &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff], // Q31
    1421             :                               num_freq_bands_diff );
    1422             : 
    1423             :             // Scale to bring in common Q-factor
    1424       36753 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx[ch_idx * num_freq_bands_diff],
    1425             :                          num_freq_bands_diff,
    1426       36753 :                          sub( q_com, Q31 ) ); /*q31->q_com*/
    1427       36753 :             Scale_sig32( &h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx[ch_idx * num_freq_bands_diff],
    1428             :                          num_freq_bands_diff,
    1429       36753 :                          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*/
    1430             :         }
    1431             : 
    1432       12251 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth = q_com;
    1433       12251 :         move16();
    1434       12251 :         h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev = q_com;
    1435       12251 :         move16();
    1436             :     }
    1437             : 
    1438             :     /*-----------------------------------------------------------------*
    1439             :      * compute gains
    1440             :      *-----------------------------------------------------------------*/
    1441             : 
    1442      235404 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx;
    1443      235404 :     p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx;
    1444             : 
    1445    12747984 :     FOR( l = 0; l < num_freq_bands; l++ )
    1446             :     {
    1447    12512580 :         g1[l] = Madd_32_32( POINT_3679_Q31, onset_filter[l], POINT_1175_Q31 - POINT_3679_Q31 ); // Q31, (Q31, Q31) -> Q31
    1448    12512580 :         move32();
    1449             :     }
    1450             : 
    1451      235404 :     q_shift = sub( 26, h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev );
    1452             : 
    1453             :     /* Direct gains */
    1454      235404 :     IF( hodirac_flag )
    1455             :     {
    1456       53156 :         cmp1 = L_shr( 66437775 /* 0.99f in Q26 */, q_shift );
    1457       53156 :         cmp2 = L_shr( ONE_IN_Q27 /* 2.0f in Q26 */, q_shift );
    1458      265780 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1459             :         {
    1460    12861264 :             FOR( l = 0; l < num_freq_bands; l++ )
    1461             :             {
    1462    12648640 :                 g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1463    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
    1464    12648640 :                 g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1465    12648640 :                 g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1466    12648640 :                 *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1467    12648640 :                 move32();
    1468             :             }
    1469             :         }
    1470             :     }
    1471             :     ELSE
    1472             :     {
    1473      182248 :         cmp1 = L_shr( 57042534 /* 0.85f in Q26 */, q_shift );
    1474      182248 :         cmp2 = L_shr( 77175193 /* 1.15f in Q26 */, q_shift );
    1475      874487 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1476             :         {
    1477    35888739 :             FOR( l = 0; l < num_freq_bands; l++ )
    1478             :             {
    1479    35196500 :                 g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1480    35196500 :                 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
    1481    35196500 :                 g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1482    35196500 :                 g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1483    35196500 :                 *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1484    35196500 :                 move32();
    1485             :             }
    1486             :         }
    1487             :     }
    1488             : 
    1489             :     /*Directional gains*/
    1490      235404 :     cmp1 = L_shr( -DIRAC_GAIN_LIMIT_Q26, q_shift );
    1491      235404 :     cmp2 = L_negate( cmp1 );
    1492     2830593 :     FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1493             :     {
    1494   139666609 :         FOR( l = 0; l < num_freq_bands; l++ )
    1495             :         {
    1496   137071420 :             g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1497   137071420 :             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
    1498   137071420 :             g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1499   137071420 :             g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1500   137071420 :             *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1501   137071420 :             move32();
    1502             :         }
    1503             :     }
    1504             : 
    1505      235404 :     IF( hodirac_flag )
    1506             :     {
    1507       53156 :         p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx + prod;
    1508       53156 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx + prod;
    1509             : 
    1510             :         /*Direct gains*/
    1511      265780 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1512             :         {
    1513    12861264 :             FOR( l = 0; l < num_freq_bands; l++ )
    1514             :             {
    1515    12648640 :                 p_cy_cross_dir_smooth++;
    1516    12648640 :                 p_gains_dir++;
    1517             :             }
    1518             :         }
    1519             : 
    1520             :         /*Directional gains*/
    1521      630268 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1522             :         {
    1523    34972632 :             FOR( l = 0; l < num_freq_bands; l++ )
    1524             :             {
    1525    34395520 :                 g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[l] ), *( p_gains_dir ) );             // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1526    34395520 :                 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
    1527    34395520 :                 g2 = L_max( g2, cmp1 );                                                     // p_gains_dir_q
    1528    34395520 :                 g2 = L_min( g2, cmp2 );                                                     // p_gains_dir_q
    1529    34395520 :                 *( p_gains_dir++ ) = g2;                                                    // p_gains_dir_q
    1530    34395520 :                 move32();
    1531             :             }
    1532             :         }
    1533             :     }
    1534             : 
    1535             :     /*Diffuse gains*/
    1536      235404 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
    1537      235404 :     p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + imult1616( nchan_transport_foa, num_freq_bands_diff );
    1538      235404 :     g1[0] = POINT_1175_Q31; // Q31
    1539      235404 :     move32();
    1540      272157 :     FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1541             :     {
    1542      845319 :         FOR( l = 0; l < num_freq_bands_diff; l++ )
    1543             :         {
    1544      808566 :             move32();
    1545      808566 :             g2 = Mpy_32_32( L_sub( ONE_IN_Q31, g1[0] ), *( p_gains_diff ) );            // (Q31, p_gains_dir_q) -> p_gains_dir_q
    1546      808566 :             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
    1547      808566 :             g2 = L_max( g2, 0 );                                                        // p_gains_diff_q
    1548      808566 :             g2 = L_min( g2, cmp2 );                                                     // p_gains_diff_q
    1549      808566 :             *( p_gains_diff++ ) = g2;                                                   // p_gains_diff_q
    1550      808566 :             move32();
    1551             :         }
    1552             :     }
    1553             : 
    1554             :     /*-----------------------------------------------------------------*
    1555             :      * gain interpolation and output streams
    1556             :      *-----------------------------------------------------------------*/
    1557             : 
    1558     1171335 :     FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    1559             :     {
    1560      935931 :         g1[0] = L_deposit_h( h_dirac_output_synthesis_params.interpolator_fx[buf_idx] ); // Q31
    1561      935931 :         move32();
    1562      935931 :         g2 = L_sub( ONE_IN_Q31, g1[0] ); // Q31
    1563             : 
    1564             :         /*Direct input->output*/
    1565      935931 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev_fx; // (p_gains_dir_q)
    1566      935931 :         p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev_fx;
    1567      935931 :         q_shift = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev_q );
    1568    14845179 :         FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
    1569             :         {
    1570    13909248 :             Scale_sig32( &h_dirac_output_synthesis_state.gains_dir_prev_fx[ch_idx * num_freq_bands],
    1571             :                          num_freq_bands,
    1572             :                          q_shift ); /*h_dirac_output_synthesis_state.gains_dir_prev_q->h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev*/
    1573             :         }
    1574      935931 :         h_dirac_output_synthesis_state.gains_dir_prev_q = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
    1575      935931 :         move16();
    1576             : 
    1577     4532643 :         FOR( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1578             :         {
    1579     7193424 :             p_proto_diff = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
    1580     3596712 :                            shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
    1581     3596712 :                            shl( ch_idx * num_freq_bands, Q1 );
    1582   193910872 :             FOR( l = 0; l < num_freq_bands; l++ )
    1583             :             {
    1584   190314160 :                 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)
    1585             : 
    1586   190314160 :                 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)
    1587   190314160 :                 move32();
    1588   190314160 :                 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)
    1589   190314160 :                 move32();
    1590             :             }
    1591             :         }
    1592             : 
    1593             :         /*Directional stream*/
    1594      935931 :         Word16 offset = shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 );
    1595    11248467 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1596             :         {
    1597    10312536 :             IF( hodirac_flag )
    1598             :             {
    1599     2308448 :                 IF( proto_direct_index[ch_idx] == 0 )
    1600             :                 {
    1601             :                     Word32 *p_proto2;
    1602             :                     Word32 gs1, gs2;
    1603     2266944 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1604     1133472 :                               shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    1605     1133472 :                               shl( i_mult( proto_direct_index[0], num_freq_bands ), Q1 );
    1606     2266944 :                     p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1607     1133472 :                                shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    1608     1133472 :                                shl( i_mult( proto_direct_index[1], num_freq_bands ), Q1 );
    1609    68677792 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1610             :                     {
    1611             : 
    1612             :                         Word32 temp1, temp2;
    1613    67544320 :                         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)
    1614    67544320 :                         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)
    1615    67544320 :                         p_gains_dir++;
    1616    67544320 :                         p_gains_dir_prev++;
    1617             : 
    1618    67544320 :                         temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
    1619    67544320 :                         temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
    1620             :                         // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
    1621   135088640 :                         output_real[l * num_channels_dir + ch_idx] =
    1622    67544320 :                             Madd_32_32(
    1623             :                                 Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ), /* s1 */
    1624             :                                 gs2, L_sub( temp1, temp2 ) );                /* s2 */
    1625    67544320 :                         move32();
    1626    67544320 :                         p_proto++;
    1627    67544320 :                         p_proto2++;
    1628             : 
    1629    67544320 :                         temp1 = Mpy_32_32( 1903158016 /* 1.772454e+00f / 2 in Q31 */, ( *p_proto ) );
    1630    67544320 :                         temp2 = Mpy_32_32( 1098788992 /* 1.023327e+00f / 2 in Q31 */, ( *p_proto2 ) );
    1631             :                         // ((p_gains_dir_q, p_proto_dir_q) >> 1) -> (p_gains_dir_q + p_proto_dir_q - 31)
    1632   135088640 :                         output_imag[l * num_channels_dir + ch_idx] =
    1633    67544320 :                             Madd_32_32(
    1634             :                                 Mpy_32_32( gs1, ( L_add( temp1, temp2 ) ) ),
    1635             :                                 gs2, L_sub( temp1, temp2 ) );
    1636    67544320 :                         move32();
    1637    67544320 :                         p_proto++;
    1638    67544320 :                         p_proto2++;
    1639             :                     }
    1640             :                 }
    1641             :                 ELSE
    1642             :                 {
    1643     2349952 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1644     1174976 :                               shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    1645     1174976 :                               shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
    1646     1174976 :                     Word16 diff = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
    1647    71212736 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1648             :                     {
    1649    70037760 :                         p_gains_dir++;
    1650    70037760 :                         p_gains_dir_prev++;
    1651             : 
    1652    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)
    1653    70037760 :                         move32();
    1654    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)
    1655    70037760 :                         move32();
    1656             :                     }
    1657             :                 }
    1658             :             }
    1659             :             ELSE
    1660             :             {
    1661    16008176 :                 p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f_fx +
    1662    16008176 :                           offset +
    1663     8004088 :                           shl( i_mult( proto_direct_index[ch_idx], num_freq_bands ), Q1 );
    1664     8004088 :                 IF( EQ_16( proto_direct_index[ch_idx], 0 ) )
    1665             :                 {
    1666   401776328 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1667             :                     {
    1668   394019600 :                         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)
    1669             : 
    1670   394019600 :                         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)
    1671   394019600 :                         move32();
    1672   394019600 :                         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)
    1673   394019600 :                         move32();
    1674             :                     }
    1675             :                 }
    1676             :                 ELSE
    1677             :                 {
    1678      247360 :                     Word16 shift_q = sub( h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev, 31 );
    1679    13732160 :                     FOR( l = 0; l < num_freq_bands; l++ )
    1680             :                     {
    1681    13484800 :                         p_gains_dir++;
    1682    13484800 :                         p_gains_dir_prev++;
    1683             : 
    1684    13484800 :                         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)
    1685    13484800 :                         move32();
    1686    13484800 :                         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)
    1687    13484800 :                         move32();
    1688             :                     }
    1689             :                 }
    1690             :             }
    1691             :         }
    1692             : 
    1693             :         /*Diffuse stream*/
    1694      935931 :         p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
    1695      935931 :         p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev_fx + i_mult( nchan_transport_foa, num_freq_bands_diff );
    1696     1082943 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1697             :         {
    1698      147012 :             Scale_sig32( &h_dirac_output_synthesis_state.gains_diff_prev_fx[ch_idx * num_freq_bands_diff],
    1699             :                          num_freq_bands_diff,
    1700      147012 :                          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*/
    1701             :         }
    1702      935931 :         h_dirac_output_synthesis_state.gains_diff_prev_q = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
    1703      935931 :         move16();
    1704             : 
    1705      935931 :         ch_idx_diff = nchan_transport_foa;
    1706      935931 :         move16();
    1707     1082943 :         FOR( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1708             :         {
    1709      147012 :             IF( proto_direct_index[ch_idx] == 0 )
    1710             :             {
    1711      294024 :                 p_proto = h_dirac_output_synthesis_state.proto_diffuse_buffer_f_fx +
    1712      147012 :                           shl( i_mult( buf_idx, i_mult( num_freq_bands, num_channels_diff ) ), Q1 ) +
    1713      147012 :                           shl( i_mult( ch_idx_diff, num_freq_bands ), Q1 );
    1714      147012 :                 ch_idx_diff = add( ch_idx_diff, 1 );
    1715     3381276 :                 FOR( l = 0; l < num_freq_bands_diff; l++ )
    1716             :                 {
    1717     3234264 :                     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
    1718             : 
    1719             :                     // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
    1720     6468528 :                     output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
    1721     3234264 :                         Madd_32_32( output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
    1722     3234264 :                                     g, ( *( p_proto++ ) ) );
    1723     3234264 :                     move32();
    1724             : 
    1725             :                     // ((p_gains_diff_q, p_proto_diff_q) >> Q1) -> (p_gains_diff_q + p_proto_diff_q - 31)
    1726     6468528 :                     output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] =
    1727     3234264 :                         Madd_32_32( output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]],
    1728     3234264 :                                     g, ( *( p_proto++ ) ) );
    1729     3234264 :                     move32();
    1730             :                 }
    1731             :             }
    1732             :             ELSE
    1733             :             {
    1734           0 :                 p_gains_diff += num_freq_bands_diff;
    1735           0 :                 p_gains_diff_prev += num_freq_bands_diff;
    1736             :             }
    1737             :         }
    1738             : 
    1739             :         /*-----------------------------------------------------------------*
    1740             :          * Copy output or HOA decoder
    1741             :          *-----------------------------------------------------------------*/
    1742             : 
    1743      935931 :         test();
    1744             :         /*q=(p_gains_dir_q + p_proto_dir_q - 31)*/
    1745      935931 :         IF( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
    1746      172000 :         {
    1747             :             Word32 *p_real, *p_imag;
    1748             :             const Word32 *hoa_decoder;
    1749             : 
    1750      172000 :             hoa_decoder = hDirACRend->hoa_decoder;
    1751             : 
    1752     1784000 :             FOR( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
    1753             :             {
    1754     1612000 :                 p_real = RealBuffer[ch_idx][buf_idx]; /*q - Q2*/
    1755     1612000 :                 p_imag = ImagBuffer[ch_idx][buf_idx]; /*q - Q2*/
    1756             : 
    1757    91292000 :                 FOR( l = 0; l < num_freq_bands; l++ )
    1758             :                 {
    1759    89680000 :                     p_out_real = output_real + i_mult( l, num_channels_dir );
    1760    89680000 :                     p_out_imag = output_imag + i_mult( l, num_channels_dir );
    1761    89680000 :                     p_real[l] = Mpy_32_32( *( p_out_real++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
    1762    89680000 :                     move32();
    1763    89680000 :                     p_imag[l] = Mpy_32_32( *( p_out_imag++ ), hoa_decoder[0] ); // (q, Q29) -> q - Q2
    1764    89680000 :                     move32();
    1765  1434880000 :                     FOR( i = 1; i < num_channels_dir; i++ )
    1766             :                     {
    1767  1345200000 :                         p_real[l] = Madd_32_32( p_real[l], *( p_out_real++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
    1768  1345200000 :                         move32();
    1769  1345200000 :                         p_imag[l] = Madd_32_32( p_imag[l], *( p_out_imag++ ), hoa_decoder[i] ); // (q, Q29) -> q - Q2
    1770  1345200000 :                         move32();
    1771             :                     }
    1772             :                 }
    1773     1612000 :                 hoa_decoder += 16;
    1774             :             }
    1775             :         }
    1776             :         ELSE
    1777             :         {
    1778    11921179 :             FOR( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
    1779             :             {
    1780   591677888 :                 FOR( l = 0; l < num_freq_bands; l++ )
    1781             :                 {
    1782   580520640 :                     RealBuffer[ch_idx][buf_idx][l] = L_shr( output_real[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
    1783   580520640 :                     move32();
    1784   580520640 :                     ImagBuffer[ch_idx][buf_idx][l] = L_shr( output_imag[l * num_channels_dir + ch_idx], Q2 ); /* q - Q2*/
    1785   580520640 :                     move32();
    1786             :                 }
    1787             :             }
    1788             :         }
    1789             :     }
    1790             : 
    1791             :     /*-----------------------------------------------------------------*
    1792             :      * update buffers
    1793             :      *-----------------------------------------------------------------*/
    1794             : 
    1795             :     /* store estimates for next synthesis block */
    1796      235404 :     IF( hodirac_flag )
    1797             :     {
    1798       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*/
    1799             :     }
    1800             :     ELSE
    1801             :     {
    1802      182248 :         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*/
    1803             :     }
    1804      235404 :     *q_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state.q_cy_cross_dir_smooth_prev;
    1805      235404 :     move16();
    1806             : 
    1807      235404 :     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*/
    1808      235404 :     *q_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state.q_cy_auto_diff_smooth_prev;
    1809      235404 :     move16();
    1810             : 
    1811             :     /* reset values */
    1812      235404 :     IF( hodirac_flag )
    1813             :     {
    1814       53156 :         set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod * DIRAC_HO_NUMSECTORS );
    1815             :     }
    1816             :     ELSE
    1817             :     {
    1818      182248 :         set_zero_fx( h_dirac_output_synthesis_state.cy_cross_dir_smooth_fx, prod );
    1819             :     }
    1820             : 
    1821      235404 :     set_zero_fx( h_dirac_output_synthesis_state.cy_auto_diff_smooth_fx, imult1616( num_freq_bands_diff, num_channels_diff ) );
    1822             : 
    1823      235404 :     return;
    1824             : }
    1825             : 
    1826             : 
    1827             : /*-------------------------------------------------------------------------
    1828             :  * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
    1829             :  *
    1830             :  *
    1831             :  *------------------------------------------------------------------------*/
    1832       92927 : void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx(
    1833             :     Word32 RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                        Q(q_Cldfb)*/
    1834             :     Word32 ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                        Q(q_Cldfb)*/
    1835             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,                    /* i/o: common spatial renderer data handle         */
    1836             :     DIRAC_REND_HANDLE hDirACRend,                                            /* i/o: DirAC renderer handle                       */
    1837             :     const Word16 nbslots,                                                    /* i  : number of slots to process                  */
    1838             :     Word32 *diffuseness_vector,                                              /* i  : diffuseness (needed for direction smoothing) Q(31)*/
    1839             :     Word32 *reference_power_smooth,                                          /*Q(q_reference_power_smooth)*/
    1840             :     Word16 *q_reference_power_smooth,
    1841             :     Word32 qualityBasedSmFactor, /*Q(31)*/
    1842             :     const Word16 enc_param_start_band,
    1843             :     Word16 *q_Cldfb )
    1844             : {
    1845             :     Word16 buf_idx, num_freq_bands;
    1846             :     Word16 diff_start_band;
    1847             :     Word16 k, l;
    1848             :     Word16 nchan_out_woLFE;
    1849             :     Word32 *p_power_smooth_prev, *p_power_diff_smooth_prev;
    1850             :     Word32 *p_gain_1, *p_gain_2;
    1851             :     Word32 *p_power_smooth_diff, *p_power_smooth;
    1852             :     Word32 *p_gains_dir, *p_gains_diff;
    1853             :     Word32 g, g1, g2;
    1854             :     Word32 *p_cy_auto_dir_smooth, *p_cy_auto_dir_smooth_prev;
    1855             :     Word16 q_cy_auto_dir_smooth_local[MAX_OUTPUT_CHANNELS], q_cy_auto_dir_smooth_prev_local[MAX_OUTPUT_CHANNELS];
    1856             :     Word32 *p_cy_cross_dir_smooth, *p_cy_cross_dir_smooth_prev;
    1857             :     Word32 *p_cy_auto_diff_smooth, *p_cy_auto_diff_smooth_prev;
    1858             :     Word32 gains_dir[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1859             :     Word32 gains_diff[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1860             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
    1861             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
    1862             :     Word16 *proto_direct_index, num_protos_dir;
    1863             :     Word32 target_power_y, target_power_y1;
    1864             :     Word16 q_target_power_y, q_target_power_y1;
    1865             :     Word32 subtract_power_y;
    1866             :     Word32 subtract_target_ratio;
    1867             :     Word32 subtract_target_ratio_db;
    1868             :     Word32 a, b;
    1869             :     UWord16 nchan_target_psds;
    1870             :     Word32 alpha[CLDFB_NO_CHANNELS_MAX];
    1871             :     Word16 *alpha_synthesis;
    1872             :     Word16 *alpha_synthesis_fast;
    1873             :     Word16 alphaMaxBin;
    1874             :     Word16 alphaMaxBinFast;
    1875             :     Word32 L_tmp;
    1876             :     Word16 exp_arr[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1877       92927 :     Word16 exp = 0, exp1, tmp, q_com, q_tmp, min_exp;
    1878             :     Word32 tmp32;
    1879       92927 :     move16();
    1880             : 
    1881             :     Word64 Cldfb_RealBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1882             :     Word64 Cldfb_ImagBuffer64_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    1883       92927 :     Word64 W_temp = 0;
    1884       92927 :     move64();
    1885       92927 :     push_wmops( "dirac_out_synth_sfr" );
    1886             : 
    1887       92927 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
    1888       92927 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
    1889             : 
    1890             :     /* collect some often used parameters */
    1891       92927 :     proto_direct_index = hDirACRend->proto_index_dir;
    1892       92927 :     move16();
    1893       92927 :     num_protos_dir = hDirACRend->num_protos_dir;
    1894       92927 :     move16();
    1895       92927 :     nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
    1896       92927 :     move16();
    1897       92927 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
    1898       92927 :     move16();
    1899       92927 :     set16_fx( q_cy_auto_dir_smooth_local, h_dirac_output_synthesis_state->q_cy_auto_dir_smooth, nchan_out_woLFE );
    1900             : 
    1901             :     /*-----------------------------------------------------------------*
    1902             :      * compute target PSDs
    1903             :      *-----------------------------------------------------------------*/
    1904       92927 :     IF( enc_param_start_band == 0 )
    1905             :     {
    1906       78927 :         IF( EQ_16( h_dirac_output_synthesis_params->use_onset_filters, 1 ) )
    1907             :         {
    1908       53475 :             diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
    1909       53475 :             move16();
    1910             :         }
    1911             :         ELSE
    1912             :         {
    1913       25452 :             diff_start_band = 0;
    1914       25452 :             move16();
    1915             :         }
    1916             : 
    1917       78927 :         IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
    1918             :         {
    1919        9417 :             nchan_target_psds = 2;
    1920        9417 :             move16();
    1921             :         }
    1922             :         ELSE
    1923             :         {
    1924       69510 :             nchan_target_psds = nchan_out_woLFE;
    1925       69510 :             move16();
    1926             :         }
    1927             : 
    1928       78927 :         computeTargetPSDs_direct_subframe_fx( nchan_target_psds, num_freq_bands,
    1929       78927 :                                               h_dirac_output_synthesis_state->direct_power_factor_fx,
    1930             :                                               reference_power_smooth,
    1931             :                                               q_reference_power_smooth,
    1932       78927 :                                               h_dirac_output_synthesis_state->direct_responses_fx,
    1933       78927 :                                               h_dirac_output_synthesis_state->direct_responses_square_fx,
    1934             :                                               h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx,
    1935             :                                               q_cy_auto_dir_smooth_local,
    1936             :                                               h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx,
    1937             :                                               &h_dirac_output_synthesis_state->q_cy_cross_dir_smooth );
    1938             : 
    1939             : 
    1940       78927 :         computeTargetPSDs_diffuse_subframe_fx( nchan_target_psds, num_freq_bands, diff_start_band,
    1941       78927 :                                                h_dirac_output_synthesis_state->diffuse_power_factor_fx,
    1942             :                                                reference_power_smooth,
    1943             :                                                q_reference_power_smooth,
    1944       78927 :                                                h_dirac_output_synthesis_state->diffuse_responses_square_fx,
    1945             :                                                h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx,
    1946             :                                                &h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    1947             :     }
    1948             : 
    1949             :     /*-----------------------------------------------------------------*
    1950             :      * compute variables for stereo transport signal type detection
    1951             :      *-----------------------------------------------------------------*/
    1952             : 
    1953       92927 :     IF( hDirACRend->masa_stereo_type_detect != NULL )
    1954             :     {
    1955       16209 :         MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
    1956             : 
    1957       16209 :         p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx;   // q_cy_auto_dir_smooth
    1958       16209 :         p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx; // q_cy_auto_diff_smooth
    1959       16209 :         q_com = s_min( q_cy_auto_dir_smooth_local[1], h_dirac_output_synthesis_state->q_cy_auto_diff_smooth );
    1960             : 
    1961       16209 :         IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
    1962             :         {
    1963        9417 :             exp = Q31 - Q31;
    1964        9417 :             move16();
    1965        9417 :             exp1 = 0;
    1966        9417 :             move16();
    1967        9417 :             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] ) ),
    1968        9417 :                                                         ( L_add( Sqrt32( h_dirac_output_synthesis_state->direct_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
    1969             :                                                         &exp1 );
    1970        9417 :             target_power_y = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
    1971        9417 :             q_target_power_y = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
    1972        9417 :             q_target_power_y = sub( q_target_power_y, 1 );
    1973             : 
    1974        9417 :             exp = Q31 - Q31;
    1975        9417 :             move16();
    1976        9417 :             exp1 = 0;
    1977        9417 :             move16();
    1978        9417 :             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 ) ),
    1979        9417 :                                                         ( L_add( Sqrt32( h_dirac_output_synthesis_state->diffuse_power_factor_fx[0], &exp ), EPSILON_FX ) ), // (Q31 - exp)
    1980             :                                                         &exp1 );
    1981        9417 :             target_power_y1 = L_shr( tmp32, 1 ); // Q31 + (q_com - (31 - exp))
    1982        9417 :             q_target_power_y1 = add( sub( Q31, exp1 ), sub( q_com, sub( Q31, exp ) ) );
    1983        9417 :             q_target_power_y1 = sub( q_target_power_y1, 1 );
    1984             : 
    1985        9417 :             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 )*/
    1986        9417 :             exp = s_min( q_target_power_y1, q_target_power_y );
    1987             :         }
    1988             :         ELSE
    1989             :         {
    1990        6792 :             target_power_y = L_add(
    1991        6792 :                 L_shl( p_cy_auto_dir_smooth[num_freq_bands], sub( q_com, q_cy_auto_dir_smooth_local[1] ) ),
    1992        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
    1993        6792 :             exp = q_com;
    1994        6792 :             move16();
    1995             :         }
    1996             : 
    1997       16209 :         a = 858993; /* ( 0.0004f in Q31 ); Temporal smoothing coefficient */
    1998       16209 :         move32();
    1999       16209 :         b = L_sub( ONE_IN_Q31, a ); /* Temporal smoothing coefficient */
    2000             : 
    2001       16209 :         q_com = s_min( exp, masa_stereo_type_detect->q_target_power_y_smooth );
    2002       16209 :         target_power_y = L_shl( target_power_y, sub( q_com, exp ) );
    2003       16209 :         masa_stereo_type_detect->target_power_y_smooth_fx = L_shl( masa_stereo_type_detect->target_power_y_smooth_fx,
    2004       16209 :                                                                    sub( q_com, masa_stereo_type_detect->q_target_power_y_smooth ) );
    2005       16209 :         move32();
    2006       16209 :         masa_stereo_type_detect->target_power_y_smooth_fx =
    2007       16209 :             L_add( Mpy_32_32( a, target_power_y ),
    2008             :                    Mpy_32_32( b, masa_stereo_type_detect->target_power_y_smooth_fx ) ); //(Q31, q_com) -> q_com
    2009       16209 :         move32();
    2010       16209 :         masa_stereo_type_detect->q_target_power_y_smooth = q_com;
    2011       16209 :         move16();
    2012             : 
    2013       16209 :         IF( NE_16( masa_stereo_type_detect->q_subtract_power_y, masa_stereo_type_detect->q_subtract_power_y_smooth ) )
    2014             :         {
    2015           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 ) ) );
    2016           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 ) );
    2017           0 :             move32();
    2018           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 ) );
    2019           0 :             move32();
    2020           0 :             masa_stereo_type_detect->q_subtract_power_y = exp;
    2021           0 :             move16();
    2022           0 :             masa_stereo_type_detect->q_subtract_power_y_smooth = exp;
    2023           0 :             move16();
    2024             :         }
    2025       16209 :         subtract_power_y = masa_stereo_type_detect->subtract_power_y_fx; // q_subtract_power_y
    2026       16209 :         move32();
    2027             : 
    2028       16209 :         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
    2029       16209 :         IF( W_temp )
    2030             :         {
    2031       16196 :             exp = W_norm( W_temp );
    2032       16196 :             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
    2033       16196 :             move32();
    2034       16196 :             masa_stereo_type_detect->q_subtract_power_y_smooth = sub( add( masa_stereo_type_detect->q_subtract_power_y_smooth, exp ), 1 );
    2035       16196 :             move16();
    2036             :         }
    2037             :         ELSE
    2038             :         {
    2039          13 :             masa_stereo_type_detect->subtract_power_y_smooth_fx = 0; // Q31
    2040          13 :             move32();
    2041          13 :             masa_stereo_type_detect->q_subtract_power_y_smooth = Q31;
    2042          13 :             move16();
    2043             :         }
    2044       16209 :         exp = 0;
    2045       16209 :         move16();
    2046       16209 :         test();
    2047       16209 :         IF( masa_stereo_type_detect->target_power_y_smooth_fx && masa_stereo_type_detect->subtract_power_y_smooth_fx )
    2048             :         {
    2049       16193 :             subtract_target_ratio = L_sub( BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ),
    2050             :                                            BASOP_Util_Log2( masa_stereo_type_detect->target_power_y_smooth_fx ) ); // Q25
    2051       16193 :             exp = sub( masa_stereo_type_detect->q_subtract_power_y_smooth, q_com );
    2052       16193 :             L_tmp = Mpy_32_32( L_sub( subtract_target_ratio, L_shl( exp, 25 ) ), LOG10_2_Q31 ); // Q25
    2053             :         }
    2054             :         ELSE
    2055             :         {
    2056          16 :             subtract_target_ratio = BASOP_Util_Log2( masa_stereo_type_detect->subtract_power_y_smooth_fx ); // Q25
    2057          16 :             exp = sub( 31, masa_stereo_type_detect->q_subtract_power_y_smooth );
    2058          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
    2059             :         }
    2060       16209 :         subtract_target_ratio_db = Mpy_32_32( 1342177280 /* 10.0f * in Q27*/, L_tmp ); // (Q27, (Q25, Q31)) -> (Q27, Q25) -> Q21
    2061             : 
    2062       16209 :         masa_stereo_type_detect->subtract_target_ratio_db_fx = subtract_target_ratio_db; // Q21
    2063       16209 :         move32();
    2064       16209 :         masa_stereo_type_detect->subtract_power_y_fx = 0;
    2065       16209 :         move32();
    2066       16209 :         masa_stereo_type_detect->q_subtract_power_y = Q31;
    2067       16209 :         move16();
    2068             :     }
    2069             : 
    2070             :     /*-----------------------------------------------------------------*
    2071             :      * compute smoothing coefficients
    2072             :      *-----------------------------------------------------------------*/
    2073             : 
    2074       92927 :     alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis_fx;           // Q15
    2075       92927 :     alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast_fx; // Q15
    2076       92927 :     alphaMaxBin = sub( h_dirac_output_synthesis_params->numAlphas, 1 );
    2077       92927 :     alphaMaxBinFast = sub( h_dirac_output_synthesis_params->numAlphasFast, 1 );
    2078             : 
    2079     5403347 :     FOR( l = 0; l < num_freq_bands; l++ )
    2080             :     {
    2081             :         Word32 instDirectionSmoothness, weightedDirectionSmoothness, smoothedDirectionSmoothness;
    2082             :         Word32 currWeight, prevWeight, sumWeight;
    2083             :         Word16 indexFast, indexSlow;
    2084     5310420 :         Word32 alpha_quality_based = 42949672; /* 0.02f in Q31 */
    2085     5310420 :         move32();
    2086             : 
    2087     5310420 :         indexSlow = s_min( l, alphaMaxBin );
    2088     5310420 :         indexFast = s_min( l, alphaMaxBinFast );
    2089             : 
    2090             :         /* Estimate the smoothness of the directions based on the diffuseness parameter */
    2091     5310420 :         instDirectionSmoothness = L_sub( ONE_IN_Q31, diffuseness_vector[l] );               // Q31
    2092     5310420 :         instDirectionSmoothness = L_min( L_max( instDirectionSmoothness, 0 ), ONE_IN_Q31 ); // Q31
    2093             : 
    2094             :         /* Average the direction smoothness parameter over time */
    2095     5310420 :         currWeight = Mpy_32_32( DIRECTION_SMOOTHNESS_ALPHA_Q31,
    2096     5310420 :                                 reference_power_smooth[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
    2097     5310420 :         prevWeight = Mpy_32_32( L_sub( ONE_IN_Q31, DIRECTION_SMOOTHNESS_ALPHA_Q31 ),
    2098     5310420 :                                 h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] ); //(Q31, q_reference_power_smooth) -> q_reference_power_smooth
    2099             : 
    2100     5310420 :         assert( q_reference_power_smooth[0] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[0] );
    2101     5310420 :         assert( q_reference_power_smooth[1] == h_dirac_output_synthesis_state->reference_power_smooth_prev_q[1] );
    2102             :         weightedDirectionSmoothness =
    2103     5310420 :             L_add( Mpy_32_32( currWeight, instDirectionSmoothness ),
    2104     5310420 :                    Mpy_32_32( prevWeight, h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] ) ); //(q_reference_power_smooth, Q31) -> q_reference_power_smooth
    2105     5310420 :         sumWeight = L_add( currWeight, prevWeight );                                                           // q_reference_power_smooth
    2106             : 
    2107     5310420 :         exp = 0;
    2108     5310420 :         move16();
    2109             : 
    2110     5310420 :         tmp = BASOP_Util_Divide3232_Scale( weightedDirectionSmoothness, L_add( sumWeight, EPSILON_FX ), &exp ); /*Q(15-exp)*/
    2111     5310420 :         smoothedDirectionSmoothness = L_shl_sat( L_deposit_l( tmp ), add( sub( Q31, Q15 ), exp ) );             // Q31
    2112             : 
    2113     5310420 :         h_dirac_output_synthesis_state->direction_smoothness_prev_fx[l] = smoothedDirectionSmoothness; // Q31
    2114     5310420 :         move32();
    2115     5310420 :         h_dirac_output_synthesis_state->reference_power_smooth_prev_fx[l] = sumWeight; // q_reference_power_smooth
    2116     5310420 :         move32();
    2117             : 
    2118             :         /* Determine smoothing parameter for rendering. The smoother the directions, the less smoothing is required (i.e., faster smoothing can be used). */
    2119    10620840 :         alpha[l] =
    2120     5310420 :             L_add( Mpy_32_16_1( smoothedDirectionSmoothness, alpha_synthesis_fast[indexFast] ),
    2121     5310420 :                    Mpy_32_16_1( L_sub( ONE_IN_Q31, smoothedDirectionSmoothness ), alpha_synthesis[indexSlow] ) ); //(Q31, Q15) -> Q31
    2122     5310420 :         move32();
    2123             : 
    2124             :         /* Adjust smoothing parameter based on encoding quality */
    2125    10620840 :         alpha[l] =
    2126     5310420 :             L_add( Mpy_32_32( qualityBasedSmFactor, alpha[l] ),
    2127             :                    Mpy_32_32( L_sub( ONE_IN_Q31, qualityBasedSmFactor ), alpha_quality_based ) ); //(Q31, Q31) -> Q31
    2128     5310420 :         move32();
    2129             :     }
    2130             : 
    2131             :     /*-----------------------------------------------------------------*
    2132             :      * compute gains
    2133             :      *-----------------------------------------------------------------*/
    2134             : 
    2135             :     /*Direct normalization gains on reduced number of protos*/
    2136       92927 :     p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev_fx;
    2137       92927 :     p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
    2138       92927 :     set16_fx( exp_arr, 0, i_mult( num_protos_dir, num_freq_bands ) );
    2139             : 
    2140      374531 :     FOR( k = 0; k < num_protos_dir; k++ )
    2141             :     {
    2142    16711344 :         FOR( l = 0; l < num_freq_bands; l++ )
    2143             :         {
    2144    16429740 :             g1 = alpha[l]; // Q31
    2145    16429740 :             move32();
    2146    16429740 :             g2 = L_sub( ONE_IN_Q31, g1 );                                                          // Q31
    2147    16429740 :             *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
    2148    16429740 :             move32();
    2149    16429740 :             *( 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
    2150    16429740 :             move32();
    2151             : 
    2152    16429740 :             assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] == h_dirac_output_synthesis_state->proto_power_smooth_q[0] );
    2153    16429740 :             assert( h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] == h_dirac_output_synthesis_state->proto_power_smooth_q[1] );
    2154    16429740 :             IF( EQ_32( *( p_power_smooth_prev ), EPSILON_FX ) )
    2155             :             {
    2156       23481 :                 p_power_smooth_prev++;
    2157       23481 :                 L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, EPSILON_FX, &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2158       23481 :                 exp_arr[k * num_freq_bands + l] = exp;
    2159       23481 :                 move16();
    2160             : 
    2161       23481 :                 *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2162       23481 :                 move32();
    2163             :             }
    2164             :             ELSE
    2165             :             {
    2166    16406259 :                 L_tmp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q31, *( p_power_smooth_prev++ ), &exp ); /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2167    16406259 :                 exp_arr[k * num_freq_bands + l] = exp;
    2168    16406259 :                 move16();
    2169             : 
    2170    16406259 :                 *( p_power_smooth++ ) = L_tmp; /*Q=31-(exp-(31-q_proto_power_smooth))*/
    2171    16406259 :                 move32();
    2172             :             }
    2173             :         }
    2174             :     }
    2175             : 
    2176             :     // Move proto_power_smooth_fx to common Q-factor
    2177             : 
    2178       92927 :     Word16 min_exp2 = -64;
    2179       92927 :     min_exp = MIN_16;
    2180       92927 :     move16();
    2181       92927 :     move16();
    2182       92927 :     Word16 q_tmp2 = Q31;
    2183       92927 :     q_tmp = Q31;
    2184       92927 :     move16();
    2185       92927 :     move16();
    2186             : 
    2187      374531 :     FOR( k = 0; k < num_protos_dir; k++ )
    2188             :     {
    2189     8686524 :         FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
    2190             :         {
    2191     8404920 :             min_exp = s_max( min_exp, exp_arr[k * num_freq_bands + l] );
    2192             :         }
    2193     8306424 :         FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2194             :         {
    2195     8024820 :             min_exp2 = s_max( min_exp2, exp_arr[k * num_freq_bands + l] );
    2196             :         }
    2197             :     }
    2198             : 
    2199       92927 :     p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth_fx;
    2200             : 
    2201      374531 :     FOR( k = 0; k < num_protos_dir; k++ )
    2202             :     {
    2203     8686524 :         FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
    2204             :         {
    2205     8404920 :             *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)))*/
    2206     8404920 :             move32();
    2207     8404920 :             p_power_smooth++;
    2208             :         }
    2209     8306424 :         FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2210             :         {
    2211     8024820 :             *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)))*/
    2212     8024820 :             move32();
    2213     8024820 :             p_power_smooth++;
    2214             :         }
    2215             :     }
    2216             : 
    2217             :     // Update the Q-factor
    2218       92927 :     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] );
    2219       92927 :     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] );
    2220       92927 :     move16();
    2221       92927 :     move16();
    2222             : 
    2223       92927 :     q_tmp = add( sub( Q31, min_exp ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[0] ) );
    2224       92927 :     q_tmp2 = add( sub( Q31, min_exp2 ), sub( Q31, h_dirac_output_synthesis_state->proto_power_smooth_prev_q[1] ) );
    2225             : 
    2226       92927 :     h_dirac_output_synthesis_state->proto_power_smooth_q[0] = q_tmp;
    2227       92927 :     h_dirac_output_synthesis_state->proto_power_smooth_q[1] = q_tmp2;
    2228       92927 :     move16();
    2229       92927 :     move16();
    2230             : 
    2231             :     /*Direct gains and diffuse gains on number of output channels*/
    2232       92927 :     p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev_fx;
    2233       92927 :     p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth_fx;
    2234             : 
    2235       92927 :     p_gains_diff = gains_diff;
    2236       92927 :     p_gains_dir = gains_dir;
    2237             : 
    2238       92927 :     p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx;
    2239       92927 :     p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev_fx;
    2240      744059 :     FOR( k = 0; k < nchan_out_woLFE; k++ )
    2241             :     {
    2242      651132 :         q_cy_auto_dir_smooth_prev_local[k] = getScaleFactor32( p_cy_auto_dir_smooth_prev + imult1616( k, num_freq_bands ), num_freq_bands );
    2243      651132 :         move16();
    2244      651132 :         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*/
    2245      651132 :         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 );
    2246      651132 :         move16();
    2247      651132 :         q_com = s_min( q_cy_auto_dir_smooth_local[k], q_cy_auto_dir_smooth_prev_local[k] );
    2248      651132 :         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*/
    2249      651132 :         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*/
    2250      651132 :         q_cy_auto_dir_smooth_local[k] = q_cy_auto_dir_smooth_prev_local[k] = q_com;
    2251      651132 :         move16();
    2252      651132 :         move16();
    2253             :     }
    2254             : 
    2255             : 
    2256       92927 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx;
    2257       92927 :     p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev_fx;
    2258       92927 :     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 );
    2259       92927 :     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*/
    2260       92927 :     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*/
    2261       92927 :     h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev = q_com;
    2262       92927 :     move16();
    2263       92927 :     move16();
    2264             : 
    2265       92927 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx;
    2266       92927 :     p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev_fx;
    2267       92927 :     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 );
    2268       92927 :     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*/
    2269       92927 :     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*/
    2270       92927 :     h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev = q_com;
    2271       92927 :     move16();
    2272       92927 :     move16();
    2273             : 
    2274       92927 :     Word32 cmp = W_shl_sat_l( DIRAC_GAIN_LIMIT_Q26, sub( h_dirac_output_synthesis_state->gains_dir_prev_q, 26 ) );
    2275       92927 :     Word32 cmp2 = 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 ) );
    2276             : 
    2277      744059 :     FOR( k = 0; k < nchan_out_woLFE; k++ )
    2278             :     {
    2279             :         Word32 power_smooth_temp;
    2280             :         Word16 qidx;
    2281      651132 :         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
    2282     8266857 :         FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    2283             :         {
    2284             :             /*Direct*/
    2285     7615725 :             g1 = alpha[l]; // Q31
    2286     7615725 :             move32();
    2287     7615725 :             g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
    2288     7615725 :             assert( q_cy_auto_dir_smooth_local[k] == q_cy_auto_dir_smooth_prev_local[k] );
    2289     7615725 :             *( p_cy_auto_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
    2290             :                                                     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
    2291     7615725 :             move32();
    2292     7615725 :             assert( h_dirac_output_synthesis_state->q_cy_cross_dir_smooth == h_dirac_output_synthesis_state->q_cy_cross_dir_smooth_prev );
    2293     7615725 :             *( p_cy_cross_dir_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth++ ) ) ),
    2294             :                                                      Mpy_32_32( g2, ( *( p_cy_cross_dir_smooth_prev ) ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
    2295     7615725 :             move32();
    2296             : 
    2297     7615725 :             power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );      // proto_power_smooth_q + norm_l( *p_power_smooth )
    2298     7615725 :             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
    2299     7615725 :             qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    2300     7615725 :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
    2301     7615725 :                                       q_cy_auto_dir_smooth_prev_local[k] ),
    2302             :                                  Q31 ) );
    2303             : 
    2304     7615725 :             p_power_smooth++;
    2305             : 
    2306     7615725 :             *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
    2307     7615725 :             move32();
    2308     7615725 :             *( 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
    2309     7615725 :             move32();
    2310             : 
    2311     7615725 :             IF( *( p_gains_dir ) < 0 )
    2312             :             {
    2313           0 :                 *( p_gains_dir ) = 0;
    2314           0 :                 move32();
    2315             :             }
    2316     7615725 :             ELSE IF( GT_32( *( p_gains_dir ), cmp ) )
    2317             :             {
    2318       18545 :                 *( p_gains_dir ) = cmp; /*26 + h_dirac_output_synthesis_state->gains_dir_prev_q + 1 + 5 - 32 -> h_dirac_output_synthesis_state->gains_dir_prev_q*/
    2319       18545 :                 move32();
    2320             :             }
    2321             : 
    2322     7615725 :             IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    2323             :             {
    2324      884529 :                 *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*h_dirac_output_synthesis_state->gains_dir_prev_q*/
    2325      884529 :                 move32();
    2326             :             }
    2327     7615725 :             p_gains_dir++;
    2328             : 
    2329             :             /*diffuse*/
    2330     7615725 :             *p_power_diff_smooth_prev = L_add( L_add( Mpy_32_32( g1, ( *( p_power_smooth_diff++ ) ) ),
    2331             :                                                       Mpy_32_32( g2, ( *( p_power_diff_smooth_prev ) ) ) ),
    2332             :                                                EPSILLON_FX ); // (Q31, q_power_diff_smooth_prev) -> q_power_diff_smooth_prev
    2333     7615725 :             move32();
    2334     7615725 :             *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth++ ) ) ),
    2335             :                                                      Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
    2336     7615725 :             move32();
    2337             : 
    2338     7615725 :             exp = 0;
    2339     7615725 :             move16();
    2340     7615725 :             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)
    2341     7615725 :             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 ) ) );
    2342             : 
    2343     7615725 :             *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); // (31 - exp)
    2344     7615725 :             move32();
    2345     7615725 :             *( 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
    2346     7615725 :             move32();
    2347             : 
    2348     7615725 :             IF( *( p_gains_diff ) < 0 )
    2349             :             {
    2350           0 :                 *( p_gains_diff ) = 0;
    2351           0 :                 move32();
    2352             :             }
    2353     7615725 :             ELSE IF( GT_32( *( p_gains_diff ), cmp2 ) ) /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
    2354             :             {
    2355      144762 :                 *( p_gains_diff ) = cmp2; /*h_dirac_output_synthesis_state->gains_diff_prev_q*/
    2356      144762 :                 move32();
    2357             :             }
    2358     7615725 :             p_gains_diff++;
    2359             :         }
    2360             : 
    2361             :         /*Only direct prototype*/
    2362    30734527 :         FOR( ; l < num_freq_bands; l++ )
    2363             :         {
    2364             :             /*Direct*/
    2365    30083395 :             g1 = alpha[l]; // Q31
    2366    30083395 :             move32();
    2367    30083395 :             g2 = L_sub( ONE_IN_Q31, g1 ); // Q31
    2368    30083395 :             W_temp = W_mac_32_32( W_mult_32_32( g1, ( *( p_cy_auto_dir_smooth++ ) ) ),
    2369             :                                   g2, ( *( p_cy_auto_dir_smooth_prev ) ) ); /*32+q_cy_auto_dir_smooth_prev_local*/
    2370    30083395 :             q_tmp = W_norm( W_temp );
    2371    30083395 :             L_tmp = W_extract_h( W_shl( W_temp, q_tmp ) );              // q_cy_auto_dir_smooth_prev_local + q_tmp
    2372    30083395 :             *( p_cy_auto_dir_smooth_prev++ ) = L_shr_r( L_tmp, q_tmp ); // q_cy_auto_dir_smooth_prev_local
    2373             : 
    2374    30083395 :             move32();
    2375    30083395 :             *( p_cy_cross_dir_smooth_prev ) = Madd_32_32( Mpy_32_32( g1, ( *( p_cy_cross_dir_smooth ) ) ),
    2376             :                                                           g2, ( *( p_cy_cross_dir_smooth_prev ) ) ); // (Q31, q_cy_cross_dir_smooth_prev) -> q_cy_cross_dir_smooth_prev
    2377    30083395 :             move32();
    2378    30083395 :             test();
    2379    30083395 :             if ( *( p_cy_cross_dir_smooth_prev ) == 0 && ( *( p_cy_cross_dir_smooth ) != 0 ) )
    2380             :             {
    2381     1311178 :                 *( p_cy_cross_dir_smooth_prev ) = 1;
    2382     1311178 :                 move32();
    2383             :             }
    2384    30083395 :             ( p_cy_cross_dir_smooth++ );
    2385    30083395 :             power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );
    2386    30083395 :             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
    2387    30083395 :             qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    2388    30083395 :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
    2389    30083395 :                                       add( q_cy_auto_dir_smooth_prev_local[k], q_tmp ) ),
    2390             :                                  Q31 ) );
    2391             : 
    2392    30083395 :             *( p_gains_dir ) = Sqrt32( L_tmp, &exp ); // (Q31 - exp)
    2393    30083395 :             move32();
    2394    30083395 :             *( 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
    2395    30083395 :             move32();
    2396             : 
    2397    30083395 :             IF( *( p_gains_dir ) < 0 )
    2398             :             {
    2399           0 :                 *( p_gains_dir ) = 0;
    2400           0 :                 move32();
    2401             :             }
    2402    30083395 :             ELSE IF( GT_32( *( p_gains_dir ), cmp ) ) /*gains_dir_prev_q*/
    2403             :             {
    2404       25782 :                 *( p_gains_dir ) = cmp; /*gains_dir_prev_q*/
    2405       25782 :                 move32();
    2406             :             }
    2407             : 
    2408    30083395 :             IF( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    2409             :             {
    2410     3035844 :                 *( p_gains_dir ) = L_negate( *( p_gains_dir ) ); /*gains_dir_prev_q*/
    2411     3035844 :                 move32();
    2412             :             }
    2413    30083395 :             p_gains_dir++;
    2414             : 
    2415             :             /*diffuse*/
    2416    30083395 :             *( p_cy_auto_diff_smooth_prev ) = L_add( Mpy_32_32( g1, ( *( p_cy_auto_diff_smooth ) ) ),
    2417             :                                                      Mpy_32_32( g2, ( *( p_cy_auto_diff_smooth_prev ) ) ) ); // (Q31, q_cy_auto_diff_smooth_prev) -> q_cy_auto_diff_smooth_prev
    2418             : 
    2419    30083395 :             test();
    2420    30083395 :             if ( *( p_cy_auto_diff_smooth_prev ) == 0 && ( *( p_cy_auto_diff_smooth ) != 0 ) )
    2421             :             {
    2422     2050113 :                 *( p_cy_auto_diff_smooth_prev ) = 1;
    2423     2050113 :                 move32();
    2424             :             }
    2425    30083395 :             ( p_cy_auto_diff_smooth++ );
    2426    30083395 :             move32();
    2427             : 
    2428    30083395 :             power_smooth_temp = L_shl( *p_power_smooth, norm_l( *p_power_smooth ) );     // proto_power_smooth_q + norm_l( *p_power_smooth )
    2429    30083395 :             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
    2430             : 
    2431    30083395 :             test();
    2432    30083395 :             test();
    2433    30083395 :             if ( L_tmp == 0 && ( power_smooth_temp != 0 && *( p_cy_auto_diff_smooth_prev ) != 0 ) )
    2434             :             {
    2435     2544299 :                 L_tmp = 1;
    2436     2544299 :                 move32();
    2437             :             }
    2438    30083395 :             ( p_cy_auto_diff_smooth_prev++ );
    2439    30083395 :             exp = sub( Q31, sub( add( add( h_dirac_output_synthesis_state->proto_power_smooth_q[qidx], norm_l( *p_power_smooth ) ),
    2440    30083395 :                                       h_dirac_output_synthesis_state->q_cy_auto_diff_smooth_prev ),
    2441             :                                  Q31 ) );
    2442    30083395 :             p_power_smooth++;
    2443             : 
    2444    30083395 :             *( p_gains_diff ) = Sqrt32( L_tmp, &exp ); /*31-exp*/
    2445    30083395 :             move32();
    2446    30083395 :             *( 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
    2447    30083395 :             move32();
    2448             : 
    2449    30083395 :             IF( *( p_gains_diff ) < 0 )
    2450             :             {
    2451           0 :                 *( p_gains_diff ) = 0;
    2452           0 :                 move32();
    2453             :             }
    2454    30083395 :             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
    2455             :             {
    2456       18547 :                 *( 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
    2457       18547 :                 move32();
    2458             :             }
    2459    30083395 :             p_gains_diff++;
    2460             :         }
    2461             :     }
    2462             : 
    2463             :     /*-----------------------------------------------------------------*
    2464             :      * gain interpolation and output streams
    2465             :      *-----------------------------------------------------------------*/
    2466       92927 :     Word16 q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_power_diff_smooth_q );
    2467       92927 :     if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
    2468             :     {
    2469       69510 :         q_align = sub( h_dirac_output_synthesis_state->proto_direct_buffer_f_q, h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q );
    2470             :     }
    2471             : 
    2472      461651 :     FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    2473             :     {
    2474      368724 :         g1 = L_deposit_h( h_dirac_output_synthesis_params->interpolator_fx[buf_idx] ); // Q15 -> Q31
    2475      368724 :         g2 = L_sub( ONE_IN_Q31, g1 );                                                  // Q31
    2476             : 
    2477             :         /*Direct stream*/
    2478      368724 :         p_gain_1 = gains_dir;
    2479      368724 :         p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev_fx; // gains_dir_prev_q
    2480     2969722 :         FOR( k = 0; k < nchan_out_woLFE; k++ )
    2481             :         {
    2482     5201996 :             p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
    2483     2600998 :                              shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    2484     2600998 :                              shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 );
    2485   153243538 :             FOR( l = 0; l < num_freq_bands; l++ )
    2486             :             {
    2487   150642540 :                 g = Madd_32_32( Mpy_32_32( g1, *( p_gain_1++ ) ), g2, *( p_gain_2++ ) ); // (Q31, gains_dir_prev_q) -> gains_dir_prev_q
    2488             : 
    2489   150642540 :                 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
    2490   150642540 :                 move64();
    2491             : 
    2492   150642540 :                 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
    2493   150642540 :                 move64();
    2494             :             }
    2495             :         }
    2496             : 
    2497             :         /*Diffuse stream*/
    2498      368724 :         IF( h_dirac_output_synthesis_params->max_band_decorr != 0 )
    2499             :         {
    2500      555898 :             p_power_smooth_diff = h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx +
    2501      277949 :                                   shl( i_mult( buf_idx, i_mult( h_dirac_output_synthesis_params->max_band_decorr, nchan_out_woLFE ) ), Q1 );
    2502             :         }
    2503      368724 :         p_gain_1 = gains_diff;
    2504      368724 :         p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev_fx; // gains_diff_prev_q
    2505     2969722 :         FOR( k = 0; k < nchan_out_woLFE; k++ )
    2506             :         {
    2507    33054343 :             FOR( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    2508             :             {
    2509    30453345 :                 g = Madd_32_32( Mpy_32_32( g1, *( p_gain_1++ ) ), g2, *( p_gain_2++ ) ); // (Q31, gains_diff_prev_q) -> gains_diff_prev_q
    2510    30453345 :                 Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
    2511    30453345 :                                                               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
    2512    30453345 :                 move64();
    2513             : 
    2514    30453345 :                 if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
    2515             :                 {
    2516      215301 :                     W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
    2517             :                 }
    2518             : 
    2519    30453345 :                 Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
    2520    30453345 :                                                               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
    2521    30453345 :                 move64();
    2522             : 
    2523    30453345 :                 if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
    2524             :                 {
    2525      120320 :                     W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] );
    2526             :                 }
    2527             :             }
    2528             : 
    2529             :             /*Direct proto*/
    2530     5201996 :             p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f_fx +
    2531     2600998 :                              shl( i_mult( buf_idx, i_mult( num_freq_bands, num_protos_dir ) ), Q1 ) +
    2532     2600998 :                              shl( i_mult( proto_direct_index[k], num_freq_bands ), Q1 ) +
    2533     2600998 :                              shl( h_dirac_output_synthesis_params->max_band_decorr, Q1 );
    2534   122790193 :             FOR( ; l < num_freq_bands; l++ )
    2535             :             {
    2536   120189195 :                 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
    2537   120189195 :                 Cldfb_RealBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_RealBuffer64_fx[k][buf_idx][l],
    2538   120189195 :                                                               W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
    2539   120189195 :                 move64();
    2540             : 
    2541   120189195 :                 if ( LT_64( W_temp, W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] ) ) )
    2542             :                 {
    2543       70956 :                     W_temp = W_abs( Cldfb_RealBuffer64_fx[k][buf_idx][l] );
    2544             :                 }
    2545             : 
    2546   120189195 :                 Cldfb_ImagBuffer64_fx[k][buf_idx][l] = W_add( Cldfb_ImagBuffer64_fx[k][buf_idx][l],
    2547   120189195 :                                                               W_mult0_32_32( g, ( *( p_power_smooth++ ) ) ) ); // (gains_diff_prev_q, q_proto_direct_buffer) -> gains_diff_prev_q + q_proto_direct_buffer
    2548   120189195 :                 move64();
    2549             : 
    2550   120189195 :                 if ( LT_64( W_temp, W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ) ) )
    2551             :                 {
    2552       40466 :                     W_temp = W_abs( Cldfb_ImagBuffer64_fx[k][buf_idx][l] ); // gains_diff_prev_q + q_proto_direct_buffer
    2553             :                 }
    2554             :             }
    2555             :         }
    2556             :     }
    2557       92927 :     q_align = W_norm( W_temp );
    2558       92927 :     Word16 shift = sub( q_align, 32 );
    2559             : 
    2560      461651 :     FOR( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    2561             :     {
    2562     2969722 :         FOR( k = 0; k < nchan_out_woLFE; k++ )
    2563             :         {
    2564   153243538 :             FOR( l = 0; l < num_freq_bands; l++ )
    2565             :             {
    2566   150642540 :                 RealBuffer[k][buf_idx][l] = W_shl_sat_l( Cldfb_RealBuffer64_fx[k][buf_idx][l], shift ); /*( ( ( h_dirac_output_synthesis_state->proto_direct_buffer_f_q+h_dirac_output_synthesis_state->gains_dir_prev_q )+ q_align )- 32 )*/
    2567   150642540 :                 move32();
    2568   150642540 :                 ImagBuffer[k][buf_idx][l] = W_shl_sat_l( Cldfb_ImagBuffer64_fx[k][buf_idx][l], shift ); /*( ( ( h_dirac_output_synthesis_state->proto_direct_buffer_f_q+h_dirac_output_synthesis_state->gains_dir_prev_q )+ q_align )- 32 )*/
    2569   150642540 :                 move32();
    2570             :             }
    2571             :         }
    2572             :     }
    2573             : 
    2574       92927 :     *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 );
    2575       92927 :     move16();
    2576             : 
    2577             :     /*-----------------------------------------------------------------*
    2578             :      * update buffers
    2579             :      *-----------------------------------------------------------------*/
    2580             : 
    2581             :     /* store estimates for next synthesis block */
    2582       92927 :     Copy32( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );   /*gains_dir_prev_q*/
    2583       92927 :     Copy32( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev_fx, imult1616( num_freq_bands, nchan_out_woLFE ) ); /*gains_diff_prev_q*/
    2584             : 
    2585             :     /* reset values */
    2586       92927 :     set_zero_fx( h_dirac_output_synthesis_state->proto_power_smooth_fx, imult1616( num_freq_bands, num_protos_dir ) );
    2587       92927 :     IF( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx != NULL )
    2588             :     {
    2589       92927 :         set_zero_fx( h_dirac_output_synthesis_state->proto_power_diff_smooth_fx, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
    2590             :     }
    2591             : 
    2592       92927 :     minimum_fx( q_cy_auto_dir_smooth_prev_local, nchan_out_woLFE, &h_dirac_output_synthesis_state->q_cy_auto_dir_smooth_prev );
    2593      744059 :     FOR( k = 0; k < nchan_out_woLFE; k++ )
    2594             :     {
    2595      651132 :         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*/
    2596             :     }
    2597             : 
    2598       92927 :     set_zero_fx( h_dirac_output_synthesis_state->cy_auto_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
    2599       92927 :     h_dirac_output_synthesis_state->q_cy_auto_dir_smooth = 0;
    2600       92927 :     move16();
    2601       92927 :     set_zero_fx( h_dirac_output_synthesis_state->cy_cross_dir_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
    2602       92927 :     h_dirac_output_synthesis_state->q_cy_cross_dir_smooth = 0;
    2603       92927 :     move16();
    2604       92927 :     set_zero_fx( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, imult1616( num_freq_bands, nchan_out_woLFE ) );
    2605       92927 :     h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = 0;
    2606       92927 :     move16();
    2607             : 
    2608       92927 :     pop_wmops();
    2609             : 
    2610       92927 :     return;
    2611             : }
    2612             : 
    2613             : 
    2614             : /*-------------------------------------------------------------------------
    2615             :  * ivas_dirac_dec_compute_directional_responses()
    2616             :  *
    2617             :  *
    2618             :  *------------------------------------------------------------------------*/
    2619             : 
    2620     1087261 : void ivas_dirac_dec_compute_directional_responses_fx(
    2621             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle                            */
    2622             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                                          */
    2623             :     const VBAP_HANDLE hVBAPdata,                          /* i  : VBAP structure                                                 */
    2624             :     const Word16 *masa_band_mapping,                      /* i  : Band mapping for MASA, NULL assumes not using MASA in any form */
    2625             :     MASA_ISM_DATA_HANDLE hMasaIsm,                        /* i  : MASA_ISM data structure                                        */
    2626             :     const Word16 *azimuth,
    2627             :     const Word16 *elevation,
    2628             :     const Word16 md_idx,
    2629             :     const Word32 *surCohRatio_fx, /*i:Q_surCohRatio*/
    2630             :     Word16 Q_surCohRatio,
    2631             :     const Word16 hodirac_flag /* i  : flag to indicate HO-DirAC mode */
    2632             : )
    2633             : {
    2634             :     Word16 k, l, i;
    2635             :     Word16 num_channels_dir;
    2636             :     const Word16 *azimuth2, *elevation2;
    2637             : 
    2638             :     Word32 direct_response_hoa_fx[MAX_OUTPUT_CHANNELS]; /*  number of output channels (HOA 3rd order) -> 16 */
    2639             :     Word32 direct_response_ls_fx[MAX_OUTPUT_CHANNELS];
    2640             :     Word32 direct_response_square_fx[MAX_OUTPUT_CHANNELS];
    2641             :     Word32 direct_response_dir2_fx[MAX_OUTPUT_CHANNELS];
    2642             :     Word32 directRatio_fx[MASA_MAXIMUM_DIRECTIONS];
    2643             :     Word16 Q_direct_response_ls, exp_direct_response_ls;
    2644             :     Word16 Q_direct_response_dir2, exp_direct_response_dir2;
    2645             :     Word16 Q_direct_response_hoa, exp_direct_response_hoa;
    2646             :     Word16 direct_response_square_q, direct_response_q;
    2647     1087261 :     Word16 exp_surCohRatio = sub( 31, Q_surCohRatio );
    2648             :     Word32 totalDirect_fx;
    2649             :     Word32 *direct_response_fx;
    2650             :     Word16 codingBand;
    2651             :     Word16 dipole_freq_range[2];
    2652             :     MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type;
    2653             : 
    2654     1087261 :     Q_direct_response_ls = Q31;
    2655     1087261 :     move16();
    2656     1087261 :     exp_direct_response_ls = 0;
    2657     1087261 :     move16();
    2658     1087261 :     Q_direct_response_dir2 = Q31;
    2659     1087261 :     move16();
    2660     1087261 :     exp_direct_response_dir2 = 0;
    2661     1087261 :     move16();
    2662     1087261 :     Q_direct_response_hoa = Q31;
    2663     1087261 :     move16();
    2664     1087261 :     exp_direct_response_hoa = 0;
    2665     1087261 :     move16();
    2666     1087261 :     direct_response_square_q = Q31;
    2667     1087261 :     move16();
    2668     1087261 :     direct_response_q = Q29;
    2669     1087261 :     move16();
    2670             : 
    2671     1087261 :     azimuth2 = NULL;
    2672     1087261 :     elevation2 = NULL;
    2673     1087261 :     transport_signal_type = MASA_STEREO_NOT_DEFINED;
    2674     1087261 :     move32();
    2675             : 
    2676     1087261 :     IF( hDirACRend->masa_stereo_type_detect != NULL )
    2677             :     {
    2678       16209 :         dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
    2679       16209 :         move16();
    2680       16209 :         dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
    2681       16209 :         move16();
    2682       16209 :         transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
    2683       16209 :         move16();
    2684             :     }
    2685             : 
    2686     1087261 :     num_channels_dir = hDirACRend->num_outputs_dir;
    2687     1087261 :     move16();
    2688     1087261 :     IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    2689             :     {
    2690      280616 :         azimuth2 = hSpatParamRendCom->azimuth2[md_idx]; /*q0*/
    2691      280616 :         move16();
    2692      280616 :         elevation2 = hSpatParamRendCom->elevation2[md_idx]; /*q0*/
    2693      280616 :         move16();
    2694             :     }
    2695             : 
    2696     1087261 :     codingBand = -1;
    2697             : 
    2698     1087261 :     assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
    2699             : 
    2700    59658381 :     FOR( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
    2701             :     {
    2702    58571120 :         test();
    2703    58571120 :         if ( masa_band_mapping != NULL && EQ_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) )
    2704             :         {
    2705     1031998 :             codingBand = add( codingBand, 1 );
    2706             :         }
    2707             : 
    2708    58571120 :         test();
    2709    58571120 :         test();
    2710    58571120 :         test();
    2711    58571120 :         IF( masa_band_mapping != NULL && GT_16( k, MASA_band_grouping_24[masa_band_mapping[codingBand]] ) &&
    2712             :             LT_16( k, MASA_band_grouping_24[masa_band_mapping[add( codingBand, 1 )]] ) &&
    2713             :             NE_16( k, hDirACRend->h_output_synthesis_psd_params.max_band_decorr ) )
    2714             :         {
    2715             :             /* 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 */
    2716     4157668 :             IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    2717             :             {
    2718     3567163 :                 mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k - 1],
    2719     3567163 :                                  hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx[k],
    2720     3567163 :                                  hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_square_q*/
    2721             :             }
    2722     4157668 :             mvr2r_inc_fixed( &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k - 1],
    2723     4157668 :                              hSpatParamRendCom->num_freq_bands,
    2724     4157668 :                              &hDirACRend->h_output_synthesis_psd_state.direct_responses_fx[k],
    2725     4157668 :                              hSpatParamRendCom->num_freq_bands, num_channels_dir ); /*direct_response_q*/
    2726             :         }
    2727             :         ELSE
    2728             :         {
    2729             :             /* HOA3 PANNING */
    2730    54413452 :             IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_HOA3 ) )
    2731             :             {
    2732    50453749 :                 set32_fx( direct_response_hoa_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS );  /*q29*/
    2733    50453749 :                 set32_fx( direct_response_dir2_fx, ONE_IN_Q29, MAX_OUTPUT_CHANNELS ); /*q29*/
    2734             : 
    2735    50453749 :                 Q_direct_response_hoa = Q29;
    2736    50453749 :                 move16();
    2737    50453749 :                 Q_direct_response_dir2 = Q29;
    2738    50453749 :                 move16();
    2739    50453749 :                 exp_direct_response_hoa = 0;
    2740    50453749 :                 move16();
    2741    50453749 :                 exp_direct_response_dir2 = 0;
    2742    50453749 :                 move16();
    2743             : 
    2744    50453749 :                 ivas_dirac_dec_get_response_fx_29( azimuth[k], elevation[k], direct_response_hoa_fx, hDirACRend->hOutSetup.ambisonics_order );
    2745             : 
    2746    50453749 :                 IF( hodirac_flag )
    2747             :                 {
    2748    15810800 :                     ivas_dirac_dec_get_response_fx_29( azimuth2[k], elevation2[k], direct_response_dir2_fx, hDirACRend->hOutSetup.ambisonics_order );
    2749             :                 }
    2750             : 
    2751    50453749 :                 test();
    2752    50453749 :                 test();
    2753    50453749 :                 test();
    2754    50453749 :                 test();
    2755    50453749 :                 IF( masa_band_mapping == NULL && EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    2756             :                 {
    2757    50005640 :                     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*/
    2758             : 
    2759    50005640 :                     IF( hodirac_flag )
    2760             :                     {
    2761    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*/
    2762             :                     }
    2763             :                 }
    2764      448109 :                 ELSE IF( ( ( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) ) && ( masa_band_mapping != NULL ) ) ||
    2765             :                          EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
    2766             :                 {
    2767             :                     /* Synthesize the first direction */
    2768      448109 :                     IF( GT_16( Q_direct_response_hoa, Q29 ) )
    2769             :                     {
    2770           0 :                         Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_hoa, Q29 ) ); /*Q_direct_response_hoa->q29*/
    2771           0 :                         Q_direct_response_hoa = Q29;
    2772           0 :                         move16();
    2773           0 :                         exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    2774             :                     }
    2775      448109 :                     spreadCoherencePanningHoa_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
    2776      448109 :                                                   direct_response_hoa_fx, &Q_direct_response_hoa, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
    2777             : 
    2778      448109 :                     exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    2779             :                     /* Synthesize the second direction and combine the gains */
    2780      448109 :                     IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    2781             :                     {
    2782      118200 :                         IF( GT_16( Q_direct_response_dir2, Q29 ) )
    2783             :                         {
    2784           0 :                             Scale_sig32( direct_response_dir2_fx, MAX_OUTPUT_CHANNELS, sub( Q_direct_response_dir2, Q29 ) ); /*Q_direct_response_dir2->q29*/
    2785           0 :                             Q_direct_response_dir2 = Q29;
    2786           0 :                             move16();
    2787           0 :                             exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
    2788             :                         }
    2789      118200 :                         spreadCoherencePanningHoa_fx( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2_fx[md_idx][k],
    2790      118200 :                                                       direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
    2791             : 
    2792      118200 :                         exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    2793             :                         /* Combine gains from the two directions */
    2794      118200 :                         totalDirect_fx = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
    2795      118200 :                         IF( totalDirect_fx == 0 )
    2796             :                         {
    2797          10 :                             totalDirect_fx = EPSILON_FIX;
    2798          10 :                             move32();
    2799             :                         }
    2800             : 
    2801             :                         Word16 var_a, var_b, exp_1, exp_2;
    2802      118200 :                         var_a = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); /*15-exp_1*/
    2803      118200 :                         var_b = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); /*15-exp_2*/
    2804             : 
    2805      118200 :                         directRatio_fx[0] = L_deposit_h( var_a ); /*15-exp_1+16*/
    2806      118200 :                         move32();
    2807      118200 :                         directRatio_fx[1] = L_deposit_h( var_b ); /*15-exp_2+16*/
    2808      118200 :                         move32();
    2809             : 
    2810             :                         Word32 temp_a;
    2811             :                         Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_a, final_exp;
    2812      118200 :                         set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
    2813      118200 :                         exp_direct_response_hoa = sub( 31, Q_direct_response_hoa );
    2814             : 
    2815     1023000 :                         FOR( l = 0; l < num_channels_dir; l++ )
    2816             :                         {
    2817      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)*/
    2818      904800 :                             move32();
    2819      904800 :                             exp_arr[l] = add( exp_1, sub( 31, Q_direct_response_hoa ) );
    2820      904800 :                             move16();
    2821      904800 :                             temp_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); /*Q(Q_direct_response_dir2+31-exp_2-31)*/
    2822      904800 :                             exp_temp_a = add( exp_2, sub( 31, Q_direct_response_dir2 ) );
    2823      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)*/
    2824      904800 :                             move32();
    2825      904800 :                             exp_arr[l] = final_exp;
    2826      904800 :                             move16();
    2827             :                         }
    2828             : 
    2829      118200 :                         Word16 max_exp = MIN16B;
    2830      118200 :                         move16();
    2831      118200 :                         maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
    2832     2009400 :                         FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
    2833             :                         {
    2834     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)*/
    2835     1891200 :                             move32();
    2836             :                         }
    2837      118200 :                         exp_direct_response_hoa = max_exp;
    2838      118200 :                         move16();
    2839      118200 :                         Q_direct_response_hoa = sub( 31, max_exp );
    2840             :                     }
    2841             : 
    2842      448109 :                     IF( hSpatParamRendCom->numIsmDirections > 0 )
    2843             :                     {
    2844             :                         Word16 dir;
    2845             :                         Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
    2846             :                         Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
    2847        8152 :                         Word16 exp_direct_response_ism = 0, exp_direct_response_temp;
    2848             :                         Word32 masaDirect_fx;
    2849             :                         Word32 ismDirect_fx;
    2850        8152 :                         move16();
    2851             : 
    2852        8152 :                         set32_fx( direct_response_ism_fx, 0, num_channels_dir );
    2853             : 
    2854       40760 :                         FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    2855             :                         {
    2856       32608 :                             IF( hMasaIsm->ism_is_edited[dir] )
    2857             :                             {
    2858           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 );
    2859             :                             }
    2860             :                             ELSE
    2861             :                             {
    2862       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 );
    2863             :                             }
    2864       32608 :                             exp_direct_response_temp = 2;
    2865       32608 :                             move16();
    2866             : 
    2867       32608 :                             Word32 temp_1 = 0;
    2868       32608 :                             Word16 exp_temp = 0, exp_arr[MAX_OUTPUT_CHANNELS];
    2869       32608 :                             move16();
    2870       32608 :                             move16();
    2871       32608 :                             set16_fx( exp_arr, 0, MAX_OUTPUT_CHANNELS );
    2872      348992 :                             FOR( l = 0; l < num_channels_dir; l++ )
    2873             :                             {
    2874      316384 :                                 temp_1 = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] );                                                                   // Q28
    2875      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)
    2876      316384 :                                 move32();
    2877      316384 :                                 exp_arr[l] = exp_temp;
    2878      316384 :                                 move16();
    2879             :                             }
    2880       32608 :                             Word16 max_exp = MIN16B;
    2881       32608 :                             move16();
    2882       32608 :                             maximum_fx( exp_arr, num_channels_dir, &max_exp );
    2883      348992 :                             FOR( l = 0; l < num_channels_dir; l++ )
    2884             :                             {
    2885      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)*/
    2886      316384 :                                 move32();
    2887             :                             }
    2888       32608 :                             exp_direct_response_ism = max_exp;
    2889       32608 :                             move16();
    2890             :                         }
    2891             :                         Word16 exp_1, exp_2;
    2892        8152 :                         masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; /*q30*/
    2893        8152 :                         move32();
    2894        8152 :                         if ( masaDirect_fx == 0 )
    2895             :                         {
    2896          92 :                             masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); /*q30*/
    2897             :                         }
    2898        8152 :                         if ( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    2899             :                         {
    2900           0 :                             masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
    2901             :                         }
    2902             : 
    2903        8152 :                         ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; /*q30*/
    2904        8152 :                         move32();
    2905       32608 :                         FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    2906             :                         {
    2907       24456 :                             ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); /*q30*/
    2908             :                         }
    2909             : 
    2910        8152 :                         totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); /*q30*/ // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
    2911        8152 :                         Word16 var_a = 0, var_b = 0;
    2912        8152 :                         var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); /*Q(15-exp_1)*/
    2913        8152 :                         var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 );  /*q(15-exp_2)*/
    2914        8152 :                         directRatio_fx[0] = L_deposit_h( var_a );                                     // Q(31-exp_1)
    2915        8152 :                         move32();
    2916        8152 :                         directRatio_fx[1] = L_deposit_h( var_b ); // Q(31-exp_2)
    2917        8152 :                         move32();
    2918             : 
    2919             :                         Word32 temp_2, temp_3;
    2920             :                         Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
    2921        8152 :                         set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
    2922       87248 :                         FOR( l = 0; l < num_channels_dir; l++ )
    2923             :                         {
    2924       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*/
    2925       79096 :                             move32();
    2926       79096 :                             exp_arr[l] = add( exp_direct_response_hoa, exp_1 );
    2927       79096 :                             move16();
    2928       79096 :                             temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] );                                                                     /*31-exp_direct_response_ism+31-exp_2-31*/
    2929       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*/
    2930             : 
    2931       79096 :                             direct_response_hoa_fx[l] = temp_3; /*31-exp_temp_3*/
    2932       79096 :                             move32();
    2933       79096 :                             exp_arr[l] = exp_temp_3;
    2934       79096 :                             move16();
    2935             :                         }
    2936             : 
    2937        8152 :                         Word16 max_exp = MIN16B;
    2938        8152 :                         move16();
    2939        8152 :                         maximum_fx( exp_arr, num_channels_dir, &max_exp );
    2940       87248 :                         FOR( l = 0; l < num_channels_dir; l++ )
    2941             :                         {
    2942       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)*/
    2943       79096 :                             move32();
    2944             :                         }
    2945        8152 :                         Q_direct_response_hoa = sub( 31, max_exp );
    2946        8152 :                         exp_direct_response_hoa = max_exp;
    2947        8152 :                         move16();
    2948             :                     }
    2949             : 
    2950             :                     /* Synthesize surrounding coherence */
    2951      448109 :                     IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
    2952             :                     {
    2953             :                         Word32 var_a, var_b;
    2954             :                         Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp;
    2955      279212 :                         set16_fx( exp_arr, exp_direct_response_hoa, MAX_OUTPUT_CHANNELS );
    2956             : 
    2957     1864379 :                         FOR( l = 1; l < num_channels_dir; l++ )
    2958             :                         {
    2959     1585167 :                             exp = 0;
    2960     1585167 :                             move16();
    2961     1585167 :                             var_a = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp ); /*q(31-exp)*/
    2962     1585167 :                             var_b = Sqrt32( var_a, &exp );                                                                                     /*31-exp*/
    2963     1585167 :                             direct_response_hoa_fx[l] = Mpy_32_32( direct_response_hoa_fx[l], var_b );                                         /*Q_direct_response_hoa+31-exp-31*/
    2964     1585167 :                             move32();
    2965     1585167 :                             exp_arr[l] = add( sub( 31, Q_direct_response_hoa ), exp );
    2966     1585167 :                             move16();
    2967             :                         }
    2968      279212 :                         Word16 max_exp = MIN_16;
    2969      279212 :                         move16();
    2970      279212 :                         maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
    2971     4746604 :                         FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
    2972             :                         {
    2973     4467392 :                             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)*/
    2974     4467392 :                             move32();
    2975             :                         }
    2976      279212 :                         Q_direct_response_hoa = sub( 31, max_exp );
    2977      279212 :                         exp_direct_response_hoa = max_exp;
    2978      279212 :                         move16();
    2979             :                     }
    2980             : 
    2981      448109 :                     Q_direct_response_hoa = sub( Q31, exp_direct_response_hoa );
    2982             : 
    2983      448109 :                     Scale_sig32( direct_response_hoa_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_hoa ) ); /*Q_direct_response_hoa->q29*/
    2984      448109 :                     direct_response_q = Q29;
    2985      448109 :                     move16();
    2986             : 
    2987      448109 :                     direct_response_fx = direct_response_hoa_fx;
    2988      448109 :                     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    2989             :                     {
    2990      303554 :                         v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*Q(2*direct_response_q-31)*/
    2991      303554 :                         direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
    2992             : 
    2993      303554 :                         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*/
    2994             : 
    2995      303554 :                         IF( EQ_16( transport_signal_type, MASA_STEREO_SPACED_MICS ) )
    2996             :                         {
    2997       30683 :                             direct_response_fx[0] = ONE_IN_Q29; /*q29*/
    2998       30683 :                             move32();
    2999       30683 :                             test();
    3000       30683 :                             IF( GE_16( k, dipole_freq_range[0] ) && LT_16( k, dipole_freq_range[1] ) )
    3001             :                             {
    3002        3897 :                                 direct_response_fx[1] = ONE_IN_Q29; /*q29*/
    3003        3897 :                                 move32();
    3004             :                             }
    3005             :                         }
    3006             :                         ELSE
    3007             :                         {
    3008      272871 :                             set32_fx( direct_response_fx, ONE_IN_Q29, hDirACRend->num_protos_ambi ); /*q29*/
    3009             :                         }
    3010             :                     }
    3011             : 
    3012      448109 :                     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*/
    3013             :                 }
    3014             :                 ELSE
    3015             :                 {
    3016           0 :                     assert( 0 && "Not supported synthesis method!" );
    3017             :                 }
    3018             :             }
    3019     3959703 :             ELSE IF( EQ_16( hDirACRend->panningConf, DIRAC_PANNING_VBAP ) ) /*VBAP*/
    3020             :             {
    3021             :                 /* Synthesize the first direction */
    3022     3959703 :                 spreadCoherencePanningVbap_fx( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence_fx[md_idx][k],
    3023             :                                                direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir, hVBAPdata );
    3024     3959703 :                 normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3025     3959703 :                 exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3026             : 
    3027             :                 /* Synthesize the second direction and combine the gains */
    3028     3959703 :                 IF( EQ_16( hSpatParamRendCom->numParametricDirections, 2 ) )
    3029             :                 {
    3030      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 );
    3031      204188 :                     normalizePanningGains_fx( direct_response_dir2_fx, &Q_direct_response_dir2, num_channels_dir );
    3032             : 
    3033             :                     /* Combine gains from the two directions */
    3034      204188 :                     Word32 test = L_add( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); /*q30*/
    3035             : 
    3036      204188 :                     IF( test == 0 )
    3037             :                     {
    3038        1337 :                         totalDirect_fx = L_add( test, EPSILON_FIX ); // Q30
    3039             :                     }
    3040             :                     ELSE
    3041             :                     {
    3042      202851 :                         totalDirect_fx = test; // q30
    3043      202851 :                         move32();
    3044             :                     }
    3045             :                     Word16 var_1, var_2, exp_1, exp_2;
    3046      204188 :                     var_1 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio1_fx[md_idx][k], totalDirect_fx, &exp_1 ); // 15-exp_1
    3047      204188 :                     var_2 = BASOP_Util_Divide3232_Scale( hSpatParamRendCom->energy_ratio2_fx[md_idx][k], totalDirect_fx, &exp_2 ); // 15-exp_2
    3048             : 
    3049      204188 :                     directRatio_fx[0] = L_deposit_h( var_1 ); // 31-exp_1
    3050      204188 :                     move32();
    3051      204188 :                     directRatio_fx[1] = L_deposit_h( var_2 ); // 31-exp_2
    3052      204188 :                     move32();
    3053             : 
    3054             :                     Word32 var_a;
    3055             :                     Word16 exp_tmp;
    3056      204188 :                     Word16 exp_max = MIN16B, exp_table[MAX_OUTPUT_CHANNELS];
    3057      204188 :                     move16();
    3058      204188 :                     set16_fx( exp_table, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
    3059             : 
    3060      204188 :                     exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3061      204188 :                     exp_direct_response_dir2 = sub( 31, Q_direct_response_dir2 );
    3062             : 
    3063      204188 :                     Word32 temp = 0;
    3064      204188 :                     move32();
    3065     1855504 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3066             :                     {
    3067     1651316 :                         temp = Mpy_32_32( direct_response_ls_fx[l], directRatio_fx[0] );    // exp_direct_response_ls + exp_1
    3068     1651316 :                         var_a = Mpy_32_32( directRatio_fx[1], direct_response_dir2_fx[l] ); // exp_direct_response_dir2 + exp_2
    3069     1651316 :                         exp_tmp = 0;
    3070     1651316 :                         move16();
    3071     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)
    3072     1651316 :                         move32();
    3073     1651316 :                         exp_table[l] = exp_tmp;
    3074     1651316 :                         move16();
    3075             :                     }
    3076             : 
    3077      204188 :                     maximum_fx( exp_table, MAX_OUTPUT_CHANNELS, &exp_max );
    3078             : 
    3079     3471196 :                     FOR( i = 0; i < MAX_OUTPUT_CHANNELS; i++ )
    3080             :                     {
    3081     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))*/
    3082     3267008 :                         move32();
    3083             :                     }
    3084      204188 :                     Q_direct_response_ls = sub( 31, exp_max );
    3085      204188 :                     exp_direct_response_ls = exp_max;
    3086      204188 :                     move16();
    3087             : 
    3088      204188 :                     normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3089      204188 :                     exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3090             :                 }
    3091             : 
    3092     3959703 :                 IF( hSpatParamRendCom->numIsmDirections > 0 )
    3093             :                 {
    3094             :                     Word16 dir;
    3095             : 
    3096             :                     Word32 direct_response_temp_fx[MAX_OUTPUT_CHANNELS];
    3097        9195 :                     set32_fx( direct_response_temp_fx, 0, MAX_OUTPUT_CHANNELS );
    3098        9195 :                     Word16 Q_direct_response_temp = Q31;
    3099        9195 :                     move16();
    3100             :                     Word32 direct_response_ism_fx[MAX_OUTPUT_CHANNELS];
    3101        9195 :                     set32_fx( direct_response_ism_fx, 0, num_channels_dir );
    3102             :                     Word32 masaDirect_fx;
    3103             :                     Word32 ismDirect_fx;
    3104             : 
    3105       35695 :                     FOR( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    3106             :                     {
    3107       26500 :                         IF( hMasaIsm->ism_is_edited[dir] )
    3108             :                         {
    3109           0 :                             vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 );
    3110             :                         }
    3111             :                         ELSE
    3112             :                         {
    3113       26500 :                             vbap_determine_gains_fx( hVBAPdata, direct_response_temp_fx, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
    3114             :                         }
    3115       26500 :                         Word32 tmp = 0;
    3116       26500 :                         move32();
    3117             :                         Word16 Q_arr[MAX_OUTPUT_CHANNELS], exp_tmp;
    3118      245264 :                         FOR( l = 0; l < num_channels_dir; l++ )
    3119             :                         {
    3120      218764 :                             tmp = Mpy_32_32( direct_response_temp_fx[l], hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] );                          // Q30 * 2 - 31
    3121      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)
    3122      218764 :                             move32();
    3123      218764 :                             Q_arr[l] = sub( 31, exp_tmp );
    3124      218764 :                             move16();
    3125             :                         }
    3126       26500 :                         Word16 Q_min = MAX16B;
    3127       26500 :                         move32();
    3128       26500 :                         minimum_fx( Q_arr, num_channels_dir, &Q_min );
    3129      245264 :                         FOR( i = 0; i < num_channels_dir; i++ )
    3130             :                         {
    3131      218764 :                             direct_response_ism_fx[i] = L_shr( direct_response_ism_fx[i], sub( Q_arr[i], Q_min ) ); // Q_arr[i]->Q_min
    3132      218764 :                             move32();
    3133             :                         }
    3134       26500 :                         Q_direct_response_temp = Q_min;
    3135       26500 :                         move16();
    3136       26500 :                         normalizePanningGains_fx( direct_response_ism_fx, &Q_direct_response_temp, num_channels_dir );
    3137             :                     }
    3138             : 
    3139             :                     Word16 exp_1, exp_2;
    3140        9195 :                     masaDirect_fx = hSpatParamRendCom->energy_ratio1_fx[md_idx][k]; // q30
    3141        9195 :                     move32();
    3142        9195 :                     IF( masaDirect_fx == 0 )
    3143             :                     {
    3144          39 :                         masaDirect_fx = L_add( masaDirect_fx, EPSILLON_FX ); // q30
    3145             :                     }
    3146        9195 :                     IF( EQ_32( hSpatParamRendCom->numParametricDirections, 2 ) )
    3147             :                     {
    3148        3000 :                         masaDirect_fx = L_add( masaDirect_fx, hSpatParamRendCom->energy_ratio2_fx[md_idx][k] ); // q30
    3149             :                     }
    3150             : 
    3151        9195 :                     ismDirect_fx = hMasaIsm->energy_ratio_ism_fx[0][md_idx][k]; // q30
    3152        9195 :                     move32();
    3153       26500 :                     FOR( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    3154             :                     {
    3155       17305 :                         ismDirect_fx = L_add( ismDirect_fx, hMasaIsm->energy_ratio_ism_fx[dir][md_idx][k] ); // q30
    3156             :                     }
    3157             : 
    3158        9195 :                     totalDirect_fx = L_add_sat( masaDirect_fx, ismDirect_fx ); // q30 // saturating as 1.0 (Q30) + 1.0 (Q30) is observed
    3159             :                     Word16 var_a, var_b;
    3160        9195 :                     var_a = BASOP_Util_Divide3232_Scale( masaDirect_fx, totalDirect_fx, &exp_1 ); // 15-exp_1
    3161        9195 :                     var_b = BASOP_Util_Divide3232_Scale( ismDirect_fx, totalDirect_fx, &exp_2 );  // 15- exp_2
    3162        9195 :                     directRatio_fx[0] = L_deposit_h( var_a );                                     // 31- exp_1
    3163        9195 :                     move32();
    3164        9195 :                     directRatio_fx[1] = L_deposit_h( var_b ); // 31 - exp_2
    3165        9195 :                     move32();
    3166             : 
    3167             :                     Word32 temp_2, temp_3;
    3168             :                     Word16 exp_arr[MAX_OUTPUT_CHANNELS], exp_temp_3;
    3169        9195 :                     set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
    3170       84648 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3171             :                     {
    3172       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)
    3173       75453 :                         move32();
    3174       75453 :                         exp_arr[l] = add( exp_direct_response_ls, exp_1 );
    3175       75453 :                         move16();
    3176       75453 :                         temp_2 = Mpy_32_32( directRatio_fx[1], direct_response_ism_fx[l] );                                                                              // q(Q_direct_response_temp+31-exp_2-31)
    3177       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
    3178             : 
    3179       75453 :                         direct_response_ls_fx[l] = temp_3; // 31-exp_temp_3
    3180       75453 :                         move32();
    3181       75453 :                         exp_arr[l] = exp_temp_3;
    3182       75453 :                         move16();
    3183             :                     }
    3184             : 
    3185        9195 :                     Word16 max_exp = MIN16B;
    3186        9195 :                     move16();
    3187        9195 :                     maximum_fx( exp_arr, num_channels_dir, &max_exp );
    3188       84648 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3189             :                     {
    3190       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)*/
    3191       75453 :                         move16();
    3192             :                     }
    3193        9195 :                     Q_direct_response_ls = sub( 31, max_exp );
    3194        9195 :                     exp_direct_response_ls = max_exp;
    3195        9195 :                     move16();
    3196             : 
    3197        9195 :                     normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3198        9195 :                     exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3199             :                 }
    3200             : 
    3201             :                 /* Synthesize surrounding coherence */
    3202     3959703 :                 test();
    3203     3959703 :                 IF( surCohRatio_fx != NULL && surCohRatio_fx[k] > 0 )
    3204             :                 {
    3205             :                     Word16 num_channels_surrCoh;
    3206             : 
    3207      352823 :                     num_channels_surrCoh = num_channels_dir;
    3208      352823 :                     move16();
    3209      352823 :                     num_channels_surrCoh = sub( num_channels_surrCoh, hDirACRend->num_ele_spk_no_diffuse_rendering );
    3210             : 
    3211             :                     Word32 temp, final;
    3212             :                     Word16 exp_temp, exp_temp_a, temp_a, final_exp;
    3213      352823 :                     Word16 exp_arr[MAX_OUTPUT_CHANNELS], max_exp = MIN16B;
    3214      352823 :                     move16();
    3215      352823 :                     set16_fx( exp_arr, exp_direct_response_ls, MAX_OUTPUT_CHANNELS );
    3216     3015202 :                     FOR( l = 0; l < num_channels_dir; l++ )
    3217             :                     {
    3218     2662379 :                         exp_temp = 0;
    3219     2662379 :                         move16();
    3220     2662379 :                         temp = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30 /*1 Q30*/, 1, L_negate( surCohRatio_fx[k] ), exp_surCohRatio, &exp_temp ); // q(31-exp_temp)
    3221     2662379 :                         temp = Sqrt32( temp, &exp_temp );                                                                                      // q(31-exp_temp)
    3222     2662379 :                         direct_response_ls_fx[l] = Mpy_32_32( direct_response_ls_fx[l], temp );                                                // Q31-(exp_direct_response_ls + exp_temp)
    3223     2662379 :                         move32();
    3224             : 
    3225     2662379 :                         exp_arr[l] = add( exp_direct_response_ls, exp_temp );
    3226     2662379 :                         move16();
    3227     2662379 :                         IF( hDirACRend->diffuse_response_function_fx[l] > 0 )
    3228             :                         {
    3229     2651179 :                             exp_temp_a = 0;
    3230     2651179 :                             move16();
    3231     2651179 :                             temp_a = BASOP_Util_Divide3216_Scale( surCohRatio_fx[k], num_channels_surrCoh, &exp_temp_a ); /*15-(exp_temp_a+exp_surCohRatio-15)*/
    3232     2651179 :                             exp_temp_a = add( exp_temp_a, sub( exp_surCohRatio, 15 ) );
    3233     2651179 :                             temp_a = Sqrt16( temp_a, &exp_temp_a ); /*15-temp_a*/
    3234     2651179 :                             final_exp = 0;
    3235     2651179 :                             move16();
    3236     2651179 :                             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*/
    3237     2651179 :                             direct_response_ls_fx[l] = final;                                                                                        /*31-final_exp*/
    3238     2651179 :                             move32();
    3239     2651179 :                             exp_arr[l] = final_exp;
    3240     2651179 :                             move16();
    3241             :                         }
    3242             :                     }
    3243             : 
    3244      352823 :                     max_exp = MIN16B; /*Q0*/
    3245      352823 :                     move16();
    3246      352823 :                     maximum_fx( exp_arr, MAX_OUTPUT_CHANNELS, &max_exp );
    3247     5997991 :                     FOR( l = 0; l < MAX_OUTPUT_CHANNELS; l++ )
    3248             :                     {
    3249     5645168 :                         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)*/
    3250     5645168 :                         move32();
    3251             :                     }
    3252             : 
    3253      352823 :                     Q_direct_response_ls = sub( 31, max_exp );
    3254      352823 :                     exp_direct_response_ls = max_exp;
    3255      352823 :                     move16();
    3256             :                 }
    3257             : 
    3258     3959703 :                 normalizePanningGains_fx( direct_response_ls_fx, &Q_direct_response_ls, num_channels_dir );
    3259     3959703 :                 exp_direct_response_ls = sub( 31, Q_direct_response_ls );
    3260             : 
    3261     3959703 :                 Scale_sig32( direct_response_ls_fx, MAX_OUTPUT_CHANNELS, sub( Q29, Q_direct_response_ls ) ); /*Q_direct_response_ls->Q29*/
    3262     3959703 :                 direct_response_q = Q29;
    3263     3959703 :                 move16();
    3264             : 
    3265             :                 /* Set computed gains */
    3266     3959703 :                 direct_response_fx = direct_response_ls_fx;
    3267     3959703 :                 v_mult_fixed( direct_response_fx, direct_response_fx, direct_response_square_fx, num_channels_dir ); /*2*direct_response_q-31*/
    3268     3959703 :                 direct_response_square_q = sub( add( direct_response_q, direct_response_q ), 31 );
    3269             : 
    3270     3959703 :                 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*/
    3271     3959703 :                 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*/
    3272             :             }
    3273             :             ELSE
    3274             :             {
    3275           0 :                 assert( 0 && "Not supported panning method!" );
    3276             :             }
    3277             :         }
    3278             :     }
    3279             : 
    3280     1087261 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_q = direct_response_q;
    3281     1087261 :     move16();
    3282     1087261 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = direct_response_square_q;
    3283     1087261 :     move16();
    3284             : 
    3285     1087261 :     return;
    3286             : }
    3287             : 
    3288             : 
    3289             : /*-------------------------------------------------------------------------
    3290             :  * ivas_dirac_dec_compute_gain_factors()
    3291             :  *
    3292             :  *
    3293             :  *------------------------------------------------------------------------*/
    3294             : 
    3295      739710 : void ivas_dirac_dec_compute_gain_factors_fx(
    3296             :     const Word16 num_freq_bands,
    3297             :     const Word32 *diffuseness_fx, /*i:q30*/
    3298             :     Word32 *direct_gain_factor,   /*o:exponent is max_exp_direct*/
    3299             :     Word32 *diffuse_gain_factor,  /*o:exponent is max_exp_diffusion*/
    3300             :     Word16 *max_exp_direct_fx,
    3301             :     Word16 *max_exp_diffusion )
    3302             : {
    3303             :     Word16 i;
    3304             :     Word16 exp1, exp2;
    3305             :     Word16 exp_diffuse_gain_factor[60], exp_direct_gain_factor[60]; /*exp buffers*/
    3306             : 
    3307    38831770 :     FOR( i = 0; i < num_freq_bands; i++ )
    3308             :     {
    3309    38092060 :         exp1 = 1;
    3310    38092060 :         move16();
    3311    38092060 :         exp2 = 1;
    3312    38092060 :         move16();
    3313    38092060 :         direct_gain_factor[i] = Sqrt32( L_sub( ONE_IN_Q30 /*1 Q30*/, diffuseness_fx[i] ), &exp1 ); /*31-exp1*/
    3314    38092060 :         move32();
    3315    38092060 :         diffuse_gain_factor[i] = Sqrt32( diffuseness_fx[i], &exp2 ); /*31-exp2*/
    3316    38092060 :         move32();
    3317    38092060 :         exp_direct_gain_factor[i] = exp1;
    3318    38092060 :         move16();
    3319    38092060 :         exp_diffuse_gain_factor[i] = exp2;
    3320    38092060 :         move16();
    3321             :     }
    3322             : 
    3323             :     /*make common exp for both buffers*/
    3324      739710 :     Word16 max_exp_direct = MIN16B; /*Q0*/
    3325      739710 :     move16();
    3326      739710 :     Word16 max_exp_diffuse = MIN16B; /*Q0*/
    3327      739710 :     move16();
    3328    38831770 :     FOR( i = 0; i < num_freq_bands; i++ )
    3329             :     {
    3330    38092060 :         max_exp_direct = s_max( max_exp_direct, exp_direct_gain_factor[i] );
    3331    38092060 :         max_exp_diffuse = s_max( max_exp_diffuse, exp_diffuse_gain_factor[i] );
    3332             :     }
    3333             : 
    3334      739710 :     *max_exp_direct_fx = max_exp_direct;
    3335      739710 :     move16();
    3336      739710 :     *max_exp_diffusion = max_exp_diffuse;
    3337      739710 :     move16();
    3338             : 
    3339    38831770 :     FOR( i = 0; i < num_freq_bands; i++ )
    3340             :     {
    3341    38092060 :         direct_gain_factor[i] = L_shr( direct_gain_factor[i], sub( max_exp_direct, exp_direct_gain_factor[i] ) ); /*Q(31-max_exp_direct)*/
    3342    38092060 :         move32();
    3343    38092060 :         diffuse_gain_factor[i] = L_shr( diffuse_gain_factor[i], sub( max_exp_diffuse, exp_diffuse_gain_factor[i] ) ); /*Q(31-max_exp_diffuse)*/
    3344    38092060 :         move32();
    3345             :     }
    3346             : 
    3347             : 
    3348      739710 :     return;
    3349             : }
    3350             : 
    3351             : 
    3352             : /*-------------------------------------------------------------------------
    3353             :  * ivas_dirac_dec_compute_power_factors()
    3354             :  *
    3355             :  *
    3356             :  *------------------------------------------------------------------------*/
    3357             : 
    3358      134927 : void ivas_dirac_dec_compute_power_factors_fx(
    3359             :     const Word16 num_freq_bands,
    3360             :     const Word32 *diffuseness_fx, // Q3O
    3361             :     const Word16 max_band_decorr,
    3362             :     Word32 *direct_power_factor, /*input is q30 and ouput is q29*/
    3363             :     Word32 *diffuse_power_factor /*input is q30 and ouput is q29*/ )
    3364             : {
    3365             :     Word16 i;
    3366             : 
    3367      134927 :     v_multc_fixed( diffuseness_fx, L_negate( ( ONE_IN_Q31 ) ), direct_power_factor, num_freq_bands ); // Q30
    3368             : 
    3369      134927 :     v_addc_fixed( direct_power_factor, ONE_IN_Q30, direct_power_factor, num_freq_bands ); // Q30
    3370             : 
    3371      134927 :     Copy32( diffuseness_fx, diffuse_power_factor, num_freq_bands ); // Q30
    3372             : 
    3373      134927 :     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
    3374             : 
    3375      134927 :     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
    3376             : 
    3377             : 
    3378     1177577 :     FOR( i = 0; i < max_band_decorr; i++ )
    3379             :     {
    3380     1042650 :         direct_power_factor[i] = L_shr( direct_power_factor[i], 1 ); // Q29
    3381     1042650 :         move32();
    3382     1042650 :         diffuse_power_factor[i] = L_shr( diffuse_power_factor[i], 1 ); // Q29
    3383     1042650 :         move32();
    3384             :     }
    3385      134927 :     return;
    3386             : }
    3387             : 
    3388             : 
    3389             : /*-------------------------------------------------------------------------
    3390             :  * ivas_lfe_synth_with_filters()
    3391             :  *
    3392             :  *
    3393             :  *------------------------------------------------------------------------*/
    3394         195 : void ivas_lfe_synth_with_filters_fx(
    3395             :     MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: LFE synthesis structure for McMASA  */
    3396             :     Word32 *data_fx[],                          /* o  : output signals (Q11)             */
    3397             :     const Word16 output_frame,                  /* i  : output frame length per channel     */
    3398             :     const Word16 separateChannelIndex,          /* i  : separate channel index              */
    3399             :     const Word16 lfeChannelIndex                /* i  : LFE channel index                   */
    3400             : )
    3401             : {
    3402             :     Word16 lowpassCoef_fx;
    3403             :     Word16 lowpassCoef_fx_exp;
    3404             :     Word16 i, j;
    3405             :     Word32 lowPassSignal_fx[L_FRAME48k];
    3406             :     Word32 highPassSignal_fx[L_FRAME48k];
    3407             :     Word16 slot_index;
    3408             :     Word16 subframe_index;
    3409             :     Word16 slotSize;
    3410             :     Word32 transportEne_fx, targetEneLfe_fx, targetEneTrans_fx;
    3411             :     Word16 mrange[2];
    3412             :     Word16 lfeGain_fx;
    3413             :     Word16 lfeGain_fx_exp;
    3414             :     Word16 transportGain_fx;
    3415             :     Word16 transportGain_fx_exp;
    3416             :     Word16 delay;
    3417             : 
    3418             :     /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */
    3419         195 :     delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
    3420         195 :     move16();
    3421         195 :     delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC_fx, delay ); /*q11*/
    3422             : 
    3423             :     /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */
    3424         195 :     lowpassCoef_fx_exp = 15;
    3425         195 :     move16();
    3426         195 :     lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize, &lowpassCoef_fx_exp ); /*15-lowpassCoef_fx_exp*/
    3427      180995 :     FOR( i = 0; i < output_frame; i++ )
    3428             :     {
    3429      180800 :         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
    3430      180800 :         lowPassSignal_fx[i] = hMasaLfeSynth->lowpassSum_fx;                                                                                                                                                                                                    // Q11
    3431      180800 :         move32();
    3432      180800 :         highPassSignal_fx[i] = L_sub( hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferHiPointer], lowPassSignal_fx[i] ); // Q11
    3433      180800 :         move32();
    3434      180800 :         hMasaLfeSynth->lfeSynthRingBuffer_fx[hMasaLfeSynth->ringBufferLoPointer] = data_fx[separateChannelIndex][i]; // Q11
    3435      180800 :         move32();
    3436             : 
    3437      180800 :         hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferLoPointer, 1 );
    3438      180800 :         move16();
    3439      180800 :         IF( hMasaLfeSynth->ringBufferLoPointer < 0 )
    3440             :         {
    3441         780 :             hMasaLfeSynth->ringBufferLoPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
    3442         780 :             move16();
    3443             :         }
    3444             : 
    3445      180800 :         hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferHiPointer, 1 );
    3446      180800 :         move16();
    3447      180800 :         IF( hMasaLfeSynth->ringBufferHiPointer < 0 )
    3448             :         {
    3449         780 :             hMasaLfeSynth->ringBufferHiPointer = sub( hMasaLfeSynth->ringBufferSize, 1 );
    3450         780 :             move16();
    3451             :         }
    3452             :     }
    3453             : 
    3454             :     /* Synthesize the LFE signal */
    3455         195 :     slotSize = shr_r( output_frame, 4 ); // output_frame / CLDFB_NO_COL_MAX
    3456        3315 :     FOR( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
    3457             :     {
    3458        3120 :         subframe_index = shr( slot_index, 4 );
    3459             : 
    3460        3120 :         mrange[0] = i_mult( slot_index, slotSize );
    3461        3120 :         move16();
    3462        3120 :         mrange[1] = i_mult( add( slot_index, 1 ), slotSize );
    3463        3120 :         move16();
    3464             : 
    3465        3120 :         transportEne_fx = 0;
    3466        3120 :         move32();
    3467        3120 :         Word64 W_tmp = 0;
    3468        3120 :         move64();
    3469      183920 :         FOR( i = mrange[0]; i < mrange[1]; i++ )
    3470             :         {
    3471      180800 :             W_tmp = W_add( W_tmp, W_mult0_32_32( lowPassSignal_fx[i], lowPassSignal_fx[i] ) ); // Q22
    3472             :         }
    3473             : 
    3474        3120 :         Word16 tmp_shift = W_norm( W_tmp );
    3475             : 
    3476        3120 :         W_tmp = W_shl( W_tmp, tmp_shift ); /*Q22+tmp_shift*/
    3477             : 
    3478        3120 :         Word16 tmp_q = sub( add( Q22, tmp_shift ), 32 );
    3479             :         Word16 tmp_exp;
    3480             : 
    3481        3120 :         transportEne_fx = W_extract_h( W_tmp );                                                                                                                                      /* Q22 + tmp_shift - 32 */
    3482        3120 :         targetEneLfe_fx = W_extract_l( W_shr( W_mult0_32_32( transportEne_fx, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ), Q14 ) );                                    /* Q22 + tmp_shift - 32 */
    3483        3120 :         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 */
    3484             : 
    3485        3120 :         hMasaLfeSynth->transportEneSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->transportEneSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* transportEneSmooth_q */
    3486        3120 :         move32();
    3487        3120 :         hMasaLfeSynth->targetEneLfeSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneLfeSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneLfeSmooth_q */
    3488        3120 :         move32();
    3489        3120 :         hMasaLfeSynth->targetEneTransSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneTransSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); /* targetEneTransSmooth_q */
    3490        3120 :         move32();
    3491             : 
    3492        3120 :         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 */
    3493        3120 :         move32();
    3494        3120 :         hMasaLfeSynth->transportEneSmooth_q = sub( Q31, tmp_exp );
    3495        3120 :         move16();
    3496        3120 :         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 */
    3497        3120 :         move32();
    3498        3120 :         hMasaLfeSynth->targetEneLfeSmooth_q = sub( Q31, tmp_exp );
    3499        3120 :         move16();
    3500        3120 :         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 */
    3501        3120 :         move32();
    3502        3120 :         hMasaLfeSynth->targetEneTransSmooth_q = sub( Q31, tmp_exp );
    3503        3120 :         move16();
    3504             : 
    3505        3120 :         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 ) )
    3506             :         {
    3507           0 :             lfeGain_fx = MAX_16; /* 1.0 in q15*/
    3508           0 :             move16();
    3509             :         }
    3510             :         ELSE
    3511             :         {
    3512        3120 :             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*/
    3513        3120 :             lfeGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneLfeSmooth_q ), lfeGain_fx_exp );
    3514        3120 :             lfeGain_fx = Sqrt16( lfeGain_fx, &lfeGain_fx_exp );             // Q15-lfeGain_fx_exp
    3515        3120 :             lfeGain_fx = shr_r_sat( lfeGain_fx, negate( lfeGain_fx_exp ) ); // Q15
    3516             :         }
    3517        3120 :         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 ) )
    3518             :         {
    3519           0 :             transportGain_fx = MAX_16; // q15
    3520           0 :             move16();
    3521             :         }
    3522             :         ELSE
    3523             :         {
    3524        3120 :             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)*/
    3525        3120 :             transportGain_fx_exp = add( sub( hMasaLfeSynth->transportEneSmooth_q, hMasaLfeSynth->targetEneTransSmooth_q ), transportGain_fx_exp );
    3526        3120 :             transportGain_fx = Sqrt16( transportGain_fx, &transportGain_fx_exp );             // q15-transportGain_fx_exp
    3527        3120 :             transportGain_fx = shr_r_sat( transportGain_fx, negate( transportGain_fx_exp ) ); // Q15
    3528             :         }
    3529        3120 :         j = 0;
    3530        3120 :         move16();
    3531      183920 :         FOR( i = mrange[0]; i < mrange[1]; i++ )
    3532             :         {
    3533      180800 :             Word32 L_tmp1 = L_mult( transportGain_fx, hMasaLfeSynth->interpolator_fx[j] );                                               // Q31
    3534      180800 :             Word32 L_tmp2 = L_mult( hMasaLfeSynth->transportGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) );             // Q31
    3535      180800 :             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*/
    3536      180800 :             move32();
    3537      180800 :             Word32 L_tmp3 = L_mult( lfeGain_fx, hMasaLfeSynth->interpolator_fx[j] );                                   // Q31
    3538      180800 :             Word32 L_tmp4 = L_mult( hMasaLfeSynth->lfeGainPrev_fx, sub( MAX_16, hMasaLfeSynth->interpolator_fx[j] ) ); /*q31*/
    3539      180800 :             data_fx[lfeChannelIndex][i] = Mpy_32_32( L_add( L_tmp3, L_tmp4 ), lowPassSignal_fx[i] );                   /*q31+q11-q31->q11*/
    3540      180800 :             move32();
    3541      180800 :             j = add( j, 1 );
    3542             :         }
    3543             : 
    3544        3120 :         hMasaLfeSynth->lfeGainPrev_fx = lfeGain_fx; /*q15*/
    3545        3120 :         move16();
    3546        3120 :         hMasaLfeSynth->transportGainPrev_fx = transportGain_fx; /*q15*/
    3547        3120 :         move16();
    3548             :     }
    3549             : 
    3550             :     /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
    3551         195 :     lowpassCoef_fx_exp = 15;
    3552         195 :     move16();
    3553         195 :     lowpassCoef_fx = Inv16( hMasaLfeSynth->ringBufferSize2, &lowpassCoef_fx_exp ); // q15-lowpassCoef_fx_exp
    3554      180995 :     FOR( i = 0; i < output_frame; i++ )
    3555             :     {
    3556      180800 :         hMasaLfeSynth->lowpassSum2_fx = L_add( hMasaLfeSynth->lowpassSum2_fx,
    3557      180800 :                                                L_shl_r( L_sub( Mpy_32_16_1( data_fx[lfeChannelIndex][i], lowpassCoef_fx ),
    3558      180800 :                                                                Mpy_32_16_1( hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2], lowpassCoef_fx ) ),
    3559             :                                                         lowpassCoef_fx_exp ) ); /*q11+15-lowpassCoef_fx_exp-15+lowpassCoef_fx_exp->q11*/
    3560      180800 :         move32();
    3561      180800 :         hMasaLfeSynth->lfeSynthRingBuffer2_fx[hMasaLfeSynth->ringBufferLoPointer2] = data_fx[lfeChannelIndex][i]; /*q11*/
    3562      180800 :         move32();
    3563             : 
    3564      180800 :         hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferLoPointer2, 1 );
    3565      180800 :         move16();
    3566      180800 :         IF( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
    3567             :         {
    3568        1560 :             hMasaLfeSynth->ringBufferLoPointer2 = sub( hMasaLfeSynth->ringBufferSize2, 1 );
    3569        1560 :             move16();
    3570             :         }
    3571             : 
    3572      180800 :         data_fx[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2_fx; /*q11*/
    3573      180800 :         move32();
    3574             :     }
    3575             : 
    3576             :     /* Delay the separated channel to match the delay of the lowpass filter */
    3577         195 :     delay = hMasaLfeSynth->delayBuffer_syncLp_size;
    3578         195 :     move16();
    3579         195 :     delay_signal32_fx( data_fx[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp_fx, delay ); /*q11*/
    3580             : 
    3581         195 :     return;
    3582             : }
    3583             : 
    3584             : /*-------------------------------------------------------------------------
    3585             :  * Local functions
    3586             :  *------------------------------------------------------------------------*/
    3587             : 
    3588       56000 : static void computeTargetPSDs_direct_fx(
    3589             :     const Word16 num_channels,
    3590             :     const Word16 num_freq_bands,
    3591             :     const Word32 *direct_power_factor, /*q31*/
    3592             :     const Word32 *reference_power,     /*q_reference_power*/
    3593             :     const Word16 *q_reference_power,
    3594             :     const Word32 *direct_responses,        /*q31*/
    3595             :     const Word32 *direct_responses_square, /*q31*/
    3596             :     Word32 *cy_auto_dir_smooth,            /*q_cy_auto_dir_smooth*/
    3597             :     Word16 *q_cy_auto_dir_smooth,
    3598             :     Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
    3599             :     Word16 *q_cy_cross_dir_smooth )
    3600             : {
    3601             :     Word16 ch_idx, cur_idx;
    3602             : 
    3603             :     /* segment auxiliary buffer */
    3604             :     Word32 direct_power[CLDFB_NO_CHANNELS_MAX];   /* size: num_freq_bands. */
    3605             :     Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    3606             : 
    3607             :     /* estimate direct and diffuse power */
    3608       56000 :     v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
    3609             : 
    3610       56000 :     Word16 common1_q = s_min( *q_cy_auto_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
    3611       56000 :     Word16 common2_q = s_min( *q_cy_cross_dir_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
    3612             : 
    3613             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    3614      592000 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    3615             :     {
    3616      536000 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    3617             : 
    3618      536000 :         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) */
    3619      536000 :         scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common1_q, q_reference_power[0] ) );                                    /* Q(common1_q) */
    3620      536000 :         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) */
    3621      536000 :         scale_sig32( &cy_auto_dir_smooth[cur_idx], num_freq_bands, sub( common1_q, *q_cy_auto_dir_smooth ) );                                                      /* Q(common1_q) */
    3622      536000 :         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 */
    3623             : 
    3624      536000 :         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) */
    3625      536000 :         scale_sig32( aux_buffer_res, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( common2_q, q_reference_power[0] ) );                                    /* Q(common2_q) */
    3626      536000 :         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) */
    3627      536000 :         scale_sig32( &cy_cross_dir_smooth[cur_idx], num_freq_bands, sub( common2_q, *q_cy_cross_dir_smooth ) );                                                    /* Q(common2_q) */
    3628      536000 :         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 */
    3629             :     }
    3630             : 
    3631             :     /* Q adjustment */
    3632       56000 :     *q_cy_auto_dir_smooth = sub( common1_q, Q1 );
    3633       56000 :     move16();
    3634       56000 :     *q_cy_cross_dir_smooth = sub( common2_q, Q1 );
    3635       56000 :     move16();
    3636             : 
    3637       56000 :     return;
    3638             : }
    3639             : 
    3640             : 
    3641       78927 : static void computeTargetPSDs_direct_subframe_fx(
    3642             :     const Word16 num_channels,
    3643             :     const Word16 num_freq_bands,
    3644             :     const Word32 *direct_power_factor, /*q31*/
    3645             :     const Word32 *reference_power,     /*q_reference_power*/
    3646             :     const Word16 *q_reference_power,
    3647             :     const Word32 *direct_responses,        /*q31*/
    3648             :     const Word32 *direct_responses_square, /*q31*/
    3649             :     Word32 *cy_auto_dir_smooth,            /*q_cy_auto_dir_smooth*/
    3650             :     Word16 *q_cy_auto_dir_smooth,
    3651             :     Word32 *cy_cross_dir_smooth, /*q_cy_cross_dir_smooth*/
    3652             :     Word16 *q_cy_cross_dir_smooth )
    3653             : {
    3654             :     Word16 ch_idx, cur_idx, q_tmp;
    3655             :     Word32 L_tmp[CLDFB_NO_CHANNELS_MAX];
    3656             :     Word16 q_cy_auto_dir_smooth_local[2];
    3657             : 
    3658             :     /* segment auxiliary buffer */
    3659             :     Word32 direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    3660             : 
    3661             :     /* estimate direct and diffuse power */
    3662       78927 :     v_mult_fixed( direct_power_factor, reference_power, direct_power, num_freq_bands );
    3663             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    3664      605476 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    3665             :     {
    3666      526549 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    3667             : 
    3668      526549 :         q_tmp = L_norm_arr( &direct_responses_square[cur_idx], num_freq_bands );
    3669      526549 :         Copy_Scale_sig32( &direct_responses_square[cur_idx], L_tmp, num_freq_bands, q_tmp );
    3670      526549 :         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
    3671             : 
    3672      526549 :         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 ) ) );
    3673      526549 :         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 ) ) );
    3674      526549 :         q_cy_auto_dir_smooth[ch_idx] = s_min( q_cy_auto_dir_smooth_local[0], q_cy_auto_dir_smooth_local[1] );
    3675      526549 :         move16();
    3676             : 
    3677      526549 :         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 ) ) );
    3678      526549 :         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 ) ) );
    3679             : 
    3680      526549 :         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
    3681      526549 :         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] ) );
    3682             :     }
    3683             : 
    3684       78927 :     *q_cy_cross_dir_smooth = q_reference_power[0];
    3685       78927 :     move16();
    3686             : 
    3687       78927 :     return;
    3688             : }
    3689             : 
    3690             : 
    3691       56000 : static void computeTargetPSDs_diffuse_fx(
    3692             :     const Word16 num_channels,
    3693             :     const Word16 num_freq_bands,
    3694             :     const Word16 start_band,
    3695             :     const Word32 *diffuse_power_factor, /*q31*/
    3696             :     const Word32 *reference_power,      /*q_reference_power*/
    3697             :     const Word16 *q_reference_power,
    3698             :     const Word32 *diffuse_responses_square, /*Q31*/
    3699             :     Word32 *cy_auto_diff_smooth,            /*q_cy_auto_diff_smooth*/
    3700             :     Word16 *q_cy_auto_diff_smooth )
    3701             : {
    3702             :     Word16 ch_idx, cur_idx;
    3703             : 
    3704             :     /* segment auxiliary buffer */
    3705             :     Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX];  /* size: num_freq_bands. */
    3706             :     Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    3707             : 
    3708             :     /* estimate direct and diffuse power */
    3709       56000 :     v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); /* Q31 + Q(q_reference_power) - Q31 = Q(q_reference_power) */
    3710             : 
    3711       56000 :     Word16 common_q = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power[0], q_reference_power[1] ) );
    3712             : 
    3713             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    3714      592000 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    3715             :     {
    3716      536000 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    3717             : 
    3718      536000 :         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) */
    3719      536000 :         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) */
    3720      536000 :         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) */
    3721      536000 :         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) */
    3722      536000 :         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 */
    3723             :     }
    3724             : 
    3725             :     /* Q adjustment */
    3726       56000 :     *q_cy_auto_diff_smooth = sub( common_q, Q1 );
    3727       56000 :     move16();
    3728             : 
    3729       56000 :     return;
    3730             : }
    3731             : 
    3732             : 
    3733       78927 : static void computeTargetPSDs_diffuse_subframe_fx(
    3734             :     const Word16 num_channels,
    3735             :     const Word16 num_freq_bands,
    3736             :     const Word16 start_band,
    3737             :     const Word32 *diffuse_power_factor, /*q31*/
    3738             :     const Word32 *reference_power,      /*q_reference_power*/
    3739             :     const Word16 *q_reference_power,
    3740             :     const Word32 *diffuse_responses_square, /*q31*/
    3741             :     Word32 *cy_auto_diff_smooth,            /*q_cy_auto_diff_smooth*/
    3742             :     Word16 *q_cy_auto_diff_smooth )
    3743             : {
    3744             :     Word16 ch_idx, cur_idx;
    3745             :     Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */
    3746             :     Word16 q_cy_auto_diff_smooth_new, q_diffuse_power;
    3747             : 
    3748             :     /* estimate direct and diffuse power */
    3749       78927 :     v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
    3750             : 
    3751       78927 :     q_diffuse_power = s_min( q_reference_power[0], q_reference_power[1] );
    3752       78927 :     Scale_sig32( diffuse_power, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_diffuse_power, q_reference_power[0] ) );
    3753       78927 :     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] ) );
    3754       78927 :     q_cy_auto_diff_smooth_new = q_diffuse_power;
    3755       78927 :     IF( LT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
    3756             :     {
    3757        4314 :         Scale_sig32( diffuse_power, num_freq_bands, sub( *q_cy_auto_diff_smooth, q_cy_auto_diff_smooth_new ) );
    3758        4314 :         q_cy_auto_diff_smooth_new = *q_cy_auto_diff_smooth;
    3759        4314 :         move16();
    3760             :     }
    3761             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    3762      605476 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    3763             :     {
    3764      526549 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    3765             : 
    3766      526549 :         IF( GT_16( *q_cy_auto_diff_smooth, q_diffuse_power ) )
    3767             :         {
    3768      467143 :             Scale_sig32( &cy_auto_diff_smooth[cur_idx], start_band, sub( q_diffuse_power, *q_cy_auto_diff_smooth ) );
    3769             :         }
    3770      526549 :         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
    3771             :     }
    3772             : 
    3773       78927 :     *q_cy_auto_diff_smooth = q_cy_auto_diff_smooth_new;
    3774       78927 :     move16();
    3775             : 
    3776       78927 :     return;
    3777             : }
    3778             : 
    3779             : 
    3780      213809 : static void computeTargetPSDs_diffuse_with_onsets_fx(
    3781             :     const Word16 num_channels,
    3782             :     const Word16 num_freq_bands,
    3783             :     const Word16 num_decorr_freq_bands,
    3784             :     const Word16 *proto_frame_diff_index,
    3785             :     const Word32 *diffuse_power_factor, /*q31*/
    3786             :     const Word32 *reference_power,      /* q_reference_power */
    3787             :     const Word16 *q_reference_power,
    3788             :     const Word32 *diffuse_responses_square, /*q31*/
    3789             :     const Word32 *onset_filter,             /*q31*/
    3790             :     Word32 *cy_auto_diff_smooth,            /*q_cy_auto_diff_smooth*/
    3791             :     Word16 *q_cy_auto_diff_smooth )
    3792             : {
    3793             :     Word16 ch_idx, cur_idx, diff_idx;
    3794             :     Word32 diffuse_response_p4, aux_buffer_res1[CLDFB_NO_CHANNELS_MAX];
    3795             :     /* segment auxiliary buffer */
    3796             :     Word32 diffuse_power[CLDFB_NO_CHANNELS_MAX];  /* size: num_freq_bands. */
    3797             :     Word32 aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    3798             :     Word16 q_common, q_reference_power_min_one[2];
    3799             : 
    3800      213809 :     q_reference_power_min_one[0] = sub( q_reference_power[0], Q1 );
    3801      213809 :     q_reference_power_min_one[1] = sub( q_reference_power[1], Q1 );
    3802             : 
    3803             :     /* estimate direct and diffuse power */
    3804      213809 :     v_mult_fixed( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands ); // (Q31, q_reference_power) -> q_reference_power
    3805             : 
    3806      213809 :     q_common = s_min( *q_cy_auto_diff_smooth, s_min( q_reference_power_min_one[0], q_reference_power_min_one[1] ) );
    3807             : 
    3808             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    3809     1721072 :     FOR( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    3810             :     {
    3811     1507263 :         diffuse_response_p4 = Mpy_32_32( diffuse_responses_square[ch_idx], diffuse_responses_square[ch_idx] ); // (Q31, Q31) -> Q31
    3812             : 
    3813     1507263 :         cur_idx = imult1616( ch_idx, num_freq_bands );
    3814     1507263 :         diff_idx = imult1616( proto_frame_diff_index[ch_idx], num_freq_bands );
    3815             : 
    3816     1507263 :         v_multc_fixed( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands ); // (Q31, Q31) -> Q31
    3817     1507263 :         v_multc_fixed( &onset_filter[diff_idx], INT_MIN, aux_buffer_res, num_decorr_freq_bands );                           // (Q31, Q31) -> Q31
    3818     1507263 :         v_addc_fixed( aux_buffer_res, ONE_IN_Q31, aux_buffer_res, num_decorr_freq_bands );                                  // Q31
    3819     1507263 :         v_multc_fixed( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands );                        // (Q31, Q31) -> Q31
    3820     1507263 :         v_add_fixed( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands, Q1 );                          // Q30
    3821     1507263 :         v_mult_fixed( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands );                               // (Q30, q_reference_power) -> q_reference_power - Q1
    3822             : 
    3823     1507263 :         IF( NE_16( q_common, q_reference_power_min_one[0] ) )
    3824             :         {
    3825       18201 :             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
    3826             :         }
    3827     1507263 :         IF( NE_16( q_common, q_reference_power_min_one[1] ) )
    3828             :         {
    3829      703545 :             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
    3830             :         }
    3831     1507263 :         IF( NE_16( q_common, *q_cy_auto_diff_smooth ) )
    3832             :         {
    3833     1202556 :             scale_sig32( &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands, sub( q_common, *q_cy_auto_diff_smooth ) ); // q_common
    3834             :         }
    3835     1507263 :         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)
    3836     1507263 :         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)
    3837             :     }
    3838             : 
    3839             :     /* Q adjustment */
    3840      213809 :     *q_cy_auto_diff_smooth = sub( q_common, Q1 );
    3841      213809 :     move16();
    3842             : 
    3843      213809 :     return;
    3844             : }
    3845             : 
    3846             : 
    3847        2838 : 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 )
    3848             : {
    3849             :     Word16 k;
    3850             :     Word16 avg_length_f_ms_fx;
    3851             : 
    3852             :     /* check input pointer */
    3853        2838 :     IF( alpha_synthesis_fx == NULL )
    3854             :     {
    3855           0 :         return;
    3856             :     }
    3857             : 
    3858        2838 :     IF( averaging_length_ms == 0 )
    3859             :     {
    3860           0 :         set16_fx( alpha_synthesis_fx, MAX16B, num_freq_bands ); /*q15*/
    3861             :     }
    3862             :     ELSE
    3863             :     {
    3864       11352 :         FOR( k = 0; k < num_freq_bands; k++ )
    3865             :         {
    3866       11352 :             Word16 faxis_idx = s_max( k, 1 );
    3867             : 
    3868             :             // avg_length_f_ms = 1000.f * (float)averaging_length_ms / fabsf(frequency_axis[faxis_idx]);
    3869       11352 :             Word16 tmp_exp = 0;
    3870       11352 :             Word16 tmp_1 = BASOP_Util_Divide1616_Scale( averaging_length_ms, frequency_axis_fx[faxis_idx], &tmp_exp ); /*Q(15-(tmp_exp+15-15))*/
    3871       11352 :             Word16 tmp_2 = mult( tmp_1, 1000 );                                                                        // 15 - tmp_exp + 0 -15 = -tmp_exp (Q-fac)
    3872       11352 :             avg_length_f_ms_fx = tmp_2;                                                                                // Q(-tmp_exp)
    3873       11352 :             move16();
    3874       11352 :             move16();
    3875             : 
    3876             :             /*            alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );*/
    3877       11352 :             Word32 tmp_3 = Mpy_32_16_1( output_Fs, avg_length_f_ms_fx ); // 0 - tmp_exp - 15 (Q-fac)
    3878             :             Word16 tmp_exp_3;
    3879       11352 :             Word16 tmp_4 = BASOP_Util_Divide3232_Scale( tmp_3, 1000, &tmp_exp_3 ); /*tmp_exp_4 stores resultant exponent*/
    3880       11352 :             Word16 tmp_exp_4 = sub( add( tmp_exp_3, add( add( 31, tmp_exp ), 15 ) ), 31 );
    3881             :             Word16 tmp_exp_5;
    3882       11352 :             Word16 tmp_5 = BASOP_Util_Divide1616_Scale( slot_size, tmp_4, &tmp_exp_5 ); /*res_exp stores resultant exponent*/
    3883       11352 :             Word16 res_exp = sub( add( tmp_exp_5, 15 ), tmp_exp_4 );
    3884             : 
    3885       11352 :             Word16 flag = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( tmp_5 ), res_exp, 1, 31 );
    3886       11352 :             IF( EQ_16( flag, -1 ) )
    3887             :             {
    3888       11352 :                 alpha_synthesis_fx[k] = shr( tmp_5, negate( res_exp ) ); // q15
    3889       11352 :                 move16();
    3890             :             }
    3891             :             ELSE
    3892             :             {
    3893           0 :                 alpha_synthesis_fx[k] = MAX16B; /*q15*/
    3894           0 :                 move16();
    3895             :             }
    3896             : 
    3897       11352 :             Word16 flag2 = BASOP_Util_Cmp_Mant32Exp( L_deposit_h( alpha_synthesis_fx[k] ), 0, L_deposit_h( maxAlpha_fx ), 0 );
    3898       11352 :             test();
    3899       11352 :             IF( flag2 == 0 || EQ_16( flag2, 1 ) )
    3900             :             {
    3901        2838 :                 alpha_synthesis_fx[k] = maxAlpha_fx; /*q15*/
    3902        2838 :                 move16();
    3903        2838 :                 *numAlphas = add( k, 1 );
    3904        2838 :                 move16();
    3905        2838 :                 BREAK;
    3906             :             }
    3907             :         }
    3908             :     }
    3909             : 
    3910        2838 :     return;
    3911             : }
    3912             : 
    3913             : 
    3914      566309 : static void spreadCoherencePanningHoa_fx(
    3915             :     const Word16 azimuth,
    3916             :     const Word16 elevation,
    3917             :     const Word16 spreadCoh_fx,  /*i:Q15*/
    3918             :     Word32 *direct_response_fx, /*i/o:Q_direct_response*/
    3919             :     Word16 *Q_direct_response,  /*i/o:stores q for direct_response_fx*/
    3920             :     const Word16 num_channels_dir,
    3921             :     const Word16 ambisonics_order )
    3922             : {
    3923             :     Word16 i;
    3924             : 
    3925             :     Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
    3926             :     Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
    3927             :     Word32 gainCenter_fx;
    3928             :     Word32 gainSide_fx;
    3929             : 
    3930      566309 :     ivas_dirac_dec_get_response_fx( azimuth, elevation, direct_response_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
    3931             : 
    3932             :     Word16 exp_Gain_side, exp_Gain_center;
    3933      566309 :     IF( spreadCoh_fx > 0 )
    3934             :     {
    3935      322754 :         ivas_dirac_dec_get_response_fx( add( azimuth, 30 ), elevation, direct_response_left_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
    3936      322754 :         ivas_dirac_dec_get_response_fx( add( azimuth, 330 ), elevation, direct_response_right_fx /*Q_direct_response*/, ambisonics_order, *Q_direct_response );
    3937             : 
    3938             : 
    3939             :         Word16 var_a, var_b, exp_a;
    3940             : 
    3941      322754 :         IF( LT_16( spreadCoh_fx, ONE_IN_Q14 /*0.5 q15*/ ) )
    3942             :         {
    3943             :             /*gainCenter  = (3 - 4*spreadCoh )/3*/
    3944      317882 :             var_a = sub( 24576 /*3 in Q13*/, spreadCoh_fx ); // Q13
    3945      317882 :             var_a = mult( var_a, ONE_BY_THREE_Q15 );         // Q13
    3946             : 
    3947      317882 :             gainCenter_fx = L_deposit_h( shr( var_a, 2 ) );                      // Q11 + 16 = Q27
    3948      317882 :             gainSide_fx = L_deposit_h( mult( spreadCoh_fx, ONE_BY_THREE_Q15 ) ); // Q14 + 16 (reduce Q by 1 to *2) = Q30
    3949      317882 :             exp_Gain_side = 31 - Q30;
    3950      317882 :             move16();
    3951      317882 :             exp_Gain_center = 31 - Q27;
    3952      317882 :             move16();
    3953             :         }
    3954             :         ELSE
    3955             :         {
    3956        4872 :             var_a = shl( sub( 16384 /*2 in Q13*/, shr( spreadCoh_fx, 2 ) ), 1 ); // q13
    3957        4872 :             exp_a = 15 - Q13;
    3958        4872 :             move16();
    3959        4872 :             var_a = Inv16( var_a, &exp_a );     // 15-exp_a
    3960        4872 :             gainSide_fx = L_deposit_h( var_a ); // 15-exp_a + 16 = Q31 -exp_a
    3961        4872 :             exp_Gain_side = exp_a;
    3962        4872 :             move16();
    3963             : 
    3964        4872 :             var_b = sub( 8192 /*2 in Q12*/, shr( spreadCoh_fx, 2 ) /*Q14*/ ); // exp => 3
    3965        4872 :             gainCenter_fx = L_deposit_h( mult( var_b, var_a ) );              // 15-exp_a + 12-15+16=>28-exp_a =  // 3 + exp_a
    3966        4872 :             exp_Gain_center = add( 3, exp_a );
    3967             :         }
    3968             : 
    3969             : 
    3970             :         Word32 mpy1, mpy2;
    3971             :         Word16 exp_arr[16], exp;
    3972      322754 :         set16_fx( exp_arr, sub( 31, *Q_direct_response ), 16 );
    3973     2589685 :         FOR( i = 0; i < num_channels_dir; i++ )
    3974             :         {
    3975     2266931 :             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
    3976     2266931 :             mpy2 = Mpy_32_32( direct_response_fx[i], gainCenter_fx );                                          // 31 - Q_direct_response + exp_Gain_Center
    3977     2266931 :             exp = 0;
    3978     2266931 :             move16();
    3979     2266931 :             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
    3980     2266931 :             move32();
    3981     2266931 :             exp_arr[i] = exp;
    3982     2266931 :             move16();
    3983             :         }
    3984      322754 :         Word16 max_val = MIN_16;
    3985      322754 :         move16();
    3986     5486818 :         FOR( i = 0; i < 16; i++ )
    3987             :         {
    3988     5164064 :             max_val = s_max( max_val, exp_arr[i] );
    3989             :         }
    3990     5486818 :         FOR( i = 0; i < 16; i++ )
    3991             :         {
    3992     5164064 :             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)
    3993     5164064 :             move32();
    3994             :         }
    3995      322754 :         *Q_direct_response = sub( 31, max_val );
    3996      322754 :         move16();
    3997             :     }
    3998             : 
    3999      566309 :     return;
    4000             : }
    4001             : 
    4002             : 
    4003     4163891 : static void spreadCoherencePanningVbap_fx(
    4004             :     const Word16 azimuth,       /*i:q0*/
    4005             :     const Word16 elevation,     /*i:q0*/
    4006             :     const Word16 spreadCoh_fx,  /*i:q15*/
    4007             :     Word32 *direct_response_fx, /*i/o:Q_direct_response*/
    4008             :     Word16 *Q_direct_response,  /*o: stores q for direct_response_fx*/
    4009             :     const Word16 num_channels_dir,
    4010             :     const VBAP_HANDLE hVBAPdata )
    4011             : {
    4012             :     Word16 i;
    4013             :     Word32 direct_response_left_fx[MAX_OUTPUT_CHANNELS];
    4014             :     Word32 direct_response_right_fx[MAX_OUTPUT_CHANNELS];
    4015     4163891 :     set32_fx( direct_response_left_fx, 0, MAX_OUTPUT_CHANNELS );
    4016     4163891 :     set32_fx( direct_response_right_fx, 0, MAX_OUTPUT_CHANNELS );
    4017             :     Word32 gainCenter_fx;
    4018             :     Word32 gainSide_fx;
    4019             : 
    4020     4163891 :     IF( hVBAPdata == NULL )
    4021             :     {
    4022             :         /* Distribute signal to all channels if VBAP is not properly initialized. */
    4023           0 :         Word16 exp_tmp = 0;
    4024           0 :         move16();
    4025           0 :         Word16 var_temp = ISqrt16( num_channels_dir, &exp_tmp );
    4026           0 :         set32_fx( direct_response_fx, var_temp, num_channels_dir );
    4027           0 :         *Q_direct_response = sub( 31, exp_tmp );
    4028           0 :         move16();
    4029             : 
    4030           0 :         return;
    4031             :     }
    4032             : 
    4033     4163891 :     set32_fx( direct_response_fx, 0, MAX_OUTPUT_CHANNELS );
    4034     4163891 :     vbap_determine_gains_fx( hVBAPdata, direct_response_fx /*q29*/, azimuth, elevation, 0 );
    4035     4163891 :     *Q_direct_response = Q29;
    4036     4163891 :     move16();
    4037             : 
    4038     4163891 :     IF( spreadCoh_fx > 0 )
    4039             :     {
    4040      462442 :         vbap_determine_gains_fx( hVBAPdata, direct_response_left_fx /*q29*/, add( azimuth, 30 ), elevation, 0 );
    4041      462442 :         vbap_determine_gains_fx( hVBAPdata, direct_response_right_fx /*q29*/, sub( azimuth, 30 ), elevation, 0 );
    4042             : 
    4043      462442 :         Word32 var1 = 0;
    4044      462442 :         move32();
    4045      462442 :         Word32 var2 = 0;
    4046      462442 :         move32();
    4047      462442 :         Word16 var_a = 0;
    4048      462442 :         move16();
    4049      462442 :         Word16 var_b = 0;
    4050      462442 :         move16();
    4051      462442 :         IF( LT_16( spreadCoh_fx, 16384 ) ) // 16384 = 0.5 in Q15
    4052             :         {
    4053      451111 :             var_a = mult( spreadCoh_fx, INV_SQRT3_FX );         // Q14
    4054      451111 :             var_b = sub( ONE_IN_Q14, spreadCoh_fx );            // Q14
    4055      451111 :             gainCenter_fx = L_deposit_h( add( var_a, var_b ) ); // Q30
    4056      451111 :             gainSide_fx = L_deposit_h( var_a );                 // Q30
    4057             :         }
    4058             :         ELSE
    4059             :         {
    4060       11331 :             var_a = sub( ONE_IN_Q14, shr( spreadCoh_fx, 1 ) ); // Q13
    4061       11331 :             gainCenter_fx = L_shl( L_deposit_h( var_a ), 1 );  // Q30
    4062       11331 :             gainSide_fx = ONE_IN_Q30;
    4063       11331 :             move32();
    4064             :         }
    4065             : 
    4066      462442 :         Word32 var3 = 0;
    4067      462442 :         move32();
    4068      462442 :         *Q_direct_response = Q28;
    4069      462442 :         move16();
    4070     4013167 :         FOR( i = 0; i < num_channels_dir; i++ )
    4071             :         {
    4072     3550725 :             var1 = L_add( direct_response_left_fx[i], direct_response_right_fx[i] ); // Q29
    4073     3550725 :             var2 = Mpy_32_32( var1, gainSide_fx );                                   // Q28
    4074     3550725 :             var3 = Mpy_32_32( direct_response_fx[i], gainCenter_fx );                // Q28
    4075     3550725 :             direct_response_fx[i] = L_add( var3, var2 );                             // Q28
    4076     3550725 :             move32();
    4077             :         }
    4078             :     }
    4079             : 
    4080     4163891 :     return;
    4081             : }
    4082             : 
    4083             : 
    4084     8363477 : static void normalizePanningGains_fx(
    4085             :     Word32 *direct_response_fx, /*i/o:resultant q is q_direct_res*/
    4086             :     Word16 *q_direct_res,       /*i/o: stores q for direct_response_fx*/
    4087             :     const Word16 num_channels_dir )
    4088             : {
    4089             :     Word32 energySum_fx;
    4090     8363477 :     Word16 exp_energySum = 0;
    4091             :     Word32 normVal_fx;
    4092             :     Word16 i;
    4093     8363477 :     move16();
    4094             : 
    4095     8363477 :     Word16 gb = find_guarded_bits_fx( num_channels_dir );
    4096     8363477 :     energySum_fx = sum2_f_32_fx( direct_response_fx, num_channels_dir, gb ); // exp_energySum stores resultant exponent
    4097     8363477 :     IF( GT_16( *q_direct_res, Q31 ) )
    4098             :     {
    4099        1509 :         exp_energySum = add( shl( sub( Q31, *q_direct_res ), 1 ), gb );
    4100             :     }
    4101     8363477 :     exp_energySum = sub( Q31, sub( sub( shl( *q_direct_res, 1 ), Q31 ), gb ) );
    4102             : 
    4103     8363477 :     IF( energySum_fx > 0 )
    4104             :     {
    4105     8349865 :         normVal_fx = ISqrt32( energySum_fx, &exp_energySum ); // 31-exp_energySum
    4106             :     }
    4107             :     ELSE
    4108             :     {
    4109       13612 :         energySum_fx = BASOP_Util_Add_Mant32Exp( energySum_fx, exp_energySum, ONE_IN_Q30, 1, &exp_energySum ); // 31-exp_energySum
    4110       13612 :         normVal_fx = ISqrt32( energySum_fx, &exp_energySum );                                                  // 31-exp_energySum
    4111             :     }
    4112             : 
    4113    85164284 :     FOR( i = 0; i < num_channels_dir; i++ )
    4114             :     {
    4115    76800807 :         direct_response_fx[i] = Mpy_32_32( direct_response_fx[i], normVal_fx ); // q_direct_res stores resultant q for the same
    4116    76800807 :         move32();
    4117             :     }
    4118     8363477 :     Word16 exp = add( sub( Q31, *q_direct_res ), exp_energySum );
    4119     8363477 :     *q_direct_res = sub( Q31, exp );
    4120             : 
    4121     8363477 :     return;
    4122             : }

Generated by: LCOV version 1.14