LCOV - code coverage report
Current view: top level - lib_rend - ivas_dirac_output_synthesis_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- merged total coverage @ a21f94bc6bac334fe001a5bad2f7b32b79038097 Lines: 845 889 95.1 %
Date: 2025-11-01 08:50:45 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "cnst.h"
      38             : #include "prot.h"
      39             : #include "ivas_prot.h"
      40             : #include "ivas_prot_rend.h"
      41             : #include "ivas_stat_dec.h"
      42             : #include "ivas_cnst.h"
      43             : #include "ivas_rom_com.h"
      44             : #include "ivas_rom_dec.h"
      45             : #ifdef DEBUGGING
      46             : #include "debug.h"
      47             : #endif
      48             : #include "wmc_auto.h"
      49             : 
      50             : /*-------------------------------------------------------------------------
      51             :  * Local constants
      52             :  *------------------------------------------------------------------------*/
      53             : 
      54             : #define DIRAC_AVG_LENGTH_SYNTH_MS      20 /*averaging length in ms for DirAC synthesis*/
      55             : #define DIRAC_ALPHA_MAX                0.1f
      56             : #define DIRAC_AVG_LENGTH_SYNTH_MS_FAST 10
      57             : #define DIRAC_ALPHA_MAX_FAST           0.12f
      58             : #define DIRECTION_SMOOTHNESS_ALPHA     0.01f
      59             : 
      60             : 
      61             : /*-------------------------------------------------------------------------
      62             :  * Local function prototypes
      63             :  *------------------------------------------------------------------------*/
      64             : 
      65             : static void computeTargetPSDs_direct( const int16_t num_channels, const int16_t num_freq_bands, const float *direct_power_factor, const float *reference_power, const float *direct_responses, const float *direct_responses_square, float *cy_auto_dir_smooth, float *cy_cross_dir_smooth );
      66             : 
      67             : static void computeTargetPSDs_direct_subframe( const int16_t num_channels, const int16_t num_freq_bands, const float *direct_power_factor, const float *reference_power, const float *direct_responses, const float *direct_responses_square, float *cy_auto_dir_smooth, float *cy_cross_dir_smooth );
      68             : 
      69             : static void computeTargetPSDs_diffuse( const int16_t num_channels, const int16_t num_freq_bands, const int16_t start_band, const float *diffuse_power_factor, const float *reference_power, const float *diffuse_responses_square, float *cy_auto_diff_smooth );
      70             : 
      71             : static void computeTargetPSDs_diffuse_subframe( const int16_t num_channels, const int16_t num_freq_bands, const int16_t start_band, const float *diffuse_power_factor, const float *reference_power, const float *diffuse_responses_square, float *cy_auto_diff_smooth );
      72             : 
      73             : static void computeTargetPSDs_diffuse_with_onsets( const int16_t num_channels, const int16_t num_freq_bands, const int16_t num_decorr_freq_bands, const int16_t *proto_frame_diff_index, const float *diffuse_power_factor, const float *reference_power, const float *diffuse_responses_square, const float *onset_filter, float *cy_auto_diff_smooth );
      74             : 
      75             : static void computeAlphaSynthesis( float *alpha_synthesis, const int16_t averaging_length_ms, const float maxAlpha, int16_t *numAlphas, const int16_t slot_size, const int16_t num_freq_bands, const float *frequency_axis, const int32_t output_Fs );
      76             : 
      77             : static void spreadCoherencePanningHoa( const int16_t azimuth, const int16_t elevation, const float spreadCoh, float *direct_response, const int16_t num_channels_dir, const int16_t ambisonics_order );
      78             : 
      79             : static void spreadCoherencePanningVbap( const int16_t azimuth, const int16_t elevation, const float spreadCoh, float *direct_response, const int16_t num_channels_dir, const VBAP_HANDLE hVBAPdata );
      80             : 
      81             : static void normalizePanningGains( float *direct_response, const int16_t num_channels_dir );
      82             : 
      83             : 
      84             : /*-------------------------------------------------------------------------
      85             :  * ivas_dirac_dec_output_synthesis_open()
      86             :  *
      87             :  *
      88             :  *------------------------------------------------------------------------*/
      89             : 
      90      165917 : ivas_error ivas_dirac_dec_output_synthesis_open(
      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 int16_t nchan_transport,                        /* i  : number of transport channels          */
      95             :     const int32_t output_Fs,                              /* i  : output sampling rate                  */
      96             :     const int16_t hodirac_flag                            /* i  : flag to indicate HO-DirAC mode        */
      97             : )
      98             : {
      99             :     int16_t idx, ch_idx;
     100             :     int16_t size;
     101             :     float tmp;
     102             :     uint16_t num_diffuse_responses;
     103             :     float temp_alpha_synthesis[CLDFB_NO_CHANNELS_MAX];
     104             : 
     105             :     /* pointers to structs for allocation */
     106      165917 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     107      165917 :     DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     108             : 
     109             :     /* check / set input parameters */
     110      165917 :     assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
     111      165917 :     assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
     112      165917 :     assert( hDirACRend->num_outputs_diff > 0 );
     113      165917 :     assert( hSpatParamRendCom->slot_size > 0 );
     114      165917 :     assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
     115      165917 :     assert( hDirACRend->diffuse_response_function != NULL );
     116             : 
     117      165917 :     if ( hDirACRend->proto_signal_decorr_on )
     118             :     {
     119      157918 :         dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
     120             :     }
     121             :     else
     122             :     {
     123        7999 :         dirac_output_synthesis_params->max_band_decorr = 0;
     124             :     }
     125             : 
     126             :     /*-----------------------------------------------------------------*
     127             :      * memory allocation
     128             :      *-----------------------------------------------------------------*/
     129             : 
     130      165917 :     dirac_output_synthesis_state->diffuse_responses_square = NULL;
     131      165917 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
     132             :     {
     133        5005 :         if ( ( dirac_output_synthesis_state->diffuse_responses_square = (float *) malloc( 2 * sizeof( float ) ) ) == NULL )
     134             :         {
     135           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     136             :         }
     137             :     }
     138      160912 :     else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
     139             :     {
     140       99103 :         if ( ( dirac_output_synthesis_state->diffuse_responses_square = (float *) malloc( hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
     141             :         {
     142           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     143             :         }
     144             :     }
     145             : 
     146             :     /* prototype power buffers */
     147      165917 :     dirac_output_synthesis_state->proto_power_smooth_prev = NULL;
     148      165917 :     if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
     149             :     {
     150      104108 :         if ( ( dirac_output_synthesis_state->proto_power_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir * sizeof( float ) ) ) == NULL )
     151             :         {
     152           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     153             :         }
     154             :     }
     155      165917 :     if ( dirac_output_synthesis_params->max_band_decorr > 0 && ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) )
     156             :     {
     157       96109 :         if ( ( dirac_output_synthesis_state->proto_power_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
     158             :         {
     159           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     160             :         }
     161             :     }
     162             :     else
     163             :     {
     164       69808 :         dirac_output_synthesis_state->proto_power_diff_smooth_prev = NULL;
     165             :     }
     166             : 
     167             :     /* buffer length and interpolator */
     168      165917 :     if ( ( dirac_output_synthesis_params->interpolator = (float *) malloc( JBM_CLDFB_SLOTS_IN_SUBFRAME * sizeof( float ) ) ) == NULL )
     169             :     {
     170           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     171             :     }
     172             : 
     173             :     /* target PSD buffers */
     174      165917 :     if ( hodirac_flag )
     175             :     {
     176        9810 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
     177             :     }
     178             :     else
     179             :     {
     180      156107 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
     181             :     }
     182      165917 :     if ( ( dirac_output_synthesis_state->cy_cross_dir_smooth_prev = (float *) malloc( size * sizeof( float ) ) ) == NULL )
     183             :     {
     184           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     185             :     }
     186             : 
     187      165917 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     188             :     {
     189       61809 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev = NULL;
     190       61809 :         if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
     191             :         {
     192           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     193             :         }
     194             :     }
     195             :     else
     196             :     {
     197      104108 :         if ( ( dirac_output_synthesis_state->cy_auto_dir_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
     198             :         {
     199           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     200             :         }
     201             : 
     202      104108 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
     203             :         {
     204       28171 :             if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
     205             :             {
     206           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     207             :             }
     208             :         }
     209             :         else
     210             :         {
     211       75937 :             if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
     212             :             {
     213           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     214             :             }
     215             :         }
     216             :     }
     217             : 
     218             :     /* direct and diffuse gain buffers */
     219      165917 :     if ( ( dirac_output_synthesis_state->gains_dir_prev = (float *) malloc( size * sizeof( float ) ) ) == NULL )
     220             :     {
     221           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     222             :     }
     223             : 
     224      165917 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     225             :     {
     226       61809 :         if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
     227             :         {
     228           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     229             :         }
     230             :     }
     231      104108 :     else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD && hDirACRend->synthesisConf != DIRAC_SYNTHESIS_MONO )
     232             :     {
     233       70932 :         if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
     234             :         {
     235           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     236             :         }
     237             :     }
     238             :     else
     239             :     {
     240       33176 :         if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
     241             :         {
     242           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     243             :         }
     244             :     }
     245             : 
     246             :     /*-----------------------------------------------------------------*
     247             :      * prepare processing parameters
     248             :      *-----------------------------------------------------------------*/
     249             : 
     250             :     /* compute alpha */
     251      165917 :     if ( !( renderer_type == RENDERER_BINAURAL_PARAMETRIC || renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) )
     252             :     {
     253      104108 :         computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS, DIRAC_ALPHA_MAX, &dirac_output_synthesis_params->numAlphas, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis, output_Fs );
     254      104108 :         if ( ( dirac_output_synthesis_params->alpha_synthesis = (float *) malloc( dirac_output_synthesis_params->numAlphas * sizeof( float ) ) ) == NULL )
     255             :         {
     256           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     257             :         }
     258      104108 :         mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis, dirac_output_synthesis_params->numAlphas );
     259             : 
     260      104108 :         computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS_FAST, DIRAC_ALPHA_MAX_FAST, &dirac_output_synthesis_params->numAlphasFast, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis, output_Fs );
     261      104108 :         if ( ( dirac_output_synthesis_params->alpha_synthesis_fast = (float *) malloc( dirac_output_synthesis_params->numAlphasFast * sizeof( float ) ) ) == NULL )
     262             :         {
     263           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     264             :         }
     265      104108 :         mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis_fast, dirac_output_synthesis_params->numAlphasFast );
     266             : 
     267      104108 :         if ( ( dirac_output_synthesis_state->reference_power_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
     268             :         {
     269           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     270             :         }
     271      104108 :         if ( ( dirac_output_synthesis_state->direction_smoothness_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
     272             :         {
     273           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
     274             :         }
     275      104108 :         set_zero( dirac_output_synthesis_state->reference_power_smooth_prev, hSpatParamRendCom->num_freq_bands );
     276      104108 :         set_zero( dirac_output_synthesis_state->direction_smoothness_prev, hSpatParamRendCom->num_freq_bands );
     277             :     }
     278             :     else
     279             :     {
     280       61809 :         dirac_output_synthesis_params->alpha_synthesis = NULL;
     281       61809 :         dirac_output_synthesis_params->alpha_synthesis_fast = NULL;
     282       61809 :         dirac_output_synthesis_state->reference_power_smooth_prev = NULL;
     283       61809 :         dirac_output_synthesis_state->direction_smoothness_prev = NULL;
     284             :     }
     285             : 
     286             :     /* compute interpolator */
     287      829585 :     for ( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
     288             :     {
     289      663668 :         dirac_output_synthesis_params->interpolator[idx - 1] = (float) idx / (float) JBM_CLDFB_SLOTS_IN_SUBFRAME;
     290             :     }
     291             : 
     292             :     /* prepare diffuse response function */
     293      165917 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
     294             :     {
     295        5005 :         num_diffuse_responses = 2;
     296             :     }
     297             :     else
     298             :     {
     299      160912 :         num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
     300             :     }
     301             : 
     302      165917 :     if ( dirac_output_synthesis_state->diffuse_responses_square != NULL )
     303             :     {
     304      989461 :         for ( ch_idx = 0; ch_idx < num_diffuse_responses; ++ch_idx )
     305             :         {
     306             :             /*dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = pow(dirac_output_synthesis_params->diffuse_response_function[ch_idx]/max_response, 2.0f);*/
     307      885353 :             tmp = hDirACRend->diffuse_response_function[ch_idx];
     308             : 
     309      885353 :             dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = tmp * tmp;
     310             :         }
     311             :     }
     312             : 
     313      165917 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     314             :     {
     315             :         int16_t diff_compensation_order;
     316             :         float diff_nrg_total, diff_nrg, diff_nrg_trans, diff_nrg_decorr;
     317             : 
     318       61809 :         diff_compensation_order = nchan_transport >= 3 ? 3 : 2; /* compensate missing diffuseness modelling up order 2, except for HR*/
     319       61809 :         diff_compensation_order = min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
     320             : 
     321       61809 :         diff_nrg_total = 0;
     322       61809 :         diff_nrg_trans = 0;
     323       61809 :         diff_nrg_decorr = 0;
     324      936267 :         for ( ch_idx = 0; ch_idx < ( diff_compensation_order + 1 ) * ( diff_compensation_order + 1 ); ch_idx++ )
     325             :         {
     326      874458 :             diff_nrg = hDirACRend->diffuse_response_function[ch_idx] * hDirACRend->diffuse_response_function[ch_idx];
     327      874458 :             diff_nrg_total += diff_nrg;
     328             :             /* is it a transport channel?*/
     329      874458 :             if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
     330             :             {
     331      300534 :                 diff_nrg_trans += diff_nrg;
     332             :             }
     333             :             /* is it a decorrelated or transport channel?*/
     334      874458 :             if ( ch_idx < hDirACRend->num_outputs_diff )
     335             :             {
     336      247236 :                 diff_nrg_decorr += diff_nrg;
     337             :             }
     338             :         }
     339       61809 :         dirac_output_synthesis_params->diffuse_compensation_factor = diff_nrg_total / diff_nrg_trans;
     340       61809 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr = diff_nrg_total / diff_nrg_decorr;
     341             :     }
     342             :     else
     343             :     {
     344      104108 :         dirac_output_synthesis_params->diffuse_compensation_factor = 0.f;
     345      104108 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr = 0.f;
     346             :     }
     347             : 
     348      165917 :     return IVAS_ERR_OK;
     349             : }
     350             : 
     351             : 
     352             : /*-------------------------------------------------------------------------
     353             :  * ivas_dirac_dec_output_synthesis_init()
     354             :  *
     355             :  *
     356             :  *------------------------------------------------------------------------*/
     357             : 
     358      167980 : void ivas_dirac_dec_output_synthesis_init(
     359             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle         */
     360             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                       */
     361             :     const int16_t nchan_out_woLFE,                        /* i  : number of output audio channels without LFE */
     362             :     const int16_t hodirac_flag                            /* i  : flag to indicate HO-DirAC mode              */
     363             : )
     364             : {
     365             :     int16_t size;
     366             : 
     367             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
     368             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
     369             : 
     370      167980 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     371      167980 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     372             : 
     373             :     /*-----------------------------------------------------------------*
     374             :      * init outputSynthesisPSD_Init
     375             :      *-----------------------------------------------------------------*/
     376             : 
     377             :     /* initialize buffers */
     378      167980 :     if ( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev != NULL )
     379             :     {
     380      104168 :         set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
     381             :     }
     382             : 
     383      167980 :     if ( hodirac_flag )
     384             :     {
     385        9810 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
     386             :     }
     387             :     else
     388             :     {
     389      158170 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
     390             :     }
     391      167980 :     set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev, size );
     392             : 
     393      167980 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     394             :     {
     395       63812 :         set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff );
     396             :     }
     397      104168 :     else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
     398             :     {
     399       75997 :         set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff );
     400             :     }
     401             :     else
     402             :     {
     403       28171 :         set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
     404             :     }
     405             : 
     406      167980 :     if ( h_dirac_output_synthesis_state->proto_power_smooth_prev != NULL )
     407             :     {
     408      104168 :         set_zero( h_dirac_output_synthesis_state->proto_power_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir );
     409             :     }
     410      167980 :     set_zero( h_dirac_output_synthesis_state->gains_dir_prev, size );
     411             : 
     412      167980 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     413             :     {
     414       63812 :         set_zero( h_dirac_output_synthesis_state->gains_diff_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff );
     415             :     }
     416             :     else
     417             :     {
     418      104168 :         set_zero( h_dirac_output_synthesis_state->gains_diff_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
     419             :     }
     420             : 
     421      167980 :     if ( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev != NULL )
     422             :     {
     423       96109 :         set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
     424             :     }
     425             : 
     426      167980 :     return;
     427             : }
     428             : 
     429             : 
     430             : /*-------------------------------------------------------------------------
     431             :  * ivas_dirac_dec_output_synthesis_close()
     432             :  *
     433             :  * Memory deallocation of Output synthesis sub-module
     434             :  *------------------------------------------------------------------------*/
     435             : 
     436      165917 : void ivas_dirac_dec_output_synthesis_close(
     437             :     DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle                    */
     438             : )
     439             : {
     440             :     /* pointers to structs for allocation */
     441      165917 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     442      165917 :     DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     443             : 
     444             :     /*-----------------------------------------------------------------*
     445             :      * memory deallocation
     446             :      *-----------------------------------------------------------------*/
     447             : 
     448             :     /* free interpolator */
     449      165917 :     if ( ( dirac_output_synthesis_params )->interpolator != NULL )
     450             :     {
     451      165917 :         free( ( dirac_output_synthesis_params )->interpolator );
     452      165917 :         ( dirac_output_synthesis_params )->interpolator = NULL;
     453             :     }
     454             : 
     455             :     /* free alpha */
     456      165917 :     if ( ( dirac_output_synthesis_params )->alpha_synthesis != NULL )
     457             :     {
     458      104108 :         free( ( dirac_output_synthesis_params )->alpha_synthesis );
     459      104108 :         ( dirac_output_synthesis_params )->alpha_synthesis = NULL;
     460             :     }
     461      165917 :     if ( ( dirac_output_synthesis_params )->alpha_synthesis_fast != NULL )
     462             :     {
     463      104108 :         free( ( dirac_output_synthesis_params )->alpha_synthesis_fast );
     464      104108 :         ( dirac_output_synthesis_params )->alpha_synthesis_fast = NULL;
     465             :     }
     466             : 
     467      165917 :     if ( ( dirac_output_synthesis_state )->reference_power_smooth_prev != NULL )
     468             :     {
     469      104108 :         free( ( dirac_output_synthesis_state )->reference_power_smooth_prev );
     470      104108 :         ( dirac_output_synthesis_state )->reference_power_smooth_prev = NULL;
     471             :     }
     472             : 
     473      165917 :     if ( ( dirac_output_synthesis_state )->direction_smoothness_prev != NULL )
     474             :     {
     475      104108 :         free( ( dirac_output_synthesis_state )->direction_smoothness_prev );
     476      104108 :         ( dirac_output_synthesis_state )->direction_smoothness_prev = NULL;
     477             :     }
     478             : 
     479      165917 :     if ( ( dirac_output_synthesis_state )->diffuse_responses_square != NULL )
     480             :     {
     481      104108 :         free( ( dirac_output_synthesis_state )->diffuse_responses_square );
     482      104108 :         ( dirac_output_synthesis_state )->diffuse_responses_square = NULL;
     483             :     }
     484             : 
     485             :     /* free power buffers */
     486      165917 :     if ( ( dirac_output_synthesis_state )->proto_power_smooth_prev != NULL )
     487             :     {
     488      104108 :         free( ( dirac_output_synthesis_state )->proto_power_smooth_prev );
     489      104108 :         ( dirac_output_synthesis_state )->proto_power_smooth_prev = NULL;
     490             :     }
     491             : 
     492      165917 :     if ( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev != NULL )
     493             :     {
     494       96109 :         free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev );
     495       96109 :         ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev = NULL;
     496             :     }
     497             : 
     498             :     /* free target power buffers */
     499      165917 :     if ( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev != NULL )
     500             :     {
     501      104108 :         free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev );
     502      104108 :         ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev = NULL;
     503             :     }
     504      165917 :     if ( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev != NULL )
     505             :     {
     506      165917 :         free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev );
     507      165917 :         ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev = NULL;
     508             :     }
     509      165917 :     if ( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev != NULL )
     510             :     {
     511      165917 :         free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev );
     512      165917 :         ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev = NULL;
     513             :     }
     514             : 
     515             :     /* free gain buffers */
     516      165917 :     if ( ( dirac_output_synthesis_state )->gains_dir_prev != NULL )
     517             :     {
     518      165917 :         free( ( dirac_output_synthesis_state )->gains_dir_prev );
     519      165917 :         ( dirac_output_synthesis_state )->gains_dir_prev = NULL;
     520             :     }
     521      165917 :     if ( ( dirac_output_synthesis_state )->gains_diff_prev != NULL )
     522             :     {
     523      165917 :         free( ( dirac_output_synthesis_state )->gains_diff_prev );
     524      165917 :         ( dirac_output_synthesis_state )->gains_diff_prev = NULL;
     525             :     }
     526             : 
     527      165917 :     return;
     528             : }
     529             : 
     530             : 
     531             : /*-------------------------------------------------------------------------
     532             :  * ivas_dirac_dec_output_synthesis_process_slot()
     533             :  *
     534             :  *
     535             :  *------------------------------------------------------------------------*/
     536             : 
     537   137694504 : void ivas_dirac_dec_output_synthesis_process_slot(
     538             :     const float *reference_power, /* i  : Estimated power             */
     539             :     const float *onset,           /* i  : onset filter                */
     540             :     const int16_t *azimuth,
     541             :     const int16_t *elevation,
     542             :     const float *diffuseness,
     543             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle         */
     544             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                       */
     545             :     const VBAP_HANDLE hVBAPdata,                          /* i  : VBAP structure              */
     546             :     const IVAS_OUTPUT_SETUP hOutSetup,                    /* i  : output setup structure      */
     547             :     const int16_t nchan_transport,                        /* i  : number of transport channels*/
     548             :     const int16_t md_idx,
     549             :     const int16_t hodirac_flag, /* i  : flag to indicate HO-DirAC mode   */
     550             :     const int16_t dec_param_estim )
     551             : {
     552             :     int16_t num_freq_bands, num_channels_dir;
     553             :     int16_t num_freq_bands_diff, num_channels_diff;
     554             :     int16_t ch_idx;
     555             :     float aux_buf[CLDFB_NO_CHANNELS_MAX];
     556             :     int16_t diff_start_band;
     557             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
     558             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
     559             : 
     560   137694504 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     561   137694504 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     562             : 
     563   137694504 :     h_dirac_output_synthesis_state->onset_filter = onset;
     564             : 
     565             :     /*-----------------------------------------------------------------*
     566             :      * processing
     567             :      *-----------------------------------------------------------------*/
     568             : 
     569             :     /* collect some often used parameters */
     570   137694504 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
     571   137694504 :     num_channels_dir = hDirACRend->num_outputs_dir;
     572   137694504 :     num_channels_diff = hDirACRend->num_outputs_diff;
     573   137694504 :     num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
     574             : 
     575   137694504 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
     576             :     {
     577    58102824 :         num_channels_dir = hOutSetup.nchan_out_woLFE;
     578             :     }
     579             : 
     580   137694504 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD && hodirac_flag )
     581             :     {
     582     9727412 :         ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
     583             :                                                       hDirACRend,
     584             :                                                       hVBAPdata,
     585             :                                                       NULL,
     586             :                                                       NULL,
     587             :                                                       azimuth,
     588             :                                                       elevation,
     589             :                                                       md_idx,
     590             :                                                       NULL,
     591             :                                                       hodirac_flag );
     592             :     }
     593             : 
     594   137694504 :     if ( dec_param_estim == FALSE && hodirac_flag )
     595             :     {
     596     9727412 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     597             :         {
     598     9727412 :             v_multc( hSpatParamRendCom->energy_ratio1[md_idx], -1.f, aux_buf, num_freq_bands );
     599     9727412 :             v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
     600     9727412 :             mvr2r( hSpatParamRendCom->energy_ratio1[md_idx],
     601             :                    h_dirac_output_synthesis_state->direct_power_factor,
     602             :                    num_freq_bands );
     603     9727412 :             mvr2r( aux_buf,
     604             :                    h_dirac_output_synthesis_state->diffuse_power_factor,
     605             :                    num_freq_bands );
     606             : 
     607     9727412 :             v_multc( hSpatParamRendCom->energy_ratio2[md_idx], -1.f, aux_buf, num_freq_bands );
     608     9727412 :             v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
     609     9727412 :             mvr2r( hSpatParamRendCom->energy_ratio2[md_idx],
     610     9727412 :                    &h_dirac_output_synthesis_state->direct_power_factor[hSpatParamRendCom->num_freq_bands],
     611             :                    num_freq_bands );
     612     9727412 :             mvr2r( aux_buf,
     613     9727412 :                    &h_dirac_output_synthesis_state->diffuse_power_factor[hSpatParamRendCom->num_freq_bands],
     614             :                    num_freq_bands );
     615             :         }
     616             :         else
     617             :         {
     618           0 :             ivas_dirac_dec_compute_gain_factors( num_freq_bands,
     619           0 :                                                  hSpatParamRendCom->diffuseness_vector[md_idx],
     620           0 :                                                  h_dirac_output_synthesis_params->max_band_decorr,
     621             :                                                  h_dirac_output_synthesis_state->direct_power_factor,
     622             :                                                  h_dirac_output_synthesis_state->diffuse_power_factor );
     623             :         }
     624             :     }
     625   127967092 :     else if ( dec_param_estim == TRUE )
     626             :     {
     627             :         /* compute direct responses */
     628    42514324 :         ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
     629             :                                                       hDirACRend,
     630             :                                                       hVBAPdata,
     631             :                                                       NULL,
     632             :                                                       NULL,
     633             :                                                       azimuth,
     634             :                                                       elevation,
     635             :                                                       md_idx,
     636             :                                                       NULL,
     637             :                                                       hodirac_flag );
     638             : 
     639    42514324 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     640             :         {
     641    39606580 :             ivas_dirac_dec_compute_gain_factors( num_freq_bands,
     642             :                                                  diffuseness,
     643    39606580 :                                                  h_dirac_output_synthesis_params->max_band_decorr,
     644             :                                                  h_dirac_output_synthesis_state->direct_power_factor,
     645             :                                                  h_dirac_output_synthesis_state->diffuse_power_factor );
     646             : 
     647    39606580 :             v_multc( h_dirac_output_synthesis_state->direct_power_factor,
     648             :                      0.25f,
     649             :                      h_dirac_output_synthesis_state->direct_power_factor,
     650             :                      num_freq_bands );
     651    39606580 :             v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
     652             :                      0.25f,
     653             :                      h_dirac_output_synthesis_state->diffuse_power_factor,
     654             :                      num_freq_bands );
     655             : 
     656             :             /*Direct gain*/
     657   198032900 :             for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ )
     658             :             {
     659             :                 int16_t k;
     660   158426320 :                 if ( ch_idx != 0 )
     661             :                 {
     662             :                     float a, b, c;
     663             : 
     664             :                     /*Directonal sound gain nrg compensation*/
     665   712918440 :                     for ( k = 0; k < num_freq_bands_diff; k++ )
     666             :                     {
     667   594098700 :                         a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
     668   594098700 :                         b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
     669   594098700 :                         c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/
     670   594098700 :                         h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
     671             :                     }
     672  5059198440 :                     for ( ; k < num_freq_bands; k++ )
     673             :                     {
     674  4940378700 :                         a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
     675  4940378700 :                         b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
     676  4940378700 :                         c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/
     677  4940378700 :                         h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
     678             :                     }
     679             :                 }
     680             :                 else
     681             :                 {
     682             :                     /*Diffuseness modellling nrg compensation*/
     683   237639480 :                     for ( k = 0; k < num_freq_bands_diff; k++ )
     684             :                     {
     685   198032900 :                         h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) );
     686             :                     }
     687  1686399480 :                     for ( ; k < num_freq_bands; k++ )
     688             :                     {
     689  1646792900 :                         h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) );
     690             :                     }
     691             :                 }
     692             :             }
     693             : 
     694             :             /*Directional gain (panning)*/
     695   484801108 :             for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
     696             :             {
     697   445194528 :                 v_mult( h_dirac_output_synthesis_state->direct_power_factor,
     698   445194528 :                         &h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands],
     699             :                         aux_buf,
     700             :                         num_freq_bands );
     701             : 
     702   445194528 :                 v_add( aux_buf,
     703   445194528 :                        &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
     704   445194528 :                        &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
     705             :                        num_freq_bands );
     706             :             }
     707             : 
     708             :             /*Diffuse gain*/
     709    39606580 :             for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
     710             :             {
     711           0 :                 v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
     712           0 :                          hDirACRend->diffuse_response_function[ch_idx],
     713             :                          aux_buf,
     714             :                          num_freq_bands_diff );
     715             : 
     716           0 :                 v_add( aux_buf,
     717           0 :                        &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
     718           0 :                        &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
     719             :                        num_freq_bands_diff );
     720             :             }
     721             : 
     722    39606580 :             return;
     723             :         }
     724             :         else
     725             :         {
     726             :             /* compute reference and diffuse power factor for this frame */
     727     2907744 :             ivas_dirac_dec_compute_power_factors( num_freq_bands,
     728             :                                                   diffuseness,
     729     2907744 :                                                   h_dirac_output_synthesis_params->max_band_decorr,
     730             :                                                   h_dirac_output_synthesis_state->direct_power_factor,
     731             :                                                   h_dirac_output_synthesis_state->diffuse_power_factor );
     732             :         }
     733             :     }
     734             : 
     735    98087924 :     diff_start_band = 0;
     736    98087924 :     if ( h_dirac_output_synthesis_params->use_onset_filters )
     737             :     {
     738    55195080 :         computeTargetPSDs_diffuse_with_onsets( num_channels_dir,
     739    55195080 :                                                num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
     740    55195080 :                                                hDirACRend->proto_index_diff,
     741    55195080 :                                                h_dirac_output_synthesis_state->diffuse_power_factor,
     742             :                                                reference_power,
     743    55195080 :                                                h_dirac_output_synthesis_state->diffuse_responses_square,
     744             :                                                onset,
     745             :                                                h_dirac_output_synthesis_state->cy_auto_diff_smooth );
     746             : 
     747    55195080 :         diff_start_band = h_dirac_output_synthesis_params->max_band_decorr;
     748             :     }
     749             : 
     750             :     /* process other PSDs only slot wise for 4 transport channels */
     751    98087924 :     if ( dec_param_estim == TRUE )
     752             :     {
     753     2907744 :         computeTargetPSDs_direct( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor, reference_power, h_dirac_output_synthesis_state->direct_responses, h_dirac_output_synthesis_state->direct_responses_square, h_dirac_output_synthesis_state->cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth );
     754             : 
     755     2907744 :         computeTargetPSDs_diffuse( num_channels_dir, num_freq_bands, diff_start_band, h_dirac_output_synthesis_state->diffuse_power_factor, reference_power, h_dirac_output_synthesis_state->diffuse_responses_square, h_dirac_output_synthesis_state->cy_auto_diff_smooth );
     756             :     }
     757             : 
     758    98087924 :     return;
     759             : }
     760             : 
     761             : 
     762             : /*-------------------------------------------------------------------------
     763             :  * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
     764             :  *
     765             :  *
     766             :  *------------------------------------------------------------------------*/
     767             : 
     768    14971836 : void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
     769             :     float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
     770             :     float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
     771             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,                   /* i/o: common spatial renderer data handle         */
     772             :     DIRAC_REND_HANDLE hDirACRend,                                           /* i/o: DirAC renderer handle                       */
     773             :     const int16_t nchan_transport,                                          /* i  : number of transport channels                */
     774             :     const int16_t nbslots,                                                  /* i  : number of slots to process                  */
     775             :     const float *onset_filter,
     776             :     float *diffuseness,
     777             :     const int16_t hodirac_flag, /* i  : flag to indicate HO-DirAC mode */
     778             :     const int16_t dec_param_estim )
     779             : {
     780             :     int16_t buf_idx, ch_idx, i, l;
     781             :     int16_t num_freq_bands, num_freq_bands_diff;
     782             :     int16_t num_channels_dir, num_channels_diff;
     783             :     float g, g1, g2;
     784             :     float *p_gains_dir, *p_gains_diff;
     785             :     float *p_gains_dir_prev, *p_gains_diff_prev;
     786             :     float *p_cy_cross_dir_smooth;
     787             :     float *p_cy_auto_diff_smooth;
     788             :     float *p_proto, *p_out_real, *p_out_imag;
     789             :     float *p_proto_diff;
     790             :     int16_t *proto_direct_index, num_protos_dir;
     791             :     float output_real[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
     792             :     float output_imag[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
     793             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS h_dirac_output_synthesis_params;
     794             :     DIRAC_OUTPUT_SYNTHESIS_STATE h_dirac_output_synthesis_state;
     795             :     int16_t nchan_transport_foa;
     796             :     int16_t ch_idx_diff;
     797             :     float aux_buf[CLDFB_NO_CHANNELS_MAX];
     798             :     float ratio[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX];
     799             : 
     800             :     /* collect some often used parameters */
     801    14971836 :     h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
     802    14971836 :     h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
     803    14971836 :     proto_direct_index = hDirACRend->proto_index_dir;
     804             : 
     805    14971836 :     num_protos_dir = hDirACRend->num_protos_dir;
     806    14971836 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
     807    14971836 :     num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
     808    14971836 :     num_channels_dir = hDirACRend->num_outputs_dir;
     809    14971836 :     num_channels_diff = hDirACRend->num_outputs_diff;
     810    14971836 :     nchan_transport_foa = min( 4, nchan_transport );
     811             : 
     812             : 
     813             :     /*-----------------------------------------------------------------*
     814             :      * comput target Gains
     815             :      *-----------------------------------------------------------------*/
     816             : 
     817    14971836 :     if ( hodirac_flag )
     818             :     {
     819             :         /*Direct gain*/
     820    12196410 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     821             :         {
     822     9757128 :             v_multc( diffuseness,
     823             :                      1.f,
     824     9757128 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     825             :                      num_freq_bands );
     826     9757128 :             v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     827     9757128 :                      h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
     828     9757128 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     829             :                      num_freq_bands );
     830             : 
     831   530199208 :             for ( l = 0; l < num_freq_bands; l++ )
     832             :             {
     833   520442080 :                 h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] = sqrtf( 1.f + h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] );
     834             :             }
     835             :         }
     836             : 
     837             :         /*Directional gain*/
     838    29343658 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     839             :         {
     840  1461710936 :             for ( l = 0; l < num_freq_bands; l++ )
     841             :             {
     842  1434806560 :                 aux_buf[l] = 1.f - diffuseness[l];
     843  1434806560 :                 ratio[l] = 1.f - h_dirac_output_synthesis_state.direct_power_factor[hSpatParamRendCom->num_freq_bands + l];
     844  1434806560 :                 ratio[l + num_freq_bands] = 1.f - ratio[l];
     845             :             }
     846             : 
     847    26904376 :             v_mult( aux_buf, ratio, ratio, num_freq_bands );
     848    26904376 :             v_mult( aux_buf, &ratio[num_freq_bands], &ratio[num_freq_bands], num_freq_bands );
     849             : 
     850    26904376 :             v_mult( ratio,
     851    26904376 :                     &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
     852    26904376 :                     &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     853             :                     num_freq_bands );
     854    26904376 :             v_mult( &ratio[num_freq_bands],
     855    26904376 :                     &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
     856    26904376 :                     &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
     857             :                     num_freq_bands );
     858             :         }
     859             : 
     860             :         /*Diffuse gain*/
     861     2439282 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
     862             :         {
     863           0 :             v_multc( h_dirac_output_synthesis_state.diffuse_power_factor,
     864           0 :                      hDirACRend->diffuse_response_function[ch_idx],
     865           0 :                      &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
     866             :                      num_freq_bands_diff );
     867             :         }
     868             :     }
     869    12532554 :     else if ( dec_param_estim == FALSE )
     870             :     {
     871             :         /*Direct gain*/
     872     5165480 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     873             :         {
     874     2582740 :             v_mult( h_dirac_output_synthesis_state.diffuse_power_factor,
     875     2582740 :                     h_dirac_output_synthesis_state.diffuse_power_factor,
     876     2582740 :                     &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     877             :                     num_freq_bands );
     878     2582740 :             v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     879     2582740 :                      h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr - 1.f,
     880     2582740 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     881             :                      num_freq_bands_diff );
     882     2582740 :             v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
     883     2582740 :                      h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
     884     2582740 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
     885     2582740 :                      num_freq_bands - num_freq_bands_diff );
     886             : 
     887   110803480 :             for ( l = 0; l < num_freq_bands; l++ )
     888             :             {
     889   108220740 :                 h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] = sqrtf( 1.f + h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + l] );
     890             :             }
     891             :         }
     892             : 
     893             :         /*Directional gain*/
     894    24413714 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     895             :         {
     896    21830974 :             v_mult( h_dirac_output_synthesis_state.direct_power_factor,
     897    21830974 :                     &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
     898    21830974 :                     &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], num_freq_bands );
     899             :         }
     900             : 
     901             :         /*Diffuse gain*/
     902    10330960 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
     903             :         {
     904     7748220 :             v_multc( h_dirac_output_synthesis_state.diffuse_power_factor, hDirACRend->diffuse_response_function[ch_idx], &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff], num_freq_bands_diff );
     905             :         }
     906             :     }
     907             : 
     908             :     /*-----------------------------------------------------------------*
     909             :      * compute gains
     910             :      *-----------------------------------------------------------------*/
     911             : 
     912    14971836 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth;
     913    14971836 :     p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
     914             : 
     915             :     /* Direct gains */
     916    14971836 :     if ( hodirac_flag )
     917             :     {
     918    12196410 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     919             :         {
     920   530199208 :             for ( l = 0; l < num_freq_bands; l++ )
     921             :             {
     922   520442080 :                 g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     923   520442080 :                 g2 = ( 1.f - g1 ) * *( p_gains_dir );
     924   520442080 :                 g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     925   520442080 :                 g2 = max( g2, 0.99f );
     926   520442080 :                 g2 = min( g2, 2.0f );
     927   520442080 :                 *( p_gains_dir++ ) = g2;
     928             :             }
     929             :         }
     930             :     }
     931             :     else
     932             :     {
     933    54914550 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     934             :         {
     935  2004841536 :             for ( l = 0; l < num_freq_bands; l++ )
     936             :             {
     937  1962459540 :                 g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     938  1962459540 :                 g2 = ( 1.f - g1 ) * *( p_gains_dir );
     939  1962459540 :                 g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     940  1962459540 :                 g2 = max( g2, 0.85f );
     941  1962459540 :                 g2 = min( g2, 1.15f );
     942  1962459540 :                 *( p_gains_dir++ ) = g2;
     943             :             }
     944             :         }
     945             :     }
     946             : 
     947             :     /*Directional gains*/
     948   175583846 :     for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     949             :     {
     950  7729497450 :         for ( l = 0; l < num_freq_bands; l++ )
     951             :         {
     952  7568885440 :             g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     953  7568885440 :             g2 = ( 1.f - g1 ) * *( p_gains_dir );
     954  7568885440 :             g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     955  7568885440 :             g2 = max( g2, -DIRAC_GAIN_LIMIT );
     956  7568885440 :             g2 = min( g2, DIRAC_GAIN_LIMIT );
     957  7568885440 :             *( p_gains_dir++ ) = g2;
     958             :         }
     959             :     }
     960             : 
     961    14971836 :     if ( hodirac_flag )
     962             :     {
     963     2439282 :         p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth + num_freq_bands * num_channels_dir;
     964     2439282 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev + num_freq_bands * num_channels_dir;
     965             : 
     966             :         /*Direct gains*/
     967    12196410 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     968             :         {
     969   530199208 :             for ( l = 0; l < num_freq_bands; l++ )
     970             :             {
     971   520442080 :                 p_cy_cross_dir_smooth++;
     972   520442080 :                 p_gains_dir++;
     973             :             }
     974             :         }
     975             : 
     976             :         /*Directional gains*/
     977    29343658 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     978             :         {
     979  1461710936 :             for ( l = 0; l < num_freq_bands; l++ )
     980             :             {
     981  1434806560 :                 g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     982  1434806560 :                 g2 = ( 1.f - g1 ) * *( p_gains_dir );
     983  1434806560 :                 g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     984  1434806560 :                 g2 = max( g2, -DIRAC_GAIN_LIMIT );
     985  1434806560 :                 g2 = min( g2, DIRAC_GAIN_LIMIT );
     986  1434806560 :                 *( p_gains_dir++ ) = g2;
     987             :             }
     988             :         }
     989             :     }
     990             : 
     991             :     /*Diffuse gains*/
     992    14971836 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth + nchan_transport_foa * num_freq_bands_diff;
     993    14971836 :     p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
     994    22720056 :     for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
     995             :     {
     996   173534694 :         for ( l = 0; l < num_freq_bands_diff; l++ )
     997             :         {
     998   165786474 :             g1 = 0.1175f;
     999   165786474 :             g2 = ( 1.f - g1 ) * *( p_gains_diff );
    1000   165786474 :             g2 += g1 * ( *( p_cy_auto_diff_smooth++ ) );
    1001   165786474 :             g2 = max( g2, 0.f );
    1002   165786474 :             g2 = min( g2, DIRAC_GAIN_LIMIT );
    1003   165786474 :             *( p_gains_diff++ ) = g2;
    1004             :         }
    1005             :     }
    1006             : 
    1007             :     /*-----------------------------------------------------------------*
    1008             :      * gain interpolation and output streams
    1009             :      *-----------------------------------------------------------------*/
    1010             : 
    1011    74609263 :     for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    1012             :     {
    1013    59637427 :         g1 = h_dirac_output_synthesis_params.interpolator[buf_idx];
    1014    59637427 :         g2 = 1.f - g1;
    1015             : 
    1016             :         /*Direct input->output*/
    1017    59637427 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
    1018    59637427 :         p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev;
    1019   267276830 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1020             :         {
    1021   207639403 :             p_proto_diff = h_dirac_output_synthesis_state.proto_diffuse_buffer_f + buf_idx * 2 * num_freq_bands * num_channels_diff + ch_idx * 2 * num_freq_bands;
    1022 10092810543 :             for ( l = 0; l < num_freq_bands; l++ )
    1023             :             {
    1024  9885171140 :                 g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
    1025  9885171140 :                 output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
    1026  9885171140 :                 output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
    1027             :             }
    1028             :         }
    1029             : 
    1030             :         /*Directional stream*/
    1031   699334188 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1032             :         {
    1033   639696761 :             if ( hodirac_flag )
    1034             :             {
    1035   107260912 :                 if ( proto_direct_index[ch_idx] == 0 )
    1036             :                 {
    1037             :                     float *p_proto2;
    1038             :                     float gs1, gs2;
    1039    56386740 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1040    56386740 :                               buf_idx * 2 * num_freq_bands * num_protos_dir +
    1041    56386740 :                               proto_direct_index[0] * 2 * num_freq_bands;
    1042    56386740 :                     p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1043    56386740 :                                buf_idx * 2 * num_freq_bands * num_protos_dir +
    1044    56386740 :                                proto_direct_index[1] * 2 * num_freq_bands;
    1045  3002605540 :                     for ( l = 0; l < num_freq_bands; l++ )
    1046             :                     {
    1047  2946218800 :                         gs1 = g1 * ( *( p_gains_dir ) ) + g2 * ( *( p_gains_dir_prev ) );
    1048  2946218800 :                         gs2 = g1 * ( *( p_gains_dir + num_freq_bands * num_channels_dir ) ) + g2 * ( *( p_gains_dir_prev + num_freq_bands * num_channels_dir ) );
    1049  2946218800 :                         p_gains_dir++;
    1050  2946218800 :                         p_gains_dir_prev++;
    1051             : 
    1052  2946218800 :                         output_real[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) + /* s1 */
    1053  2946218800 :                                                                      0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) );  /* s2 */
    1054  2946218800 :                         p_proto++;
    1055  2946218800 :                         p_proto2++;
    1056  2946218800 :                         output_imag[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) +
    1057  2946218800 :                                                                      0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) );
    1058  2946218800 :                         p_proto++;
    1059  2946218800 :                         p_proto2++;
    1060             :                     }
    1061             :                 }
    1062             :                 else
    1063             :                 {
    1064    50874172 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1065    50874172 :                               buf_idx * 2 * num_freq_bands * num_protos_dir +
    1066    50874172 :                               proto_direct_index[ch_idx] * 2 * num_freq_bands;
    1067  2822486092 :                     for ( l = 0; l < num_freq_bands; l++ )
    1068             :                     {
    1069  2771611920 :                         p_gains_dir++;
    1070  2771611920 :                         p_gains_dir_prev++;
    1071             : 
    1072             : 
    1073  2771611920 :                         output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1074  2771611920 :                         output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1075             :                     }
    1076             :                 }
    1077             :             }
    1078             :             else
    1079             :             {
    1080   532435849 :                 p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1081   532435849 :                           buf_idx * 2 * num_freq_bands * num_protos_dir +
    1082   532435849 :                           proto_direct_index[ch_idx] * 2 * num_freq_bands;
    1083   532435849 :                 if ( proto_direct_index[ch_idx] == 0 )
    1084             :                 {
    1085 24234260837 :                     for ( l = 0; l < num_freq_bands; l++ )
    1086             :                     {
    1087 23715244700 :                         g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
    1088 23715244700 :                         output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
    1089 23715244700 :                         output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
    1090             :                     }
    1091             :                 }
    1092             :                 else
    1093             :                 {
    1094   716580032 :                     for ( l = 0; l < num_freq_bands; l++ )
    1095             :                     {
    1096   703160320 :                         p_gains_dir++;
    1097   703160320 :                         p_gains_dir_prev++;
    1098   703160320 :                         output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1099   703160320 :                         output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1100             :                     }
    1101             :                 }
    1102             :             }
    1103             :         }
    1104             : 
    1105             :         /*Diffuse stream*/
    1106    59637427 :         p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
    1107    59637427 :         p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev + nchan_transport_foa * num_freq_bands_diff;
    1108    59637427 :         ch_idx_diff = nchan_transport_foa;
    1109    90547732 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1110             :         {
    1111    30910305 :             if ( proto_direct_index[ch_idx] == 0 )
    1112             :             {
    1113    30910305 :                 p_proto = h_dirac_output_synthesis_state.proto_diffuse_buffer_f + buf_idx * 2 * num_freq_bands * num_channels_diff + ch_idx_diff * 2 * num_freq_bands;
    1114    30910305 :                 ch_idx_diff++;
    1115   692239551 :                 for ( l = 0; l < num_freq_bands_diff; l++ )
    1116             :                 {
    1117   661329246 :                     g = g1 * ( *( p_gains_diff++ ) ) + g2 * ( *( p_gains_diff_prev++ ) );
    1118   661329246 :                     output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */
    1119   661329246 :                     output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) );
    1120             :                 }
    1121             :             }
    1122             :             else
    1123             :             {
    1124           0 :                 for ( l = 0; l < num_freq_bands_diff; l++ )
    1125             :                 {
    1126           0 :                     p_gains_diff++;
    1127           0 :                     p_gains_diff_prev++;
    1128             :                 }
    1129             :             }
    1130             :         }
    1131             : 
    1132             :         /*-----------------------------------------------------------------*
    1133             :          * Copy output or HOA decoder
    1134             :          *-----------------------------------------------------------------*/
    1135             : 
    1136    59637427 :         if ( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
    1137    16261072 :         {
    1138             :             float *p_real, *p_imag;
    1139             :             const float *hoa_decoder;
    1140             : 
    1141    16261072 :             hoa_decoder = hDirACRend->hoa_decoder;
    1142             : 
    1143   154984480 :             for ( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
    1144             :             {
    1145   138723408 :                 p_real = RealBuffer[ch_idx][buf_idx];
    1146   138723408 :                 p_imag = ImagBuffer[ch_idx][buf_idx];
    1147             : 
    1148  6476265808 :                 for ( l = 0; l < num_freq_bands; l++ )
    1149             :                 {
    1150  6337542400 :                     p_out_real = output_real + l * num_channels_dir;
    1151  6337542400 :                     p_out_imag = output_imag + l * num_channels_dir;
    1152  6337542400 :                     p_real[l] = *( p_out_real++ ) * hoa_decoder[0];
    1153  6337542400 :                     p_imag[l] = *( p_out_imag++ ) * hoa_decoder[0];
    1154 >10140*10^7 :                     for ( i = 1; i < num_channels_dir; i++ )
    1155             :                     {
    1156 95063136000 :                         p_real[l] += *( p_out_real++ ) * hoa_decoder[i];
    1157 95063136000 :                         p_imag[l] += *( p_out_imag++ ) * hoa_decoder[i];
    1158             :                     }
    1159             :                 }
    1160   138723408 :                 hoa_decoder += 16;
    1161             :             }
    1162             :         }
    1163             :         else
    1164             :         {
    1165   630535367 :             for ( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
    1166             :             {
    1167 28803863172 :                 for ( l = 0; l < num_freq_bands; l++ )
    1168             :                 {
    1169 28216704160 :                     RealBuffer[ch_idx][buf_idx][l] = output_real[l * num_channels_dir + ch_idx];
    1170 28216704160 :                     ImagBuffer[ch_idx][buf_idx][l] = output_imag[l * num_channels_dir + ch_idx];
    1171             :                 }
    1172             :             }
    1173             :         }
    1174             :     }
    1175             : 
    1176             :     /*-----------------------------------------------------------------*
    1177             :      * update buffers
    1178             :      *-----------------------------------------------------------------*/
    1179             : 
    1180             :     /* store estimates for next synthesis block */
    1181    14971836 :     if ( hodirac_flag )
    1182             :     {
    1183     2439282 :         mvr2r( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev, num_freq_bands * num_channels_dir * DIRAC_HO_NUMSECTORS );
    1184             :     }
    1185             :     else
    1186             :     {
    1187    12532554 :         mvr2r( h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev, h_dirac_output_synthesis_state.gains_dir_prev, num_freq_bands * num_channels_dir );
    1188             :     }
    1189             : 
    1190    14971836 :     mvr2r( h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev, h_dirac_output_synthesis_state.gains_diff_prev, num_freq_bands_diff * num_channels_diff );
    1191             : 
    1192             :     /* reset values */
    1193    14971836 :     if ( hodirac_flag )
    1194             :     {
    1195     2439282 :         set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir * DIRAC_HO_NUMSECTORS );
    1196             :     }
    1197             :     else
    1198             :     {
    1199    12532554 :         set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir );
    1200             :     }
    1201             : 
    1202    14971836 :     set_zero( h_dirac_output_synthesis_state.cy_auto_diff_smooth, num_freq_bands_diff * num_channels_diff );
    1203             : 
    1204    14971836 :     return;
    1205             : }
    1206             : 
    1207             : 
    1208             : /*-------------------------------------------------------------------------
    1209             :  * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
    1210             :  *
    1211             :  *
    1212             :  *------------------------------------------------------------------------*/
    1213             : 
    1214    19595805 : void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
    1215             :     float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
    1216             :     float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i  : LS signals                                  */
    1217             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,                   /* i/o: common spatial renderer data handle         */
    1218             :     DIRAC_REND_HANDLE hDirACRend,                                           /* i/o: DirAC renderer handle                       */
    1219             :     const int16_t nbslots,                                                  /* i  : number of slots to process                  */
    1220             :     float *diffuseness_vector,
    1221             :     float *reference_power_smooth,
    1222             :     float qualityBasedSmFactor,
    1223             :     const int16_t enc_param_start_band )
    1224             : {
    1225             :     int16_t buf_idx, num_freq_bands;
    1226             :     int16_t diff_start_band;
    1227             :     int16_t k, l;
    1228             :     int16_t nchan_out_woLFE;
    1229             :     float *p_power_smooth_prev, *p_power_diff_smooth_prev;
    1230             :     float *p_gain_1, *p_gain_2;
    1231             :     float *p_power_smooth_diff, *p_power_smooth;
    1232             :     float *p_gains_dir, *p_gains_diff;
    1233             :     float g, g1, g2;
    1234             :     float *p_cy_auto_dir_smooth, *p_cy_auto_dir_smooth_prev;
    1235             :     float *p_cy_cross_dir_smooth, *p_cy_cross_dir_smooth_prev;
    1236             :     float *p_cy_auto_diff_smooth, *p_cy_auto_diff_smooth_prev;
    1237             :     float gains_dir[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1238             :     float gains_diff[CLDFB_NO_CHANNELS_MAX * MAX_OUTPUT_CHANNELS];
    1239             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
    1240             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
    1241             :     int16_t *proto_direct_index, num_protos_dir;
    1242             :     float target_power_y;
    1243             :     float subtract_power_y;
    1244             :     float subtract_target_ratio;
    1245             :     float subtract_target_ratio_db;
    1246             :     float a, b;
    1247             :     uint16_t nchan_target_psds;
    1248             :     float alpha[CLDFB_NO_CHANNELS_MAX];
    1249             :     float *alpha_synthesis;
    1250             :     float *alpha_synthesis_fast;
    1251             :     int16_t alphaMaxBin;
    1252             :     int16_t alphaMaxBinFast;
    1253             : 
    1254    19595805 :     push_wmops( "dirac_out_synth_sfr" );
    1255             : 
    1256    19595805 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
    1257    19595805 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
    1258    19595805 :     proto_direct_index = hDirACRend->proto_index_dir;
    1259    19595805 :     num_protos_dir = hDirACRend->num_protos_dir;
    1260    19595805 :     nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
    1261             : 
    1262             :     /* collect some often used parameters */
    1263    19595805 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
    1264             : 
    1265             :     /*-----------------------------------------------------------------*
    1266             :      * compute target PSDs
    1267             :      *-----------------------------------------------------------------*/
    1268             : 
    1269    19595805 :     if ( enc_param_start_band == 0 )
    1270             :     {
    1271    18868869 :         diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0;
    1272             : 
    1273    18868869 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
    1274             :         {
    1275     1188426 :             nchan_target_psds = 2;
    1276             :         }
    1277             :         else
    1278             :         {
    1279    17680443 :             nchan_target_psds = nchan_out_woLFE;
    1280             :         }
    1281             : 
    1282    18868869 :         computeTargetPSDs_direct_subframe( nchan_target_psds, num_freq_bands,
    1283    18868869 :                                            h_dirac_output_synthesis_state->direct_power_factor,
    1284             :                                            reference_power_smooth,
    1285    18868869 :                                            h_dirac_output_synthesis_state->direct_responses,
    1286    18868869 :                                            h_dirac_output_synthesis_state->direct_responses_square,
    1287             :                                            h_dirac_output_synthesis_state->cy_auto_dir_smooth,
    1288             :                                            h_dirac_output_synthesis_state->cy_cross_dir_smooth );
    1289             : 
    1290    18868869 :         computeTargetPSDs_diffuse_subframe( nchan_target_psds, num_freq_bands, diff_start_band,
    1291    18868869 :                                             h_dirac_output_synthesis_state->diffuse_power_factor,
    1292             :                                             reference_power_smooth,
    1293    18868869 :                                             h_dirac_output_synthesis_state->diffuse_responses_square,
    1294             :                                             h_dirac_output_synthesis_state->cy_auto_diff_smooth );
    1295             :     }
    1296             : 
    1297             :     /*-----------------------------------------------------------------*
    1298             :      * compute variables for stereo transport signal type detection
    1299             :      *-----------------------------------------------------------------*/
    1300             : 
    1301    19595805 :     if ( hDirACRend->masa_stereo_type_detect != NULL )
    1302             :     {
    1303     4050257 :         MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
    1304             : 
    1305     4050257 :         p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
    1306     4050257 :         p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
    1307     4050257 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
    1308             :         {
    1309     1188426 :             target_power_y = p_cy_auto_dir_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->direct_power_factor[0] ) + EPSILON );
    1310     1188426 :             target_power_y += p_cy_auto_diff_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->diffuse_power_factor[0] ) + EPSILON );
    1311             :         }
    1312             :         else
    1313             :         {
    1314     2861831 :             target_power_y = p_cy_auto_dir_smooth[num_freq_bands] + p_cy_auto_diff_smooth[num_freq_bands];
    1315             :         }
    1316     4050257 :         subtract_power_y = masa_stereo_type_detect->subtract_power_y;
    1317             : 
    1318     4050257 :         a = 0.0004f;  /* Temporal smoothing coefficient */
    1319     4050257 :         b = 1.0f - a; /* Temporal smoothing coefficient */
    1320             : 
    1321     4050257 :         masa_stereo_type_detect->target_power_y_smooth = a * target_power_y + b * masa_stereo_type_detect->target_power_y_smooth;
    1322     4050257 :         masa_stereo_type_detect->subtract_power_y_smooth = a * subtract_power_y + b * masa_stereo_type_detect->subtract_power_y_smooth;
    1323             : 
    1324     4050257 :         subtract_target_ratio = masa_stereo_type_detect->subtract_power_y_smooth / ( masa_stereo_type_detect->target_power_y_smooth + EPSILON );
    1325     4050257 :         subtract_target_ratio_db = 10.0f * log10f( subtract_target_ratio );
    1326     4050257 :         masa_stereo_type_detect->subtract_target_ratio_db = subtract_target_ratio_db;
    1327             : 
    1328     4050257 :         masa_stereo_type_detect->subtract_power_y = 0.0f;
    1329             :     }
    1330             : 
    1331             :     /*-----------------------------------------------------------------*
    1332             :      * compute smoothing coefficients
    1333             :      *-----------------------------------------------------------------*/
    1334             : 
    1335    19595805 :     alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis;
    1336    19595805 :     alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast;
    1337    19595805 :     alphaMaxBin = h_dirac_output_synthesis_params->numAlphas - 1;
    1338    19595805 :     alphaMaxBinFast = h_dirac_output_synthesis_params->numAlphasFast - 1;
    1339             : 
    1340   870401265 :     for ( l = 0; l < num_freq_bands; l++ )
    1341             :     {
    1342             :         float instDirectionSmoothness, weightedDirectionSmoothness, smoothedDirectionSmoothness;
    1343             :         float currWeight, prevWeight, sumWeight;
    1344             :         int16_t indexFast, indexSlow;
    1345   850805460 :         float alpha_quality_based = 0.02f;
    1346             : 
    1347   850805460 :         indexSlow = min( l, alphaMaxBin );
    1348   850805460 :         indexFast = min( l, alphaMaxBinFast );
    1349             : 
    1350             :         /* Estimate the smoothness of the directions based on the diffuseness parameter */
    1351   850805460 :         instDirectionSmoothness = 1.0f - diffuseness_vector[l];
    1352   850805460 :         instDirectionSmoothness = min( max( instDirectionSmoothness, 0.0f ), 1.0f );
    1353             : 
    1354             :         /* Average the direction smoothness parameter over time */
    1355   850805460 :         currWeight = DIRECTION_SMOOTHNESS_ALPHA * reference_power_smooth[l];
    1356   850805460 :         prevWeight = ( 1.0f - DIRECTION_SMOOTHNESS_ALPHA ) * h_dirac_output_synthesis_state->reference_power_smooth_prev[l];
    1357             : 
    1358   850805460 :         weightedDirectionSmoothness = currWeight * instDirectionSmoothness + prevWeight * h_dirac_output_synthesis_state->direction_smoothness_prev[l];
    1359   850805460 :         sumWeight = currWeight + prevWeight;
    1360   850805460 :         smoothedDirectionSmoothness = weightedDirectionSmoothness / ( sumWeight + EPSILON );
    1361             : 
    1362   850805460 :         h_dirac_output_synthesis_state->direction_smoothness_prev[l] = smoothedDirectionSmoothness;
    1363   850805460 :         h_dirac_output_synthesis_state->reference_power_smooth_prev[l] = sumWeight;
    1364             : 
    1365             :         /* Determine smoothing parameter for rendering. The smoother the directions, the less smoothing is required (i.e., faster smoothing can be used). */
    1366   850805460 :         alpha[l] = smoothedDirectionSmoothness * alpha_synthesis_fast[indexFast] + ( 1.0f - smoothedDirectionSmoothness ) * alpha_synthesis[indexSlow];
    1367             : 
    1368             :         /* Adjust smoothing parameter based on encoding quality */
    1369   850805460 :         alpha[l] = qualityBasedSmFactor * alpha[l] + ( 1.0f - qualityBasedSmFactor ) * alpha_quality_based;
    1370             :     }
    1371             : 
    1372             :     /*-----------------------------------------------------------------*
    1373             :      * compute gains
    1374             :      *-----------------------------------------------------------------*/
    1375             : 
    1376             :     /*Direct normalization gains on reduced number of protos*/
    1377    19595805 :     p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev;
    1378    19595805 :     p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth;
    1379             : 
    1380    64566397 :     for ( k = 0; k < num_protos_dir; k++ )
    1381             :     {
    1382  2044628152 :         for ( l = 0; l < num_freq_bands; l++ )
    1383             :         {
    1384  1999657560 :             g1 = alpha[l];
    1385  1999657560 :             g2 = ( 1.f - g1 );
    1386  1999657560 :             *p_power_smooth_prev = EPSILON + g2 * ( *p_power_smooth_prev );
    1387  1999657560 :             *( p_power_smooth_prev ) += g1 * ( *p_power_smooth );
    1388  1999657560 :             *( p_power_smooth++ ) = 1.f / ( *( p_power_smooth_prev++ ) );
    1389             :         }
    1390             :     }
    1391             : 
    1392             :     /*Direct gains and diffuse gains on number of output channels*/
    1393    19595805 :     p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev;
    1394    19595805 :     p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth;
    1395             : 
    1396    19595805 :     p_gains_diff = gains_diff;
    1397    19595805 :     p_gains_dir = gains_dir;
    1398             : 
    1399    19595805 :     p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
    1400    19595805 :     p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev;
    1401    19595805 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth;
    1402    19595805 :     p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev;
    1403             : 
    1404    19595805 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
    1405    19595805 :     p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev;
    1406   178707563 :     for ( k = 0; k < nchan_out_woLFE; k++ )
    1407             :     {
    1408   159111758 :         p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth + proto_direct_index[k] * num_freq_bands;
    1409  2432483318 :         for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    1410             :         {
    1411             :             /*Direct*/
    1412  2273371560 :             g1 = alpha[l];
    1413  2273371560 :             g2 = 1.f - g1;
    1414  2273371560 :             *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
    1415  2273371560 :             *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
    1416             : 
    1417  2273371560 :             *( p_gains_dir ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
    1418             : 
    1419  2273371560 :             if ( *( p_gains_dir ) < 0.f )
    1420             :             {
    1421           0 :                 *( p_gains_dir ) = 0.f;
    1422             :             }
    1423  2273371560 :             else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
    1424             :             {
    1425     5682256 :                 *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
    1426             :             }
    1427             : 
    1428  2273371560 :             if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    1429             :             {
    1430   228454511 :                 *( p_gains_dir ) *= -1.f;
    1431             :             }
    1432  2273371560 :             p_gains_dir++;
    1433             : 
    1434             :             /*diffuse*/
    1435  2273371560 :             *p_power_diff_smooth_prev = g1 * ( *p_power_smooth_diff++ ) + g2 * ( *p_power_diff_smooth_prev ) + EPSILON;
    1436  2273371560 :             *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
    1437             : 
    1438  2273371560 :             *( p_gains_diff ) = sqrtf( *( p_cy_auto_diff_smooth_prev++ ) / ( *( p_power_diff_smooth_prev++ ) ) );
    1439             : 
    1440  2273371560 :             if ( *( p_gains_diff ) < 0.f )
    1441             :             {
    1442           0 :                 *( p_gains_diff ) = 0.f;
    1443             :             }
    1444  2273371560 :             else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
    1445             :             {
    1446    56938959 :                 *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
    1447             :             }
    1448  2273371560 :             p_gains_diff++;
    1449             :         }
    1450             : 
    1451             :         /*Only direct prototype*/
    1452  4722906078 :         for ( ; l < num_freq_bands; l++ )
    1453             :         {
    1454             :             /*Direct*/
    1455  4563794320 :             g1 = alpha[l];
    1456  4563794320 :             g2 = 1.f - g1;
    1457  4563794320 :             *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
    1458  4563794320 :             *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
    1459             : 
    1460  4563794320 :             *( p_gains_dir ) = sqrtf( *( p_power_smooth ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
    1461             : 
    1462  4563794320 :             if ( *( p_gains_dir ) < 0.f )
    1463             :             {
    1464           0 :                 *( p_gains_dir ) = 0.f;
    1465             :             }
    1466  4563794320 :             else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
    1467             :             {
    1468    11767129 :                 *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
    1469             :             }
    1470             : 
    1471  4563794320 :             if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    1472             :             {
    1473   444695802 :                 *( p_gains_dir ) *= -1.f;
    1474             :             }
    1475  4563794320 :             p_gains_dir++;
    1476             : 
    1477             :             /*diffuse*/
    1478  4563794320 :             *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
    1479  4563794320 :             *( p_gains_diff ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_diff_smooth_prev++ ) ) );
    1480  4563794320 :             if ( *( p_gains_diff ) < 0.f )
    1481             :             {
    1482           0 :                 *( p_gains_diff ) = 0.f;
    1483             :             }
    1484  4563794320 :             else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
    1485             :             {
    1486    14912871 :                 *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
    1487             :             }
    1488  4563794320 :             p_gains_diff++;
    1489             :         }
    1490             :     }
    1491             : 
    1492             :     /*-----------------------------------------------------------------*
    1493             :      * gain interpolation and output streams
    1494             :      *-----------------------------------------------------------------*/
    1495             : 
    1496    97652882 :     for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    1497             :     {
    1498    78057077 :         g1 = h_dirac_output_synthesis_params->interpolator[buf_idx];
    1499    78057077 :         g2 = 1.f - g1;
    1500             : 
    1501             :         /*Direct stream*/
    1502    78057077 :         p_gain_1 = gains_dir;
    1503    78057077 :         p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev;
    1504   713042145 :         for ( k = 0; k < nchan_out_woLFE; k++ )
    1505             :         {
    1506   634985068 :             p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f + buf_idx * 2 * num_freq_bands * num_protos_dir + proto_direct_index[k] * 2 * num_freq_bands;
    1507 27901800268 :             for ( l = 0; l < num_freq_bands; l++ )
    1508             :             {
    1509 27266815200 :                 g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
    1510 27266815200 :                 RealBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
    1511 27266815200 :                 ImagBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
    1512             :             }
    1513             :         }
    1514             : 
    1515             :         /*Diffuse stream*/
    1516    78057077 :         if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
    1517             :         {
    1518    70450993 :             p_power_smooth_diff = h_dirac_output_synthesis_state->proto_diffuse_buffer_f + buf_idx * 2 * h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE;
    1519             :         }
    1520    78057077 :         p_gain_1 = gains_diff;
    1521    78057077 :         p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev;
    1522   713042145 :         for ( k = 0; k < nchan_out_woLFE; k++ )
    1523             :         {
    1524  9707372308 :             for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    1525             :             {
    1526  9072387240 :                 g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
    1527  9072387240 :                 RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
    1528  9072387240 :                 ImagBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
    1529             :             }
    1530             : 
    1531             :             /*Direct proto*/
    1532   634985068 :             p_power_smooth = h_dirac_output_synthesis_state->proto_direct_buffer_f + buf_idx * 2 * num_freq_bands * num_protos_dir + proto_direct_index[k] * 2 * num_freq_bands + 2 * h_dirac_output_synthesis_params->max_band_decorr;
    1533 18829413028 :             for ( ; l < num_freq_bands; l++ )
    1534             :             {
    1535 18194427960 :                 g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
    1536 18194427960 :                 RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth++ ) );
    1537 18194427960 :                 ImagBuffer[k][buf_idx][l] += g * ( *( p_power_smooth++ ) );
    1538             :             }
    1539             :         }
    1540             :     }
    1541             : 
    1542             :     /*-----------------------------------------------------------------*
    1543             :      * update buffers
    1544             :      *-----------------------------------------------------------------*/
    1545             : 
    1546             :     /* store estimates for next synthesis block */
    1547    19595805 :     mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE );
    1548    19595805 :     mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE );
    1549             : 
    1550             :     /* reset values */
    1551    19595805 :     set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir );
    1552             : 
    1553    19595805 :     if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL )
    1554             :     {
    1555    19595805 :         set_zero( h_dirac_output_synthesis_state->proto_power_diff_smooth, h_dirac_output_synthesis_params->max_band_decorr * nchan_out_woLFE );
    1556             :     }
    1557             : 
    1558    19595805 :     set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE );
    1559    19595805 :     set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE );
    1560    19595805 :     set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE );
    1561             : 
    1562    19595805 :     pop_wmops();
    1563             : 
    1564    19595805 :     return;
    1565             : }
    1566             : 
    1567             : 
    1568             : /*-------------------------------------------------------------------------
    1569             :  * ivas_dirac_dec_compute_directional_responses()
    1570             :  *
    1571             :  *
    1572             :  *------------------------------------------------------------------------*/
    1573             : 
    1574    76132627 : void ivas_dirac_dec_compute_directional_responses(
    1575             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle                            */
    1576             :     DIRAC_REND_HANDLE hDirACRend,                         /* i/o: DirAC renderer handle                                          */
    1577             :     const VBAP_HANDLE hVBAPdata,                          /* i  : VBAP structure                                                 */
    1578             :     const int16_t *masa_band_mapping,                     /* i  : Band mapping for MASA, NULL assumes not using MASA in any form */
    1579             :     MASA_ISM_DATA_HANDLE hMasaIsm,                        /* i  : MASA_ISM data structure                                        */
    1580             :     const int16_t *azimuth,
    1581             :     const int16_t *elevation,
    1582             :     const int16_t md_idx,
    1583             :     const float *surCohRatio,
    1584             :     const int16_t hodirac_flag /* i  : flag to indicate HO-DirAC mode */
    1585             : )
    1586             : {
    1587             :     int16_t k, l;
    1588             :     int16_t num_channels_dir;
    1589             :     float direct_response_hoa[MAX_OUTPUT_CHANNELS]; /*  number of output channels (HOA 3rd order) -> 16 */
    1590             :     float direct_response_ls[MAX_OUTPUT_CHANNELS];
    1591             :     float direct_response_square[MAX_OUTPUT_CHANNELS];
    1592             :     float *direct_response;
    1593             :     const int16_t *azimuth2, *elevation2;
    1594             :     float direct_response_dir2[MAX_OUTPUT_CHANNELS];
    1595             :     float directRatio[MASA_MAXIMUM_DIRECTIONS];
    1596             :     float totalDirect;
    1597             :     int16_t codingBand;
    1598             :     int16_t dipole_freq_range[2];
    1599             :     MASA_TRANSPORT_SIGNAL_TYPE transport_signal_type;
    1600             : 
    1601    76132627 :     azimuth2 = NULL;
    1602    76132627 :     elevation2 = NULL;
    1603    76132627 :     transport_signal_type = MASA_STEREO_NOT_DEFINED;
    1604             : 
    1605    76132627 :     if ( hDirACRend->masa_stereo_type_detect != NULL )
    1606             :     {
    1607     4050257 :         dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
    1608     4050257 :         dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
    1609     4050257 :         transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
    1610             :     }
    1611             : 
    1612    76132627 :     num_channels_dir = hDirACRend->num_outputs_dir;
    1613    76132627 :     if ( hSpatParamRendCom->numParametricDirections == 2 )
    1614             :     {
    1615    20137449 :         azimuth2 = hSpatParamRendCom->azimuth2[md_idx];
    1616    20137449 :         elevation2 = hSpatParamRendCom->elevation2[md_idx];
    1617             :     }
    1618             : 
    1619    76132627 :     codingBand = -1;
    1620             : 
    1621    76132627 :     assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
    1622             : 
    1623  3640630747 :     for ( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
    1624             :     {
    1625  3564498120 :         if ( masa_band_mapping != NULL && k == MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] )
    1626             :         {
    1627   400364782 :             codingBand++;
    1628             :         }
    1629             : 
    1630  3564498120 :         if ( masa_band_mapping != NULL && k > MASA_band_grouping_24[masa_band_mapping[codingBand]] &&
    1631   521369258 :              k < MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] &&
    1632   521369258 :              k != hDirACRend->h_output_synthesis_psd_params.max_band_decorr )
    1633             :         {
    1634             :             /* 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 */
    1635   518925242 :             if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
    1636             :             {
    1637   465156728 :                 mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k - 1],
    1638   465156728 :                            hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k],
    1639   465156728 :                            hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1640             :             }
    1641   518925242 :             mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses[k - 1],
    1642   518925242 :                        hSpatParamRendCom->num_freq_bands,
    1643   518925242 :                        &hDirACRend->h_output_synthesis_psd_state.direct_responses[k],
    1644   518925242 :                        hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1645             :         }
    1646             :         else
    1647             :         {
    1648             :             /* HOA3 PANNING */
    1649  3045572878 :             if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 )
    1650             :             {
    1651  2636956176 :                 set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS );
    1652  2636956176 :                 set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS );
    1653             : 
    1654  2636956176 :                 ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order );
    1655             : 
    1656  2636956176 :                 if ( hodirac_flag )
    1657             :                 {
    1658   648769640 :                     ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order );
    1659             :                 }
    1660             : 
    1661  2636956176 :                 if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
    1662             :                 {
    1663  2493595440 :                     mvr2r_inc( direct_response_hoa, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1664             : 
    1665  2493595440 :                     if ( hodirac_flag )
    1666             :                     {
    1667   648769640 :                         mvr2r_inc( direct_response_dir2, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1668             :                     }
    1669             :                 }
    1670   143360736 :                 else if ( ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( masa_band_mapping != NULL ) ) ||
    1671    88908510 :                           hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
    1672             :                 {
    1673             :                     /* Synthesize the first direction */
    1674   143360736 :                     spreadCoherencePanningHoa( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_hoa, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
    1675             : 
    1676             :                     /* Synthesize the second direction and combine the gains */
    1677   143360736 :                     if ( hSpatParamRendCom->numParametricDirections == 2 )
    1678             :                     {
    1679    61378107 :                         spreadCoherencePanningHoa( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
    1680             :                         /* Combine gains from the two directions */
    1681    61378107 :                         totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
    1682    61378107 :                         directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
    1683    61378107 :                         directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
    1684   584132736 :                         for ( l = 0; l < num_channels_dir; l++ )
    1685             :                         {
    1686   522754629 :                             direct_response_hoa[l] *= directRatio[0];
    1687   522754629 :                             direct_response_hoa[l] += directRatio[1] * direct_response_dir2[l];
    1688             :                         }
    1689             :                     }
    1690             : 
    1691   143360736 :                     if ( hSpatParamRendCom->numIsmDirections > 0 )
    1692             :                     {
    1693             :                         int16_t dir;
    1694             :                         float direct_response_temp[MAX_OUTPUT_CHANNELS];
    1695             :                         float direct_response_ism[MAX_OUTPUT_CHANNELS];
    1696             :                         float masaDirect;
    1697             :                         float ismDirect;
    1698             : 
    1699     1140819 :                         set_zero( direct_response_ism, num_channels_dir );
    1700             : 
    1701     5561535 :                         for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1702             :                         {
    1703     4420716 :                             if ( hMasaIsm->ism_dir_is_edited[dir] )
    1704             :                             {
    1705           0 :                                 ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], direct_response_temp, hDirACRend->hOutSetup.ambisonics_order );
    1706             :                             }
    1707             :                             else
    1708             :                             {
    1709     4420716 :                                 ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], direct_response_temp, hDirACRend->hOutSetup.ambisonics_order );
    1710             :                             }
    1711             : 
    1712    45458268 :                             for ( l = 0; l < num_channels_dir; l++ )
    1713             :                             {
    1714    41037552 :                                 direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1715             :                             }
    1716             :                         }
    1717             : 
    1718     1140819 :                         masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
    1719     1140819 :                         if ( hSpatParamRendCom->numParametricDirections == 2 )
    1720             :                         {
    1721       86943 :                             masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
    1722             :                         }
    1723             : 
    1724     1140819 :                         ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
    1725     4420716 :                         for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1726             :                         {
    1727     3279897 :                             ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1728             :                         }
    1729             : 
    1730     1140819 :                         totalDirect = masaDirect + ismDirect;
    1731     1140819 :                         directRatio[0] = masaDirect / totalDirect;
    1732     1140819 :                         directRatio[1] = ismDirect / totalDirect;
    1733    11744727 :                         for ( l = 0; l < num_channels_dir; l++ )
    1734             :                         {
    1735    10603908 :                             direct_response_hoa[l] *= directRatio[0];
    1736    10603908 :                             direct_response_hoa[l] += directRatio[1] * direct_response_ism[l];
    1737             :                         }
    1738             :                     }
    1739             : 
    1740             :                     /* Synthesize surrounding coherence */
    1741   143360736 :                     if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
    1742             :                     {
    1743   774782082 :                         for ( l = 1; l < num_channels_dir; l++ )
    1744             :                         {
    1745   683304723 :                             direct_response_hoa[l] *= sqrtf( 1.0f - surCohRatio[k] );
    1746             :                         }
    1747             :                     }
    1748             : 
    1749             :                     /* Set computed gains */
    1750   143360736 :                     direct_response = direct_response_hoa;
    1751   143360736 :                     if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
    1752             :                     {
    1753    88908510 :                         v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
    1754    88908510 :                         mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1755             : 
    1756    88908510 :                         if ( transport_signal_type == MASA_STEREO_SPACED_MICS )
    1757             :                         {
    1758    37730855 :                             direct_response[0] = 1.0f;
    1759    37730855 :                             if ( k >= dipole_freq_range[0] && k < dipole_freq_range[1] )
    1760             :                             {
    1761     3470606 :                                 direct_response[1] = 1.0f;
    1762             :                             }
    1763             :                         }
    1764             :                         else
    1765             :                         {
    1766    51177655 :                             set_f( direct_response, 1.0f, hDirACRend->num_protos_ambi );
    1767             :                         }
    1768             :                     }
    1769             : 
    1770   143360736 :                     mvr2r_inc( direct_response, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1771             :                 }
    1772             :                 else
    1773             :                 {
    1774           0 :                     assert( 0 && "Not supported synthesis method!" );
    1775             :                 }
    1776             :             }
    1777   408616702 :             else if ( hDirACRend->panningConf == DIRAC_PANNING_VBAP ) /*VBAP*/
    1778             :             {
    1779             :                 /* Synthesize the first direction */
    1780   408616702 :                 spreadCoherencePanningVbap( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata );
    1781   408616702 :                 normalizePanningGains( direct_response_ls, num_channels_dir );
    1782             : 
    1783             :                 /* Synthesize the second direction and combine the gains */
    1784   408616702 :                 if ( hSpatParamRendCom->numParametricDirections == 2 )
    1785             :                 {
    1786   111828292 :                     spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata );
    1787   111828292 :                     normalizePanningGains( direct_response_dir2, num_channels_dir );
    1788             : 
    1789             :                     /* Combine gains from the two directions */
    1790   111828292 :                     totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
    1791   111828292 :                     directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
    1792   111828292 :                     directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
    1793  1087321898 :                     for ( l = 0; l < num_channels_dir; l++ )
    1794             :                     {
    1795   975493606 :                         direct_response_ls[l] *= directRatio[0];
    1796   975493606 :                         direct_response_ls[l] += directRatio[1] * direct_response_dir2[l];
    1797             :                     }
    1798   111828292 :                     normalizePanningGains( direct_response_ls, num_channels_dir );
    1799             :                 }
    1800             : 
    1801   408616702 :                 if ( hSpatParamRendCom->numIsmDirections > 0 )
    1802             :                 {
    1803             :                     int16_t dir;
    1804             :                     float direct_response_temp[MAX_OUTPUT_CHANNELS];
    1805             :                     float direct_response_ism[MAX_OUTPUT_CHANNELS];
    1806             :                     float masaDirect;
    1807             :                     float ismDirect;
    1808             : 
    1809     1349869 :                     set_zero( direct_response_ism, num_channels_dir );
    1810             : 
    1811     5363421 :                     for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1812             :                     {
    1813     4013552 :                         if ( hMasaIsm->ism_dir_is_edited[dir] )
    1814             :                         {
    1815           0 :                             vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 );
    1816             :                         }
    1817             :                         else
    1818             :                         {
    1819     4013552 :                             vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
    1820             :                         }
    1821             : 
    1822    37160224 :                         for ( l = 0; l < num_channels_dir; l++ )
    1823             :                         {
    1824    33146672 :                             direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1825             :                         }
    1826             :                     }
    1827     1349869 :                     normalizePanningGains( direct_response_ism, num_channels_dir );
    1828             : 
    1829     1349869 :                     masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
    1830     1349869 :                     if ( hSpatParamRendCom->numParametricDirections == 2 )
    1831             :                     {
    1832      347652 :                         masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
    1833             :                     }
    1834             : 
    1835     1349869 :                     ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
    1836     4013552 :                     for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1837             :                     {
    1838     2663683 :                         ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1839             :                     }
    1840             : 
    1841     1349869 :                     totalDirect = masaDirect + ismDirect;
    1842     1349869 :                     directRatio[0] = masaDirect / totalDirect;
    1843     1349869 :                     directRatio[1] = ismDirect / totalDirect;
    1844    12451208 :                     for ( l = 0; l < num_channels_dir; l++ )
    1845             :                     {
    1846    11101339 :                         direct_response_ls[l] *= directRatio[0];
    1847    11101339 :                         direct_response_ls[l] += directRatio[1] * direct_response_ism[l];
    1848             :                     }
    1849     1349869 :                     normalizePanningGains( direct_response_ls, num_channels_dir );
    1850             :                 }
    1851             : 
    1852             :                 /* Synthesize surrounding coherence */
    1853   408616702 :                 if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
    1854             :                 {
    1855             :                     int16_t num_channels_surrCoh;
    1856             : 
    1857   165563231 :                     num_channels_surrCoh = num_channels_dir;
    1858   165563231 :                     num_channels_surrCoh -= hDirACRend->num_ele_spk_no_diffuse_rendering;
    1859             : 
    1860  1592935500 :                     for ( l = 0; l < num_channels_dir; l++ )
    1861             :                     {
    1862  1427372269 :                         direct_response_ls[l] *= sqrtf( 1.0f - surCohRatio[k] );
    1863  1427372269 :                         if ( hDirACRend->diffuse_response_function[l] > 0.f )
    1864             :                         {
    1865  1426904349 :                             direct_response_ls[l] += sqrtf( surCohRatio[k] / (float) num_channels_surrCoh );
    1866             :                         }
    1867             :                     }
    1868             :                 }
    1869             : 
    1870   408616702 :                 normalizePanningGains( direct_response_ls, num_channels_dir );
    1871             : 
    1872             :                 /* Set computed gains */
    1873   408616702 :                 direct_response = direct_response_ls;
    1874   408616702 :                 v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
    1875   408616702 :                 mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1876   408616702 :                 mvr2r_inc( direct_response, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1877             :             }
    1878             :             else
    1879             :             {
    1880           0 :                 assert( 0 && "Not supported panning method!" );
    1881             :             }
    1882             :         }
    1883             :     }
    1884             : 
    1885    76132627 :     return;
    1886             : }
    1887             : 
    1888             : 
    1889             : /*-------------------------------------------------------------------------
    1890             :  * ivas_dirac_dec_compute_gain_factors()
    1891             :  *
    1892             :  *
    1893             :  *------------------------------------------------------------------------*/
    1894             : 
    1895    44628602 : void ivas_dirac_dec_compute_gain_factors(
    1896             :     const int16_t num_freq_bands,
    1897             :     const float *diffuseness,
    1898             :     const int16_t max_band_decorr,
    1899             :     float *direct_gain_factor,
    1900             :     float *diffuse_gain_factor )
    1901             : {
    1902             :     int16_t i;
    1903             : 
    1904   310120070 :     for ( i = 0; i < max_band_decorr; i++ )
    1905             :     {
    1906   265491468 :         direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
    1907   265491468 :         diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
    1908             :     }
    1909  1862294194 :     for ( ; i < num_freq_bands; i++ )
    1910             :     {
    1911  1817665592 :         direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
    1912  1817665592 :         diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
    1913             :     }
    1914             : 
    1915    44628602 :     return;
    1916             : }
    1917             : 
    1918             : 
    1919             : /*-------------------------------------------------------------------------
    1920             :  * ivas_dirac_dec_compute_power_factors()
    1921             :  *
    1922             :  *
    1923             :  *------------------------------------------------------------------------*/
    1924             : 
    1925    21776613 : void ivas_dirac_dec_compute_power_factors(
    1926             :     const int16_t num_freq_bands,
    1927             :     const float *diffuseness,
    1928             :     const int16_t max_band_decorr,
    1929             :     float *direct_power_factor,
    1930             :     float *diffuse_power_factor )
    1931             : {
    1932    21776613 :     v_multc( diffuseness, -1.0f, direct_power_factor, num_freq_bands );
    1933             : 
    1934    21776613 :     v_addc( direct_power_factor, 1.0f, direct_power_factor, num_freq_bands );
    1935             : 
    1936    21776613 :     mvr2r( diffuseness, diffuse_power_factor, num_freq_bands );
    1937             : 
    1938    21776613 :     v_mult( &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], &direct_power_factor[max_band_decorr], num_freq_bands - max_band_decorr );
    1939             : 
    1940    21776613 :     v_mult( &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], &diffuse_power_factor[max_band_decorr], num_freq_bands - max_band_decorr );
    1941             : 
    1942    21776613 :     return;
    1943             : }
    1944             : 
    1945             : 
    1946             : /*-------------------------------------------------------------------------
    1947             :  * ivas_lfe_synth_with_filters()
    1948             :  *
    1949             :  *
    1950             :  *------------------------------------------------------------------------*/
    1951             : 
    1952       42481 : void ivas_lfe_synth_with_filters(
    1953             :     MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, /* i/o: LFE synthesis structure for McMASA  */
    1954             :     float *data_f[],                            /* o  : output signals                      */
    1955             :     const int16_t output_frame,                 /* i  : output frame length per channel     */
    1956             :     const int16_t separateChannelIndex,         /* i  : separate channel index              */
    1957             :     const int16_t lfeChannelIndex               /* i  : LFE channel index                   */
    1958             : )
    1959             : {
    1960             :     float lowpassCoef;
    1961             :     int16_t i, j;
    1962             :     float lowPassSignal[L_FRAME48k];
    1963             :     float highPassSignal[L_FRAME48k];
    1964             :     int16_t slot_index;
    1965             :     int16_t subframe_index;
    1966             :     int16_t slotSize;
    1967             :     float transportEne, targetEneLfe, targetEneTrans;
    1968             :     int16_t mrange[2];
    1969             :     float lfeGain;
    1970             :     float transportGain;
    1971             :     int16_t delay;
    1972             : 
    1973             :     /* Delay the separated channel to sync the LFE synthesis with the DirAC rendering */
    1974       42481 :     delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
    1975       42481 :     delay_signal( data_f[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncDirAC, delay );
    1976             : 
    1977             :     /* Filterbank for dividing the separated channel to LFE frequencies and higher frequencies */
    1978       42481 :     lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize );
    1979    37025841 :     for ( i = 0; i < output_frame; i++ )
    1980             :     {
    1981    36983360 :         hMasaLfeSynth->lowpassSum += lowpassCoef * data_f[separateChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer];
    1982    36983360 :         lowPassSignal[i] = hMasaLfeSynth->lowpassSum;
    1983    36983360 :         highPassSignal[i] = hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferHiPointer] - lowPassSignal[i];
    1984    36983360 :         hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer] = data_f[separateChannelIndex][i];
    1985             : 
    1986    36983360 :         hMasaLfeSynth->ringBufferLoPointer--;
    1987    36983360 :         if ( hMasaLfeSynth->ringBufferLoPointer < 0 )
    1988             :         {
    1989      169924 :             hMasaLfeSynth->ringBufferLoPointer = hMasaLfeSynth->ringBufferSize - 1;
    1990             :         }
    1991             : 
    1992    36983360 :         hMasaLfeSynth->ringBufferHiPointer--;
    1993    36983360 :         if ( hMasaLfeSynth->ringBufferHiPointer < 0 )
    1994             :         {
    1995      169924 :             hMasaLfeSynth->ringBufferHiPointer = hMasaLfeSynth->ringBufferSize - 1;
    1996             :         }
    1997             :     }
    1998             : 
    1999             :     /* Synthesize the LFE signal */
    2000       42481 :     slotSize = output_frame / CLDFB_NO_COL_MAX;
    2001      722177 :     for ( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
    2002             :     {
    2003      679696 :         subframe_index = slot_index / 4;
    2004             : 
    2005      679696 :         mrange[0] = slot_index * slotSize;
    2006      679696 :         mrange[1] = ( slot_index + 1 ) * slotSize;
    2007             : 
    2008      679696 :         transportEne = 0.0f;
    2009    37663056 :         for ( i = mrange[0]; i < mrange[1]; i++ )
    2010             :         {
    2011    36983360 :             transportEne += lowPassSignal[i] * lowPassSignal[i];
    2012             :         }
    2013             : 
    2014      679696 :         targetEneLfe = transportEne * hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index];
    2015      679696 :         targetEneTrans = transportEne * max( ( 1.0f - hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index] ), 0.01f );
    2016             : 
    2017      679696 :         hMasaLfeSynth->transportEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
    2018      679696 :         hMasaLfeSynth->targetEneLfeSmooth *= MCMASA_LFE_SYNTH_ALPHA;
    2019      679696 :         hMasaLfeSynth->targetEneTransSmooth *= MCMASA_LFE_SYNTH_ALPHA;
    2020             : 
    2021      679696 :         hMasaLfeSynth->transportEneSmooth += transportEne;
    2022      679696 :         hMasaLfeSynth->targetEneLfeSmooth += targetEneLfe;
    2023      679696 :         hMasaLfeSynth->targetEneTransSmooth += targetEneTrans;
    2024             : 
    2025      679696 :         lfeGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneLfeSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
    2026      679696 :         transportGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneTransSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
    2027             : 
    2028    37663056 :         for ( i = mrange[0], j = 0; i < mrange[1]; i++, j++ )
    2029             :         {
    2030    36983360 :             data_f[separateChannelIndex][i] = ( transportGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->transportGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i] + highPassSignal[i];
    2031    36983360 :             data_f[lfeChannelIndex][i] = ( lfeGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->lfeGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i];
    2032             :         }
    2033             : 
    2034      679696 :         hMasaLfeSynth->lfeGainPrev = lfeGain;
    2035      679696 :         hMasaLfeSynth->transportGainPrev = transportGain;
    2036             :     }
    2037             : 
    2038             :     /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
    2039       42481 :     lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize2 );
    2040    37025841 :     for ( i = 0; i < output_frame; i++ )
    2041             :     {
    2042    36983360 :         hMasaLfeSynth->lowpassSum2 += lowpassCoef * data_f[lfeChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2];
    2043    36983360 :         hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2] = data_f[lfeChannelIndex][i];
    2044             : 
    2045    36983360 :         hMasaLfeSynth->ringBufferLoPointer2--;
    2046    36983360 :         if ( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
    2047             :         {
    2048      339848 :             hMasaLfeSynth->ringBufferLoPointer2 = hMasaLfeSynth->ringBufferSize2 - 1;
    2049             :         }
    2050             : 
    2051    36983360 :         data_f[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2;
    2052             :     }
    2053             : 
    2054             :     /* Delay the separated channel to match the delay of the lowpass filter */
    2055       42481 :     delay = hMasaLfeSynth->delayBuffer_syncLp_size;
    2056       42481 :     delay_signal( data_f[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp, delay );
    2057             : 
    2058       42481 :     return;
    2059             : }
    2060             : 
    2061             : 
    2062             : /*-------------------------------------------------------------------------
    2063             :  * Local functions
    2064             :  *------------------------------------------------------------------------*/
    2065             : 
    2066     2907744 : static void computeTargetPSDs_direct(
    2067             :     const int16_t num_channels,
    2068             :     const int16_t num_freq_bands,
    2069             :     const float *direct_power_factor,
    2070             :     const float *reference_power,
    2071             :     const float *direct_responses,
    2072             :     const float *direct_responses_square,
    2073             :     float *cy_auto_dir_smooth,
    2074             :     float *cy_cross_dir_smooth )
    2075             : {
    2076             :     int16_t ch_idx, cur_idx;
    2077             : 
    2078             :     /* segment auxiliary buffer */
    2079             :     float direct_power[CLDFB_NO_CHANNELS_MAX];   /* size: num_freq_bands. */
    2080             :     float aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    2081             : 
    2082             :     /* estimate direct and diffuse power */
    2083     2907744 :     v_mult( direct_power_factor, reference_power, direct_power, num_freq_bands );
    2084             : 
    2085             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    2086    28368656 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2087             :     {
    2088    25460912 :         cur_idx = ch_idx * num_freq_bands;
    2089             : 
    2090    25460912 :         v_mult( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands );
    2091    25460912 :         v_add( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands );
    2092             : 
    2093    25460912 :         v_mult( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands );
    2094    25460912 :         v_add( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands );
    2095             :     }
    2096             : 
    2097     2907744 :     return;
    2098             : }
    2099             : 
    2100             : 
    2101    18868869 : static void computeTargetPSDs_direct_subframe(
    2102             :     const int16_t num_channels,
    2103             :     const int16_t num_freq_bands,
    2104             :     const float *direct_power_factor,
    2105             :     const float *reference_power,
    2106             :     const float *direct_responses,
    2107             :     const float *direct_responses_square,
    2108             :     float *cy_auto_dir_smooth,
    2109             :     float *cy_cross_dir_smooth )
    2110             : {
    2111             :     int16_t ch_idx, cur_idx;
    2112             : 
    2113             :     /* segment auxiliary buffer */
    2114             :     float direct_power[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    2115             : 
    2116             :     /* estimate direct and diffuse power */
    2117    18868869 :     v_mult( direct_power_factor, reference_power, direct_power, num_freq_bands );
    2118             : 
    2119             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    2120   172803825 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2121             :     {
    2122   153934956 :         cur_idx = ch_idx * num_freq_bands;
    2123             : 
    2124   153934956 :         v_mult( direct_power, &direct_responses_square[cur_idx], &cy_auto_dir_smooth[cur_idx], num_freq_bands );
    2125   153934956 :         v_mult( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands );
    2126             :     }
    2127             : 
    2128    18868869 :     return;
    2129             : }
    2130             : 
    2131             : 
    2132     2907744 : static void computeTargetPSDs_diffuse(
    2133             :     const int16_t num_channels,
    2134             :     const int16_t num_freq_bands,
    2135             :     const int16_t start_band,
    2136             :     const float *diffuse_power_factor,
    2137             :     const float *reference_power,
    2138             :     const float *diffuse_responses_square,
    2139             :     float *cy_auto_diff_smooth )
    2140             : {
    2141             :     int16_t ch_idx, cur_idx;
    2142             : 
    2143             :     /* segment auxiliary buffer */
    2144             :     float diffuse_power[CLDFB_NO_CHANNELS_MAX];  /* size: num_freq_bands. */
    2145             :     float aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    2146             : 
    2147             :     /* estimate direct and diffuse power */
    2148     2907744 :     v_mult( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands );
    2149             : 
    2150             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    2151    28368656 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2152             :     {
    2153    25460912 :         cur_idx = ch_idx * num_freq_bands;
    2154    25460912 :         v_multc( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, num_freq_bands - start_band );
    2155    25460912 :         v_add( &cy_auto_diff_smooth[cur_idx + start_band], aux_buffer_res, &cy_auto_diff_smooth[cur_idx + start_band], num_freq_bands - start_band );
    2156             :     }
    2157             : 
    2158     2907744 :     return;
    2159             : }
    2160             : 
    2161             : 
    2162    18868869 : static void computeTargetPSDs_diffuse_subframe(
    2163             :     const int16_t num_channels,
    2164             :     const int16_t num_freq_bands,
    2165             :     const int16_t start_band,
    2166             :     const float *diffuse_power_factor,
    2167             :     const float *reference_power,
    2168             :     const float *diffuse_responses_square,
    2169             :     float *cy_auto_diff_smooth )
    2170             : {
    2171             :     int16_t ch_idx, cur_idx;
    2172             :     float diffuse_power[CLDFB_NO_CHANNELS_MAX]; /* segment auxiliary buffer; size: num_freq_bands. */
    2173             : 
    2174             :     /* estimate direct and diffuse power */
    2175    18868869 :     v_mult( diffuse_power_factor, reference_power, diffuse_power, num_freq_bands );
    2176             : 
    2177             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    2178   172803825 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2179             :     {
    2180   153934956 :         cur_idx = ch_idx * num_freq_bands;
    2181             : 
    2182   153934956 :         v_multc( &diffuse_power[start_band], diffuse_responses_square[ch_idx], &cy_auto_diff_smooth[cur_idx + start_band], num_freq_bands - start_band );
    2183             :     }
    2184             : 
    2185    18868869 :     return;
    2186             : }
    2187             : 
    2188             : 
    2189    55195080 : static void computeTargetPSDs_diffuse_with_onsets(
    2190             :     const int16_t num_channels,
    2191             :     const int16_t num_freq_bands,
    2192             :     const int16_t num_decorr_freq_bands,
    2193             :     const int16_t *proto_frame_diff_index,
    2194             :     const float *diffuse_power_factor,
    2195             :     const float *reference_power,
    2196             :     const float *diffuse_responses_square,
    2197             :     const float *onset_filter,
    2198             :     float *cy_auto_diff_smooth )
    2199             : {
    2200             :     int16_t ch_idx, cur_idx, diff_idx;
    2201             :     float diffuse_response_p4, aux_buffer_res1[CLDFB_NO_CHANNELS_MAX];
    2202             :     /* segment auxiliary buffer */
    2203             :     float diffuse_power[CLDFB_NO_CHANNELS_MAX];  /* size: num_freq_bands. */
    2204             :     float aux_buffer_res[CLDFB_NO_CHANNELS_MAX]; /* size: num_freq_bands. */
    2205             : 
    2206             :     /* estimate direct and diffuse power */
    2207    55195080 :     v_mult( diffuse_power_factor, reference_power, diffuse_power, num_decorr_freq_bands );
    2208             : 
    2209             :     /* compute target auto and cross PSDs of current frame (smoothed) */
    2210   518055380 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2211             :     {
    2212   462860300 :         diffuse_response_p4 = diffuse_responses_square[ch_idx] * diffuse_responses_square[ch_idx];
    2213             : 
    2214   462860300 :         cur_idx = ch_idx * num_freq_bands;
    2215   462860300 :         diff_idx = proto_frame_diff_index[ch_idx] * num_freq_bands;
    2216             : 
    2217   462860300 :         v_multc( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands );
    2218   462860300 :         v_multc( &onset_filter[diff_idx], -1.0f, aux_buffer_res, num_decorr_freq_bands );
    2219   462860300 :         v_addc( aux_buffer_res, 1.0f, aux_buffer_res, num_decorr_freq_bands );
    2220   462860300 :         v_multc( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands );
    2221   462860300 :         v_add( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands );
    2222   462860300 :         v_mult( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands );
    2223   462860300 :         v_add( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands );
    2224             :     }
    2225             : 
    2226    55195080 :     return;
    2227             : }
    2228             : 
    2229      208216 : static void computeAlphaSynthesis(
    2230             :     float *alpha_synthesis,
    2231             :     const int16_t averaging_length_ms,
    2232             :     const float maxAlpha,
    2233             :     int16_t *numAlphas,
    2234             :     const int16_t slot_size,
    2235             :     const int16_t num_freq_bands,
    2236             :     const float *frequency_axis,
    2237             :     const int32_t output_Fs )
    2238             : {
    2239             :     int16_t k;
    2240             :     float avg_length_f_ms;
    2241             : 
    2242             :     /* check input pointer */
    2243      208216 :     if ( alpha_synthesis == NULL )
    2244             :     {
    2245             : #ifdef DEBUGGING
    2246             :         assert( !"Error: NULL pointer.\n" );
    2247             : #endif
    2248           0 :         return;
    2249             :     }
    2250             : 
    2251      208216 :     if ( averaging_length_ms == 0 )
    2252             :     {
    2253           0 :         set_f( alpha_synthesis, 1.0f, num_freq_bands );
    2254             :     }
    2255             :     else
    2256             :     {
    2257      832864 :         for ( k = 0; k < num_freq_bands; k++ )
    2258             :         {
    2259      832864 :             int16_t faxis_idx = max( k, 1 );
    2260      832864 :             avg_length_f_ms = 1000.f * (float) averaging_length_ms / fabsf( frequency_axis[faxis_idx] );
    2261      832864 :             alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );
    2262      832864 :             if ( alpha_synthesis[k] >= maxAlpha )
    2263             :             {
    2264      208216 :                 alpha_synthesis[k] = maxAlpha;
    2265      208216 :                 *numAlphas = k + 1;
    2266      208216 :                 break;
    2267             :             }
    2268             :         }
    2269             :     }
    2270             : 
    2271      208216 :     return;
    2272             : }
    2273             : 
    2274   204738843 : static void spreadCoherencePanningHoa(
    2275             :     const int16_t azimuth,
    2276             :     const int16_t elevation,
    2277             :     const float spreadCoh,
    2278             :     float *direct_response,
    2279             :     const int16_t num_channels_dir,
    2280             :     const int16_t ambisonics_order )
    2281             : {
    2282             :     int16_t i;
    2283             :     float direct_response_left[MAX_OUTPUT_CHANNELS];
    2284             :     float direct_response_right[MAX_OUTPUT_CHANNELS];
    2285             :     float gainCenter;
    2286             :     float gainSide;
    2287             : 
    2288   204738843 :     ivas_dirac_dec_get_response( azimuth, elevation, direct_response, ambisonics_order );
    2289             : 
    2290   204738843 :     if ( spreadCoh > 0.f )
    2291             :     {
    2292   126344342 :         ivas_dirac_dec_get_response( azimuth + 30, elevation, direct_response_left, ambisonics_order );
    2293             : 
    2294   126344342 :         ivas_dirac_dec_get_response( azimuth + 330, elevation, direct_response_right, ambisonics_order );
    2295             : 
    2296   126344342 :         if ( spreadCoh < 0.5f )
    2297             :         {
    2298   111416019 :             gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh / 3.0f;
    2299   111416019 :             gainSide = 2.0f * spreadCoh / 3.0f;
    2300             :         }
    2301             :         else
    2302             :         {
    2303    14928323 :             gainSide = 1.0f / ( 4.0f - 2.0f * spreadCoh );
    2304    14928323 :             gainCenter = ( 2.0f - 2.0f * spreadCoh ) * gainSide;
    2305             :         }
    2306             : 
    2307  1198420792 :         for ( i = 0; i < num_channels_dir; i++ )
    2308             :         {
    2309  1072076450 :             direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
    2310             :         }
    2311             :     }
    2312             : 
    2313   204738843 :     return;
    2314             : }
    2315             : 
    2316   520444994 : static void spreadCoherencePanningVbap(
    2317             :     const int16_t azimuth,
    2318             :     const int16_t elevation,
    2319             :     const float spreadCoh,
    2320             :     float *direct_response,
    2321             :     const int16_t num_channels_dir,
    2322             :     const VBAP_HANDLE hVBAPdata )
    2323             : {
    2324             :     int16_t i;
    2325             :     float direct_response_left[MAX_OUTPUT_CHANNELS];
    2326             :     float direct_response_right[MAX_OUTPUT_CHANNELS];
    2327             :     float gainCenter;
    2328             :     float gainSide;
    2329             : 
    2330   520444994 :     if ( hVBAPdata == NULL )
    2331             :     {
    2332             :         /* Distribute signal to all channels if VBAP is not properly initialized. */
    2333           0 :         set_f( direct_response, inv_sqrt( num_channels_dir ), num_channels_dir );
    2334             : 
    2335           0 :         return;
    2336             :     }
    2337             : 
    2338   520444994 :     vbap_determine_gains( hVBAPdata, direct_response, azimuth, elevation, 0 );
    2339             : 
    2340   520444994 :     if ( spreadCoh > 0.f )
    2341             :     {
    2342   232172490 :         vbap_determine_gains( hVBAPdata, direct_response_left, azimuth + 30, elevation, 0 );
    2343   232172490 :         vbap_determine_gains( hVBAPdata, direct_response_right, azimuth - 30, elevation, 0 );
    2344             : 
    2345   232172490 :         if ( spreadCoh < 0.5f )
    2346             :         {
    2347   205267691 :             gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh * INV_SQRT3;
    2348   205267691 :             gainSide = 2.0f * spreadCoh * INV_SQRT3;
    2349             :         }
    2350             :         else
    2351             :         {
    2352    26904799 :             gainCenter = 2.0f - 2.0f * spreadCoh;
    2353    26904799 :             gainSide = 1.0f;
    2354             :         }
    2355             : 
    2356  2241678247 :         for ( i = 0; i < num_channels_dir; i++ )
    2357             :         {
    2358  2009505757 :             direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
    2359             :         }
    2360             :     }
    2361             : 
    2362   520444994 :     return;
    2363             : }
    2364             : 
    2365             : 
    2366  1043589726 : static void normalizePanningGains(
    2367             :     float *direct_response,
    2368             :     const int16_t num_channels_dir )
    2369             : {
    2370             :     float energySum;
    2371             :     float normVal;
    2372             :     int16_t i;
    2373             : 
    2374  1043589726 :     energySum = sum2_f( direct_response, num_channels_dir ) + 1e-12f;
    2375  1043589726 :     normVal = sqrtf( 1.0f / energySum );
    2376 10133631212 :     for ( i = 0; i < num_channels_dir; i++ )
    2377             :     {
    2378  9090041486 :         direct_response[i] *= normVal;
    2379             :     }
    2380             : 
    2381  1043589726 :     return;
    2382             : }

Generated by: LCOV version 1.14