LCOV - code coverage report
Current view: top level - lib_rend - ivas_dirac_output_synthesis_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 2136 2244 95.2 %
Date: 2025-06-27 02:59:36 Functions: 20 20 100.0 %

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

Generated by: LCOV version 1.14