LCOV - code coverage report
Current view: top level - lib_dec - ivas_ism_param_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 805 861 93.5 %
Date: 2025-05-03 01:55:50 Functions: 17 17 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 <stdint.h>
      34             : #include <assert.h>
      35             : #include <math.h>
      36             : #include "options.h"
      37             : #include "ivas_prot_rend_fx.h"
      38             : #include "prot_fx.h"
      39             : #include "rom_com.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_rom_dec.h"
      42             : #include "wmc_auto.h"
      43             : #include "ivas_prot_fx.h"
      44             : #include "debug.h"
      45             : #include "ivas_rom_com_fx.h"
      46             : 
      47             : /*-----------------------------------------------------------------------*
      48             :  * Local function definitions
      49             :  *-----------------------------------------------------------------------*/
      50             : 
      51       12884 : static void ivas_param_ism_dec_dequant_DOA_fx(
      52             :     PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle         */
      53             :     const Word16 nchan_ism             /* i  : number of ISM channels       */
      54             : )
      55             : {
      56             :     Word16 i;
      57             :     PARAM_ISM_CONFIG_HANDLE hParamIsm;
      58             : 
      59       12884 :     hParamIsm = hParamIsmDec->hParamIsm;
      60             : 
      61       12884 :     assert( nchan_ism <= MAX_NUM_OBJECTS );
      62             : 
      63             :     /* Get the azimuth and elevation values */
      64       60669 :     FOR( i = 0; i < nchan_ism; i++ )
      65             :     {
      66       47785 :         hParamIsmDec->azimuth_values_fx[i] = ism_dequant_meta_fx( hParamIsm->azi_index[i], ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); // Q22
      67       47785 :         move16();
      68       47785 :         hParamIsmDec->elevation_values_fx[i] = ism_dequant_meta_fx( hParamIsm->ele_index[i], ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS ); // Q22
      69       47785 :         move16();
      70             :     }
      71             : 
      72       12884 :     return;
      73             : }
      74             : 
      75       12884 : static void ivas_param_ism_dec_dequant_powrat_fx(
      76             :     PARAM_ISM_DEC_HANDLE hParamIsmDec /* i/o: decoder ParamISM handle         */
      77             : )
      78             : {
      79             :     Word16 band_idx, slot_idx;
      80             :     PARAM_ISM_CONFIG_HANDLE hParamIsm;
      81             : 
      82       12884 :     hParamIsm = hParamIsmDec->hParamIsm;
      83             :     /* Get the power ratio values */
      84      154608 :     FOR( band_idx = 0; band_idx < hParamIsm->nbands; band_idx++ )
      85             :     {
      86      283448 :         FOR( slot_idx = 0; slot_idx < hParamIsm->nblocks[band_idx]; slot_idx++ )
      87             :         {
      88      141724 :             hParamIsmDec->power_ratios_fx[band_idx][slot_idx][0] = add( shr( imult1616( hParamIsm->power_ratios_idx[band_idx][slot_idx], 4681 /* ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) in Q15 */ ), 1 ), 16384 /*.5f in Q15 */ ); /* Q15 */
      89      141724 :             move16();
      90      141724 :             hParamIsmDec->power_ratios_fx[band_idx][slot_idx][1] = sub( 32767, hParamIsmDec->power_ratios_fx[band_idx][slot_idx][0] ); // Q15 , 32767= (1.0f in Q15) -1
      91      141724 :             move16();
      92             :         }
      93             :     }
      94       12884 :     return;
      95             : }
      96             : 
      97             : 
      98         166 : static void ivas_ism_get_interpolator_fx(
      99             :     const Word16 subframe_nbslots,
     100             :     Word16 *interpolator /*Q15*/
     101             : )
     102             : {
     103             :     Word16 interp_idx, q_tmp, tmp;
     104             : 
     105        4038 :     FOR( interp_idx = 0; interp_idx < subframe_nbslots; interp_idx++ )
     106             :     {
     107        3872 :         tmp = BASOP_Util_Divide1616_Scale( add( interp_idx, 1 ), subframe_nbslots, &q_tmp ); /*Q = 15 - q_tmp*/
     108        3872 :         interpolator[interp_idx] = shl_sat( tmp, q_tmp );                                    /* Q15 */
     109        3872 :         move16();
     110             :     }
     111             : 
     112         166 :     return;
     113             : }
     114             : 
     115             : 
     116          21 : static void ivas_ism_get_proto_matrix_fx(
     117             :     IVAS_OUTPUT_SETUP hOutSetup,
     118             :     const Word16 nchan_transport,
     119             :     Word16 *proto_matrix /*Q15*/
     120             : )
     121             : {
     122             :     Word16 idx;
     123             : 
     124             :     /* compute proto_matrix */
     125          21 :     SWITCH( nchan_transport )
     126             :     {
     127          21 :         case 2:
     128             :         {
     129          21 :             IF( hOutSetup.nchan_out_woLFE )
     130             :             {
     131         248 :                 FOR( idx = 0; idx < hOutSetup.nchan_out_woLFE; idx++ )
     132             :                 {
     133         227 :                     IF( hOutSetup.ls_azimuth_fx[idx] > 0 )
     134             :                     {
     135         103 :                         proto_matrix[idx] = 32767; /* 1.0f in Q15 */
     136         103 :                         move16();
     137         103 :                         proto_matrix[idx + hOutSetup.nchan_out_woLFE] = 0;
     138         103 :                         move16();
     139             :                     }
     140         124 :                     ELSE IF( hOutSetup.ls_azimuth_fx[idx] < 0 )
     141             :                     {
     142         103 :                         proto_matrix[idx] = 0;
     143         103 :                         move16();
     144         103 :                         proto_matrix[idx + hOutSetup.nchan_out_woLFE] = 32767; /* 1.0f in Q15 */
     145         103 :                         move16();
     146             :                     }
     147             :                     ELSE
     148             :                     {
     149          21 :                         proto_matrix[idx] = ONE_IN_Q14; /* 0.5 -> Q15*/
     150          21 :                         move16();
     151          21 :                         proto_matrix[idx + hOutSetup.nchan_out_woLFE] = ONE_IN_Q14; /* 0.5 -> Q15*/
     152          21 :                         move16();
     153             :                     }
     154             :                 }
     155             :             }
     156             :             ELSE
     157             :             {
     158           0 :                 assert( 0 && "Error: number of output channels not supported" );
     159             :             }
     160          21 :             BREAK;
     161             :         }
     162             : 
     163           0 :         default:
     164           0 :             assert( 0 && "Error: number of transport channels not supported" );
     165             :     }
     166             : 
     167          21 :     return;
     168             : }
     169             : 
     170      168096 : static void ivas_param_ism_collect_slot_fx(
     171             :     PARAM_ISM_DEC_HANDLE hParamIsmDec, /* i/o: decoder ParamISM handle */
     172             :     Word32 *Cldfb_RealBuffer_in_fx,    /*Q(31-exp_real)*/
     173             :     Word16 exp_real,
     174             :     Word32 *Cldfb_ImagBuffer_in_fx, /*Q(31-exp_imag)*/
     175             :     Word16 exp_imag,
     176             :     const Word16 ch,
     177             :     Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-exp_cx_diag)*/
     178             :     Word16 exp_cx_diag[][PARAM_ISM_MAX_DMX] )
     179             : {
     180             :     Word16 band_idx, bin_idx;
     181             :     Word16 brange[2];
     182             :     Word32 tmp_fx;
     183             :     Word16 exp_tmp;
     184             : 
     185             :     /* loop over parameter bands to collect transport channel energies */
     186             : 
     187     2017152 :     FOR( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ )
     188             :     {
     189     1849056 :         brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx];
     190     1849056 :         move16();
     191     1849056 :         brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1];
     192     1849056 :         move16();
     193    11934816 :         FOR( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ )
     194             :         {
     195    10085760 :             tmp_fx = 0;
     196    10085760 :             move32();
     197    10085760 :             exp_tmp = 0;
     198    10085760 :             move16();
     199    10085760 :             Word32 var1 = Mpy_32_32( Cldfb_RealBuffer_in_fx[bin_idx], Cldfb_RealBuffer_in_fx[bin_idx] ); // Q(31-2 * exp_real)
     200    10085760 :             Word32 var2 = Mpy_32_32( Cldfb_ImagBuffer_in_fx[bin_idx], Cldfb_ImagBuffer_in_fx[bin_idx] ); // Q(31-2 * exp_imag)
     201    10085760 :             tmp_fx = BASOP_Util_Add_Mant32Exp( tmp_fx, exp_tmp, var1, add( exp_real, exp_real ), &exp_tmp );
     202    10085760 :             tmp_fx = BASOP_Util_Add_Mant32Exp( tmp_fx, exp_tmp, var2, add( exp_imag, exp_imag ), &exp_tmp );
     203             : 
     204             :             Word16 exp_cx_diag_new;
     205    10085760 :             move16();
     206    10085760 :             move16();
     207    10085760 :             cx_diag_fx[bin_idx][ch] = BASOP_Util_Add_Mant32Exp( cx_diag_fx[bin_idx][ch], exp_cx_diag[bin_idx][ch], tmp_fx, exp_tmp, &exp_cx_diag_new );
     208    10085760 :             move32();
     209    10085760 :             exp_cx_diag[bin_idx][ch] = exp_cx_diag_new;
     210    10085760 :             move16();
     211             :         }
     212             :     }
     213      168096 :     return;
     214             : }
     215             : 
     216        5253 : static void ivas_param_ism_compute_mixing_matrix_fx(
     217             :     const Word16 nchan_ism,                                         /* i  : number of ISM channels       */
     218             :     PARAM_ISM_DEC_HANDLE hParamIsmDec,                              /* i/o: decoder ParamISM handle */
     219             :     ISM_DTX_DATA_DEC hISMDTX,                                       /* i  : ISM DTX handle                */
     220             :     Word32 direct_response_fx[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN], // Q30
     221             :     const Word16 nchan_transport,
     222             :     const Word16 nchan_out_woLFE,
     223             :     Word32 cx_diag_fx[][PARAM_ISM_MAX_DMX], /*Q(31-cx_diag_e)*/
     224             :     Word16 cx_diag_e[][PARAM_ISM_MAX_DMX],
     225             :     Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], /*Q(31-mixing_matrix_e)*/
     226             :     Word16 mixing_matrix_e[CLDFB_NO_CHANNELS_MAX] )
     227             : {
     228             :     Word16 band_idx, bin_idx;
     229             :     Word16 i, w, obj_indx;
     230             :     Word16 brange[2];
     231             :     Word32 direct_power_fx[MAX_NUM_OBJECTS];
     232             :     Word32 cy_diag_fx[PARAM_ISM_MAX_CHAN];
     233             :     Word32 cy_diag_tmp_fx[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN];
     234             :     Word32 *dir_res_ptr_fx;
     235             :     Word16 *proto_matrix_fx;
     236             :     Word32 response_matrix_fx[PARAM_ISM_MAX_CHAN * MAX_NUM_OBJECTS];
     237             :     Word16 num_wave;
     238             :     Word16 dir_res_ptr_e, cy_diag_e, cy_diag_e_arr[PARAM_ISM_MAX_CHAN], cy_diag_tmp_e[MAX_NUM_OBJECTS], response_matrix_e, direct_power_e, temp_e[PARAM_ISM_MAX_CHAN];
     239             : 
     240        5253 :     proto_matrix_fx = hParamIsmDec->hParamIsmRendering->proto_matrix_fx;
     241             : 
     242        5253 :     assert( ( nchan_ism == 3 ) || ( nchan_ism == 4 ) );
     243        5253 :     assert( nchan_transport == 2 );
     244             : 
     245        5253 :     test();
     246        5253 :     IF( hParamIsmDec->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag )
     247             :     {
     248          60 :         num_wave = nchan_ism;
     249          60 :         move16();
     250             :     }
     251             :     ELSE
     252             :     {
     253        5193 :         num_wave = MAX_PARAM_ISM_WAVE;
     254        5193 :         move16();
     255             :     }
     256        5253 :     set32_fx( response_matrix_fx, 0, PARAM_ISM_MAX_CHAN * MAX_NUM_OBJECTS );
     257        5253 :     response_matrix_e = 0;
     258        5253 :     move16();
     259             : 
     260             :     /* loop over parameter bands to compute the mixing matrix */
     261       63036 :     FOR( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ )
     262             :     {
     263       57783 :         brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx];
     264       57783 :         move16();
     265       57783 :         brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1];
     266       57783 :         move16();
     267             : 
     268             :         /* Compute covaraince matrix from direct response*/
     269      174669 :         FOR( w = 0; w < num_wave; w++ )
     270             :         {
     271      116886 :             set32_fx( cy_diag_tmp_fx[w], 0, nchan_out_woLFE );
     272      116886 :             test();
     273      116886 :             IF( hParamIsmDec->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag )
     274             :             {
     275        2640 :                 dir_res_ptr_fx = direct_response_fx[w];
     276             :             }
     277             :             ELSE
     278             :             {
     279      114246 :                 obj_indx = hParamIsmDec->hParamIsm->obj_indices[band_idx][0][w];
     280      114246 :                 move16();
     281      114246 :                 dir_res_ptr_fx = direct_response_fx[obj_indx];
     282             :             }
     283      116886 :             Copy32( dir_res_ptr_fx, response_matrix_fx + w * nchan_out_woLFE, nchan_out_woLFE ); // Q30
     284      116886 :             dir_res_ptr_e = 1;
     285      116886 :             move16();
     286      116886 :             response_matrix_e = 1;
     287      116886 :             move16();
     288             :             /* we only need the diagonal of Cy*/
     289      116886 :             matrix_product_diag_fx( dir_res_ptr_fx, dir_res_ptr_e, nchan_out_woLFE, 1, 0, dir_res_ptr_fx, dir_res_ptr_e, 1, nchan_out_woLFE, 0, cy_diag_tmp_fx[w], &cy_diag_tmp_e[w] );
     290             :         }
     291             : 
     292      372963 :         FOR( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ )
     293             :         {
     294             : 
     295      315180 :             set32_fx( cy_diag_fx, 0, nchan_out_woLFE );
     296      315180 :             set16_fx( cy_diag_e_arr, 0, nchan_out_woLFE );
     297             : 
     298             :             /* equal cx diag exponents, compute ref power from cx_diag*/
     299             :             Word16 max_exp_cx_diag;
     300             :             Word32 cx_diag_eq_exp_fx[PARAM_ISM_MAX_DMX];
     301             :             Word32 ref_power_fx;
     302             :             Word16 ref_power_e, ref_power_e_new;
     303      315180 :             ref_power_fx = cx_diag_fx[bin_idx][0];
     304      315180 :             ref_power_e = cx_diag_e[bin_idx][0];
     305             : 
     306      630360 :             FOR( i = 1; i < PARAM_ISM_MAX_DMX; i++ )
     307             :             {
     308      315180 :                 ref_power_fx = BASOP_Util_Add_Mant32Exp( ref_power_fx, ref_power_e, cx_diag_fx[bin_idx][i], cx_diag_e[bin_idx][i], &ref_power_e_new );
     309      315180 :                 ref_power_e = ref_power_e_new;
     310             :             }
     311      315180 :             max_exp_cx_diag = ref_power_e;
     312      945540 :             FOR( i = 0; i < PARAM_ISM_MAX_DMX; i++ )
     313             :             {
     314      630360 :                 cx_diag_eq_exp_fx[i] = L_shr_r( cx_diag_fx[bin_idx][i], sub( max_exp_cx_diag, cx_diag_e[bin_idx][i] ) ); // Q(31-max_exp_cx_diag)
     315             :             }
     316             : 
     317             : 
     318      952740 :             FOR( w = 0; w < num_wave; w++ )
     319             :             {
     320      637560 :                 test();
     321      637560 :                 IF( hParamIsmDec->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag )
     322             :                 {
     323             :                     // direct_power[w] = ( 1.0f / nchan_ism ) * ref_power[bin_idx];
     324       14400 :                     SWITCH( nchan_ism )
     325             :                     {
     326           0 :                         case 2:
     327           0 :                             direct_power_fx[w] = L_shr_r( ref_power_fx, 1 );
     328           0 :                             move32();
     329           0 :                             BREAK;
     330           0 :                         case 3:
     331           0 :                             direct_power_fx[w] = Mpy_32_16_1( ref_power_fx, 10923 ); // 10923 = 1/3f in Q15
     332           0 :                             move32();
     333           0 :                             BREAK;
     334       14400 :                         case 4:
     335       14400 :                             direct_power_fx[w] = L_shr_r( ref_power_fx, 2 );
     336       14400 :                             move32();
     337       14400 :                             BREAK;
     338             :                     }
     339       14400 :                 }
     340             :                 ELSE
     341             :                 {
     342      623160 :                     direct_power_fx[w] = Mpy_32_16_1( ref_power_fx, hParamIsmDec->power_ratios_fx[band_idx][0][w] ); // Q(31-ref_power_e[bin_idx])
     343      623160 :                     move32();
     344             :                 }
     345             :                 // direct_power_e = ref_power_e[bin_idx];
     346      637560 :                 direct_power_e = ref_power_e;
     347      637560 :                 move16();
     348      637560 :                 IF( direct_power_fx[w] != 0 )
     349             :                 {
     350     5440521 :                     FOR( i = 0; i < nchan_out_woLFE; i++ )
     351             :                     {
     352     4904301 :                         cy_diag_fx[i] = BASOP_Util_Add_Mant32Exp( cy_diag_fx[i], cy_diag_e_arr[i], Mpy_32_32( direct_power_fx[w], cy_diag_tmp_fx[w][i] ), add( direct_power_e, cy_diag_tmp_e[w] ), &cy_diag_e_arr[i] );
     353     4904301 :                         move32();
     354             :                     }
     355             :                 }
     356      637560 :                 temp_e[w] = direct_power_e;
     357      637560 :                 move16();
     358      637560 :                 direct_power_fx[w] = Sqrt32( direct_power_fx[w], &temp_e[w] );
     359      637560 :                 move32();
     360             :             }
     361      315180 :             cy_diag_e = cy_diag_e_arr[0];
     362      315180 :             move16();
     363     2878920 :             FOR( i = 1; i < nchan_out_woLFE; i++ )
     364             :             {
     365     2563740 :                 cy_diag_e = s_max( cy_diag_e, cy_diag_e_arr[i] );
     366             :             }
     367     3194100 :             FOR( i = 0; i < nchan_out_woLFE; i++ )
     368             :             {
     369     2878920 :                 cy_diag_fx[i] = L_shr_r( cy_diag_fx[i], sub( cy_diag_e, cy_diag_e_arr[i] ) ); // cy_diag_e
     370     2878920 :                 move32();
     371             :             }
     372             : 
     373      315180 :             direct_power_e = temp_e[0];
     374      315180 :             move16();
     375      637560 :             FOR( w = 1; w < num_wave; w++ )
     376             :             {
     377      322380 :                 direct_power_e = s_max( direct_power_e, temp_e[w] );
     378             :             }
     379      952740 :             FOR( w = 0; w < num_wave; w++ )
     380             :             {
     381      637560 :                 direct_power_fx[w] = L_shr_r( direct_power_fx[w], sub( direct_power_e, temp_e[w] ) ); // diract_power_e
     382      637560 :                 move32();
     383             :             }
     384             : 
     385             :             /* Compute mixing matrix */
     386      315180 :             computeMixingMatricesISM_fx( nchan_transport, num_wave, nchan_out_woLFE, response_matrix_fx, response_matrix_e, direct_power_fx, direct_power_e, cx_diag_eq_exp_fx, max_exp_cx_diag, cy_diag_fx, cy_diag_e, proto_matrix_fx, 1,
     387      315180 :                                          PARAM_MC_REG_SX_FX, PARAM_MC_REG_GHAT_FX, mixing_matrix_fx[bin_idx], &mixing_matrix_e[bin_idx] );
     388             :         }
     389             :     }
     390             : 
     391        5253 :     return;
     392             : }
     393             : 
     394       84048 : static void ivas_param_ism_render_slot_fx(
     395             :     PARAM_ISM_DEC_HANDLE hParamIsmDec,
     396             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
     397             :     Word32 *Cldfb_RealBuffer_in_fx[PARAM_ISM_MAX_DMX],                                                  /*Q11 (31-Cldfb_RealBuffer_tc_exp)*/
     398             :     Word32 *Cldfb_ImagBuffer_in_fx[PARAM_ISM_MAX_DMX],                                                  /*Q11 (31-Cldfb_ImagBuffer_tc_exp)*/
     399             :     Word32 Cldfb_RealBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*Q(31-exp_real)*/
     400             :     Word32 Cldfb_ImagBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*Q(31-exp_imag)*/
     401             :     Word16 *exp_real,
     402             :     Word16 *exp_imag,
     403             :     Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], /*Q(31-exp_mixing_matrix_lin_fx)*/
     404             :     const Word16 interpolator_idx,
     405             :     const Word16 out_slot_idx,
     406             :     const Word16 num_ch_LS,
     407             :     const Word16 nchan_transport )
     408             : {
     409             :     Word16 outchIdx, inchIdx, bin_idx;
     410             :     Word32 tmp_1_fx, mixing_matrix_smooth_fx;
     411             : 
     412       84048 :     tmp_1_fx = L_deposit_h( hParamIsmDec->hParamIsmRendering->interpolator_fx[interpolator_idx] ); /* Q31 */
     413             : 
     414       84048 :     Word16 res_exp = 0;
     415       84048 :     move16();
     416       84048 :     Word16 real_buf_exp = hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp;
     417       84048 :     move16();
     418       84048 :     Word16 imag_buf_exp = hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp;
     419       84048 :     move16();
     420             :     Word16 i, j, k;
     421             : 
     422             :     /*exponent buffers to handle variable exp*/
     423             :     Word16 exp_buf_real[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
     424             :     Word16 exp_buf_imag[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
     425     1428816 :     FOR( i = 0; i < PARAM_ISM_MAX_CHAN; i++ )
     426             :     {
     427     6723840 :         FOR( j = 0; j < JBM_CLDFB_SLOTS_IN_SUBFRAME; j++ )
     428             :         {
     429   328123392 :             FOR( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ )
     430             :             {
     431   322744320 :                 exp_buf_real[i][j][k] = 0;
     432   322744320 :                 move16();
     433   322744320 :                 exp_buf_imag[i][j][k] = 0;
     434   322744320 :                 move16();
     435             :             }
     436             :         }
     437             :     }
     438     5126928 :     FOR( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ )
     439             :     {
     440             :         /* smooth the mixing matrix */
     441    51105600 :         FOR( outchIdx = 0; outchIdx < num_ch_LS; outchIdx++ )
     442             :         {
     443   138188160 :             FOR( inchIdx = 0; inchIdx < nchan_transport; inchIdx++ )
     444             :             {
     445    92125440 :                 Word32 tmp_2 = Mpy_32_32( tmp_1_fx, mixing_matrix_fx[bin_idx][outchIdx + inchIdx * num_ch_LS] );                                                                // hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin
     446    92125440 :                 Word32 tmp_3 = Mpy_32_32( L_sub( ONE_IN_Q31, tmp_1_fx ), hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx][outchIdx + inchIdx * num_ch_LS] ); // 1 + hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_old
     447    92125440 :                 mixing_matrix_smooth_fx = BASOP_Util_Add_Mant32Exp( tmp_2, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx[bin_idx], tmp_3, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_old_fx[bin_idx], &res_exp );
     448             : 
     449    92125440 :                 Word32 tmp_4 = Mpy_32_32( mixing_matrix_smooth_fx, Cldfb_RealBuffer_in_fx[inchIdx][bin_idx] ); // Q(31-(res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp))
     450    92125440 :                 Word32 tmp_5 = Mpy_32_32( mixing_matrix_smooth_fx, Cldfb_ImagBuffer_in_fx[inchIdx][bin_idx] ); // Q(31-(res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp))
     451             : 
     452   184250880 :                 Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx] = BASOP_Util_Add_Mant32Exp( Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx], real_buf_exp,
     453    92125440 :                                                                                                  tmp_4, res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp, &real_buf_exp );
     454    92125440 :                 move32();
     455   184250880 :                 Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx] = BASOP_Util_Add_Mant32Exp( Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx], imag_buf_exp,
     456    92125440 :                                                                                                  tmp_5, res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp, &imag_buf_exp );
     457    92125440 :                 move32();
     458    92125440 :                 exp_buf_real[outchIdx][out_slot_idx][bin_idx] = real_buf_exp;
     459    92125440 :                 move16();
     460    92125440 :                 exp_buf_imag[outchIdx][out_slot_idx][bin_idx] = imag_buf_exp;
     461    92125440 :                 move16();
     462             :             }
     463             :         }
     464             :     }
     465             : 
     466             :     /*Make same exponent for whole buffer*/
     467       84048 :     Word16 max_exp_real = MIN_16;
     468       84048 :     move16();
     469       84048 :     Word16 max_exp_imag = MIN_16;
     470       84048 :     move16();
     471     5126928 :     FOR( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ )
     472             :     {
     473    51105600 :         FOR( outchIdx = 0; outchIdx < num_ch_LS; outchIdx++ )
     474             :         {
     475    46062720 :             max_exp_real = s_max( max_exp_real, exp_buf_real[outchIdx][out_slot_idx][bin_idx] );
     476    46062720 :             max_exp_imag = s_max( max_exp_imag, exp_buf_imag[outchIdx][out_slot_idx][bin_idx] );
     477             :         }
     478             :     }
     479             : 
     480     5126928 :     FOR( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ )
     481             :     {
     482    51105600 :         FOR( outchIdx = 0; outchIdx < num_ch_LS; outchIdx++ )
     483             :         {
     484    46062720 :             Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx] = L_shr( Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx], sub( max_exp_real, exp_buf_real[outchIdx][out_slot_idx][bin_idx] ) ); // Q(31-(max_exp_real))
     485    46062720 :             move32();
     486    46062720 :             Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx] = L_shr( Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx], sub( max_exp_imag, exp_buf_imag[outchIdx][out_slot_idx][bin_idx] ) ); // Q(31-(max_exp_imag))
     487    46062720 :             move32();
     488             :         }
     489             :     }
     490             : 
     491       84048 :     *exp_real = max_exp_real;
     492       84048 :     move16();
     493       84048 :     *exp_imag = max_exp_imag;
     494       84048 :     move16();
     495             : 
     496       84048 :     return;
     497             : }
     498             : 
     499             : 
     500         166 : static ivas_error ivas_param_ism_rendering_init_fx(
     501             :     PARAM_ISM_RENDERING_HANDLE hParamIsmRendering,
     502             :     IVAS_OUTPUT_SETUP hOutSetup,
     503             :     const Word16 nchan_transport,
     504             :     const Word16 subframe_nbslots,
     505             :     AUDIO_CONFIG output_config )
     506             : {
     507             :     Word16 bin_idx;
     508             : 
     509             :     /* initialization of mixing matrix buffer for smoothing */
     510       10126 :     FOR( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ )
     511             :     {
     512        9960 :         set32_fx( hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx], 0, PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX );
     513             :     }
     514         166 :     set16_fx( hParamIsmRendering->exp_mixing_matrix_lin_old_fx, 0, CLDFB_NO_CHANNELS_MAX );
     515             : 
     516             :     /* memory allocation for proto matrix and interpolator */
     517         166 :     IF( ( hParamIsmRendering->proto_matrix_fx = (Word16 *) malloc( hOutSetup.nchan_out_woLFE * nchan_transport * sizeof( Word16 ) ) ) == NULL )
     518             :     {
     519           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for proto matrix\n" ) );
     520             :     }
     521             : 
     522             : 
     523         166 :     IF( ( hParamIsmRendering->interpolator_fx = (Word16 *) malloc( subframe_nbslots * sizeof( Word16 ) ) ) == NULL )
     524             :     {
     525           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) );
     526             :     }
     527         166 :     test();
     528         166 :     test();
     529         166 :     test();
     530         166 :     IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
     531             :     {
     532             :         /* computation of proto matrix */
     533          21 :         ivas_ism_get_proto_matrix_fx( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix_fx );
     534             :     }
     535             : 
     536             :     /* computation of interpolator*/
     537         166 :     ivas_ism_get_interpolator_fx( subframe_nbslots, hParamIsmRendering->interpolator_fx );
     538             : 
     539         166 :     return IVAS_ERR_OK;
     540             : }
     541             : 
     542        5253 : static void ivas_param_ism_update_mixing_matrix_fx(
     543             :     PARAM_ISM_DEC_HANDLE hParamIsmDec,
     544             :     Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], /*Q(31-mixing_matrix_exp)*/
     545             :     Word16 mixing_matrix_exp[CLDFB_NO_CHANNELS_MAX],
     546             :     const Word16 nchan_in,
     547             :     const Word16 nchan_out )
     548             : {
     549             :     Word16 inchIdx, outchIdx, bin_idx, band_idx;
     550             :     Word16 brange[2];
     551             : 
     552       63036 :     FOR( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ )
     553             :     {
     554       57783 :         brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx];
     555       57783 :         move16();
     556       57783 :         brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1];
     557       57783 :         move16();
     558             : 
     559      372963 :         FOR( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ )
     560             :         {
     561      945540 :             FOR( inchIdx = 0; inchIdx < nchan_in; inchIdx++ )
     562             :             {
     563     6388200 :                 FOR( outchIdx = 0; outchIdx < nchan_out; outchIdx++ )
     564             :                 {
     565     5757840 :                     hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx][outchIdx + inchIdx * nchan_out] = mixing_matrix_fx[bin_idx][outchIdx + inchIdx * nchan_out];
     566     5757840 :                     move32();
     567             :                 }
     568             :             }
     569             :         }
     570             :     }
     571             : 
     572        5253 :     Copy( mixing_matrix_exp, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_old_fx, CLDFB_NO_CHANNELS_MAX );
     573             : 
     574        5253 :     return;
     575             : }
     576             : 
     577             : 
     578             : /*-------------------------------------------------------------------------*
     579             :  * ivas_param_ism_dec_open()
     580             :  *
     581             :  * Open Param ISM handle
     582             :  *-------------------------------------------------------------------------*/
     583         168 : ivas_error ivas_param_ism_dec_open_fx(
     584             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
     585             : )
     586             : {
     587             :     Word16 i;
     588             :     PARAM_ISM_DEC_HANDLE hParamIsmDec;
     589             :     IVAS_OUTPUT_SETUP hOutSetup;
     590             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
     591             :     AUDIO_CONFIG output_config;
     592             :     Word32 output_Fs;
     593             :     ivas_error error;
     594             : 
     595         168 :     error = IVAS_ERR_OK;
     596         168 :     move32();
     597         168 :     push_wmops( "ivas_param_ism_dec_open" );
     598             : 
     599             :     /*-----------------------------------------------------------------*
     600             :      * prepare library opening
     601             :      *-----------------------------------------------------------------*/
     602             : 
     603         168 :     IF( ( hParamIsmDec = (PARAM_ISM_DEC_HANDLE) malloc( sizeof( PARAM_ISM_DEC_DATA ) ) ) == NULL )
     604             :     {
     605           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ParamISM\n" ) );
     606             :     }
     607             : 
     608         168 :     IF( ( hSpatParamRendCom = (SPAT_PARAM_REND_COMMON_DATA_HANDLE) malloc( sizeof( SPAT_PARAM_REND_COMMON_DATA ) ) ) == NULL )
     609             :     {
     610           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     611             :     }
     612             : 
     613             :     /* Assign memory to Param Object handle */
     614         168 :     IF( ( hParamIsmDec->hParamIsm = (PARAM_ISM_CONFIG_HANDLE) malloc( sizeof( PARAM_ISM_CONFIG_DATA ) ) ) == NULL )
     615             :     {
     616           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ParamISM\n" ) );
     617             :     }
     618             : 
     619         168 :     IF( ( hParamIsmDec->hParamIsmRendering = (PARAM_ISM_RENDERING_HANDLE) malloc( sizeof( PARAM_ISM_RENDERING_DATA ) ) ) == NULL )
     620             :     {
     621           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ParamISM Rendering handle\n" ) );
     622             :     }
     623             : 
     624         168 :     output_Fs = st_ivas->hDecoderConfig->output_Fs;
     625         168 :     move32();
     626         168 :     output_config = st_ivas->hDecoderConfig->output_config;
     627         168 :     move32();
     628         168 :     ivas_param_ism_config_fx( hParamIsmDec->hParamIsm, st_ivas->nchan_ism ); // assuming Q14 for gains;
     629             : 
     630             :     /*-----------------------------------------------------------------*
     631             :      * set input parameters
     632             :      *-----------------------------------------------------------------*/
     633             : 
     634             :     /* hSpatParamRendCom->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX ); */
     635         168 :     hSpatParamRendCom->slot_size = extract_l( L_shr( Mpy_32_32( output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ), 4 ) );
     636         168 :     move16();
     637         168 :     set16_fx( hSpatParamRendCom->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
     638         168 :     set16_fx( hSpatParamRendCom->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS );
     639         168 :     hSpatParamRendCom->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS;
     640         168 :     move16();
     641         168 :     hSpatParamRendCom->subframes_rendered = 0;
     642         168 :     move16();
     643         168 :     hSpatParamRendCom->slots_rendered = 0;
     644         168 :     move16();
     645         168 :     hSpatParamRendCom->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME;
     646         168 :     move16();
     647             :     /* hSpatParamRendCom->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); */
     648         168 :     hSpatParamRendCom->num_freq_bands = extract_l( Mpy_32_32( output_Fs, 2684355 /* INV_CLDFB_BANDWIDTH in Q31 */ ) );
     649         168 :     move16();
     650             : 
     651         168 :     hParamIsmDec->hParamIsm->nbands = MAX_PARAM_ISM_NBANDS;
     652         168 :     move16();
     653             : 
     654        2184 :     FOR( i = 0; i < ( hParamIsmDec->hParamIsm->nbands + 1 ); i++ )
     655             :     {
     656        2016 :         hParamIsmDec->hParamIsm->band_grouping[i] = Param_ISM_band_grouping[i];
     657        2016 :         move16();
     658             : 
     659        2016 :         IF( GT_16( hParamIsmDec->hParamIsm->band_grouping[i], hSpatParamRendCom->num_freq_bands ) )
     660             :         {
     661          75 :             hParamIsmDec->hParamIsm->band_grouping[i] = hSpatParamRendCom->num_freq_bands;
     662          75 :             move16();
     663             :         }
     664             :     }
     665             : 
     666             :     /*-----------------------------------------------------------------*
     667             :      * output setup
     668             :      *-----------------------------------------------------------------*/
     669             : 
     670             :     /* hIntSetup and hOutSetup differs only for Binaural rendering */
     671         168 :     IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
     672             :     {
     673             :         /* nchan_out is essential for memory initialization for CLDFB Synthesis */
     674          47 :         st_ivas->hIntSetup.nchan_out_woLFE = st_ivas->nchan_ism;
     675          47 :         move16();
     676          47 :         st_ivas->hIntSetup.is_loudspeaker_setup = 1;
     677          47 :         move16();
     678             :     }
     679             : 
     680         168 :     hOutSetup = st_ivas->hIntSetup;
     681             : 
     682         168 :     test();
     683         168 :     IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
     684             :     {
     685             :         /* Initialize Param ISM Rendering handle */
     686         166 :         IF( st_ivas->hDecoderConfig->Opt_tsm )
     687             :         {
     688          76 :             IF( NE_32( ( error = ivas_param_ism_rendering_init_fx( hParamIsmDec->hParamIsmRendering, hOutSetup, st_ivas->nchan_transport, MAX_JBM_CLDFB_TIMESLOTS, output_config ) ), IVAS_ERR_OK ) )
     689             :             {
     690           0 :                 return error;
     691             :             }
     692             :         }
     693             :         ELSE
     694             :         {
     695          90 :             IF( NE_32( ( error = ivas_param_ism_rendering_init_fx( hParamIsmDec->hParamIsmRendering, hOutSetup, st_ivas->nchan_transport, CLDFB_NO_COL_MAX, output_config ) ), IVAS_ERR_OK ) )
     696             :             {
     697           0 :                 return error;
     698             :             }
     699             :         }
     700             :     }
     701             : 
     702         168 :     test();
     703         168 :     test();
     704         168 :     test();
     705         168 :     test();
     706         168 :     test();
     707         168 :     IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ||
     708             :            EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
     709             :     {
     710             :         /* Initialize efap handle */
     711          21 :         IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), hOutSetup.ls_azimuth_fx, hOutSetup.ls_elevation_fx, hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
     712             :         {
     713           0 :             return error;
     714             :         }
     715             :     }
     716             : 
     717             :     /* Azi and Ele values are transmitted once per frame per object */
     718             : 
     719         168 :     set32_fx( hParamIsmDec->azimuth_values_fx, 0, MAX_NUM_OBJECTS );
     720         168 :     set32_fx( hParamIsmDec->elevation_values_fx, 0, MAX_NUM_OBJECTS );
     721             : 
     722         168 :     hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES;
     723         168 :     move16();
     724         168 :     hSpatParamRendCom->dirac_bs_md_write_idx = 0;
     725         168 :     move16();
     726         168 :     hSpatParamRendCom->dirac_read_idx = 0;
     727         168 :     move16();
     728             : 
     729         168 :     test();
     730         168 :     test();
     731         168 :     IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
     732             :     {
     733          98 :         IF( NE_32( ( error = ivas_dirac_allocate_parameters_fx( hSpatParamRendCom, 1 ) ), IVAS_ERR_OK ) )
     734             :         {
     735           0 :             return error;
     736             :         }
     737             : 
     738          98 :         IF( NE_32( ( error = ivas_dirac_allocate_parameters_fx( hSpatParamRendCom, 2 ) ), IVAS_ERR_OK ) )
     739             :         {
     740           0 :             return error;
     741             :         }
     742             :     }
     743             : 
     744         168 :     st_ivas->hISMDTX.dtx_flag = 0;
     745         168 :     move16();
     746             : 
     747         168 :     st_ivas->hParamIsmDec = hParamIsmDec;
     748         168 :     st_ivas->hSpatParamRendCom = hSpatParamRendCom;
     749             : 
     750             : 
     751         168 :     test();
     752         168 :     IF( NE_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) && NE_32( st_ivas->renderer_type, RENDERER_DISABLE ) )
     753         166 :     {
     754         166 :         Word16 nchan_transport = st_ivas->nchan_transport;
     755         166 :         move16();
     756         166 :         Word16 nchan_full = 0;
     757         166 :         move16();
     758             : 
     759         166 :         test();
     760         166 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
     761             :         {
     762          98 :             nchan_full = nchan_transport;
     763          98 :             move16();
     764          98 :             hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx = NULL;
     765          98 :             hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx = NULL;
     766             :         }
     767             :         ELSE
     768             :         {
     769             :             Word16 n_slots_to_alloc;
     770          68 :             IF( EQ_16( st_ivas->hDecoderConfig->Opt_tsm, 1 ) )
     771             :             {
     772           1 :                 n_slots_to_alloc = MAX_JBM_CLDFB_TIMESLOTS;
     773           1 :                 move16();
     774             :             }
     775             :             ELSE
     776             :             {
     777          67 :                 n_slots_to_alloc = CLDFB_SLOTS_PER_SUBFRAME * MAX_PARAM_SPATIAL_SUBFRAMES;
     778          67 :                 move16();
     779             :             }
     780             : 
     781          68 :             IF( ( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx = (Word32 *) malloc( n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     782             :             {
     783           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) );
     784             :             }
     785          68 :             set32_fx( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx, 0, n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands );
     786             : 
     787          68 :             IF( ( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx = (Word32 *) malloc( n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     788             :             {
     789           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) );
     790             :             }
     791          68 :             set32_fx( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx, 0, n_slots_to_alloc * nchan_transport * hSpatParamRendCom->num_freq_bands );
     792             :         }
     793             : 
     794         166 :         IF( st_ivas->hTcBuffer == NULL )
     795             :         {
     796          12 :             IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_transport, nchan_full, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) )
     797             : 
     798             :             {
     799           0 :                 return error;
     800             :             }
     801             :         }
     802             :     }
     803             :     ELSE
     804             :     {
     805           2 :         hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx = NULL;
     806           2 :         hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx = NULL;
     807           2 :         IF( st_ivas->hTcBuffer == NULL )
     808             :         {
     809           2 :             Word16 nchan_to_allocate = st_ivas->hDecoderConfig->nchan_out;
     810           2 :             move16(); // NS2SA
     811           2 :             IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, TC_BUFFER_MODE_BUFFER, nchan_to_allocate, nchan_to_allocate, nchan_to_allocate, NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ) ) ), IVAS_ERR_OK ) )
     812             :             {
     813           0 :                 return error;
     814             :             }
     815             :         }
     816             :     }
     817             : 
     818         168 :     pop_wmops();
     819         168 :     return error;
     820             : }
     821             : 
     822             : /*-------------------------------------------------------------------------*
     823             :  * ivas_param_ism_dec_close()
     824             :  *
     825             :  * Close Param ISM handle
     826             :  *-------------------------------------------------------------------------*/
     827             : 
     828         224 : void ivas_param_ism_dec_close_fx(
     829             :     PARAM_ISM_DEC_HANDLE *hParamIsmDec_out,                    /* i/o: decoder DirAC handle         */
     830             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, /* i/o: common spatial renderer data */
     831             :     AUDIO_CONFIG output_config                                 /* i  : output audio configuration   */
     832             : )
     833             : {
     834         224 :     test();
     835         224 :     IF( hParamIsmDec_out != NULL && *hParamIsmDec_out != NULL )
     836             :     {
     837             :         PARAM_ISM_DEC_HANDLE hParamIsmDec;
     838         168 :         hParamIsmDec = *hParamIsmDec_out;
     839             : 
     840             :         /* Config & CLDFB */
     841         168 :         IF( hParamIsmDec->hParamIsm != NULL )
     842             :         {
     843         168 :             free( hParamIsmDec->hParamIsm );
     844         168 :             hParamIsmDec->hParamIsm = NULL;
     845             :         }
     846             : 
     847         168 :         test();
     848         168 :         IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
     849             :         {
     850             :             /* Param ISM Rendering */
     851         166 :             IF( hParamIsmDec->hParamIsmRendering->interpolator_fx != NULL )
     852             :             {
     853         166 :                 free( hParamIsmDec->hParamIsmRendering->interpolator_fx );
     854         166 :                 hParamIsmDec->hParamIsmRendering->interpolator_fx = NULL;
     855             :             }
     856         166 :             IF( hParamIsmDec->hParamIsmRendering->proto_matrix_fx != NULL )
     857             :             {
     858         166 :                 free( hParamIsmDec->hParamIsmRendering->proto_matrix_fx );
     859         166 :                 hParamIsmDec->hParamIsmRendering->proto_matrix_fx = NULL;
     860             :             }
     861             :         }
     862         168 :         IF( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx != NULL )
     863             :         {
     864          68 :             free( hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx );
     865          68 :             hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx = NULL;
     866             :         }
     867         168 :         IF( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx != NULL )
     868             :         {
     869          68 :             free( hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx );
     870          68 :             hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx = NULL;
     871             :         }
     872         168 :         IF( hParamIsmDec->hParamIsmRendering != NULL )
     873             :         {
     874         168 :             free( hParamIsmDec->hParamIsmRendering );
     875         168 :             hParamIsmDec->hParamIsmRendering = NULL;
     876             :         }
     877             : 
     878         168 :         free( *hParamIsmDec_out );
     879         168 :         *hParamIsmDec_out = NULL;
     880             :     }
     881             : 
     882         224 :     test();
     883         224 :     IF( hSpatParamRendCom_out != NULL && *hSpatParamRendCom_out != NULL )
     884             :     {
     885         168 :         test();
     886         168 :         test();
     887         168 :         IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
     888             :         {
     889          98 :             ivas_dirac_deallocate_parameters_fx( *hSpatParamRendCom_out, 1 );
     890          98 :             ivas_dirac_deallocate_parameters_fx( *hSpatParamRendCom_out, 2 );
     891             :         }
     892             : 
     893         168 :         free( *hSpatParamRendCom_out );
     894         168 :         *hSpatParamRendCom_out = NULL;
     895             :     }
     896             : 
     897         224 :     return;
     898             : }
     899             : 
     900             : 
     901             : /*-------------------------------------------------------------------------*
     902             :  * ivas_ism_dec_digest_tc()
     903             :  *
     904             :  *
     905             :  *-------------------------------------------------------------------------*/
     906       68899 : void ivas_ism_dec_digest_tc_fx(
     907             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
     908             : )
     909             : {
     910       68899 :     ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas );
     911             : 
     912       68899 :     test();
     913       68899 :     test();
     914       68899 :     test();
     915       68899 :     test();
     916       68899 :     test();
     917       68899 :     test();
     918       68899 :     test();
     919       68899 :     test();
     920       68899 :     IF( EQ_32( st_ivas->renderer_type, RENDERER_TD_PANNING ) ||
     921             :         EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ||
     922             :         EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) ||
     923             :         EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ||
     924             :         EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) ||
     925             :         EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) ||
     926             :         EQ_32( st_ivas->renderer_type, RENDERER_OSBA_STEREO ) ||
     927             :         ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) && st_ivas->hDecoderConfig->Opt_Headrotation == 0 ) )
     928             :     {
     929             :         Word16 i, num_objects;
     930             :         Word32 azimuth_fx, elevation_fx;
     931             : 
     932             :         /* we have a full frame interpolator, adapt it */
     933             :         /* for BE testing */
     934             :         Word32 res_dec, res_frac;
     935       31936 :         iDiv_and_mod_32( st_ivas->hDecoderConfig->output_Fs, FRAMES_PER_SEC, &res_dec, &res_frac, 0 );
     936       31936 :         IF( EQ_32( extract_l( res_dec ), st_ivas->hTcBuffer->n_samples_available ) )
     937             :         {
     938       31934 :             Word16 interpolator_length = extract_l( res_dec );
     939             : 
     940       31934 :             test();
     941       31934 :             test();
     942       31934 :             IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ||
     943             :                 EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) ||
     944             :                 EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
     945             :             {
     946       10576 :                 st_ivas->hIsmRendererData->interpolator_fx[0] = 0;
     947       10576 :                 move16();
     948     9285760 :                 FOR( i = 1; i < interpolator_length; i++ )
     949             :                 {
     950     9275184 :                     Word16 tmp = div_s( 1, sub( interpolator_length, 1 ) );
     951     9275184 :                     st_ivas->hIsmRendererData->interpolator_fx[i] = add( st_ivas->hIsmRendererData->interpolator_fx[i - 1], tmp ); // Q15
     952     9275184 :                     move16();
     953             :                 }
     954             :             }
     955             :             ELSE
     956             :             {
     957    18937198 :                 FOR( i = 0; i < interpolator_length; i++ )
     958             :                 {
     959    18915840 :                     st_ivas->hIsmRendererData->interpolator_fx[i] = div_s( i, sub( interpolator_length, 1 ) ); // Q15
     960    18915840 :                     move16();
     961             :                 }
     962             :             }
     963             :         }
     964             :         ELSE
     965             :         {
     966           2 :             ivas_jbm_dec_get_adapted_linear_interpolator_fx( extract_l( Mpy_32_32( st_ivas->hDecoderConfig->output_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ), st_ivas->hTcBuffer->n_samples_available, st_ivas->hIsmRendererData->interpolator_fx );
     967           2 :             move16();
     968             :         }
     969             : 
     970             :         /* also get the gains here */
     971       31936 :         num_objects = st_ivas->nchan_transport;
     972       31936 :         move16();
     973      138026 :         FOR( i = 0; i < num_objects; i++ )
     974             :         {
     975      106090 :             Copy32( st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIsmRendererData->prev_gains_fx[i], MAX_OUTPUT_CHANNELS );
     976             : 
     977      106090 :             IF( EQ_32( st_ivas->intern_config, IVAS_AUDIO_CONFIG_STEREO ) )
     978             :             {
     979             :                 Word16 gains_fx[2];
     980       16040 :                 ivas_ism_get_stereo_gains_fx( (Word16) L_shr( st_ivas->hIsmMetaData[i]->azimuth_fx, 22 ), (Word16) L_shr( st_ivas->hIsmMetaData[i]->elevation_fx, 22 ), &gains_fx[0], &gains_fx[1] );
     981       16040 :                 st_ivas->hIsmRendererData->gains_fx[i][0] = L_shr( L_deposit_h( gains_fx[0] ), 1 ); // Q31 -> Q30
     982       16040 :                 move32();
     983       16040 :                 st_ivas->hIsmRendererData->gains_fx[i][1] = L_shr( L_deposit_h( gains_fx[1] ), 1 ); // Q31 -> Q30
     984       16040 :                 move32();
     985             :             }
     986             :             ELSE
     987             :             {
     988             :                 // TODO tmu review when #215 is resolved
     989       90050 :                 azimuth_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->azimuth_fx, 2097152 ), Q22 );     // Q0 ,2097152 = .5f in Q22
     990       90050 :                 elevation_fx = L_shr( L_add( st_ivas->hIsmMetaData[i]->elevation_fx, 2097152 ), Q22 ); // Q0 ,2097152 = .5f in Q22
     991             : 
     992       90050 :                 test();
     993       90050 :                 test();
     994       90050 :                 test();
     995       90050 :                 test();
     996       90050 :                 test();
     997       90050 :                 IF( ( EQ_32( st_ivas->renderer_type, RENDERER_TD_PANNING ) ||
     998             :                       EQ_32( st_ivas->renderer_type, RENDERER_OSBA_LS ) ||
     999             :                       EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) &&
    1000             :                     st_ivas->hCombinedOrientationData == NULL )
    1001             :                 {
    1002       43446 :                     if ( st_ivas->hIntSetup.is_planar_setup )
    1003             :                     {
    1004             :                         /* If no elevation support in output format, then rendering should be done with zero elevation */
    1005       13000 :                         elevation_fx = 0;
    1006       13000 :                         move32();
    1007             :                     }
    1008             : 
    1009       43446 :                     IF( st_ivas->hEFAPdata != NULL )
    1010             :                     {
    1011       43446 :                         azimuth_fx = L_shl( azimuth_fx, Q22 );     // Q22
    1012       43446 :                         elevation_fx = L_shl( elevation_fx, Q22 ); // Q22
    1013       43446 :                         efap_determine_gains_fx( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains_fx[i], azimuth_fx, elevation_fx, EFAP_MODE_EFAP );
    1014             :                     }
    1015             :                 }
    1016       46604 :                 ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_SBA_LINEAR_ENC ) ||
    1017             :                          EQ_32( st_ivas->renderer_type, RENDERER_OSBA_AMBI ) ||
    1018             :                          EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
    1019             :                 {
    1020             :                     /*get HOA gets for direction (ACN/SN3D)*/
    1021       38604 :                     Word16 azi = shr( extract_h( st_ivas->hIsmMetaData[i]->azimuth_fx ), 22 - 16 );   // Q0
    1022       38604 :                     Word16 ele = shr( extract_h( st_ivas->hIsmMetaData[i]->elevation_fx ), 22 - 16 ); // Q0
    1023       38604 :                     ivas_dirac_dec_get_response_fx( azi, ele, st_ivas->hIsmRendererData->gains_fx[i], st_ivas->hIntSetup.ambisonics_order, Q30 );
    1024             :                 }
    1025             :             }
    1026             :         }
    1027             :     }
    1028             : 
    1029       68899 :     return;
    1030             : }
    1031             : 
    1032             : /*-------------------------------------------------------------------------*
    1033             :  * ivas_param_ism_dec_digest_tc()
    1034             :  *
    1035             :  *
    1036             :  *-------------------------------------------------------------------------*/
    1037        5253 : void ivas_param_ism_dec_digest_tc_fx(
    1038             :     Decoder_Struct *st_ivas,      /* i/o: IVAS decoder handle                                     */
    1039             :     const UWord16 nCldfbSlots,    /* i  : number of CLFBS slots in the transport channels         */
    1040             :     Word32 *transport_channels[], /* i  : synthesized core-coder transport channels/DirAC output  q_tc_in*/
    1041             :     Word16 q_tc_in )
    1042             : {
    1043        5253 :     Word16 exp_real_tmp = 0, exp_imag_tmp = 0;
    1044        5253 :     move16();
    1045        5253 :     move16();
    1046        5253 :     move16();
    1047        5253 :     move16();
    1048             :     Word32 cx_diag_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX];
    1049             :     Word16 exp_cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX];
    1050             : 
    1051        5253 :     Word16 q_tc = q_tc_in;
    1052        5253 :     move16();
    1053             :     Word16 ch, nchan_transport, nchan_out, nchan_out_woLFE, i;
    1054             :     Word16 slot_idx, bin_idx;
    1055             :     Word32 ivas_total_brate;
    1056             :     Word16 output_frame;
    1057             :     /* Direct Response/EFAP Gains */
    1058             :     Word32 direct_response_fx[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN];
    1059             :     PARAM_ISM_DEC_HANDLE hParamIsmDec;
    1060             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    1061             :     Word16 fade_len;
    1062             : 
    1063             :     /* Initialization */
    1064        5253 :     set32_fx( &direct_response_fx[0][0], 0, MAX_NUM_OBJECTS * PARAM_ISM_MAX_CHAN );
    1065        5253 :     hParamIsmDec = st_ivas->hParamIsmDec;
    1066        5253 :     assert( hParamIsmDec );
    1067        5253 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    1068        5253 :     assert( hSpatParamRendCom );
    1069        5253 :     output_frame = imult1616( nCldfbSlots, hSpatParamRendCom->num_freq_bands );
    1070        5253 :     fade_len = shr( output_frame, 1 );
    1071             : 
    1072        5253 :     nchan_transport = st_ivas->nchan_transport;
    1073        5253 :     move16();
    1074        5253 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
    1075        5253 :     move32();
    1076             : 
    1077        5253 :     hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp = 25;
    1078        5253 :     move16();
    1079        5253 :     hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp = 25;
    1080        5253 :     move16();
    1081        5253 :     IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
    1082             :     {
    1083         543 :         nchan_out = st_ivas->nchan_ism;
    1084         543 :         move16();
    1085         543 :         nchan_out_woLFE = nchan_out;
    1086         543 :         move16();
    1087         543 :         st_ivas->hDecoderConfig->nchan_out = nchan_out;
    1088         543 :         move16();
    1089             :     }
    1090             :     ELSE
    1091             :     {
    1092        4710 :         nchan_out = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
    1093        4710 :         nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
    1094        4710 :         move16();
    1095             :     }
    1096             : 
    1097        5253 :     push_wmops( "ivas_param_ism_dec" );
    1098             : 
    1099             :     /* general setup */
    1100        5253 :     ivas_jbm_dec_get_adapted_linear_interpolator_fx( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbSlots, hParamIsmDec->hParamIsmRendering->interpolator_fx );
    1101             : 
    1102        5253 :     ivas_dirac_dec_set_md_map_fx( st_ivas, nCldfbSlots );
    1103             :     /* set buffers to zero */
    1104             : 
    1105        5253 :     set_zero_fx( &cx_diag_fx[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX );
    1106        5253 :     set16_zero_fx( &exp_cx_diag[0][0], CLDFB_NO_CHANNELS_MAX * PARAM_ISM_MAX_DMX );
    1107             : 
    1108             :     /* Frame-level Processing */
    1109             :     /* De-quantization */
    1110        5253 :     test();
    1111        5253 :     IF( !( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || EQ_32( ivas_total_brate, FRAME_NO_DATA ) ) )
    1112             :     {
    1113        5193 :         ivas_param_ism_dec_dequant_DOA_fx( hParamIsmDec, st_ivas->nchan_ism );
    1114        5193 :         ivas_param_ism_dec_dequant_powrat_fx( hParamIsmDec );
    1115        5193 :         st_ivas->hISMDTX.dtx_flag = 0;
    1116        5193 :         move16();
    1117             :     }
    1118             :     ELSE
    1119             :     {
    1120          60 :         st_ivas->hISMDTX.dtx_flag = 1;
    1121          60 :         move16();
    1122             :     }
    1123             : 
    1124             :     /* obtain the direct response using EFAP */
    1125        5253 :     IF( !( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) ) )
    1126             :     {
    1127       22050 :         FOR( i = 0; i < st_ivas->nchan_ism; i++ )
    1128             :         {
    1129       17340 :             efap_determine_gains_fx( st_ivas->hEFAPdata, direct_response_fx[i], hParamIsmDec->azimuth_values_fx[i], hParamIsmDec->elevation_values_fx[i], EFAP_MODE_EFAP );
    1130             :         }
    1131             :     }
    1132             :     ELSE
    1133             :     {
    1134             :         Word16 j;
    1135             : 
    1136        2715 :         FOR( i = 0; i < st_ivas->nchan_ism; i++ )
    1137             :         {
    1138       10860 :             FOR( j = 0; j < nchan_out_woLFE; j++ )
    1139             :             {
    1140        8688 :                 IF( EQ_16( i, j ) )
    1141             :                 {
    1142        2172 :                     direct_response_fx[i][j] = ONE_IN_Q30;
    1143        2172 :                     move32();
    1144             :                 }
    1145             :                 ELSE
    1146             :                 {
    1147        6516 :                     direct_response_fx[i][j] = 0;
    1148        6516 :                     move32();
    1149             :                 }
    1150             :             }
    1151             :         }
    1152             : 
    1153        2715 :         FOR( j = 0; j < nchan_out_woLFE; j++ )
    1154             :         {
    1155        2172 :             IF( hParamIsmDec->azimuth_values_fx[j] > 0 )
    1156             :             {
    1157         875 :                 hParamIsmDec->hParamIsmRendering->proto_matrix_fx[j] = 32767; // (1.0f in Q15) - 1
    1158         875 :                 move16();
    1159         875 :                 hParamIsmDec->hParamIsmRendering->proto_matrix_fx[nchan_out_woLFE + j] = 0;
    1160         875 :                 move16();
    1161             :             }
    1162             :             ELSE
    1163             :             {
    1164        1297 :                 IF( hParamIsmDec->azimuth_values_fx[j] < 0 )
    1165             :                 {
    1166         945 :                     hParamIsmDec->hParamIsmRendering->proto_matrix_fx[j] = 0;
    1167         945 :                     move16();
    1168         945 :                     hParamIsmDec->hParamIsmRendering->proto_matrix_fx[nchan_out_woLFE + j] = 32767; // (1.0f in Q15) - 1
    1169         945 :                     move16();
    1170             :                 }
    1171             :                 ELSE /* == 0.0f */
    1172             :                 {
    1173         352 :                     hParamIsmDec->hParamIsmRendering->proto_matrix_fx[j] = ONE_IN_Q14; // Q15
    1174         352 :                     move16();
    1175         352 :                     hParamIsmDec->hParamIsmRendering->proto_matrix_fx[nchan_out_woLFE + j] = ONE_IN_Q14; // Q15
    1176         352 :                     move16();
    1177             :                 }
    1178             :             }
    1179             :         }
    1180             :     }
    1181             : 
    1182        5253 :     IF( st_ivas->hDecoderConfig->Opt_tsm )
    1183             :     {
    1184             :         /*TODO : FhG to check*/
    1185        1506 :         ivas_ism_param_dec_tc_gain_ajust_fx( st_ivas, output_frame, fade_len, transport_channels, &q_tc );
    1186        1506 :         IF( NE_16( q_tc, q_tc_in ) )
    1187             :         {
    1188        4518 :             FOR( i = 0; i < 2; i++ )
    1189             :             {
    1190        3012 :                 scale_sig32( transport_channels[i], output_frame, sub( q_tc_in, q_tc ) ); // q_tc_in
    1191             :             }
    1192        1506 :             q_tc = q_tc_in;
    1193        1506 :             move16();
    1194             :         }
    1195             :     }
    1196             : 
    1197       15759 :     FOR( ch = 0; ch < nchan_transport; ch++ )
    1198             :     {
    1199             :         /* CLDFB Analysis */
    1200      178602 :         FOR( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ )
    1201             :         {
    1202      168096 :             IF( st_ivas->hDecoderConfig->Opt_tsm )
    1203             :             {
    1204             :                 Word32 RealBuffer_fx[CLDFB_NO_CHANNELS_MAX];
    1205             :                 Word32 ImagBuffer_fx[CLDFB_NO_CHANNELS_MAX];
    1206       48192 :                 q_tc = q_tc_in;
    1207       48192 :                 move16();
    1208       48192 :                 cldfbAnalysis_ts_fx_fixed_q( &( transport_channels[ch][hSpatParamRendCom->num_freq_bands * slot_idx] ), RealBuffer_fx, ImagBuffer_fx, hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch], &q_tc );
    1209       48192 :                 Copy32( RealBuffer_fx, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands );
    1210       48192 :                 Copy32( ImagBuffer_fx, &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands );
    1211       48192 :                 hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp = sub( 31, q_tc );
    1212       48192 :                 move16();
    1213       48192 :                 hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp = sub( 31, q_tc );
    1214       48192 :                 move16();
    1215             :             }
    1216             :             Word16 scale_factor_real, scale_factor_imag;
    1217             :             Word16 current_idx;
    1218      168096 :             exp_real_tmp = hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp;
    1219      168096 :             move16();
    1220      168096 :             exp_imag_tmp = hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp;
    1221      168096 :             move16();
    1222      168096 :             current_idx = add( imult1616( imult1616( slot_idx, hSpatParamRendCom->num_freq_bands ), nchan_transport ), imult1616( ch, hSpatParamRendCom->num_freq_bands ) );
    1223      168096 :             scale_factor_real = getScaleFactor32( &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands );
    1224      168096 :             scale_factor_imag = getScaleFactor32( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands );
    1225      168096 :             scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, scale_factor_real ); // Q(31-(exp_real_tmp-scale_factor_real))
    1226      168096 :             scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, scale_factor_imag ); // Q(31-(exp_imag_tmp-scale_factor_imag))
    1227      168096 :             exp_real_tmp = sub( exp_real_tmp, scale_factor_real );
    1228      168096 :             exp_imag_tmp = sub( exp_imag_tmp, scale_factor_imag );
    1229      168096 :             ivas_param_ism_collect_slot_fx( hParamIsmDec,
    1230      168096 :                                             &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx],
    1231             :                                             exp_real_tmp,
    1232      168096 :                                             &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx],
    1233             :                                             exp_imag_tmp,
    1234             :                                             ch,
    1235             :                                             cx_diag_fx, exp_cx_diag );
    1236             : 
    1237      168096 :             exp_real_tmp = add( exp_real_tmp, scale_factor_real );
    1238      168096 :             exp_imag_tmp = add( exp_imag_tmp, scale_factor_imag );
    1239      168096 :             scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, -scale_factor_real ); // Q(31-(exp_real_tmp))
    1240      168096 :             scale_sig32( &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[current_idx], hSpatParamRendCom->num_freq_bands, -scale_factor_imag ); // Q(31-(exp_imag_tmp))
    1241             :         }
    1242             :     }
    1243             :     /* Obtain Mixing Matrix on a frame-level */
    1244      320433 :     FOR( bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++ )
    1245             :     {
    1246      315180 :         set32_fx( hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx[bin_idx], 0, PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX );
    1247             :     }
    1248             : 
    1249             :     /* Compute mixing matrix */
    1250        5253 :     ivas_param_ism_compute_mixing_matrix_fx( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response_fx, nchan_transport, nchan_out_woLFE, cx_diag_fx, exp_cx_diag,
    1251        5253 :                                              hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx );
    1252             : 
    1253        5253 :     pop_wmops();
    1254             : 
    1255        5253 :     return;
    1256             : }
    1257             : 
    1258             : 
    1259             : /*-------------------------------------------------------------------------*
    1260             :  * ivas_ism_param_dec_tc_gain_ajust()
    1261             :  *
    1262             :  *
    1263             :  *-------------------------------------------------------------------------*/
    1264             : 
    1265        5253 : void ivas_ism_param_dec_tc_gain_ajust_fx(
    1266             :     Decoder_Struct *st_ivas,        /* i/o: IVAS decoder handle                                         */
    1267             :     const UWord16 nSamples,         /* i  : number of samples to be compensate                          */
    1268             :     const UWord16 nFadeLength,      /* i  : length of the crossfade in samples                          */
    1269             :     Word32 *transport_channels_f[], /* i  : synthesized core-coder transport channels/DirAC output  Q_tc*/
    1270             :     Word16 *Q_tc                    /* i/o : Q of input tc buffer                                       */
    1271             : )
    1272             : 
    1273             : {
    1274             :     Word16 i, tmp_e1, tmp_e2, tmp, tmp2, invFade;
    1275             :     Word32 L_tmp1, L_tmp2;
    1276             : 
    1277             :     Word16 gain_fx, last_gain_fx;
    1278             :     Word32 ene_tc_fx, ene_sum_fx;
    1279             : 
    1280             :     Word16 ene_tc_e, ene_sum_e;
    1281             : 
    1282        5253 :     ene_tc_fx = 0;
    1283        5253 :     move32();
    1284        5253 :     ene_tc_e = 0;
    1285        5253 :     move16();
    1286        5253 :     ene_sum_fx = 0;
    1287        5253 :     move32();
    1288        5253 :     ene_sum_e = 0;
    1289        5253 :     move16();
    1290             : 
    1291             : 
    1292        5253 :     last_gain_fx = st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_fx;
    1293        5253 :     move16();
    1294             : 
    1295             :     Word32 ch0, ch1;
    1296             :     Word16 ch0_e, ch1_e;
    1297        5253 :     ch0_e = 0;
    1298        5253 :     move16();
    1299        5253 :     ch1_e = 0;
    1300        5253 :     move16();
    1301             : 
    1302     5048133 :     FOR( i = 0; i < nSamples; i++ )
    1303             :     {
    1304     5042880 :         ch0_e = 0;
    1305     5042880 :         move16();
    1306     5042880 :         ch1_e = 0;
    1307     5042880 :         move16();
    1308     5042880 :         ch0 = transport_channels_f[0][i];
    1309     5042880 :         move16();
    1310     5042880 :         ch1 = transport_channels_f[1][i];
    1311     5042880 :         move16();
    1312     5042880 :         ch0 = BASOP_Util_Add_Mant32Exp( ch0, ch0_e, 0, 0, &ch0_e );
    1313     5042880 :         ch1 = BASOP_Util_Add_Mant32Exp( ch1, ch1_e, 0, 0, &ch1_e );
    1314             : 
    1315             : 
    1316     5042880 :         L_tmp1 = Mpy_32_32( ch0, ch0 ); /*L*L*/
    1317     5042880 :         tmp_e1 = add( ch0_e, ch0_e );
    1318     5042880 :         L_tmp2 = Mpy_32_32( ch1, ch1 ); /*R*R*/
    1319     5042880 :         tmp_e2 = add( ch1_e, ch1_e );
    1320             :         /*L*LL + R*R*/
    1321     5042880 :         ene_tc_fx = BASOP_Util_Add_Mant32Exp( ene_tc_fx, ene_tc_e, L_tmp1, tmp_e1, &ene_tc_e );
    1322     5042880 :         ene_tc_fx = BASOP_Util_Add_Mant32Exp( ene_tc_fx, ene_tc_e, L_tmp2, tmp_e2, &ene_tc_e );
    1323             : 
    1324             : 
    1325     5042880 :         L_tmp1 = BASOP_Util_Add_Mant32Exp( ch0, ch0_e, ch1, ch1_e, &tmp_e1 ); /*L + R*/
    1326     5042880 :         L_tmp1 = Mpy_32_32( L_tmp1, L_tmp1 );                                 // Q(31-(tmp_e1+tmp_e1           /*(L + R)*(L + R)*/
    1327     5042880 :         tmp_e1 = add( tmp_e1, tmp_e1 );
    1328             : 
    1329     5042880 :         ene_sum_fx = BASOP_Util_Add_Mant32Exp( ene_sum_fx, ene_sum_e, L_tmp1, tmp_e1, &ene_sum_e );
    1330             :     }
    1331             : 
    1332        5253 :     IF( ene_sum_fx != 0 )
    1333             :     {
    1334        5253 :         gain_fx = BASOP_Util_Divide3232_Scale( ene_tc_fx, ene_sum_fx, &tmp_e1 );
    1335             :     }
    1336             :     ELSE
    1337             :     {
    1338           0 :         IF( ene_tc_fx == 0 ) /*handling numerator equals to zero*/
    1339             :         {
    1340           0 :             gain_fx = 0;
    1341           0 :             move16();
    1342           0 :             tmp_e1 = 31;
    1343           0 :             move16();
    1344             :         }
    1345             :         ELSE
    1346             :         { /*handling denominator equals to zero*/
    1347           0 :             gain_fx = 1;
    1348           0 :             move16();
    1349           0 :             tmp_e1 = -32767; //(-1.0f in Q15) + 1
    1350           0 :             move16();
    1351             :         }
    1352             :     }
    1353        5253 :     tmp_e1 = add( tmp_e1, sub( ene_tc_e, ene_sum_e ) ); /* tmp_e1 + (ene_tc_e - ene_sum_e)*/
    1354        5253 :     gain_fx = Sqrt16( gain_fx, &tmp_e1 );
    1355             : 
    1356        5253 :     tmp_e2 = st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_e;
    1357        5253 :     move16();
    1358             : 
    1359        5253 :     IF( GT_16( tmp_e2, tmp_e1 ) )
    1360             :     {
    1361        4964 :         gain_fx = shr( gain_fx, sub( tmp_e2, tmp_e1 ) ); // Q(15-tmp_e2)
    1362        4964 :         tmp_e1 = tmp_e2;
    1363        4964 :         move16();
    1364             :     }
    1365             :     ELSE
    1366             :     {
    1367         289 :         last_gain_fx = shr( last_gain_fx, sub( tmp_e1, tmp_e2 ) ); // Q(15-tmp_e1)
    1368             :     }
    1369             : 
    1370        5253 :     IF( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 1 )
    1371             :     {
    1372             :         /* Smoothing */
    1373        5247 :         gain_fx = add( mult_r( 24574, gain_fx ), mult_r( 8192, last_gain_fx ) ); // 24574 =.75f in Q15 , 8192=.25f in Q15
    1374             :         /* 10ms ramp */
    1375             :         /* slope between two consecutive gains, 480 samples length */
    1376        5247 :         invFade = div_s( 1, nFadeLength ); // Q15
    1377        5247 :         tmp = 0;
    1378        5247 :         move16();
    1379     2523807 :         FOR( i = 0; i < ( nFadeLength ); i++ )
    1380             :         {
    1381             :             /* tmp2 = ( last_gain_fx + i * grad_fx )*/
    1382     2518560 :             tmp2 = add( mult_r( sub( 32767, tmp ), last_gain_fx ), mult_r( tmp, gain_fx ) ); // 32767= 1.0f in Q15,
    1383             : 
    1384     2518560 :             transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], tmp2 ); // Q(Q_tc-tmp_e1)
    1385     2518560 :             move32();
    1386     2518560 :             transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], tmp2 ); // Q(Q_tc-tmp_e1)
    1387     2518560 :             move32();
    1388             : 
    1389     2518560 :             tmp = add( tmp, invFade );
    1390             :         }
    1391     2523807 :         FOR( ; i < nSamples; i++ )
    1392             :         {
    1393     2518560 :             transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], gain_fx ); // Q(Q_tc-tmp_e1)
    1394     2518560 :             move32();
    1395     2518560 :             transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], gain_fx ); // Q(Q_tc-tmp_e1)
    1396     2518560 :             move32();
    1397             :         }
    1398             :     }
    1399             :     ELSE
    1400             :     {
    1401        5766 :         FOR( i = 0; i < nSamples; i++ )
    1402             :         {
    1403        5760 :             transport_channels_f[0][i] = Mpy_32_16_1( transport_channels_f[0][i], gain_fx ); // Q(Q_tc-tmp_e1)
    1404        5760 :             move32();
    1405        5760 :             transport_channels_f[1][i] = Mpy_32_16_1( transport_channels_f[1][i], gain_fx ); // Q(Q_tc-tmp_e1)
    1406        5760 :             move32();
    1407             :         }
    1408             :     }
    1409             : 
    1410        5253 :     st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_fx = gain_fx;
    1411        5253 :     move16();
    1412        5253 :     st_ivas->hParamIsmDec->hParamIsm->last_dmx_gain_e = tmp_e1;
    1413        5253 :     move16();
    1414             : 
    1415        5253 :     *Q_tc = sub( *Q_tc, tmp_e1 );
    1416        5253 :     move16();
    1417        5253 :     return;
    1418             : }
    1419             : 
    1420             : /*-------------------------------------------------------------------------*
    1421             :  * ivas_ism_param_dec_render_sf()
    1422             :  *
    1423             :  *
    1424             :  *-------------------------------------------------------------------------*/
    1425       22317 : static void ivas_ism_param_dec_render_sf_fx(
    1426             :     Decoder_Struct *st_ivas,
    1427             :     IVAS_OUTPUT_SETUP hSetup,
    1428             :     const Word16 nchan_transport,
    1429             :     const Word16 nchan_out,
    1430             :     const Word16 nchan_out_woLFE,
    1431             :     Word32 *output_f_fx[], /*Q_output*/
    1432             :     Word16 Q_output[] )
    1433             : {
    1434             :     Word16 ch, slot_idx, i, index_slot;
    1435             :     /* CLDFB Output Buffers */
    1436             :     Word32 Cldfb_RealBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; // Q(31-real_exp)
    1437             :     Word32 Cldfb_ImagBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; // Q(31-imag_exp)
    1438             :     Word32 *Cldfb_RealBuffer_in_fx[PARAM_ISM_MAX_DMX];                                                  // Q11
    1439             :     Word32 *Cldfb_ImagBuffer_in_fx[PARAM_ISM_MAX_DMX];                                                  // Q11
    1440             :     PARAM_ISM_DEC_HANDLE hParamIsmDec;
    1441             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    1442             :     Word16 slot_idx_start;
    1443             :     Word16 idx_in;
    1444             :     Word16 idx_lfe;
    1445             :     Word16 subframe_idx;
    1446             :     Word16 samplesProcessed, no_col_cldfb, size_cldfb;
    1447       22317 :     hParamIsmDec = st_ivas->hParamIsmDec;
    1448       22317 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    1449       22317 :     slot_idx_start = hSpatParamRendCom->slots_rendered;
    1450       22317 :     move16();
    1451       22317 :     subframe_idx = hSpatParamRendCom->subframes_rendered;
    1452       22317 :     move16();
    1453             :     /* Set some memories to zero */
    1454      228600 :     FOR( ch = 0; ch < nchan_out_woLFE; ch++ )
    1455             :     {
    1456      973995 :         FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    1457             :         {
    1458      767712 :             set32_fx( Cldfb_RealBuffer_fx[ch][slot_idx], 0, hSpatParamRendCom->num_freq_bands );
    1459      767712 :             set32_fx( Cldfb_ImagBuffer_fx[ch][slot_idx], 0, hSpatParamRendCom->num_freq_bands );
    1460             :         }
    1461             :     }
    1462             : 
    1463             : 
    1464             :     Word16 real_exp[JBM_CLDFB_SLOTS_IN_SUBFRAME];
    1465             :     Word16 imag_exp[JBM_CLDFB_SLOTS_IN_SUBFRAME];
    1466      106365 :     FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    1467             :     {
    1468       84048 :         index_slot = add( slot_idx_start, slot_idx );
    1469             : 
    1470             : 
    1471      252144 :         FOR( ch = 0; ch < nchan_transport; ch++ )
    1472             :         {
    1473      168096 :             Word16 cldfb_idx = add( imult1616( imult1616( index_slot, hSpatParamRendCom->num_freq_bands ), nchan_transport ), imult1616( ch, hSpatParamRendCom->num_freq_bands ) );
    1474      168096 :             Cldfb_RealBuffer_in_fx[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[cldfb_idx]; // Q11
    1475      168096 :             Cldfb_ImagBuffer_in_fx[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[cldfb_idx]; // Q11
    1476             :         }
    1477             : 
    1478             :         /* Compute bandwise rendering to target LS using covariance rendering */
    1479       84048 :         real_exp[slot_idx] = 0;
    1480       84048 :         move16();
    1481       84048 :         imag_exp[slot_idx] = 0;
    1482       84048 :         move16();
    1483       84048 :         ivas_param_ism_render_slot_fx( hParamIsmDec, hSpatParamRendCom,
    1484       84048 :                                        Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, &real_exp[slot_idx], &imag_exp[slot_idx],
    1485       84048 :                                        hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx,
    1486             :                                        index_slot, slot_idx, nchan_out_woLFE, nchan_transport );
    1487             :     }
    1488             : 
    1489             :     /* CLDFB Synthesis */
    1490       22317 :     idx_in = 0;
    1491       22317 :     move16();
    1492       22317 :     idx_lfe = 0;
    1493       22317 :     move16();
    1494             :     // Word16 tmp_buff_Q[MAX_OUTPUT_CHANNELS];
    1495             : 
    1496      248745 :     FOR( ch = 0; ch < nchan_out; ch++ )
    1497             :     {
    1498      226428 :         test();
    1499      226428 :         IF( ( hSetup.num_lfe > 0 ) && EQ_16( hSetup.index_lfe[idx_lfe], ch ) )
    1500             :         {
    1501       20145 :             set32_fx( output_f_fx[ch], 0, i_mult( hSpatParamRendCom->subframe_nbslots[subframe_idx], hSpatParamRendCom->num_freq_bands ) );
    1502             : 
    1503       20145 :             if ( LT_16( idx_lfe, sub( hSetup.num_lfe, 1 ) ) )
    1504             :             {
    1505           0 :                 idx_lfe = add( idx_lfe, 1 );
    1506             :             }
    1507             :         }
    1508             :         ELSE
    1509             :         {
    1510             : 
    1511             :             Word32 *RealBuffer_fx[16];
    1512             :             Word32 *ImagBuffer_fx[16];
    1513             : 
    1514      206283 :             Word16 Q_real = 31;
    1515      206283 :             move16();
    1516             : 
    1517      973995 :             FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
    1518             :             {
    1519      767712 :                 RealBuffer_fx[i] = Cldfb_RealBuffer_fx[idx_in][i];
    1520      767712 :                 ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i];
    1521      767712 :                 Q_real = s_min( Q_real, sub( 31, imag_exp[i] ) );
    1522      767712 :                 Q_real = s_min( Q_real, sub( 31, real_exp[i] ) );
    1523             :             }
    1524             : 
    1525      206283 :             Q_real = sub( Q_real, 3 ); // guarded bits
    1526             : 
    1527      973995 :             FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
    1528             :             {
    1529      767712 :                 Scale_sig32( RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, add( sub( Q_real, 31 ), real_exp[i] ) ); // Q_real
    1530      767712 :                 Scale_sig32( ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, add( sub( Q_real, 31 ), imag_exp[i] ) ); // Q_real
    1531             :             }
    1532             : 
    1533      206283 :             Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( sub( Q_real, 1 ), Q11 ) ); // Q_real-1
    1534      206283 :             st_ivas->cldfbSynDec[ch]->Q_cldfb_state = sub( Q_real, 1 );
    1535      206283 :             move16();
    1536             : #ifdef OPT_AVOID_STATE_BUF_RESCALE
    1537      206283 :             cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, 0, st_ivas->cldfbSynDec[ch] );
    1538             : #else                                                                                                                                         /* OPT_AVOID_STATE_BUF_RESCALE */
    1539             :             cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], i_mult( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), 0, st_ivas->cldfbSynDec[ch] );
    1540             : #endif                                                                                                                                        /* OPT_AVOID_STATE_BUF_RESCALE */
    1541      206283 :             Scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( Q11, sub( Q_real, 1 ) ) ); // Q11
    1542      206283 :             st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q11;
    1543      206283 :             move16();
    1544             : 
    1545             :             /*scaling the output_f buffer to have common Q accross the buffer*/
    1546      206283 :             samplesProcessed = imult1616( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] );
    1547      206283 :             no_col_cldfb = st_ivas->cldfbSynDec[ch]->no_col;
    1548      206283 :             move16();
    1549      206283 :             IF( GT_16( samplesProcessed, -1 ) )
    1550             :             {
    1551             :                 Word32 res_dec, res_frac;
    1552      206283 :                 iDiv_and_mod_32( sub( add( samplesProcessed, st_ivas->cldfbSynDec[ch]->no_channels ), 1 ), st_ivas->cldfbSynDec[ch]->no_channels, &res_dec, &res_frac, 0 );
    1553      206283 :                 no_col_cldfb = s_min( no_col_cldfb, extract_l( res_dec ) );
    1554             :             }
    1555             : 
    1556      206283 :             size_cldfb = imult1616( st_ivas->cldfbSynDec[ch]->no_channels, no_col_cldfb );
    1557      206283 :             Scale_sig32( output_f_fx[ch], size_cldfb, sub( Q11, sub( Q_real, 1 ) ) ); // Q11
    1558             : 
    1559      206283 :             Q_output[ch] = 11;
    1560      206283 :             move16();
    1561      206283 :             idx_in = add( idx_in, 1 );
    1562             :         }
    1563             :     }
    1564             : 
    1565       22317 :     hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe_idx] );
    1566       22317 :     move16();
    1567       22317 :     hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 );
    1568       22317 :     move16();
    1569             : 
    1570       22317 :     return;
    1571             : }
    1572             : 
    1573             : 
    1574             : /*-------------------------------------------------------------------------*
    1575             :  * ivas_param_ism_dec_render()
    1576             :  *
    1577             :  *
    1578             :  *-------------------------------------------------------------------------*/
    1579        6559 : void ivas_param_ism_dec_render_fx(
    1580             :     Decoder_Struct *st_ivas,        /* i/o: IVAS decoder handle                       */
    1581             :     const UWord16 nSamplesAsked,    /* i  : number of CLDFB slots requested           */
    1582             :     UWord16 *nSamplesRendered,      /* o  : number of CLDFB slots rendered            */
    1583             :     UWord16 *nSamplesAvailableNext, /* o  : number of CLDFB slots still to render     */
    1584             :     Word32 *output_f_fx[]           /*Q11*/
    1585             : )
    1586             : {
    1587             : 
    1588             :     Word16 ch, slots_to_render, first_sf, last_sf, subframe_idx;
    1589             :     UWord16 slot_size, n_samples_sf;
    1590             :     PARAM_ISM_DEC_HANDLE hParamIsmDec;
    1591             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    1592             :     IVAS_OUTPUT_SETUP hSetup;
    1593             :     Word16 nchan_transport, nchan_out, nchan_out_woLFE;
    1594             :     Word32 *output_f_local_fx[MAX_OUTPUT_CHANNELS];
    1595             :     Word16 Q_output[MAX_OUTPUT_CHANNELS];
    1596             : 
    1597        6559 :     set16_fx( Q_output, 0, MAX_OUTPUT_CHANNELS );
    1598             : 
    1599        6559 :     hParamIsmDec = st_ivas->hParamIsmDec;
    1600        6559 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    1601        6559 :     hSetup = st_ivas->hIntSetup;
    1602        6559 :     nchan_transport = st_ivas->nchan_transport;
    1603        6559 :     move16();
    1604             : 
    1605        6559 :     IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
    1606             :     {
    1607         543 :         nchan_out = st_ivas->nchan_ism;
    1608         543 :         move16();
    1609         543 :         nchan_out_woLFE = nchan_out;
    1610         543 :         move16();
    1611         543 :         st_ivas->hDecoderConfig->nchan_out = nchan_out;
    1612         543 :         move16();
    1613             :     }
    1614             :     ELSE
    1615             :     {
    1616        6016 :         nchan_out = add( st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hIntSetup.num_lfe );
    1617        6016 :         move16();
    1618        6016 :         nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
    1619        6016 :         move16();
    1620             :     }
    1621        6559 :     slot_size = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
    1622             : 
    1623             :     /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
    1624             :     Word32 res_dec, res_frac;
    1625        6559 :     iDiv_and_mod_32( nSamplesAsked, slot_size, &res_dec, &res_frac, 0 );
    1626             : 
    1627        6559 :     slots_to_render = s_min( sub( hSpatParamRendCom->num_slots, hSpatParamRendCom->slots_rendered ), extract_l( res_dec ) );
    1628        6559 :     *nSamplesRendered = imult1616( slots_to_render, extract_l( slot_size ) );
    1629        6559 :     move16();
    1630        6559 :     first_sf = hSpatParamRendCom->subframes_rendered;
    1631        6559 :     move16();
    1632        6559 :     last_sf = first_sf;
    1633        6559 :     move16();
    1634             : 
    1635       28876 :     WHILE( slots_to_render > 0 )
    1636             :     {
    1637       22317 :         slots_to_render = sub( slots_to_render, hSpatParamRendCom->subframe_nbslots[last_sf] );
    1638       22317 :         last_sf = add( last_sf, 1 );
    1639             :     }
    1640             : 
    1641       74923 :     FOR( ch = 0; ch < nchan_out; ch++ )
    1642             :     {
    1643       68364 :         output_f_local_fx[ch] = &output_f_fx[ch][0];
    1644             :     }
    1645             : 
    1646       28876 :     FOR( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
    1647             :     {
    1648       22317 :         ivas_ism_param_dec_render_sf_fx( st_ivas, hSetup, nchan_transport, nchan_out, nchan_out_woLFE, output_f_local_fx, Q_output );
    1649             : 
    1650       22317 :         n_samples_sf = i_mult( hSpatParamRendCom->subframe_nbslots[subframe_idx], hSpatParamRendCom->slot_size );
    1651      248745 :         FOR( ch = 0; ch < nchan_out; ch++ )
    1652             :         {
    1653      226428 :             output_f_local_fx[ch] += n_samples_sf;
    1654             :         }
    1655             :     }
    1656             : 
    1657        6559 :     IF( EQ_16( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->num_slots ) )
    1658             :     {
    1659             :         /* copy the memories */
    1660             :         /* store mixing matrix for next subframe */
    1661        5253 :         ivas_param_ism_update_mixing_matrix_fx( hParamIsmDec, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx, nchan_transport, nchan_out_woLFE );
    1662             : 
    1663             :         /* store MetaData parameters */
    1664       24765 :         FOR( ch = 0; ch < st_ivas->nchan_ism; ch++ )
    1665             :         {
    1666       19512 :             IF( GT_32( st_ivas->hParamIsmDec->azimuth_values_fx[ch], 754974720 ) /*180.f in Q22*/ )
    1667             :             {
    1668           0 :                 st_ivas->hIsmMetaData[ch]->azimuth_fx = L_sub( st_ivas->hParamIsmDec->azimuth_values_fx[ch], 1509949440 ) /*360.0F in Q22*/;
    1669           0 :                 move32();
    1670             :             }
    1671             :             ELSE
    1672             :             {
    1673       19512 :                 st_ivas->hIsmMetaData[ch]->azimuth_fx = st_ivas->hParamIsmDec->azimuth_values_fx[ch];
    1674       19512 :                 move32();
    1675             :             }
    1676             : 
    1677       19512 :             st_ivas->hIsmMetaData[ch]->elevation_fx = st_ivas->hParamIsmDec->elevation_values_fx[ch];
    1678       19512 :             move32();
    1679             :         }
    1680             :     }
    1681             : 
    1682        6559 :     *nSamplesAvailableNext = imult1616( sub( hSpatParamRendCom->num_slots, hSpatParamRendCom->slots_rendered ), (Word16) slot_size );
    1683        6559 :     move16();
    1684        6559 :     return;
    1685             : }
    1686             : 
    1687             : 
    1688             : /*-------------------------------------------------------------------------*
    1689             :  * ivas_param_ism_params_to_masa_param_mapping()
    1690             :  *
    1691             :  *
    1692             :  *-------------------------------------------------------------------------*/
    1693        7955 : void ivas_param_ism_params_to_masa_param_mapping_fx(
    1694             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure      */
    1695             : )
    1696             : {
    1697             :     PARAM_ISM_DEC_HANDLE hParamIsmDec;
    1698             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    1699             :     Word16 nBins;
    1700             :     Word16 band_idx, bin_idx, sf_idx;
    1701             :     Word16 brange[2];
    1702             :     Word16 azimuth[2];
    1703             :     Word16 elevation[2];
    1704             :     Word16 power_ratio_fx[2]; /* Q15 */
    1705             :     Word32 ivas_total_brate;
    1706             : 
    1707        7955 :     hParamIsmDec = st_ivas->hParamIsmDec;
    1708        7955 :     hSpatParamRendCom = st_ivas->hSpatParamRendCom;
    1709        7955 :     nBins = hSpatParamRendCom->num_freq_bands;
    1710        7955 :     move16();
    1711        7955 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
    1712        7955 :     move32();
    1713             : 
    1714        7955 :     test();
    1715        7955 :     IF( !( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || ivas_total_brate == FRAME_NO_DATA ) )
    1716             :     {
    1717        7691 :         ivas_param_ism_dec_dequant_DOA_fx( hParamIsmDec, st_ivas->nchan_ism );
    1718        7691 :         ivas_param_ism_dec_dequant_powrat_fx( hParamIsmDec );
    1719        7691 :         st_ivas->hISMDTX.dtx_flag = 0;
    1720        7691 :         move16();
    1721             :     }
    1722             :     ELSE
    1723             :     {
    1724         264 :         st_ivas->hISMDTX.dtx_flag = 1;
    1725         264 :         move16();
    1726             :     }
    1727             : 
    1728        7955 :     IF( GT_16( st_ivas->nchan_ism, 1 ) )
    1729             :     {
    1730        7955 :         IF( st_ivas->hISMDTX.dtx_flag )
    1731             :         {
    1732             :             Word32 energy_ratio_fx;                                                                                                                                                /* Q30 */
    1733         264 :             energy_ratio_fx = L_mult0( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx, st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx ); /* Q15 + Q15 -> Q30 */
    1734             : 
    1735         264 :             hSpatParamRendCom->numSimultaneousDirections = 1;
    1736         264 :             move16();
    1737         264 :             azimuth[0] = extract_l( L_shr( L_add( hParamIsmDec->azimuth_values_fx[0], ONE_IN_Q21 ), 22 ) ); // Q0
    1738         264 :             move16();
    1739         264 :             elevation[0] = extract_l( L_shr( L_add( hParamIsmDec->elevation_values_fx[0], ONE_IN_Q21 ), 22 ) ); // Q0
    1740         264 :             move16();
    1741             : 
    1742        1320 :             FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
    1743             :             {
    1744       64416 :                 FOR( bin_idx = 0; bin_idx < nBins; bin_idx++ )
    1745             :                 {
    1746       63360 :                     hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0];
    1747       63360 :                     move16();
    1748       63360 :                     hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0];
    1749       63360 :                     move16();
    1750       63360 :                     hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx] = energy_ratio_fx;
    1751       63360 :                     move16();
    1752       63360 :                     hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx] = 0;
    1753       63360 :                     move16();
    1754       63360 :                     hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx] = 0;
    1755       63360 :                     move16();
    1756             :                 }
    1757             :             }
    1758             :         }
    1759             :         ELSE
    1760             :         {
    1761        7691 :             hSpatParamRendCom->numSimultaneousDirections = 2;
    1762        7691 :             move16();
    1763       92292 :             FOR( band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++ )
    1764             :             {
    1765       84601 :                 brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx];
    1766       84601 :                 move16();
    1767       84601 :                 brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1];
    1768       84601 :                 move16();
    1769             : 
    1770       84601 :                 azimuth[0] = extract_l( L_shr( L_add( hParamIsmDec->azimuth_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]], ( 1 << 21 ) ), 22 ) ); // Q0
    1771       84601 :                 move16();
    1772       84601 :                 elevation[0] = extract_l( L_shr( L_add( hParamIsmDec->elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][0]], ( 1 << 21 ) ), 22 ) ); // Q0
    1773       84601 :                 move16();
    1774       84601 :                 power_ratio_fx[0] = hParamIsmDec->power_ratios_fx[band_idx][0][0];
    1775       84601 :                 move16();
    1776       84601 :                 azimuth[1] = extract_l( L_shr( L_add( hParamIsmDec->azimuth_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]], ( 1 << 21 ) ), 22 ) ); // Q0
    1777       84601 :                 move16();
    1778       84601 :                 elevation[1] = extract_l( L_shr( L_add( hParamIsmDec->elevation_values_fx[hParamIsmDec->hParamIsm->obj_indices[band_idx][0][1]], ( 1 << 21 ) ), 22 ) ); // Q0
    1779       84601 :                 move16();
    1780       84601 :                 power_ratio_fx[1] = hParamIsmDec->power_ratios_fx[band_idx][0][1];
    1781       84601 :                 move16();
    1782             : 
    1783      423005 :                 FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
    1784             :                 {
    1785     2124164 :                     FOR( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ )
    1786             :                     {
    1787     1785760 :                         hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0];
    1788     1785760 :                         move16();
    1789     1785760 :                         hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0];
    1790     1785760 :                         move16();
    1791     1785760 :                         hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx] = L_shl( power_ratio_fx[0], Q15 ); // Q30
    1792     1785760 :                         move32();
    1793     1785760 :                         hSpatParamRendCom->azimuth2[sf_idx][bin_idx] = azimuth[1];
    1794     1785760 :                         move16();
    1795     1785760 :                         hSpatParamRendCom->elevation2[sf_idx][bin_idx] = elevation[1];
    1796     1785760 :                         move16();
    1797     1785760 :                         hSpatParamRendCom->energy_ratio2_fx[sf_idx][bin_idx] = L_shl( power_ratio_fx[1], Q15 ); // Q30
    1798     1785760 :                         move32();
    1799             :                     }
    1800             :                 }
    1801             :             }
    1802             : 
    1803       38455 :             FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
    1804             :             {
    1805     1816524 :                 FOR( bin_idx = 0; bin_idx < nBins; bin_idx++ )
    1806             :                 {
    1807     1785760 :                     hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx] = 0;
    1808     1785760 :                     move16();
    1809     1785760 :                     hSpatParamRendCom->spreadCoherence2_fx[sf_idx][bin_idx] = 0;
    1810     1785760 :                     move16();
    1811     1785760 :                     hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx] = 0;
    1812     1785760 :                     move16();
    1813             :                 }
    1814             :             }
    1815             :         }
    1816             :     }
    1817             :     ELSE
    1818             :     {
    1819           0 :         hSpatParamRendCom->numSimultaneousDirections = 1;
    1820           0 :         move16();
    1821           0 :         azimuth[0] = extract_l( L_shr( ( L_add( hParamIsmDec->azimuth_values_fx[0], ( 1 << 21 ) ) ), 22 ) ); // Q0
    1822           0 :         move16();
    1823           0 :         elevation[0] = extract_l( L_shr( L_add( hParamIsmDec->elevation_values_fx[0], ( 1 << 21 ) ), 22 ) ); // Q0
    1824           0 :         move16();
    1825             : 
    1826           0 :         FOR( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ )
    1827             :         {
    1828           0 :             FOR( bin_idx = 0; bin_idx < nBins; bin_idx++ )
    1829             :             {
    1830           0 :                 hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0];
    1831           0 :                 move16();
    1832           0 :                 hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0];
    1833           0 :                 move16();
    1834           0 :                 hSpatParamRendCom->energy_ratio1_fx[sf_idx][bin_idx] = ONE_IN_Q30; /* 1.0f in Q30 */
    1835           0 :                 move32();
    1836           0 :                 hSpatParamRendCom->spreadCoherence_fx[sf_idx][bin_idx] = 0;
    1837           0 :                 move16();
    1838           0 :                 hSpatParamRendCom->surroundingCoherence_fx[sf_idx][bin_idx] = 0;
    1839           0 :                 move16();
    1840             :             }
    1841             :         }
    1842             :     }
    1843        7955 :     return;
    1844             : }

Generated by: LCOV version 1.14