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 @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 845 889 95.1 %
Date: 2025-05-29 08:28:55 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       87077 : 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       87077 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     107       87077 :     DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     108             : 
     109             :     /* check / set input parameters */
     110       87077 :     assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
     111       87077 :     assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
     112       87077 :     assert( hDirACRend->num_outputs_diff > 0 );
     113       87077 :     assert( hSpatParamRendCom->slot_size > 0 );
     114       87077 :     assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
     115       87077 :     assert( hDirACRend->diffuse_response_function != NULL );
     116             : 
     117       87077 :     if ( hDirACRend->proto_signal_decorr_on )
     118             :     {
     119       82979 :         dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
     120             :     }
     121             :     else
     122             :     {
     123        4098 :         dirac_output_synthesis_params->max_band_decorr = 0;
     124             :     }
     125             : 
     126             :     /*-----------------------------------------------------------------*
     127             :      * memory allocation
     128             :      *-----------------------------------------------------------------*/
     129             : 
     130       87077 :     dirac_output_synthesis_state->diffuse_responses_square = NULL;
     131       87077 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
     132             :     {
     133        1942 :         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       85135 :     else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
     139             :     {
     140       43128 :         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       87077 :     dirac_output_synthesis_state->proto_power_smooth_prev = NULL;
     148       87077 :     if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
     149             :     {
     150       45070 :         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       87077 :     if ( dirac_output_synthesis_params->max_band_decorr > 0 && ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) )
     156             :     {
     157       40972 :         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       46105 :         dirac_output_synthesis_state->proto_power_diff_smooth_prev = NULL;
     165             :     }
     166             : 
     167             :     /* buffer length and interpolator */
     168       87077 :     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       87077 :     if ( hodirac_flag )
     175             :     {
     176        7528 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
     177             :     }
     178             :     else
     179             :     {
     180       79549 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
     181             :     }
     182       87077 :     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       87077 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     188             :     {
     189       42007 :         dirac_output_synthesis_state->cy_auto_dir_smooth_prev = NULL;
     190       42007 :         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       45070 :         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       45070 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
     203             :         {
     204       12048 :             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       33022 :             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       87077 :     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       87077 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     225             :     {
     226       42007 :         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       45070 :     else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD && hDirACRend->synthesisConf != DIRAC_SYNTHESIS_MONO )
     232             :     {
     233       31080 :         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       13990 :         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       87077 :     if ( !( renderer_type == RENDERER_BINAURAL_PARAMETRIC || renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) )
     252             :     {
     253       45070 :         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       45070 :         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       45070 :         mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis, dirac_output_synthesis_params->numAlphas );
     259             : 
     260       45070 :         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       45070 :         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       45070 :         mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis_fast, dirac_output_synthesis_params->numAlphasFast );
     266             : 
     267       45070 :         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       45070 :         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       45070 :         set_zero( dirac_output_synthesis_state->reference_power_smooth_prev, hSpatParamRendCom->num_freq_bands );
     276       45070 :         set_zero( dirac_output_synthesis_state->direction_smoothness_prev, hSpatParamRendCom->num_freq_bands );
     277             :     }
     278             :     else
     279             :     {
     280       42007 :         dirac_output_synthesis_params->alpha_synthesis = NULL;
     281       42007 :         dirac_output_synthesis_params->alpha_synthesis_fast = NULL;
     282       42007 :         dirac_output_synthesis_state->reference_power_smooth_prev = NULL;
     283       42007 :         dirac_output_synthesis_state->direction_smoothness_prev = NULL;
     284             :     }
     285             : 
     286             :     /* compute interpolator */
     287      435385 :     for ( idx = 1; idx <= JBM_CLDFB_SLOTS_IN_SUBFRAME; ++idx )
     288             :     {
     289      348308 :         dirac_output_synthesis_params->interpolator[idx - 1] = (float) idx / (float) JBM_CLDFB_SLOTS_IN_SUBFRAME;
     290             :     }
     291             : 
     292             :     /* prepare diffuse response function */
     293       87077 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
     294             :     {
     295        1942 :         num_diffuse_responses = 2;
     296             :     }
     297             :     else
     298             :     {
     299       85135 :         num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
     300             :     }
     301             : 
     302       87077 :     if ( dirac_output_synthesis_state->diffuse_responses_square != NULL )
     303             :     {
     304      424764 :         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      379694 :             tmp = hDirACRend->diffuse_response_function[ch_idx];
     308             : 
     309      379694 :             dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = tmp * tmp;
     310             :         }
     311             :     }
     312             : 
     313       87077 :     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       42007 :         diff_compensation_order = nchan_transport >= 3 ? 3 : 2; /* compensate missing diffuseness modelling up order 2, except for HR*/
     319       42007 :         diff_compensation_order = min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
     320             : 
     321       42007 :         diff_nrg_total = 0;
     322       42007 :         diff_nrg_trans = 0;
     323       42007 :         diff_nrg_decorr = 0;
     324      643339 :         for ( ch_idx = 0; ch_idx < ( diff_compensation_order + 1 ) * ( diff_compensation_order + 1 ); ch_idx++ )
     325             :         {
     326      601332 :             diff_nrg = hDirACRend->diffuse_response_function[ch_idx] * hDirACRend->diffuse_response_function[ch_idx];
     327      601332 :             diff_nrg_total += diff_nrg;
     328             :             /* is it a transport channel?*/
     329      601332 :             if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
     330             :             {
     331      206149 :                 diff_nrg_trans += diff_nrg;
     332             :             }
     333             :             /* is it a decorrelated or transport channel?*/
     334      601332 :             if ( ch_idx < hDirACRend->num_outputs_diff )
     335             :             {
     336      168028 :                 diff_nrg_decorr += diff_nrg;
     337             :             }
     338             :         }
     339       42007 :         dirac_output_synthesis_params->diffuse_compensation_factor = diff_nrg_total / diff_nrg_trans;
     340       42007 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr = diff_nrg_total / diff_nrg_decorr;
     341             :     }
     342             :     else
     343             :     {
     344       45070 :         dirac_output_synthesis_params->diffuse_compensation_factor = 0.f;
     345       45070 :         dirac_output_synthesis_params->diffuse_compensation_factor_decorr = 0.f;
     346             :     }
     347             : 
     348       87077 :     return IVAS_ERR_OK;
     349             : }
     350             : 
     351             : 
     352             : /*-------------------------------------------------------------------------
     353             :  * ivas_dirac_dec_output_synthesis_init()
     354             :  *
     355             :  *
     356             :  *------------------------------------------------------------------------*/
     357             : 
     358       88607 : 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       88607 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     371       88607 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     372             : 
     373             :     /*-----------------------------------------------------------------*
     374             :      * init outputSynthesisPSD_Init
     375             :      *-----------------------------------------------------------------*/
     376             : 
     377             :     /* initialize buffers */
     378       88607 :     if ( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev != NULL )
     379             :     {
     380       45130 :         set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
     381             :     }
     382             : 
     383       88607 :     if ( hodirac_flag )
     384             :     {
     385        7528 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
     386             :     }
     387             :     else
     388             :     {
     389       81079 :         size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
     390             :     }
     391       88607 :     set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev, size );
     392             : 
     393       88607 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     394             :     {
     395       43477 :         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       45130 :     else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
     398             :     {
     399       33082 :         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       12048 :         set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
     404             :     }
     405             : 
     406       88607 :     if ( h_dirac_output_synthesis_state->proto_power_smooth_prev != NULL )
     407             :     {
     408       45130 :         set_zero( h_dirac_output_synthesis_state->proto_power_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir );
     409             :     }
     410       88607 :     set_zero( h_dirac_output_synthesis_state->gains_dir_prev, size );
     411             : 
     412       88607 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     413             :     {
     414       43477 :         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       45130 :         set_zero( h_dirac_output_synthesis_state->gains_diff_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
     419             :     }
     420             : 
     421       88607 :     if ( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev != NULL )
     422             :     {
     423       40972 :         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       88607 :     return;
     427             : }
     428             : 
     429             : 
     430             : /*-------------------------------------------------------------------------
     431             :  * ivas_dirac_dec_output_synthesis_close()
     432             :  *
     433             :  * Memory deallocation of Output synthesis sub-module
     434             :  *------------------------------------------------------------------------*/
     435             : 
     436       87077 : 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       87077 :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     442       87077 :     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       87077 :     if ( ( dirac_output_synthesis_params )->interpolator != NULL )
     450             :     {
     451       87077 :         free( ( dirac_output_synthesis_params )->interpolator );
     452       87077 :         ( dirac_output_synthesis_params )->interpolator = NULL;
     453             :     }
     454             : 
     455             :     /* free alpha */
     456       87077 :     if ( ( dirac_output_synthesis_params )->alpha_synthesis != NULL )
     457             :     {
     458       45070 :         free( ( dirac_output_synthesis_params )->alpha_synthesis );
     459       45070 :         ( dirac_output_synthesis_params )->alpha_synthesis = NULL;
     460             :     }
     461       87077 :     if ( ( dirac_output_synthesis_params )->alpha_synthesis_fast != NULL )
     462             :     {
     463       45070 :         free( ( dirac_output_synthesis_params )->alpha_synthesis_fast );
     464       45070 :         ( dirac_output_synthesis_params )->alpha_synthesis_fast = NULL;
     465             :     }
     466             : 
     467       87077 :     if ( ( dirac_output_synthesis_state )->reference_power_smooth_prev != NULL )
     468             :     {
     469       45070 :         free( ( dirac_output_synthesis_state )->reference_power_smooth_prev );
     470       45070 :         ( dirac_output_synthesis_state )->reference_power_smooth_prev = NULL;
     471             :     }
     472             : 
     473       87077 :     if ( ( dirac_output_synthesis_state )->direction_smoothness_prev != NULL )
     474             :     {
     475       45070 :         free( ( dirac_output_synthesis_state )->direction_smoothness_prev );
     476       45070 :         ( dirac_output_synthesis_state )->direction_smoothness_prev = NULL;
     477             :     }
     478             : 
     479       87077 :     if ( ( dirac_output_synthesis_state )->diffuse_responses_square != NULL )
     480             :     {
     481       45070 :         free( ( dirac_output_synthesis_state )->diffuse_responses_square );
     482       45070 :         ( dirac_output_synthesis_state )->diffuse_responses_square = NULL;
     483             :     }
     484             : 
     485             :     /* free power buffers */
     486       87077 :     if ( ( dirac_output_synthesis_state )->proto_power_smooth_prev != NULL )
     487             :     {
     488       45070 :         free( ( dirac_output_synthesis_state )->proto_power_smooth_prev );
     489       45070 :         ( dirac_output_synthesis_state )->proto_power_smooth_prev = NULL;
     490             :     }
     491             : 
     492       87077 :     if ( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev != NULL )
     493             :     {
     494       40972 :         free( ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev );
     495       40972 :         ( dirac_output_synthesis_state )->proto_power_diff_smooth_prev = NULL;
     496             :     }
     497             : 
     498             :     /* free target power buffers */
     499       87077 :     if ( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev != NULL )
     500             :     {
     501       45070 :         free( ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev );
     502       45070 :         ( dirac_output_synthesis_state )->cy_auto_dir_smooth_prev = NULL;
     503             :     }
     504       87077 :     if ( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev != NULL )
     505             :     {
     506       87077 :         free( ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev );
     507       87077 :         ( dirac_output_synthesis_state )->cy_cross_dir_smooth_prev = NULL;
     508             :     }
     509       87077 :     if ( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev != NULL )
     510             :     {
     511       87077 :         free( ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev );
     512       87077 :         ( dirac_output_synthesis_state )->cy_auto_diff_smooth_prev = NULL;
     513             :     }
     514             : 
     515             :     /* free gain buffers */
     516       87077 :     if ( ( dirac_output_synthesis_state )->gains_dir_prev != NULL )
     517             :     {
     518       87077 :         free( ( dirac_output_synthesis_state )->gains_dir_prev );
     519       87077 :         ( dirac_output_synthesis_state )->gains_dir_prev = NULL;
     520             :     }
     521       87077 :     if ( ( dirac_output_synthesis_state )->gains_diff_prev != NULL )
     522             :     {
     523       87077 :         free( ( dirac_output_synthesis_state )->gains_diff_prev );
     524       87077 :         ( dirac_output_synthesis_state )->gains_diff_prev = NULL;
     525             :     }
     526             : 
     527       87077 :     return;
     528             : }
     529             : 
     530             : 
     531             : /*-------------------------------------------------------------------------
     532             :  * ivas_dirac_dec_output_synthesis_process_slot()
     533             :  *
     534             :  *
     535             :  *------------------------------------------------------------------------*/
     536             : 
     537    46853247 : 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    46853247 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
     561    46853247 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
     562             : 
     563    46853247 :     h_dirac_output_synthesis_state->onset_filter = onset;
     564             : 
     565             :     /*-----------------------------------------------------------------*
     566             :      * processing
     567             :      *-----------------------------------------------------------------*/
     568             : 
     569             :     /* collect some often used parameters */
     570    46853247 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
     571    46853247 :     num_channels_dir = hDirACRend->num_outputs_dir;
     572    46853247 :     num_channels_diff = hDirACRend->num_outputs_diff;
     573    46853247 :     num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
     574             : 
     575    46853247 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
     576             :     {
     577    10410711 :         num_channels_dir = hOutSetup.nchan_out_woLFE;
     578             :     }
     579             : 
     580    46853247 :     if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD && hodirac_flag )
     581             :     {
     582     6481584 :         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    46853247 :     if ( dec_param_estim == FALSE && hodirac_flag )
     595             :     {
     596     6481584 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     597             :         {
     598     6481584 :             v_multc( hSpatParamRendCom->energy_ratio1[md_idx], -1.f, aux_buf, num_freq_bands );
     599     6481584 :             v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
     600     6481584 :             mvr2r( hSpatParamRendCom->energy_ratio1[md_idx],
     601             :                    h_dirac_output_synthesis_state->direct_power_factor,
     602             :                    num_freq_bands );
     603     6481584 :             mvr2r( aux_buf,
     604             :                    h_dirac_output_synthesis_state->diffuse_power_factor,
     605             :                    num_freq_bands );
     606             : 
     607     6481584 :             v_multc( hSpatParamRendCom->energy_ratio2[md_idx], -1.f, aux_buf, num_freq_bands );
     608     6481584 :             v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
     609     6481584 :             mvr2r( hSpatParamRendCom->energy_ratio2[md_idx],
     610     6481584 :                    &h_dirac_output_synthesis_state->direct_power_factor[hSpatParamRendCom->num_freq_bands],
     611             :                    num_freq_bands );
     612     6481584 :             mvr2r( aux_buf,
     613     6481584 :                    &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    40371663 :     else if ( dec_param_estim == TRUE )
     626             :     {
     627             :         /* compute direct responses */
     628    27254357 :         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    27254357 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
     640             :         {
     641    25327269 :             ivas_dirac_dec_compute_gain_factors( num_freq_bands,
     642             :                                                  diffuseness,
     643    25327269 :                                                  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    25327269 :             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    25327269 :             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   126636345 :             for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ )
     658             :             {
     659             :                 int16_t k;
     660   101309076 :                 if ( ch_idx != 0 )
     661             :                 {
     662             :                     float a, b, c;
     663             : 
     664             :                     /*Directonal sound gain nrg compensation*/
     665   455890842 :                     for ( k = 0; k < num_freq_bands_diff; k++ )
     666             :                     {
     667   379909035 :                         a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
     668   379909035 :                         b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
     669   379909035 :                         c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/
     670   379909035 :                         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  3009703812 :                     for ( ; k < num_freq_bands; k++ )
     673             :                     {
     674  2933722005 :                         a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
     675  2933722005 :                         b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
     676  2933722005 :                         c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/
     677  2933722005 :                         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   151963614 :                     for ( k = 0; k < num_freq_bands_diff; k++ )
     684             :                     {
     685   126636345 :                         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  1003234604 :                     for ( ; k < num_freq_bands; k++ )
     688             :                     {
     689   977907335 :                         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   305271041 :             for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
     696             :             {
     697   279943772 :                 v_mult( h_dirac_output_synthesis_state->direct_power_factor,
     698   279943772 :                         &h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands],
     699             :                         aux_buf,
     700             :                         num_freq_bands );
     701             : 
     702   279943772 :                 v_add( aux_buf,
     703   279943772 :                        &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
     704   279943772 :                        &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
     705             :                        num_freq_bands );
     706             :             }
     707             : 
     708             :             /*Diffuse gain*/
     709    25327269 :             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    25327269 :             return;
     723             :         }
     724             :         else
     725             :         {
     726             :             /* compute reference and diffuse power factor for this frame */
     727     1927088 :             ivas_dirac_dec_compute_power_factors( num_freq_bands,
     728             :                                                   diffuseness,
     729     1927088 :                                                   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    21525978 :     diff_start_band = 0;
     736    21525978 :     if ( h_dirac_output_synthesis_params->use_onset_filters )
     737             :     {
     738     8483623 :         computeTargetPSDs_diffuse_with_onsets( num_channels_dir,
     739     8483623 :                                                num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
     740     8483623 :                                                hDirACRend->proto_index_diff,
     741     8483623 :                                                h_dirac_output_synthesis_state->diffuse_power_factor,
     742             :                                                reference_power,
     743     8483623 :                                                h_dirac_output_synthesis_state->diffuse_responses_square,
     744             :                                                onset,
     745             :                                                h_dirac_output_synthesis_state->cy_auto_diff_smooth );
     746             : 
     747     8483623 :         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    21525978 :     if ( dec_param_estim == TRUE )
     752             :     {
     753     1927088 :         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     1927088 :         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    21525978 :     return;
     759             : }
     760             : 
     761             : 
     762             : /*-------------------------------------------------------------------------
     763             :  * ivas_dirac_dec_output_synthesis_process_subframe_gain_shd()
     764             :  *
     765             :  *
     766             :  *------------------------------------------------------------------------*/
     767             : 
     768     8157249 : 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     8157249 :     h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
     802     8157249 :     h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
     803     8157249 :     proto_direct_index = hDirACRend->proto_index_dir;
     804             : 
     805     8157249 :     num_protos_dir = hDirACRend->num_protos_dir;
     806     8157249 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
     807     8157249 :     num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
     808     8157249 :     num_channels_dir = hDirACRend->num_outputs_dir;
     809     8157249 :     num_channels_diff = hDirACRend->num_outputs_diff;
     810     8157249 :     nchan_transport_foa = min( 4, nchan_transport );
     811             : 
     812             : 
     813             :     /*-----------------------------------------------------------------*
     814             :      * comput target Gains
     815             :      *-----------------------------------------------------------------*/
     816             : 
     817     8157249 :     if ( hodirac_flag )
     818             :     {
     819             :         /*Direct gain*/
     820     8101980 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     821             :         {
     822     6481584 :             v_multc( diffuseness,
     823             :                      1.f,
     824     6481584 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     825             :                      num_freq_bands );
     826     6481584 :             v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     827     6481584 :                      h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
     828     6481584 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     829             :                      num_freq_bands );
     830             : 
     831   332074224 :             for ( l = 0; l < num_freq_bands; l++ )
     832             :             {
     833   325592640 :                 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    18855780 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     839             :         {
     840   875479224 :             for ( l = 0; l < num_freq_bands; l++ )
     841             :             {
     842   858243840 :                 aux_buf[l] = 1.f - diffuseness[l];
     843   858243840 :                 ratio[l] = 1.f - h_dirac_output_synthesis_state.direct_power_factor[hSpatParamRendCom->num_freq_bands + l];
     844   858243840 :                 ratio[l + num_freq_bands] = 1.f - ratio[l];
     845             :             }
     846             : 
     847    17235384 :             v_mult( aux_buf, ratio, ratio, num_freq_bands );
     848    17235384 :             v_mult( aux_buf, &ratio[num_freq_bands], &ratio[num_freq_bands], num_freq_bands );
     849             : 
     850    17235384 :             v_mult( ratio,
     851    17235384 :                     &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
     852    17235384 :                     &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     853             :                     num_freq_bands );
     854    17235384 :             v_mult( &ratio[num_freq_bands],
     855    17235384 :                     &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands + num_freq_bands * num_channels_dir],
     856    17235384 :                     &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     1620396 :         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     6536853 :     else if ( dec_param_estim == FALSE )
     870             :     {
     871             :         /*Direct gain*/
     872      387470 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     873             :         {
     874      193735 :             v_mult( h_dirac_output_synthesis_state.diffuse_power_factor,
     875      193735 :                     h_dirac_output_synthesis_state.diffuse_power_factor,
     876      193735 :                     &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     877             :                     num_freq_bands );
     878      193735 :             v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     879      193735 :                      h_dirac_output_synthesis_params.diffuse_compensation_factor_decorr - 1.f,
     880      193735 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands],
     881             :                      num_freq_bands_diff );
     882      193735 :             v_multc( &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
     883      193735 :                      h_dirac_output_synthesis_params.diffuse_compensation_factor - 1.f,
     884      193735 :                      &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands + num_freq_bands_diff],
     885      193735 :                      num_freq_bands - num_freq_bands_diff );
     886             : 
     887     9893275 :             for ( l = 0; l < num_freq_bands; l++ )
     888             :             {
     889     9699540 :                 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     1618768 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     895             :         {
     896     1425033 :             v_mult( h_dirac_output_synthesis_state.direct_power_factor,
     897     1425033 :                     &h_dirac_output_synthesis_state.direct_responses[ch_idx * num_freq_bands],
     898     1425033 :                     &h_dirac_output_synthesis_state.cy_cross_dir_smooth[ch_idx * num_freq_bands], num_freq_bands );
     899             :         }
     900             : 
     901             :         /*Diffuse gain*/
     902      774940 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
     903             :         {
     904      581205 :             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     8157249 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth;
     913     8157249 :     p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
     914             : 
     915             :     /* Direct gains */
     916     8157249 :     if ( hodirac_flag )
     917             :     {
     918     8101980 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     919             :         {
     920   332074224 :             for ( l = 0; l < num_freq_bands; l++ )
     921             :             {
     922   325592640 :                 g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     923   325592640 :                 g2 = ( 1.f - g1 ) * *( p_gains_dir );
     924   325592640 :                 g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     925   325592640 :                 g2 = max( g2, 0.99f );
     926   325592640 :                 g2 = min( g2, 2.0f );
     927   325592640 :                 *( p_gains_dir++ ) = g2;
     928             :             }
     929             :         }
     930             :     }
     931             :     else
     932             :     {
     933    32103060 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     934             :         {
     935  1141681587 :             for ( l = 0; l < num_freq_bands; l++ )
     936             :             {
     937  1116115380 :                 g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     938  1116115380 :                 g2 = ( 1.f - g1 ) * *( p_gains_dir );
     939  1116115380 :                 g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     940  1116115380 :                 g2 = max( g2, 0.85f );
     941  1116115380 :                 g2 = min( g2, 1.15f );
     942  1116115380 :                 *( p_gains_dir++ ) = g2;
     943             :             }
     944             :         }
     945             :     }
     946             : 
     947             :     /*Directional gains*/
     948    96939218 :     for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     949             :     {
     950  4076132749 :         for ( l = 0; l < num_freq_bands; l++ )
     951             :         {
     952  3987350780 :             g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     953  3987350780 :             g2 = ( 1.f - g1 ) * *( p_gains_dir );
     954  3987350780 :             g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     955  3987350780 :             g2 = max( g2, -DIRAC_GAIN_LIMIT );
     956  3987350780 :             g2 = min( g2, DIRAC_GAIN_LIMIT );
     957  3987350780 :             *( p_gains_dir++ ) = g2;
     958             :         }
     959             :     }
     960             : 
     961     8157249 :     if ( hodirac_flag )
     962             :     {
     963     1620396 :         p_cy_cross_dir_smooth = h_dirac_output_synthesis_state.cy_cross_dir_smooth + num_freq_bands * num_channels_dir;
     964     1620396 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev + num_freq_bands * num_channels_dir;
     965             : 
     966             :         /*Direct gains*/
     967     8101980 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
     968             :         {
     969   332074224 :             for ( l = 0; l < num_freq_bands; l++ )
     970             :             {
     971   325592640 :                 p_cy_cross_dir_smooth++;
     972   325592640 :                 p_gains_dir++;
     973             :             }
     974             :         }
     975             : 
     976             :         /*Directional gains*/
     977    18855780 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
     978             :         {
     979   875479224 :             for ( l = 0; l < num_freq_bands; l++ )
     980             :             {
     981   858243840 :                 g1 = 0.3679f + onset_filter[l] * ( 0.1175f - 0.3679f );
     982   858243840 :                 g2 = ( 1.f - g1 ) * *( p_gains_dir );
     983   858243840 :                 g2 += g1 * ( *( p_cy_cross_dir_smooth++ ) );
     984   858243840 :                 g2 = max( g2, -DIRAC_GAIN_LIMIT );
     985   858243840 :                 g2 = min( g2, DIRAC_GAIN_LIMIT );
     986   858243840 :                 *( p_gains_dir++ ) = g2;
     987             :             }
     988             :         }
     989             :     }
     990             : 
     991             :     /*Diffuse gains*/
     992     8157249 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state.cy_auto_diff_smooth + nchan_transport_foa * num_freq_bands_diff;
     993     8157249 :     p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
     994     8738454 :     for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
     995             :     {
     996    13175259 :         for ( l = 0; l < num_freq_bands_diff; l++ )
     997             :         {
     998    12594054 :             g1 = 0.1175f;
     999    12594054 :             g2 = ( 1.f - g1 ) * *( p_gains_diff );
    1000    12594054 :             g2 += g1 * ( *( p_cy_auto_diff_smooth++ ) );
    1001    12594054 :             g2 = max( g2, 0.f );
    1002    12594054 :             g2 = min( g2, DIRAC_GAIN_LIMIT );
    1003    12594054 :             *( p_gains_diff++ ) = g2;
    1004             :         }
    1005             :     }
    1006             : 
    1007             :     /*-----------------------------------------------------------------*
    1008             :      * gain interpolation and output streams
    1009             :      *-----------------------------------------------------------------*/
    1010             : 
    1011    40731867 :     for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    1012             :     {
    1013    32574618 :         g1 = h_dirac_output_synthesis_params.interpolator[buf_idx];
    1014    32574618 :         g2 = 1.f - g1;
    1015             : 
    1016             :         /*Direct input->output*/
    1017    32574618 :         p_gains_dir = h_dirac_output_synthesis_state.cy_cross_dir_smooth_prev;
    1018    32574618 :         p_gains_dir_prev = h_dirac_output_synthesis_state.gains_dir_prev;
    1019   160575795 :         for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
    1020             :         {
    1021   128001177 :             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  5886794117 :             for ( l = 0; l < num_freq_bands; l++ )
    1023             :             {
    1024  5758792940 :                 g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
    1025  5758792940 :                 output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
    1026  5758792940 :                 output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto_diff++ ) );
    1027             :             }
    1028             :         }
    1029             : 
    1030             :         /*Directional stream*/
    1031   387132533 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_dir; ch_idx++ )
    1032             :         {
    1033   354557915 :             if ( hodirac_flag )
    1034             :             {
    1035    68941536 :                 if ( proto_direct_index[ch_idx] == 0 )
    1036             :                 {
    1037             :                     float *p_proto2;
    1038             :                     float gs1, gs2;
    1039    37938752 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1040    37938752 :                               buf_idx * 2 * num_freq_bands * num_protos_dir +
    1041    37938752 :                               proto_direct_index[0] * 2 * num_freq_bands;
    1042    37938752 :                     p_proto2 = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1043    37938752 :                                buf_idx * 2 * num_freq_bands * num_protos_dir +
    1044    37938752 :                                proto_direct_index[1] * 2 * num_freq_bands;
    1045  1883790272 :                     for ( l = 0; l < num_freq_bands; l++ )
    1046             :                     {
    1047  1845851520 :                         gs1 = g1 * ( *( p_gains_dir ) ) + g2 * ( *( p_gains_dir_prev ) );
    1048  1845851520 :                         gs2 = g1 * ( *( p_gains_dir + num_freq_bands * num_channels_dir ) ) + g2 * ( *( p_gains_dir_prev + num_freq_bands * num_channels_dir ) );
    1049  1845851520 :                         p_gains_dir++;
    1050  1845851520 :                         p_gains_dir_prev++;
    1051             : 
    1052  1845851520 :                         output_real[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) + /* s1 */
    1053  1845851520 :                                                                      0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) );  /* s2 */
    1054  1845851520 :                         p_proto++;
    1055  1845851520 :                         p_proto2++;
    1056  1845851520 :                         output_imag[l * num_channels_dir + ch_idx] = 0.5f * gs1 * ( 1.772454e+00f * ( *p_proto ) + 1.023327e+00f * ( *p_proto2 ) ) +
    1057  1845851520 :                                                                      0.5f * gs2 * ( 1.772454e+00f * ( *p_proto ) - 1.023327e+00f * ( *p_proto2 ) );
    1058  1845851520 :                         p_proto++;
    1059  1845851520 :                         p_proto2++;
    1060             :                     }
    1061             :                 }
    1062             :                 else
    1063             :                 {
    1064    31002784 :                     p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1065    31002784 :                               buf_idx * 2 * num_freq_bands * num_protos_dir +
    1066    31002784 :                               proto_direct_index[ch_idx] * 2 * num_freq_bands;
    1067  1618126624 :                     for ( l = 0; l < num_freq_bands; l++ )
    1068             :                     {
    1069  1587123840 :                         p_gains_dir++;
    1070  1587123840 :                         p_gains_dir_prev++;
    1071             : 
    1072             : 
    1073  1587123840 :                         output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1074  1587123840 :                         output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1075             :                     }
    1076             :                 }
    1077             :             }
    1078             :             else
    1079             :             {
    1080   285616379 :                 p_proto = h_dirac_output_synthesis_state.proto_direct_buffer_f +
    1081   285616379 :                           buf_idx * 2 * num_freq_bands * num_protos_dir +
    1082   285616379 :                           proto_direct_index[ch_idx] * 2 * num_freq_bands;
    1083   285616379 :                 if ( proto_direct_index[ch_idx] == 0 )
    1084             :                 {
    1085 12355025679 :                     for ( l = 0; l < num_freq_bands; l++ )
    1086             :                     {
    1087 12077633540 :                         g = g1 * ( *( p_gains_dir++ ) ) + g2 * ( *( p_gains_dir_prev++ ) );
    1088 12077633540 :                         output_real[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
    1089 12077633540 :                         output_imag[l * num_channels_dir + ch_idx] = g * ( *( p_proto++ ) );
    1090             :                     }
    1091             :                 }
    1092             :                 else
    1093             :                 {
    1094   422901040 :                     for ( l = 0; l < num_freq_bands; l++ )
    1095             :                     {
    1096   414676800 :                         p_gains_dir++;
    1097   414676800 :                         p_gains_dir_prev++;
    1098   414676800 :                         output_real[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1099   414676800 :                         output_imag[l * num_channels_dir + ch_idx] = *( p_proto++ );
    1100             :                     }
    1101             :                 }
    1102             :             }
    1103             :         }
    1104             : 
    1105             :         /*Diffuse stream*/
    1106    32574618 :         p_gains_diff = h_dirac_output_synthesis_state.cy_auto_diff_smooth_prev + nchan_transport_foa * num_freq_bands_diff;
    1107    32574618 :         p_gains_diff_prev = h_dirac_output_synthesis_state.gains_diff_prev + nchan_transport_foa * num_freq_bands_diff;
    1108    32574618 :         ch_idx_diff = nchan_transport_foa;
    1109    34871913 :         for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
    1110             :         {
    1111     2297295 :             if ( proto_direct_index[ch_idx] == 0 )
    1112             :             {
    1113     2297295 :                 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     2297295 :                 ch_idx_diff++;
    1115    52067961 :                 for ( l = 0; l < num_freq_bands_diff; l++ )
    1116             :                 {
    1117    49770666 :                     g = g1 * ( *( p_gains_diff++ ) ) + g2 * ( *( p_gains_diff_prev++ ) );
    1118    49770666 :                     output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */
    1119    49770666 :                     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    32574618 :         if ( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
    1137    12699728 :         {
    1138             :             float *p_real, *p_imag;
    1139             :             const float *hoa_decoder;
    1140             : 
    1141    12699728 :             hoa_decoder = hDirACRend->hoa_decoder;
    1142             : 
    1143   118121120 :             for ( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
    1144             :             {
    1145   105421392 :                 p_real = RealBuffer[ch_idx][buf_idx];
    1146   105421392 :                 p_imag = ImagBuffer[ch_idx][buf_idx];
    1147             : 
    1148  4565684432 :                 for ( l = 0; l < num_freq_bands; l++ )
    1149             :                 {
    1150  4460263040 :                     p_out_real = output_real + l * num_channels_dir;
    1151  4460263040 :                     p_out_imag = output_imag + l * num_channels_dir;
    1152  4460263040 :                     p_real[l] = *( p_out_real++ ) * hoa_decoder[0];
    1153  4460263040 :                     p_imag[l] = *( p_out_imag++ ) * hoa_decoder[0];
    1154 71364208640 :                     for ( i = 1; i < num_channels_dir; i++ )
    1155             :                     {
    1156 66903945600 :                         p_real[l] += *( p_out_real++ ) * hoa_decoder[i];
    1157 66903945600 :                         p_imag[l] += *( p_out_imag++ ) * hoa_decoder[i];
    1158             :                     }
    1159             :                 }
    1160   105421392 :                 hoa_decoder += 16;
    1161             :             }
    1162             :         }
    1163             :         else
    1164             :         {
    1165   299238334 :             for ( ch_idx = 0; ch_idx < num_channels_dir; ch_idx++ )
    1166             :             {
    1167 13401860004 :                 for ( l = 0; l < num_freq_bands; l++ )
    1168             :                 {
    1169 13122496560 :                     RealBuffer[ch_idx][buf_idx][l] = output_real[l * num_channels_dir + ch_idx];
    1170 13122496560 :                     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     8157249 :     if ( hodirac_flag )
    1182             :     {
    1183     1620396 :         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     6536853 :         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     8157249 :     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     8157249 :     if ( hodirac_flag )
    1194             :     {
    1195     1620396 :         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     6536853 :         set_zero( h_dirac_output_synthesis_state.cy_cross_dir_smooth, num_freq_bands * num_channels_dir );
    1200             :     }
    1201             : 
    1202     8157249 :     set_zero( h_dirac_output_synthesis_state.cy_auto_diff_smooth, num_freq_bands_diff * num_channels_diff );
    1203             : 
    1204     8157249 :     return;
    1205             : }
    1206             : 
    1207             : 
    1208             : /*-------------------------------------------------------------------------
    1209             :  * ivas_dirac_dec_output_synthesis_process_subframe_psd_ls()
    1210             :  *
    1211             :  *
    1212             :  *------------------------------------------------------------------------*/
    1213             : 
    1214     3598409 : 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     3598409 :     push_wmops( "dirac_out_synth_sfr" );
    1255             : 
    1256     3598409 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
    1257     3598409 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
    1258     3598409 :     proto_direct_index = hDirACRend->proto_index_dir;
    1259     3598409 :     num_protos_dir = hDirACRend->num_protos_dir;
    1260     3598409 :     nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
    1261             : 
    1262             :     /* collect some often used parameters */
    1263     3598409 :     num_freq_bands = hSpatParamRendCom->num_freq_bands;
    1264             : 
    1265             :     /*-----------------------------------------------------------------*
    1266             :      * compute target PSDs
    1267             :      *-----------------------------------------------------------------*/
    1268             : 
    1269     3598409 :     if ( enc_param_start_band == 0 )
    1270             :     {
    1271     3116637 :         diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0;
    1272             : 
    1273     3116637 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
    1274             :         {
    1275      162553 :             nchan_target_psds = 2;
    1276             :         }
    1277             :         else
    1278             :         {
    1279     2954084 :             nchan_target_psds = nchan_out_woLFE;
    1280             :         }
    1281             : 
    1282     3116637 :         computeTargetPSDs_direct_subframe( nchan_target_psds, num_freq_bands,
    1283     3116637 :                                            h_dirac_output_synthesis_state->direct_power_factor,
    1284             :                                            reference_power_smooth,
    1285     3116637 :                                            h_dirac_output_synthesis_state->direct_responses,
    1286     3116637 :                                            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     3116637 :         computeTargetPSDs_diffuse_subframe( nchan_target_psds, num_freq_bands, diff_start_band,
    1291     3116637 :                                             h_dirac_output_synthesis_state->diffuse_power_factor,
    1292             :                                             reference_power_smooth,
    1293     3116637 :                                             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     3598409 :     if ( hDirACRend->masa_stereo_type_detect != NULL )
    1302             :     {
    1303      379138 :         MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
    1304             : 
    1305      379138 :         p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
    1306      379138 :         p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
    1307      379138 :         if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
    1308             :         {
    1309      162553 :             target_power_y = p_cy_auto_dir_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->direct_power_factor[0] ) + EPSILON );
    1310      162553 :             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      216585 :             target_power_y = p_cy_auto_dir_smooth[num_freq_bands] + p_cy_auto_diff_smooth[num_freq_bands];
    1315             :         }
    1316      379138 :         subtract_power_y = masa_stereo_type_detect->subtract_power_y;
    1317             : 
    1318      379138 :         a = 0.0004f;  /* Temporal smoothing coefficient */
    1319      379138 :         b = 1.0f - a; /* Temporal smoothing coefficient */
    1320             : 
    1321      379138 :         masa_stereo_type_detect->target_power_y_smooth = a * target_power_y + b * masa_stereo_type_detect->target_power_y_smooth;
    1322      379138 :         masa_stereo_type_detect->subtract_power_y_smooth = a * subtract_power_y + b * masa_stereo_type_detect->subtract_power_y_smooth;
    1323             : 
    1324      379138 :         subtract_target_ratio = masa_stereo_type_detect->subtract_power_y_smooth / ( masa_stereo_type_detect->target_power_y_smooth + EPSILON );
    1325      379138 :         subtract_target_ratio_db = 10.0f * log10f( subtract_target_ratio );
    1326      379138 :         masa_stereo_type_detect->subtract_target_ratio_db = subtract_target_ratio_db;
    1327             : 
    1328      379138 :         masa_stereo_type_detect->subtract_power_y = 0.0f;
    1329             :     }
    1330             : 
    1331             :     /*-----------------------------------------------------------------*
    1332             :      * compute smoothing coefficients
    1333             :      *-----------------------------------------------------------------*/
    1334             : 
    1335     3598409 :     alpha_synthesis = h_dirac_output_synthesis_params->alpha_synthesis;
    1336     3598409 :     alpha_synthesis_fast = h_dirac_output_synthesis_params->alpha_synthesis_fast;
    1337     3598409 :     alphaMaxBin = h_dirac_output_synthesis_params->numAlphas - 1;
    1338     3598409 :     alphaMaxBinFast = h_dirac_output_synthesis_params->numAlphasFast - 1;
    1339             : 
    1340   171743589 :     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   168145180 :         float alpha_quality_based = 0.02f;
    1346             : 
    1347   168145180 :         indexSlow = min( l, alphaMaxBin );
    1348   168145180 :         indexFast = min( l, alphaMaxBinFast );
    1349             : 
    1350             :         /* Estimate the smoothness of the directions based on the diffuseness parameter */
    1351   168145180 :         instDirectionSmoothness = 1.0f - diffuseness_vector[l];
    1352   168145180 :         instDirectionSmoothness = min( max( instDirectionSmoothness, 0.0f ), 1.0f );
    1353             : 
    1354             :         /* Average the direction smoothness parameter over time */
    1355   168145180 :         currWeight = DIRECTION_SMOOTHNESS_ALPHA * reference_power_smooth[l];
    1356   168145180 :         prevWeight = ( 1.0f - DIRECTION_SMOOTHNESS_ALPHA ) * h_dirac_output_synthesis_state->reference_power_smooth_prev[l];
    1357             : 
    1358   168145180 :         weightedDirectionSmoothness = currWeight * instDirectionSmoothness + prevWeight * h_dirac_output_synthesis_state->direction_smoothness_prev[l];
    1359   168145180 :         sumWeight = currWeight + prevWeight;
    1360   168145180 :         smoothedDirectionSmoothness = weightedDirectionSmoothness / ( sumWeight + EPSILON );
    1361             : 
    1362   168145180 :         h_dirac_output_synthesis_state->direction_smoothness_prev[l] = smoothedDirectionSmoothness;
    1363   168145180 :         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   168145180 :         alpha[l] = smoothedDirectionSmoothness * alpha_synthesis_fast[indexFast] + ( 1.0f - smoothedDirectionSmoothness ) * alpha_synthesis[indexSlow];
    1367             : 
    1368             :         /* Adjust smoothing parameter based on encoding quality */
    1369   168145180 :         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     3598409 :     p_power_smooth_prev = h_dirac_output_synthesis_state->proto_power_smooth_prev;
    1378     3598409 :     p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth;
    1379             : 
    1380    14112062 :     for ( k = 0; k < num_protos_dir; k++ )
    1381             :     {
    1382   506344493 :         for ( l = 0; l < num_freq_bands; l++ )
    1383             :         {
    1384   495830840 :             g1 = alpha[l];
    1385   495830840 :             g2 = ( 1.f - g1 );
    1386   495830840 :             *p_power_smooth_prev = EPSILON + g2 * ( *p_power_smooth_prev );
    1387   495830840 :             *( p_power_smooth_prev ) += g1 * ( *p_power_smooth );
    1388   495830840 :             *( p_power_smooth++ ) = 1.f / ( *( p_power_smooth_prev++ ) );
    1389             :         }
    1390             :     }
    1391             : 
    1392             :     /*Direct gains and diffuse gains on number of output channels*/
    1393     3598409 :     p_power_diff_smooth_prev = h_dirac_output_synthesis_state->proto_power_diff_smooth_prev;
    1394     3598409 :     p_power_smooth_diff = h_dirac_output_synthesis_state->proto_power_diff_smooth;
    1395             : 
    1396     3598409 :     p_gains_diff = gains_diff;
    1397     3598409 :     p_gains_dir = gains_dir;
    1398             : 
    1399     3598409 :     p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
    1400     3598409 :     p_cy_auto_dir_smooth_prev = h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev;
    1401     3598409 :     p_cy_cross_dir_smooth = h_dirac_output_synthesis_state->cy_cross_dir_smooth;
    1402     3598409 :     p_cy_cross_dir_smooth_prev = h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev;
    1403             : 
    1404     3598409 :     p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
    1405     3598409 :     p_cy_auto_diff_smooth_prev = h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev;
    1406    31165412 :     for ( k = 0; k < nchan_out_woLFE; k++ )
    1407             :     {
    1408    27567003 :         p_power_smooth = h_dirac_output_synthesis_state->proto_power_smooth + proto_direct_index[k] * num_freq_bands;
    1409   378394713 :         for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    1410             :         {
    1411             :             /*Direct*/
    1412   350827710 :             g1 = alpha[l];
    1413   350827710 :             g2 = 1.f - g1;
    1414   350827710 :             *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
    1415   350827710 :             *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
    1416             : 
    1417   350827710 :             *( p_gains_dir ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
    1418             : 
    1419   350827710 :             if ( *( p_gains_dir ) < 0.f )
    1420             :             {
    1421           0 :                 *( p_gains_dir ) = 0.f;
    1422             :             }
    1423   350827710 :             else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
    1424             :             {
    1425     2823863 :                 *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
    1426             :             }
    1427             : 
    1428   350827710 :             if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    1429             :             {
    1430    47652953 :                 *( p_gains_dir ) *= -1.f;
    1431             :             }
    1432   350827710 :             p_gains_dir++;
    1433             : 
    1434             :             /*diffuse*/
    1435   350827710 :             *p_power_diff_smooth_prev = g1 * ( *p_power_smooth_diff++ ) + g2 * ( *p_power_diff_smooth_prev ) + EPSILON;
    1436   350827710 :             *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
    1437             : 
    1438   350827710 :             *( p_gains_diff ) = sqrtf( *( p_cy_auto_diff_smooth_prev++ ) / ( *( p_power_diff_smooth_prev++ ) ) );
    1439             : 
    1440   350827710 :             if ( *( p_gains_diff ) < 0.f )
    1441             :             {
    1442           0 :                 *( p_gains_diff ) = 0.f;
    1443             :             }
    1444   350827710 :             else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
    1445             :             {
    1446    11726815 :                 *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
    1447             :             }
    1448   350827710 :             p_gains_diff++;
    1449             :         }
    1450             : 
    1451             :         /*Only direct prototype*/
    1452   951069713 :         for ( ; l < num_freq_bands; l++ )
    1453             :         {
    1454             :             /*Direct*/
    1455   923502710 :             g1 = alpha[l];
    1456   923502710 :             g2 = 1.f - g1;
    1457   923502710 :             *( p_cy_auto_dir_smooth_prev ) = g1 * ( *( p_cy_auto_dir_smooth++ ) ) + g2 * ( *( p_cy_auto_dir_smooth_prev ) );
    1458   923502710 :             *( p_cy_cross_dir_smooth_prev ) = g1 * ( *( p_cy_cross_dir_smooth++ ) ) + g2 * ( *( p_cy_cross_dir_smooth_prev ) );
    1459             : 
    1460   923502710 :             *( p_gains_dir ) = sqrtf( *( p_power_smooth ) * ( *( p_cy_auto_dir_smooth_prev++ ) ) );
    1461             : 
    1462   923502710 :             if ( *( p_gains_dir ) < 0.f )
    1463             :             {
    1464           0 :                 *( p_gains_dir ) = 0.f;
    1465             :             }
    1466   923502710 :             else if ( *( p_gains_dir ) > DIRAC_GAIN_LIMIT )
    1467             :             {
    1468     5095825 :                 *( p_gains_dir ) = DIRAC_GAIN_LIMIT;
    1469             :             }
    1470             : 
    1471   923502710 :             if ( *( p_cy_cross_dir_smooth_prev++ ) < 0 )
    1472             :             {
    1473    94634730 :                 *( p_gains_dir ) *= -1.f;
    1474             :             }
    1475   923502710 :             p_gains_dir++;
    1476             : 
    1477             :             /*diffuse*/
    1478   923502710 :             *( p_cy_auto_diff_smooth_prev ) = g1 * ( *( p_cy_auto_diff_smooth++ ) ) + g2 * ( *( p_cy_auto_diff_smooth_prev ) );
    1479   923502710 :             *( p_gains_diff ) = sqrtf( *( p_power_smooth++ ) * ( *( p_cy_auto_diff_smooth_prev++ ) ) );
    1480   923502710 :             if ( *( p_gains_diff ) < 0.f )
    1481             :             {
    1482           0 :                 *( p_gains_diff ) = 0.f;
    1483             :             }
    1484   923502710 :             else if ( *( p_gains_diff ) > DIRAC_GAIN_LIMIT )
    1485             :             {
    1486     5348999 :                 *( p_gains_diff ) = DIRAC_GAIN_LIMIT;
    1487             :             }
    1488   923502710 :             p_gains_diff++;
    1489             :         }
    1490             :     }
    1491             : 
    1492             :     /*-----------------------------------------------------------------*
    1493             :      * gain interpolation and output streams
    1494             :      *-----------------------------------------------------------------*/
    1495             : 
    1496    17877038 :     for ( buf_idx = 0; buf_idx < nbslots; ++buf_idx )
    1497             :     {
    1498    14278629 :         g1 = h_dirac_output_synthesis_params->interpolator[buf_idx];
    1499    14278629 :         g2 = 1.f - g1;
    1500             : 
    1501             :         /*Direct stream*/
    1502    14278629 :         p_gain_1 = gains_dir;
    1503    14278629 :         p_gain_2 = h_dirac_output_synthesis_state->gains_dir_prev;
    1504   124050611 :         for ( k = 0; k < nchan_out_woLFE; k++ )
    1505             :         {
    1506   109771982 :             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  5179384802 :             for ( l = 0; l < num_freq_bands; l++ )
    1508             :             {
    1509  5069612820 :                 g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
    1510  5069612820 :                 RealBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
    1511  5069612820 :                 ImagBuffer[k][buf_idx][l] = g * ( *( p_power_smooth++ ) );
    1512             :             }
    1513             :         }
    1514             : 
    1515             :         /*Diffuse stream*/
    1516    14278629 :         if ( h_dirac_output_synthesis_params->max_band_decorr != 0 )
    1517             :         {
    1518    11724672 :             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    14278629 :         p_gain_1 = gains_diff;
    1521    14278629 :         p_gain_2 = h_dirac_output_synthesis_state->gains_diff_prev;
    1522   124050611 :         for ( k = 0; k < nchan_out_woLFE; k++ )
    1523             :         {
    1524  1505992517 :             for ( l = 0; l < h_dirac_output_synthesis_params->max_band_decorr; l++ )
    1525             :             {
    1526  1396220535 :                 g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
    1527  1396220535 :                 RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
    1528  1396220535 :                 ImagBuffer[k][buf_idx][l] += g * ( *( p_power_smooth_diff++ ) );
    1529             :             }
    1530             : 
    1531             :             /*Direct proto*/
    1532   109771982 :             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  3783164267 :             for ( ; l < num_freq_bands; l++ )
    1534             :             {
    1535  3673392285 :                 g = g1 * ( *( p_gain_1++ ) ) + g2 * ( *( p_gain_2++ ) );
    1536  3673392285 :                 RealBuffer[k][buf_idx][l] += g * ( *( p_power_smooth++ ) );
    1537  3673392285 :                 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     3598409 :     mvr2r( gains_dir, h_dirac_output_synthesis_state->gains_dir_prev, num_freq_bands * nchan_out_woLFE );
    1548     3598409 :     mvr2r( gains_diff, h_dirac_output_synthesis_state->gains_diff_prev, num_freq_bands * nchan_out_woLFE );
    1549             : 
    1550             :     /* reset values */
    1551     3598409 :     set_zero( h_dirac_output_synthesis_state->proto_power_smooth, num_freq_bands * num_protos_dir );
    1552             : 
    1553     3598409 :     if ( h_dirac_output_synthesis_state->proto_power_diff_smooth != NULL )
    1554             :     {
    1555     3598409 :         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     3598409 :     set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth, num_freq_bands * nchan_out_woLFE );
    1559     3598409 :     set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth, num_freq_bands * nchan_out_woLFE );
    1560     3598409 :     set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth, num_freq_bands * nchan_out_woLFE );
    1561             : 
    1562     3598409 :     pop_wmops();
    1563             : 
    1564     3598409 :     return;
    1565             : }
    1566             : 
    1567             : 
    1568             : /*-------------------------------------------------------------------------
    1569             :  * ivas_dirac_dec_compute_directional_responses()
    1570             :  *
    1571             :  *
    1572             :  *------------------------------------------------------------------------*/
    1573             : 
    1574    38666709 : 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    38666709 :     azimuth2 = NULL;
    1602    38666709 :     elevation2 = NULL;
    1603    38666709 :     transport_signal_type = MASA_STEREO_NOT_DEFINED;
    1604             : 
    1605    38666709 :     if ( hDirACRend->masa_stereo_type_detect != NULL )
    1606             :     {
    1607      379138 :         dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
    1608      379138 :         dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
    1609      379138 :         transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
    1610             :     }
    1611             : 
    1612    38666709 :     num_channels_dir = hDirACRend->num_outputs_dir;
    1613    38666709 :     if ( hSpatParamRendCom->numParametricDirections == 2 )
    1614             :     {
    1615     8323617 :         azimuth2 = hSpatParamRendCom->azimuth2[md_idx];
    1616     8323617 :         elevation2 = hSpatParamRendCom->elevation2[md_idx];
    1617             :     }
    1618             : 
    1619    38666709 :     codingBand = -1;
    1620             : 
    1621    38666709 :     assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
    1622             : 
    1623  1795792869 :     for ( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
    1624             :     {
    1625  1757126160 :         if ( masa_band_mapping != NULL && k == MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] )
    1626             :         {
    1627    29042930 :             codingBand++;
    1628             :         }
    1629             : 
    1630  1757126160 :         if ( masa_band_mapping != NULL && k > MASA_band_grouping_24[masa_band_mapping[codingBand]] &&
    1631   126219470 :              k < MASA_band_grouping_24[masa_band_mapping[codingBand + 1]] &&
    1632   126219470 :              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   125709367 :             if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
    1636             :             {
    1637   117894698 :                 mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k - 1],
    1638   117894698 :                            hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k],
    1639   117894698 :                            hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1640             :             }
    1641   125709367 :             mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses[k - 1],
    1642   125709367 :                        hSpatParamRendCom->num_freq_bands,
    1643   125709367 :                        &hDirACRend->h_output_synthesis_psd_state.direct_responses[k],
    1644   125709367 :                        hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1645             :         }
    1646             :         else
    1647             :         {
    1648             :             /* HOA3 PANNING */
    1649  1631416793 :             if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 )
    1650             :             {
    1651  1522384043 :                 set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS );
    1652  1522384043 :                 set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS );
    1653             : 
    1654  1522384043 :                 ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order );
    1655             : 
    1656  1522384043 :                 if ( hodirac_flag )
    1657             :                 {
    1658   406990800 :                     ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order );
    1659             :                 }
    1660             : 
    1661  1522384043 :                 if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
    1662             :                 {
    1663  1511534480 :                     mvr2r_inc( direct_response_hoa, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1664             : 
    1665  1511534480 :                     if ( hodirac_flag )
    1666             :                     {
    1667   406990800 :                         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    10849563 :                 else if ( ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( masa_band_mapping != NULL ) ) ||
    1671     8964692 :                           hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
    1672             :                 {
    1673             :                     /* Synthesize the first direction */
    1674    10849563 :                     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    10849563 :                     if ( hSpatParamRendCom->numParametricDirections == 2 )
    1678             :                     {
    1679     1167645 :                         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     1167645 :                         totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
    1682     1167645 :                         directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
    1683     1167645 :                         directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
    1684     9807845 :                         for ( l = 0; l < num_channels_dir; l++ )
    1685             :                         {
    1686     8640200 :                             direct_response_hoa[l] *= directRatio[0];
    1687     8640200 :                             direct_response_hoa[l] += directRatio[1] * direct_response_dir2[l];
    1688             :                         }
    1689             :                     }
    1690             : 
    1691    10849563 :                     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      541273 :                         set_zero( direct_response_ism, num_channels_dir );
    1700             : 
    1701     2563805 :                         for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1702             :                         {
    1703     2022532 :                             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     2022532 :                                 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    21092276 :                             for ( l = 0; l < num_channels_dir; l++ )
    1713             :                             {
    1714    19069744 :                                 direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1715             :                             }
    1716             :                         }
    1717             : 
    1718      541273 :                         masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
    1719      541273 :                         if ( hSpatParamRendCom->numParametricDirections == 2 )
    1720             :                         {
    1721       28981 :                             masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
    1722             :                         }
    1723             : 
    1724      541273 :                         ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
    1725     2022532 :                         for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1726             :                         {
    1727     1481259 :                             ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1728             :                         }
    1729             : 
    1730      541273 :                         totalDirect = masaDirect + ismDirect;
    1731      541273 :                         directRatio[0] = masaDirect / totalDirect;
    1732      541273 :                         directRatio[1] = ismDirect / totalDirect;
    1733     5653229 :                         for ( l = 0; l < num_channels_dir; l++ )
    1734             :                         {
    1735     5111956 :                             direct_response_hoa[l] *= directRatio[0];
    1736     5111956 :                             direct_response_hoa[l] += directRatio[1] * direct_response_ism[l];
    1737             :                         }
    1738             :                     }
    1739             : 
    1740             :                     /* Synthesize surrounding coherence */
    1741    10849563 :                     if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
    1742             :                     {
    1743    60024759 :                         for ( l = 1; l < num_channels_dir; l++ )
    1744             :                         {
    1745    52753895 :                             direct_response_hoa[l] *= sqrtf( 1.0f - surCohRatio[k] );
    1746             :                         }
    1747             :                     }
    1748             : 
    1749             :                     /* Set computed gains */
    1750    10849563 :                     direct_response = direct_response_hoa;
    1751    10849563 :                     if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
    1752             :                     {
    1753     8964692 :                         v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
    1754     8964692 :                         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     8964692 :                         if ( transport_signal_type == MASA_STEREO_SPACED_MICS )
    1757             :                         {
    1758     1100412 :                             direct_response[0] = 1.0f;
    1759     1100412 :                             if ( k >= dipole_freq_range[0] && k < dipole_freq_range[1] )
    1760             :                             {
    1761      146097 :                                 direct_response[1] = 1.0f;
    1762             :                             }
    1763             :                         }
    1764             :                         else
    1765             :                         {
    1766     7864280 :                             set_f( direct_response, 1.0f, hDirACRend->num_protos_ambi );
    1767             :                         }
    1768             :                     }
    1769             : 
    1770    10849563 :                     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   109032750 :             else if ( hDirACRend->panningConf == DIRAC_PANNING_VBAP ) /*VBAP*/
    1778             :             {
    1779             :                 /* Synthesize the first direction */
    1780   109032750 :                 spreadCoherencePanningVbap( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata );
    1781   109032750 :                 normalizePanningGains( direct_response_ls, num_channels_dir );
    1782             : 
    1783             :                 /* Synthesize the second direction and combine the gains */
    1784   109032750 :                 if ( hSpatParamRendCom->numParametricDirections == 2 )
    1785             :                 {
    1786     1898527 :                     spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata );
    1787     1898527 :                     normalizePanningGains( direct_response_dir2, num_channels_dir );
    1788             : 
    1789             :                     /* Combine gains from the two directions */
    1790     1898527 :                     totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
    1791     1898527 :                     directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
    1792     1898527 :                     directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
    1793    16871002 :                     for ( l = 0; l < num_channels_dir; l++ )
    1794             :                     {
    1795    14972475 :                         direct_response_ls[l] *= directRatio[0];
    1796    14972475 :                         direct_response_ls[l] += directRatio[1] * direct_response_dir2[l];
    1797             :                     }
    1798     1898527 :                     normalizePanningGains( direct_response_ls, num_channels_dir );
    1799             :                 }
    1800             : 
    1801   109032750 :                 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      706346 :                     set_zero( direct_response_ism, num_channels_dir );
    1810             : 
    1811     2890574 :                     for ( dir = 0; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1812             :                     {
    1813     2184228 :                         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     2184228 :                             vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism[dir][md_idx], hMasaIsm->elevation_ism[dir][md_idx], 1 );
    1820             :                         }
    1821             : 
    1822    19894800 :                         for ( l = 0; l < num_channels_dir; l++ )
    1823             :                         {
    1824    17710572 :                             direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1825             :                         }
    1826             :                     }
    1827      706346 :                     normalizePanningGains( direct_response_ism, num_channels_dir );
    1828             : 
    1829      706346 :                     masaDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + EPSILON;
    1830      706346 :                     if ( hSpatParamRendCom->numParametricDirections == 2 )
    1831             :                     {
    1832      120884 :                         masaDirect += hSpatParamRendCom->energy_ratio2[md_idx][k];
    1833             :                     }
    1834             : 
    1835      706346 :                     ismDirect = hMasaIsm->energy_ratio_ism[0][md_idx][k];
    1836     2184228 :                     for ( dir = 1; dir < hSpatParamRendCom->numIsmDirections; dir++ )
    1837             :                     {
    1838     1477882 :                         ismDirect += hMasaIsm->energy_ratio_ism[dir][md_idx][k];
    1839             :                     }
    1840             : 
    1841      706346 :                     totalDirect = masaDirect + ismDirect;
    1842      706346 :                     directRatio[0] = masaDirect / totalDirect;
    1843      706346 :                     directRatio[1] = ismDirect / totalDirect;
    1844     6426080 :                     for ( l = 0; l < num_channels_dir; l++ )
    1845             :                     {
    1846     5719734 :                         direct_response_ls[l] *= directRatio[0];
    1847     5719734 :                         direct_response_ls[l] += directRatio[1] * direct_response_ism[l];
    1848             :                     }
    1849      706346 :                     normalizePanningGains( direct_response_ls, num_channels_dir );
    1850             :                 }
    1851             : 
    1852             :                 /* Synthesize surrounding coherence */
    1853   109032750 :                 if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
    1854             :                 {
    1855             :                     int16_t num_channels_surrCoh;
    1856             : 
    1857    12172153 :                     num_channels_surrCoh = num_channels_dir;
    1858    12172153 :                     num_channels_surrCoh -= hDirACRend->num_ele_spk_no_diffuse_rendering;
    1859             : 
    1860   105382124 :                     for ( l = 0; l < num_channels_dir; l++ )
    1861             :                     {
    1862    93209971 :                         direct_response_ls[l] *= sqrtf( 1.0f - surCohRatio[k] );
    1863    93209971 :                         if ( hDirACRend->diffuse_response_function[l] > 0.f )
    1864             :                         {
    1865    92926691 :                             direct_response_ls[l] += sqrtf( surCohRatio[k] / (float) num_channels_surrCoh );
    1866             :                         }
    1867             :                     }
    1868             :                 }
    1869             : 
    1870   109032750 :                 normalizePanningGains( direct_response_ls, num_channels_dir );
    1871             : 
    1872             :                 /* Set computed gains */
    1873   109032750 :                 direct_response = direct_response_ls;
    1874   109032750 :                 v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
    1875   109032750 :                 mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
    1876   109032750 :                 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    38666709 :     return;
    1886             : }
    1887             : 
    1888             : 
    1889             : /*-------------------------------------------------------------------------
    1890             :  * ivas_dirac_dec_compute_gain_factors()
    1891             :  *
    1892             :  *
    1893             :  *------------------------------------------------------------------------*/
    1894             : 
    1895    27141400 : 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   166077743 :     for ( i = 0; i < max_band_decorr; i++ )
    1905             :     {
    1906   138936343 :         direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
    1907   138936343 :         diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
    1908             :     }
    1909  1083846437 :     for ( ; i < num_freq_bands; i++ )
    1910             :     {
    1911  1056705037 :         direct_gain_factor[i] = sqrtf( 1.f - diffuseness[i] );
    1912  1056705037 :         diffuse_gain_factor[i] = sqrtf( diffuseness[i] );
    1913             :     }
    1914             : 
    1915    27141400 :     return;
    1916             : }
    1917             : 
    1918             : 
    1919             : /*-------------------------------------------------------------------------
    1920             :  * ivas_dirac_dec_compute_power_factors()
    1921             :  *
    1922             :  *
    1923             :  *------------------------------------------------------------------------*/
    1924             : 
    1925     5043725 : 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     5043725 :     v_multc( diffuseness, -1.0f, direct_power_factor, num_freq_bands );
    1933             : 
    1934     5043725 :     v_addc( direct_power_factor, 1.0f, direct_power_factor, num_freq_bands );
    1935             : 
    1936     5043725 :     mvr2r( diffuseness, diffuse_power_factor, num_freq_bands );
    1937             : 
    1938     5043725 :     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     5043725 :     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     5043725 :     return;
    1943             : }
    1944             : 
    1945             : 
    1946             : /*-------------------------------------------------------------------------
    1947             :  * ivas_lfe_synth_with_filters()
    1948             :  *
    1949             :  *
    1950             :  *------------------------------------------------------------------------*/
    1951             : 
    1952       20257 : 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       20257 :     delay = hMasaLfeSynth->delayBuffer_syncDirAC_size;
    1975       20257 :     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       20257 :     lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize );
    1979    16289377 :     for ( i = 0; i < output_frame; i++ )
    1980             :     {
    1981    16269120 :         hMasaLfeSynth->lowpassSum += lowpassCoef * data_f[separateChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer];
    1982    16269120 :         lowPassSignal[i] = hMasaLfeSynth->lowpassSum;
    1983    16269120 :         highPassSignal[i] = hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferHiPointer] - lowPassSignal[i];
    1984    16269120 :         hMasaLfeSynth->lfeSynthRingBuffer[hMasaLfeSynth->ringBufferLoPointer] = data_f[separateChannelIndex][i];
    1985             : 
    1986    16269120 :         hMasaLfeSynth->ringBufferLoPointer--;
    1987    16269120 :         if ( hMasaLfeSynth->ringBufferLoPointer < 0 )
    1988             :         {
    1989       81028 :             hMasaLfeSynth->ringBufferLoPointer = hMasaLfeSynth->ringBufferSize - 1;
    1990             :         }
    1991             : 
    1992    16269120 :         hMasaLfeSynth->ringBufferHiPointer--;
    1993    16269120 :         if ( hMasaLfeSynth->ringBufferHiPointer < 0 )
    1994             :         {
    1995       81028 :             hMasaLfeSynth->ringBufferHiPointer = hMasaLfeSynth->ringBufferSize - 1;
    1996             :         }
    1997             :     }
    1998             : 
    1999             :     /* Synthesize the LFE signal */
    2000       20257 :     slotSize = output_frame / CLDFB_NO_COL_MAX;
    2001      344369 :     for ( slot_index = 0; slot_index < CLDFB_NO_COL_MAX; slot_index++ )
    2002             :     {
    2003      324112 :         subframe_index = slot_index / 4;
    2004             : 
    2005      324112 :         mrange[0] = slot_index * slotSize;
    2006      324112 :         mrange[1] = ( slot_index + 1 ) * slotSize;
    2007             : 
    2008      324112 :         transportEne = 0.0f;
    2009    16593232 :         for ( i = mrange[0]; i < mrange[1]; i++ )
    2010             :         {
    2011    16269120 :             transportEne += lowPassSignal[i] * lowPassSignal[i];
    2012             :         }
    2013             : 
    2014      324112 :         targetEneLfe = transportEne * hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index];
    2015      324112 :         targetEneTrans = transportEne * max( ( 1.0f - hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index] ), 0.01f );
    2016             : 
    2017      324112 :         hMasaLfeSynth->transportEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
    2018      324112 :         hMasaLfeSynth->targetEneLfeSmooth *= MCMASA_LFE_SYNTH_ALPHA;
    2019      324112 :         hMasaLfeSynth->targetEneTransSmooth *= MCMASA_LFE_SYNTH_ALPHA;
    2020             : 
    2021      324112 :         hMasaLfeSynth->transportEneSmooth += transportEne;
    2022      324112 :         hMasaLfeSynth->targetEneLfeSmooth += targetEneLfe;
    2023      324112 :         hMasaLfeSynth->targetEneTransSmooth += targetEneTrans;
    2024             : 
    2025      324112 :         lfeGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneLfeSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
    2026      324112 :         transportGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneTransSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
    2027             : 
    2028    16593232 :         for ( i = mrange[0], j = 0; i < mrange[1]; i++, j++ )
    2029             :         {
    2030    16269120 :             data_f[separateChannelIndex][i] = ( transportGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->transportGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i] + highPassSignal[i];
    2031    16269120 :             data_f[lfeChannelIndex][i] = ( lfeGain * hMasaLfeSynth->interpolator[j] + hMasaLfeSynth->lfeGainPrev * ( 1.0f - hMasaLfeSynth->interpolator[j] ) ) * lowPassSignal[i];
    2032             :         }
    2033             : 
    2034      324112 :         hMasaLfeSynth->lfeGainPrev = lfeGain;
    2035      324112 :         hMasaLfeSynth->transportGainPrev = transportGain;
    2036             :     }
    2037             : 
    2038             :     /* Lowpass filter for removing remaining mid and high frequencies from the LFE signal */
    2039       20257 :     lowpassCoef = 1.0f / ( (float) hMasaLfeSynth->ringBufferSize2 );
    2040    16289377 :     for ( i = 0; i < output_frame; i++ )
    2041             :     {
    2042    16269120 :         hMasaLfeSynth->lowpassSum2 += lowpassCoef * data_f[lfeChannelIndex][i] - lowpassCoef * hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2];
    2043    16269120 :         hMasaLfeSynth->lfeSynthRingBuffer2[hMasaLfeSynth->ringBufferLoPointer2] = data_f[lfeChannelIndex][i];
    2044             : 
    2045    16269120 :         hMasaLfeSynth->ringBufferLoPointer2--;
    2046    16269120 :         if ( hMasaLfeSynth->ringBufferLoPointer2 < 0 )
    2047             :         {
    2048      162056 :             hMasaLfeSynth->ringBufferLoPointer2 = hMasaLfeSynth->ringBufferSize2 - 1;
    2049             :         }
    2050             : 
    2051    16269120 :         data_f[lfeChannelIndex][i] = hMasaLfeSynth->lowpassSum2;
    2052             :     }
    2053             : 
    2054             :     /* Delay the separated channel to match the delay of the lowpass filter */
    2055       20257 :     delay = hMasaLfeSynth->delayBuffer_syncLp_size;
    2056       20257 :     delay_signal( data_f[separateChannelIndex], output_frame, hMasaLfeSynth->delayBuffer_syncLp, delay );
    2057             : 
    2058       20257 :     return;
    2059             : }
    2060             : 
    2061             : 
    2062             : /*-------------------------------------------------------------------------
    2063             :  * Local functions
    2064             :  *------------------------------------------------------------------------*/
    2065             : 
    2066     1927088 : 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     1927088 :     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    17990832 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2087             :     {
    2088    16063744 :         cur_idx = ch_idx * num_freq_bands;
    2089             : 
    2090    16063744 :         v_mult( direct_power, &direct_responses_square[cur_idx], aux_buffer_res, num_freq_bands );
    2091    16063744 :         v_add( &cy_auto_dir_smooth[cur_idx], aux_buffer_res, &cy_auto_dir_smooth[cur_idx], num_freq_bands );
    2092             : 
    2093    16063744 :         v_mult( direct_power, &direct_responses[cur_idx], aux_buffer_res, num_freq_bands );
    2094    16063744 :         v_add( &cy_cross_dir_smooth[cur_idx], aux_buffer_res, &cy_cross_dir_smooth[cur_idx], num_freq_bands );
    2095             :     }
    2096             : 
    2097     1927088 :     return;
    2098             : }
    2099             : 
    2100             : 
    2101     3116637 : 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     3116637 :     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    26830257 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2121             :     {
    2122    23713620 :         cur_idx = ch_idx * num_freq_bands;
    2123             : 
    2124    23713620 :         v_mult( direct_power, &direct_responses_square[cur_idx], &cy_auto_dir_smooth[cur_idx], num_freq_bands );
    2125    23713620 :         v_mult( direct_power, &direct_responses[cur_idx], &cy_cross_dir_smooth[cur_idx], num_freq_bands );
    2126             :     }
    2127             : 
    2128     3116637 :     return;
    2129             : }
    2130             : 
    2131             : 
    2132     1927088 : 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     1927088 :     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    17990832 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2152             :     {
    2153    16063744 :         cur_idx = ch_idx * num_freq_bands;
    2154    16063744 :         v_multc( &diffuse_power[start_band], diffuse_responses_square[ch_idx], aux_buffer_res, num_freq_bands - start_band );
    2155    16063744 :         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     1927088 :     return;
    2159             : }
    2160             : 
    2161             : 
    2162     3116637 : 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     3116637 :     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    26830257 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2179             :     {
    2180    23713620 :         cur_idx = ch_idx * num_freq_bands;
    2181             : 
    2182    23713620 :         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     3116637 :     return;
    2186             : }
    2187             : 
    2188             : 
    2189     8483623 : 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     8483623 :     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    72195116 :     for ( ch_idx = 0; ch_idx < num_channels; ++ch_idx )
    2211             :     {
    2212    63711493 :         diffuse_response_p4 = diffuse_responses_square[ch_idx] * diffuse_responses_square[ch_idx];
    2213             : 
    2214    63711493 :         cur_idx = ch_idx * num_freq_bands;
    2215    63711493 :         diff_idx = proto_frame_diff_index[ch_idx] * num_freq_bands;
    2216             : 
    2217    63711493 :         v_multc( &onset_filter[diff_idx], diffuse_responses_square[ch_idx], aux_buffer_res1, num_decorr_freq_bands );
    2218    63711493 :         v_multc( &onset_filter[diff_idx], -1.0f, aux_buffer_res, num_decorr_freq_bands );
    2219    63711493 :         v_addc( aux_buffer_res, 1.0f, aux_buffer_res, num_decorr_freq_bands );
    2220    63711493 :         v_multc( aux_buffer_res, diffuse_response_p4, aux_buffer_res, num_decorr_freq_bands );
    2221    63711493 :         v_add( aux_buffer_res1, aux_buffer_res, aux_buffer_res, num_decorr_freq_bands );
    2222    63711493 :         v_mult( aux_buffer_res, diffuse_power, aux_buffer_res, num_decorr_freq_bands );
    2223    63711493 :         v_add( &cy_auto_diff_smooth[cur_idx], aux_buffer_res, &cy_auto_diff_smooth[cur_idx], num_decorr_freq_bands );
    2224             :     }
    2225             : 
    2226     8483623 :     return;
    2227             : }
    2228             : 
    2229       90140 : 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       90140 :     if ( alpha_synthesis == NULL )
    2244             :     {
    2245             : #ifdef DEBUGGING
    2246             :         assert( !"Error: NULL pointer.\n" );
    2247             : #endif
    2248           0 :         return;
    2249             :     }
    2250             : 
    2251       90140 :     if ( averaging_length_ms == 0 )
    2252             :     {
    2253           0 :         set_f( alpha_synthesis, 1.0f, num_freq_bands );
    2254             :     }
    2255             :     else
    2256             :     {
    2257      360560 :         for ( k = 0; k < num_freq_bands; k++ )
    2258             :         {
    2259      360560 :             int16_t faxis_idx = max( k, 1 );
    2260      360560 :             avg_length_f_ms = 1000.f * (float) averaging_length_ms / fabsf( frequency_axis[faxis_idx] );
    2261      360560 :             alpha_synthesis[k] = min( (float) slot_size / ( avg_length_f_ms * (float) output_Fs / 1000.f ), 1.0f );
    2262      360560 :             if ( alpha_synthesis[k] >= maxAlpha )
    2263             :             {
    2264       90140 :                 alpha_synthesis[k] = maxAlpha;
    2265       90140 :                 *numAlphas = k + 1;
    2266       90140 :                 break;
    2267             :             }
    2268             :         }
    2269             :     }
    2270             : 
    2271       90140 :     return;
    2272             : }
    2273             : 
    2274    12017208 : 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    12017208 :     ivas_dirac_dec_get_response( azimuth, elevation, direct_response, ambisonics_order );
    2289             : 
    2290    12017208 :     if ( spreadCoh > 0.f )
    2291             :     {
    2292     6586351 :         ivas_dirac_dec_get_response( azimuth + 30, elevation, direct_response_left, ambisonics_order );
    2293             : 
    2294     6586351 :         ivas_dirac_dec_get_response( azimuth + 330, elevation, direct_response_right, ambisonics_order );
    2295             : 
    2296     6586351 :         if ( spreadCoh < 0.5f )
    2297             :         {
    2298     6109730 :             gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh / 3.0f;
    2299     6109730 :             gainSide = 2.0f * spreadCoh / 3.0f;
    2300             :         }
    2301             :         else
    2302             :         {
    2303      476621 :             gainSide = 1.0f / ( 4.0f - 2.0f * spreadCoh );
    2304      476621 :             gainCenter = ( 2.0f - 2.0f * spreadCoh ) * gainSide;
    2305             :         }
    2306             : 
    2307    60169223 :         for ( i = 0; i < num_channels_dir; i++ )
    2308             :         {
    2309    53582872 :             direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
    2310             :         }
    2311             :     }
    2312             : 
    2313    12017208 :     return;
    2314             : }
    2315             : 
    2316   110931277 : 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   110931277 :     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   110931277 :     vbap_determine_gains( hVBAPdata, direct_response, azimuth, elevation, 0 );
    2339             : 
    2340   110931277 :     if ( spreadCoh > 0.f )
    2341             :     {
    2342    11955698 :         vbap_determine_gains( hVBAPdata, direct_response_left, azimuth + 30, elevation, 0 );
    2343    11955698 :         vbap_determine_gains( hVBAPdata, direct_response_right, azimuth - 30, elevation, 0 );
    2344             : 
    2345    11955698 :         if ( spreadCoh < 0.5f )
    2346             :         {
    2347    11031926 :             gainCenter = ( 1.0f - 2.0f * spreadCoh ) + 2.0f * spreadCoh * INV_SQRT3;
    2348    11031926 :             gainSide = 2.0f * spreadCoh * INV_SQRT3;
    2349             :         }
    2350             :         else
    2351             :         {
    2352      923772 :             gainCenter = 2.0f - 2.0f * spreadCoh;
    2353      923772 :             gainSide = 1.0f;
    2354             :         }
    2355             : 
    2356   103183775 :         for ( i = 0; i < num_channels_dir; i++ )
    2357             :         {
    2358    91228077 :             direct_response[i] = direct_response[i] * gainCenter + ( direct_response_left[i] + direct_response_right[i] ) * gainSide;
    2359             :         }
    2360             :     }
    2361             : 
    2362   110931277 :     return;
    2363             : }
    2364             : 
    2365             : 
    2366   223275246 : 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   223275246 :     energySum = sum2_f( direct_response, num_channels_dir ) + 1e-12f;
    2375   223275246 :     normVal = sqrtf( 1.0f / energySum );
    2376  2079799288 :     for ( i = 0; i < num_channels_dir; i++ )
    2377             :     {
    2378  1856524042 :         direct_response[i] *= normVal;
    2379             :     }
    2380             : 
    2381   223275246 :     return;
    2382             : }

Generated by: LCOV version 1.14