LCOV - code coverage report
Current view: top level - lib_dec - ivas_omasa_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ d40ed931793b6a50d91fe879dc4ec795971aff53 Lines: 772 850 90.8 %
Date: 2025-09-18 03:57:22 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include "options.h"
      34             : #include <stdlib.h>
      35             : #include <math.h>
      36             : #include "ivas_cnst.h"
      37             : #include "ivas_prot_fx.h"
      38             : #include "prot_fx.h"
      39             : #include "ivas_prot_rend_fx.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "wmc_auto.h"
      42             : #include "ivas_prot_fx.h"
      43             : 
      44             : 
      45             : /*-------------------------------------------------------------------------
      46             :  * Local constants
      47             :  *------------------------------------------------------------------------*/
      48             : 
      49             : 
      50             : #define EXT_RENDER_IIR_FAC              0.95f
      51             : #define MULT_17_DIV_20_Q15              ( Word16 )( ( 17.0 / 20.0f ) * pow( 2, 15 ) + 0.5f )
      52             : #define MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ( Word16 )( ( 1.0 / CLDFB_NO_COL_MAX ) * pow( 2, 15 ) + 0.5f )
      53             : #define ONEMINUX_EXT_RENDER_IIR_FAC_Q31 ( Word32 )( ( 1.0f - EXT_RENDER_IIR_FAC ) * pow( 2, 31 ) + 0.5f )
      54             : #define EXT_RENDER_IIR_FAC_Q31          ( Word32 )( EXT_RENDER_IIR_FAC * pow( 2, 31 ) + 0.5f )
      55             : 
      56             : // Calculated as (Word16)(((1.0f / (50 * MAX_PARAM_SPATIAL_SUBFRAMES)) * pow(2, 15)) + 0.5f)
      57             : #define OMASA_DELAYFRAMES_PER_SEC_Q15 (Word16) 164 // Q15
      58             : 
      59             : static Word16 interpolator_table_48k_q15[] = {
      60             :     0, 137, 273, 410, 546, 683, 819, 956, 1092, 1229,
      61             :     1365, 1502, 1638, 1775, 1911, 2048, 2185, 2321, 2458, 2594,
      62             :     2731, 2867, 3004, 3140, 3277, 3413, 3550, 3686, 3823, 3959,
      63             :     4096, 4233, 4369, 4506, 4642, 4779, 4915, 5052, 5188, 5325,
      64             :     5461, 5598, 5734, 5871, 6007, 6144, 6281, 6417, 6554, 6690,
      65             :     6827, 6963, 7100, 7236, 7373, 7509, 7646, 7782, 7919, 8055,
      66             :     8192, 8329, 8465, 8602, 8738, 8875, 9011, 9148, 9284, 9421,
      67             :     9557, 9694, 9830, 9967, 10103, 10240, 10377, 10513, 10650, 10786,
      68             :     10923, 11059, 11196, 11332, 11469, 11605, 11742, 11878, 12015, 12151,
      69             :     12288, 12425, 12561, 12698, 12834, 12971, 13107, 13244, 13380, 13517,
      70             :     13653, 13790, 13926, 14063, 14199, 14336, 14473, 14609, 14746, 14882,
      71             :     15019, 15155, 15292, 15428, 15565, 15701, 15838, 15974, 16111, 16247,
      72             :     16384, 16521, 16657, 16794, 16930, 17067, 17203, 17340, 17476, 17613,
      73             :     17749, 17886, 18022, 18159, 18295, 18432, 18569, 18705, 18842, 18978,
      74             :     19115, 19251, 19388, 19524, 19661, 19797, 19934, 20070, 20207, 20343,
      75             :     20480, 20617, 20753, 20890, 21026, 21163, 21299, 21436, 21572, 21709,
      76             :     21845, 21982, 22118, 22255, 22391, 22528, 22665, 22801, 22938, 23074,
      77             :     23211, 23347, 23484, 23620, 23757, 23893, 24030, 24166, 24303, 24439,
      78             :     24576, 24713, 24849, 24986, 25122, 25259, 25395, 25532, 25668, 25805,
      79             :     25941, 26078, 26214, 26351, 26487, 26624, 26761, 26897, 27034, 27170,
      80             :     27307, 27443, 27580, 27716, 27853, 27989, 28126, 28262, 28399, 28535,
      81             :     28672, 28809, 28945, 29082, 29218, 29355, 29491, 29628, 29764, 29901,
      82             :     30037, 30174, 30310, 30447, 30583, 30720, 30857, 30993, 31130, 31266,
      83             :     31403, 31539, 31676, 31812, 31949, 32085, 32222, 32358, 32495, 32631
      84             : };
      85             : 
      86             : static Word16 interpolator_table_32k_q15[] = {
      87             :     0, 205, 410, 614, 819, 1024, 1229, 1434, 1638, 1843,
      88             :     2048, 2253, 2458, 2662, 2867, 3072, 3277, 3482, 3686, 3891,
      89             :     4096, 4301, 4506, 4710, 4915, 5120, 5325, 5530, 5734, 5939,
      90             :     6144, 6349, 6554, 6758, 6963, 7168, 7373, 7578, 7782, 7987,
      91             :     8192, 8397, 8602, 8806, 9011, 9216, 9421, 9626, 9830, 10035,
      92             :     10240, 10445, 10650, 10854, 11059, 11264, 11469, 11674, 11878, 12083,
      93             :     12288, 12493, 12698, 12902, 13107, 13312, 13517, 13722, 13926, 14131,
      94             :     14336, 14541, 14746, 14950, 15155, 15360, 15565, 15770, 15974, 16179,
      95             :     16384, 16589, 16794, 16998, 17203, 17408, 17613, 17818, 18022, 18227,
      96             :     18432, 18637, 18842, 19046, 19251, 19456, 19661, 19866, 20070, 20275,
      97             :     20480, 20685, 20890, 21094, 21299, 21504, 21709, 21914, 22118, 22323,
      98             :     22528, 22733, 22938, 23142, 23347, 23552, 23757, 23962, 24166, 24371,
      99             :     24576, 24781, 24986, 25190, 25395, 25600, 25805, 26010, 26214, 26419,
     100             :     26624, 26829, 27034, 27238, 27443, 27648, 27853, 28058, 28262, 28467,
     101             :     28672, 28877, 29082, 29286, 29491, 29696, 29901, 30106, 30310, 30515,
     102             :     30720, 30925, 31130, 31334, 31539, 31744, 31949, 32154, 32358, 32563
     103             : };
     104             : 
     105             : static Word16 interpolator_table_16k_q15[] = {
     106             :     0, 410, 819, 1229, 1638, 2048, 2458, 2867, 3277, 3686,
     107             :     4096, 4506, 4915, 5325, 5734, 6144, 6554, 6963, 7373, 7782,
     108             :     8192, 8602, 9011, 9421, 9830, 10240, 10650, 11059, 11469, 11878,
     109             :     12288, 12698, 13107, 13517, 13926, 14336, 14746, 15155, 15565, 15974,
     110             :     16384, 16794, 17203, 17613, 18022, 18432, 18842, 19251, 19661, 20070,
     111             :     20480, 20890, 21299, 21709, 22118, 22528, 22938, 23347, 23757, 24166,
     112             :     24576, 24986, 25395, 25805, 26214, 26624, 27034, 27443, 27853, 28262,
     113             :     28672, 29082, 29491, 29901, 30310, 30720, 31130, 31539, 31949, 32358
     114             : };
     115             : 
     116             : 
     117             : /*-------------------------------------------------------------------------
     118             :  * Local functions
     119             :  *------------------------------------------------------------------------*/
     120             : 
     121             : /**
     122             :  * Calculate mantissa (Q31) * gain (Q31).
     123             :  *
     124             :  * Exponent for the mantissa value is also included as input parameter.
     125             :  * Adjust the result so that accuracy of the mantissa multiplication is maximixed
     126             :  * and the corresponding exponent is minimized.
     127             :  */
     128             : 
     129     2772480 : static Word32 mult32_mantissa_fx(
     130             :     const Word32 mantissa,
     131             :     const Word32 gain,
     132             :     const Word16 exp,
     133             :     Word16 *exp_result )
     134             : {
     135     2772480 :     Word64 mult = W_mult_32_32( mantissa, gain ); // Q31 * Q31 -> Q63
     136     2772480 :     Word16 norm = W_norm( mult );
     137     2772480 :     Word32 result = W_extract_h( W_shl( mult, norm ) ); // Q63 -> Q31
     138     2772480 :     *exp_result = sub( exp, norm );
     139             : 
     140     2772480 :     return result;
     141             : }
     142             : 
     143             : 
     144             : /**
     145             :  * Calculate re^2 + im^2 using exponent (Q0) and mantissa (Q31) format.
     146             :  */
     147      334080 : static Word32 sample_energy_fx(
     148             :     const Word32 re_m,
     149             :     const Word16 re_e,
     150             :     const Word32 im_m,
     151             :     const Word16 im_e,
     152             :     Word16 *exp_result )
     153             : {
     154      334080 :     Word16 re_exp = add( re_e, re_e );
     155      334080 :     Word32 re_mult = mult32_mantissa_fx( re_m, re_m, re_exp, &re_exp );
     156      334080 :     move32();
     157             : 
     158      334080 :     Word16 im_exp = add( im_e, im_e );
     159      334080 :     Word32 im_mult = mult32_mantissa_fx( im_m, im_m, im_exp, &im_exp );
     160      334080 :     move32();
     161             : 
     162      334080 :     return BASOP_Util_Add_Mant32Exp( re_mult, re_exp, im_mult, im_exp, exp_result );
     163             : }
     164             : 
     165             : 
     166             : /**
     167             :  * Accumulate sum of re^2 + im^2 over the specified length using exponent (Q0) and mantissa (Q31) format.
     168             :  */
     169       41472 : static void sample_energy_acc_fx(
     170             :     Word32 *re_m,
     171             :     Word16 *re_e,
     172             :     Word32 *im_m,
     173             :     Word16 *im_e,
     174             :     Word32 *out_m,
     175             :     Word16 *out_e,
     176             :     const Word16 len )
     177             : {
     178             :     Word16 i;
     179             : 
     180      145152 :     FOR( i = 0; i < len; i++ )
     181             :     {
     182             :         Word16 exp;
     183             : 
     184             :         // energy = re^2 + im^2
     185      103680 :         Word32 mantissa = sample_energy_fx( re_m[i], re_e[i], im_m[i], im_e[i], &exp );
     186      103680 :         move32();
     187             : 
     188             :         // Accumulate energy
     189      103680 :         *out_m = BASOP_Util_Add_Mant32Exp( *out_m, *out_e, mantissa, exp, out_e );
     190      103680 :         move32();
     191             :     }
     192             : 
     193       41472 :     return;
     194             : }
     195             : 
     196             : // Multiplication of vector (comprising of exponent and mantissa parts) by constant value (Q31)
     197        5120 : static void v_multc_exp_mantissa_fx(
     198             :     const Word32 *in_mantissa,
     199             :     const Word16 *in_exp,
     200             :     const Word32 c,
     201             :     Word32 *out_mantissa,
     202             :     Word16 *out_exp,
     203             :     const Word16 len )
     204             : {
     205             :     Word16 i;
     206             : 
     207      312320 :     FOR( i = 0; i < len; i++ )
     208             :     {
     209      307200 :         out_mantissa[i] = mult32_mantissa_fx( in_mantissa[i], c, in_exp[i], &out_exp[i] );
     210      307200 :         move32();
     211             :     }
     212        5120 :     return;
     213             : }
     214             : 
     215             : 
     216             : // Multiplication of vector (comprising of exponent and mantissa parts) by constant acumulate to the output
     217        5264 : static void v_multc_acc_exp_mantissa_fx(
     218             :     const Word32 *in_mantissa,
     219             :     const Word16 *in_exp,
     220             :     const Word32 c,
     221             :     Word32 *out_mantissa,
     222             :     Word16 *out_exp,
     223             :     const Word16 len )
     224             : {
     225             :     Word16 i;
     226             : 
     227      364304 :     FOR( i = 0; i < len; i++ )
     228             :     {
     229             :         Word16 exp;
     230      359040 :         Word32 mantissa = mult32_mantissa_fx( in_mantissa[i], c, in_exp[i], &exp );
     231      359040 :         move32();
     232             : 
     233      359040 :         out_mantissa[i] = BASOP_Util_Add_Mant32Exp( out_mantissa[i], out_exp[i], mantissa, exp, &out_exp[i] );
     234      359040 :         move32();
     235             :     }
     236             : 
     237        5264 :     return;
     238             : }
     239             : 
     240             : 
     241             : // Calculate min( 4, sqrtf( target / proto ) )
     242             : // target and proto values are expressed using exponent and mantissa
     243             : 
     244      192000 : static Word32 get_processing_gain_fx(
     245             :     const Word32 proto_m,
     246             :     const Word16 proto_e,
     247             :     const Word32 target_m,
     248             :     const Word16 target_e,
     249             :     Word16 *exp )
     250             : {
     251      192000 :     Word16 b = extract_h( proto_m );
     252      192000 :     IF( EQ_16( b, 0 ) )
     253             :     {
     254        2700 :         b = 1;
     255        2700 :         move16();
     256             :     }
     257             : 
     258             :     Word16 mantissa;
     259      192000 :     BASOP_Util_Divide_MantExp( extract_h( target_m ), target_e, b, proto_e, &mantissa, exp );
     260             : 
     261      192000 :     Word32 sqrt_mantissa = Sqrt32( L_shl( mantissa, 16 ), exp );
     262             : 
     263      192000 :     Word16 norm = norm_l( sqrt_mantissa );
     264      192000 :     sqrt_mantissa = L_shl( sqrt_mantissa, norm );
     265      192000 :     *exp = sub( *exp, norm );
     266             : 
     267      192000 :     test();
     268      192000 :     IF( GT_16( *exp, 2 ) && NE_32( sqrt_mantissa, 0 ) )
     269             :     {
     270             :         // (2^3) * (1073741824 / 2^31) == 4.0
     271          31 :         sqrt_mantissa = ONE_IN_Q30; // 0.5 in Q31
     272          31 :         *exp = 3;
     273          31 :         move32();
     274          31 :         move16();
     275             :     }
     276             : 
     277      192000 :     return sqrt_mantissa;
     278             : }
     279             : 
     280             : 
     281        7752 : static void mantissa_exp_to_qvalue(
     282             :     Word16 *exp,
     283             :     Word32 *output,
     284             :     const Word16 target_exp,
     285             :     const Word16 len )
     286             : {
     287             :     Word16 bin;
     288             : 
     289      537672 :     FOR( bin = 0; bin < len; bin++ )
     290             :     {
     291      529920 :         IF( LT_16( exp[bin], -Q31 ) )
     292             :         {
     293           0 :             output[bin] = 0;
     294           0 :             move32();
     295             :         }
     296             :         ELSE
     297             :         {
     298      529920 :             Word16 shift = sub( target_exp, exp[bin] );
     299      529920 :             output[bin] = W_sat_l( W_shr( output[bin], shift ) );
     300             :         }
     301             :     }
     302             : 
     303        7752 :     return;
     304             : }
     305             : 
     306             : 
     307             : /*-------------------------------------------------------------------*
     308             :  * ivas_omasa_data_open()
     309             :  *
     310             :  * Allocate and initialize MASA_ISM rendering handle
     311             :  *-------------------------------------------------------------------*/
     312             : 
     313          35 : ivas_error ivas_omasa_data_open_fx(
     314             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder handle  */
     315             : )
     316             : {
     317             :     MASA_ISM_DATA_HANDLE hMasaIsmData;
     318             :     Word16 ch, bin;
     319             :     Word16 sf, obj_idx;
     320             : 
     321          35 :     IF( ( hMasaIsmData = (MASA_ISM_DATA_HANDLE) malloc( sizeof( MASA_ISM_DATA ) ) ) == NULL )
     322             :     {
     323           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
     324             :     }
     325             : 
     326        2135 :     FOR( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ )
     327             :     {
     328        6300 :         FOR( ch = 0; ch < 2; ch++ )
     329             :         {
     330        4200 :             hMasaIsmData->ismPreprocMatrix_fx[ch][ch][bin] = 32767; /* 1.0f in Q15 */
     331        4200 :             move16();
     332        4200 :             hMasaIsmData->ismPreprocMatrix_fx[1 - ch][ch][bin] = 0; // Q15
     333        4200 :             move16();
     334        4200 :             hMasaIsmData->eneMoveIIR_fx[ch][bin] = 0; // Q22
     335        4200 :             move32();
     336        4200 :             hMasaIsmData->enePreserveIIR_fx[ch][bin] = 0; // Q22
     337        4200 :             move32();
     338             :         }
     339        2100 :         hMasaIsmData->preprocEneTarget_fx[bin] = 0; // Q19
     340        2100 :         move32();
     341        2100 :         hMasaIsmData->preprocEneRealized_fx[bin] = 0; // Q19
     342        2100 :         move32();
     343             :     }
     344             : 
     345          35 :     hMasaIsmData->objectsMoved = 0;
     346          35 :     move16();
     347          35 :     hMasaIsmData->delayBuffer_fx = NULL;
     348             : 
     349         175 :     FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
     350             :     {
     351         140 :         hMasaIsmData->ism_is_edited[ch] = 0;
     352         140 :         move16();
     353         140 :         hMasaIsmData->q_elevation_old_fx[ch] = 0; // Q22
     354         140 :         move32();
     355         140 :         hMasaIsmData->q_azimuth_old_fx[ch] = 0; // Q22
     356         140 :         move32();
     357             :     }
     358             : 
     359         175 :     FOR( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
     360             :     {
     361         140 :         set16_fx( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     362         140 :         set16_fx( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     363         980 :         FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
     364             :         {
     365         840 :             set32_fx( hMasaIsmData->energy_ratio_ism_fx[obj_idx][sf], 0, CLDFB_NO_CHANNELS_MAX );
     366             :         }
     367             :     }
     368          35 :     set16_fx( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     369          35 :     set16_fx( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
     370             : 
     371          35 :     hMasaIsmData->hExtData = NULL;
     372          35 :     move32();
     373             : 
     374          35 :     IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
     375             :     {
     376             :         MASA_ISM_EXT_DATA_HANDLE hExtData;
     377           4 :         hExtData = (MASA_ISM_EXT_DATA_HANDLE) malloc( sizeof( MASA_ISM_EXT_DATA ) );
     378           4 :         move32();
     379             : 
     380           4 :         IF( hExtData == NULL )
     381             :         {
     382           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
     383             :         }
     384             : 
     385           4 :         hExtData->prev_idx_separated_ism = 0;
     386           4 :         move16();
     387             : 
     388          20 :         FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
     389             :         {
     390          16 :             set32_fx( hExtData->prev_panning_gains[ch], 0, 2 );
     391             :         }
     392             : 
     393          20 :         FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
     394             :         {
     395          16 :             set32_fx( hExtData->ism_render_proto_energy_frac[ch], 0, CLDFB_NO_CHANNELS_MAX );
     396          16 :             set16_fx( hExtData->ism_render_proto_energy_exp[ch], 0, CLDFB_NO_CHANNELS_MAX );
     397          16 :             set32_fx( hExtData->ism_render_target_energy_frac[ch], 0, CLDFB_NO_CHANNELS_MAX );
     398          16 :             set16_fx( hExtData->ism_render_target_energy_exp[ch], 0, CLDFB_NO_CHANNELS_MAX );
     399             :         }
     400             : 
     401           4 :         set32_fx( hExtData->masa_render_proto_energy_frac, 0, CLDFB_NO_CHANNELS_MAX );
     402           4 :         set16_fx( hExtData->masa_render_proto_energy_exp, 0, CLDFB_NO_CHANNELS_MAX );
     403           4 :         set32_fx( hExtData->masa_render_target_energy_frac, 0, CLDFB_NO_CHANNELS_MAX );
     404           4 :         set16_fx( hExtData->masa_render_target_energy_exp, 0, CLDFB_NO_CHANNELS_MAX );
     405             : 
     406          28 :         FOR( sf = 0; sf < add( MAX_PARAM_SPATIAL_SUBFRAMES, DELAY_MASA_PARAM_DEC_SFR ); sf++ )
     407             :         {
     408          24 :             set32_fx( hExtData->masa_render_masa_to_total[sf], 0, CLDFB_NO_CHANNELS_MAX );
     409             :         }
     410             : 
     411           4 :         hMasaIsmData->hExtData = hExtData;
     412           4 :         move32();
     413             :     }
     414             : 
     415          35 :     st_ivas->hMasaIsmData = hMasaIsmData;
     416             : 
     417          35 :     return IVAS_ERR_OK;
     418             : }
     419             : 
     420             : 
     421             : /*-------------------------------------------------------------------*
     422             :  * ivas_omasa_data_close()
     423             :  *
     424             :  * Deallocate MASA_ISM rendering handle
     425             :  *-------------------------------------------------------------------*/
     426             : 
     427         613 : void ivas_omasa_data_close_fx(
     428             :     MASA_ISM_DATA_HANDLE *hMasaIsmData /* i/o: MASA_ISM rendering handle    */
     429             : )
     430             : {
     431             :     Word16 i;
     432             : 
     433         613 :     test();
     434         613 :     IF( hMasaIsmData == NULL || *hMasaIsmData == NULL )
     435             :     {
     436         578 :         return;
     437             :     }
     438             : 
     439          35 :     IF( ( *hMasaIsmData )->delayBuffer_fx != NULL )
     440             :     {
     441          41 :         FOR( i = 0; i < ( *hMasaIsmData )->delayBuffer_nchan; i++ )
     442             :         {
     443          28 :             free( ( *hMasaIsmData )->delayBuffer_fx[i] ); // Q11
     444             :         }
     445          13 :         free( ( *hMasaIsmData )->delayBuffer_fx );
     446          13 :         ( *hMasaIsmData )->delayBuffer_fx = NULL;
     447             :     }
     448             : 
     449          35 :     IF( ( *hMasaIsmData )->hExtData != NULL )
     450             :     {
     451           4 :         free( ( *hMasaIsmData )->hExtData );
     452           4 :         ( *hMasaIsmData )->hExtData = NULL;
     453           4 :         move32();
     454             :     }
     455             : 
     456          35 :     free( *hMasaIsmData );
     457          35 :     *hMasaIsmData = NULL;
     458             : 
     459          35 :     return;
     460             : }
     461             : 
     462             : 
     463             : /*--------------------------------------------------------------------------*
     464             :  * ivas_omasa_dec_config()
     465             :  *
     466             :  * oMASA decoder configuration
     467             :  *--------------------------------------------------------------------------*/
     468             : 
     469        1534 : ivas_error ivas_omasa_dec_config_fx(
     470             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder structure                                  */
     471             :     UWord16 *nSamplesRendered, /* o  : number of samples flushed from the previous frame (JBM) */
     472             :     Word16 *num_src,
     473             :     Word16 SrcInd[MAX_NUM_TDREND_CHANNELS],
     474             :     Word16 *data /* o  : output synthesis signal                                 Qx*/
     475             : )
     476             : {
     477             :     Word16 k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD;
     478             :     Word32 ivas_total_brate, ism_total_brate, cpe_brate;
     479             :     Word32 brate_SCE, brate_CPE;
     480             :     ISM_MODE ism_mode_old;
     481             :     IVAS_FORMAT ivas_format_orig;
     482             :     Word16 nchan_out_buff, nchan_out_buff_old;
     483             :     ivas_error error;
     484             :     RENDERER_TYPE old_renderer_type;
     485             : 
     486             :     /* initializations */
     487        1534 :     ism_total_brate = 0;
     488        1534 :     move32();
     489        1534 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
     490        1534 :     move32();
     491             : 
     492             :     /* save previous frame parameters */
     493        1534 :     ism_mode_old = ivas_omasa_ism_mode_select_fx( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism );
     494        1534 :     move16();
     495        1534 :     st_ivas->ism_mode = ism_mode_old;
     496        1534 :     move16();
     497             : 
     498        1534 :     ivas_format_orig = st_ivas->ivas_format;
     499        1534 :     move16();
     500        1534 :     st_ivas->ivas_format = st_ivas->last_ivas_format;
     501        1534 :     move16();
     502        1534 :     ivas_init_dec_get_num_cldfb_instances_fx( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
     503        1534 :     nchan_out_buff_old = ivas_get_nchan_buffers_dec_fx( st_ivas, -1, -1 );
     504        1534 :     move16();
     505             : 
     506        1534 :     st_ivas->ivas_format = ivas_format_orig;
     507        1534 :     move16();
     508             : 
     509        1534 :     nSCE_old = st_ivas->nSCE;
     510        1534 :     move16();
     511        1534 :     nchan_hp20_old = getNumChanSynthesis( st_ivas );
     512        1534 :     move16();
     513             : 
     514             :     /* set ism_mode of current frame */
     515        1534 :     st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, st_ivas->nchan_ism );
     516        1534 :     move16();
     517             : 
     518             :     /*-----------------------------------------------------------------*
     519             :      * Renderer selection
     520             :      *-----------------------------------------------------------------*/
     521             : 
     522        1534 :     old_renderer_type = st_ivas->renderer_type;
     523        1534 :     move32();
     524             : 
     525             :     /* MASA reconfig. */
     526        1534 :     cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
     527        1534 :     move32();
     528        1534 :     test();
     529        1534 :     test();
     530        1534 :     test();
     531        1534 :     IF( ( st_ivas->ini_active_frame == 0 ) && ( ivas_total_brate != FRAME_NO_DATA ) && LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) && EQ_16( st_ivas->nCPE, 1 ) )
     532             :     {
     533           0 :         st_ivas->hCPE[0]->nchan_out = 1;
     534           0 :         move16();
     535             :     }
     536             :     ELSE
     537             :     {
     538        1534 :         IF( NE_32( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
     539             :         {
     540           0 :             return error;
     541             :         }
     542             :     }
     543             : 
     544        1534 :     IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) )
     545             :     {
     546         501 :         st_ivas->hCPE[0]->nchan_out = 1;
     547         501 :         move16();
     548             :     }
     549             :     ELSE
     550             :     {
     551        1033 :         st_ivas->hCPE[0]->nchan_out = 2;
     552        1033 :         move16();
     553             :     }
     554             : 
     555             :     /* OMASA reconfig. */
     556        1534 :     test();
     557        1534 :     IF( st_ivas->hMasaIsmData == NULL && EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
     558             :     {
     559           2 :         IF( NE_32( ( error = ivas_omasa_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
     560             :         {
     561           0 :             return error;
     562             :         }
     563             :     }
     564             : 
     565        1534 :     ivas_set_omasa_TC_fx( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
     566             : 
     567             :     /* re-configure hp20 memories */
     568        1534 :     IF( NE_32( ( error = ivas_hp20_dec_reconfig_fx( st_ivas, nchan_hp20_old ) ), IVAS_ERR_OK ) )
     569             :     {
     570           0 :         return error;
     571             :     }
     572             : 
     573             :     /* reconfigure core-coders for ISMs */
     574        1534 :     k = 0;
     575        1534 :     move16();
     576       12179 :     WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) )
     577             :     {
     578       10645 :         k = add( k, 1 );
     579             :     }
     580             : 
     581        3538 :     FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
     582             :     {
     583        2004 :         ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] );
     584             :     }
     585             : 
     586        1534 :     brate_SCE = 0;
     587        1534 :     move32();
     588        1534 :     IF( st_ivas->nSCE > 0 )
     589             :     {
     590        1121 :         brate_SCE = sep_object_brate[k - 2][st_ivas->nSCE - 1];
     591        1121 :         move32();
     592             :     }
     593        1534 :     brate_CPE = L_sub( ivas_total_brate, ism_total_brate );
     594             : 
     595        1534 :     IF( NE_32( ( error = ivas_corecoder_dec_reconfig_fx( st_ivas, nSCE_old, 1, 2, 0, brate_SCE, brate_CPE ) ), IVAS_ERR_OK ) )
     596             :     {
     597           0 :         return error;
     598             :     }
     599             : 
     600        1534 :     IF( NE_16( ism_mode_old, st_ivas->ism_mode ) )
     601             :     {
     602             :         /* ISM MD reconfig. */
     603        1533 :         n_MD = 0;
     604        1533 :         move16();
     605             : 
     606        1533 :         IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
     607             :         {
     608             :             /* the full number of hIsmMetaData are needed for EXT output */
     609          74 :             IF( st_ivas->hIsmMetaData[0] == NULL )
     610             :             {
     611           0 :                 IF( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK )
     612             :                 {
     613           0 :                     return error;
     614             :                 }
     615             :             }
     616             :             ELSE
     617             :             {
     618         370 :                 FOR( k = 0; k < st_ivas->nchan_ism; k++ )
     619             :                 {
     620         296 :                     ivas_ism_reset_metadata_handle_dec_fx( st_ivas->hIsmMetaData[k] );
     621             :                 }
     622             :             }
     623             :         }
     624             :         ELSE
     625             :         {
     626        1459 :             test();
     627        1459 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     628             :             {
     629         675 :                 n_MD = 1;
     630         675 :                 move16();
     631             : 
     632         675 :                 IF( st_ivas->hIsmMetaData[0] == NULL )
     633             :                 {
     634         233 :                     error = ivas_ism_metadata_dec_create_fx( st_ivas, 1, NULL );
     635         233 :                     move32();
     636         233 :                     IF( NE_32( error, IVAS_ERR_OK ) )
     637             :                     {
     638           0 :                         return error;
     639             :                     }
     640             :                 }
     641             :                 ELSE
     642             :                 {
     643         442 :                     ivas_ism_reset_metadata_handle_dec_fx( st_ivas->hIsmMetaData[0] );
     644             :                 }
     645             :             }
     646         784 :             ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     647             :             {
     648         390 :                 n_MD = st_ivas->nchan_ism;
     649         390 :                 move16();
     650             : 
     651         390 :                 error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, NULL );
     652         390 :                 move32();
     653         390 :                 IF( NE_32( error, IVAS_ERR_OK ) )
     654             :                 {
     655           0 :                     return error;
     656             :                 }
     657             :             }
     658             : 
     659        1459 :             ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD );
     660             :         }
     661             : 
     662        1533 :         st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate );
     663             : 
     664             :         /*-----------------------------------------------------------------*
     665             :          * Renderer selection
     666             :          *-----------------------------------------------------------------*/
     667             : 
     668        1533 :         ivas_renderer_select( st_ivas );
     669             : 
     670             :         /*-------------------------------------------------------------------*
     671             :          * Reallocate rendering handles
     672             :          *--------------------------------------------------------------------*/
     673             : 
     674        1533 :         IF( NE_16( old_renderer_type, st_ivas->renderer_type ) )
     675             :         {
     676         138 :             IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
     677             :             {
     678          38 :                 IF( NE_32( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
     679             :                 {
     680           0 :                     return error;
     681             :                 }
     682             :             }
     683             :             ELSE
     684             :             {
     685         100 :                 ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
     686             :             }
     687             :         }
     688             : 
     689             :         /* objects renderer reconfig. */
     690        1533 :         test();
     691        1533 :         IF( st_ivas->hMasaIsmData != NULL || st_ivas->hIsmRendererData != NULL )
     692             :         {
     693             :             /* this calls also ivas_ism_renderer_close() closing st_ivas->hIsmRendererData used by the EXT renderers. also cleans st_ivas->hMasaIsmData */
     694        1533 :             ivas_omasa_separate_object_renderer_close( st_ivas );
     695             :         }
     696             : 
     697        1533 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) )
     698             :         {
     699         221 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     700             :             {
     701             :                 /* Allocate TD renderer for the objects in DISC mode */
     702          54 :                 if ( st_ivas->hBinRendererTd == NULL )
     703             :                 {
     704          54 :                     IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, num_src ) ), IVAS_ERR_OK ) )
     705             :                     {
     706           0 :                         return error;
     707             :                     }
     708             : 
     709          54 :                     IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
     710             :                     {
     711           0 :                         IF( NE_32( ( error = ivas_reverb_open_fx( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ), IVAS_ERR_OK ) )
     712             :                         {
     713           0 :                             return error;
     714             :                         }
     715             :                     }
     716             :                 }
     717             : 
     718             :                 /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
     719          54 :                 IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
     720             :                 {
     721           0 :                     return error;
     722             :                 }
     723             :             }
     724             :             ELSE
     725             :             {
     726         167 :                 if ( st_ivas->hBinRendererTd != NULL )
     727             :                 {
     728             :                     /* TD renderer handle */
     729          54 :                     ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd );
     730             :                 }
     731             : 
     732             :                 /* ISM renderer handle + ISM data handle */
     733         167 :                 ivas_omasa_separate_object_renderer_close( st_ivas );
     734             :             }
     735             :         }
     736             : 
     737        1533 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
     738             :         {
     739         667 :             IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
     740             :             {
     741           0 :                 return error;
     742             :             }
     743             : 
     744         667 :             test();
     745         667 :             test();
     746         667 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     747             :             {
     748             :                 /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
     749         485 :                 IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
     750             :                 {
     751           0 :                     return error;
     752             :                 }
     753             : 
     754         485 :                 IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
     755             :                 {
     756           0 :                     return error;
     757             :                 }
     758             :             }
     759             :             ELSE
     760             :             {
     761             :                 /* ISM renderer handle + ISM data handle */
     762         182 :                 ivas_omasa_separate_object_renderer_close( st_ivas );
     763             :             }
     764             :         }
     765             : 
     766        1533 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_MIX_EXT ) )
     767             :         {
     768             :             /* Allocate 'hIsmRendererData' handle */
     769          18 :             error = ivas_omasa_combine_separate_ism_with_masa_open_fx( st_ivas );
     770          18 :             move32();
     771          18 :             IF( NE_32( error, IVAS_ERR_OK ) )
     772             :             {
     773           0 :                 return error;
     774             :             }
     775             :         }
     776             : 
     777        1533 :         IF( EQ_32( st_ivas->renderer_type, RENDERER_OMASA_OBJECT_EXT ) )
     778             :         {
     779             :             DIRAC_CONFIG_FLAG common_rend_config_flag;
     780          19 :             IF( st_ivas->hSpatParamRendCom == NULL )
     781             :             {
     782          19 :                 common_rend_config_flag = DIRAC_OPEN;
     783             :             }
     784             :             ELSE
     785             :             {
     786           0 :                 common_rend_config_flag = DIRAC_RECONFIGURE;
     787             :             }
     788          19 :             move32();
     789             : 
     790             :             /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
     791          19 :             IF( NE_32( ( error = ivas_omasa_objects_delay_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
     792             :             {
     793           0 :                 return error;
     794             :             }
     795             : 
     796          19 :             IF( NE_32( ( error = ivas_spat_hSpatParamRendCom_config_fx( &st_ivas->hSpatParamRendCom, common_rend_config_flag, 0, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs, 0, 0 ) ), IVAS_ERR_OK ) )
     797             :             {
     798           0 :                 return error;
     799             :             }
     800             :         }
     801             : 
     802             :         /*-----------------------------------------------------------------*
     803             :          * TD Decorrelator
     804             :          *-----------------------------------------------------------------*/
     805             : 
     806        1533 :         IF( st_ivas->hDiracDecBin[0] != NULL )
     807             :         {
     808         657 :             IF( NE_32( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ), IVAS_ERR_OK ) )
     809             :             {
     810           0 :                 return error;
     811             :             }
     812             :         }
     813             : 
     814             :         /*-----------------------------------------------------------------*
     815             :          * CLDFB instances
     816             :          *-----------------------------------------------------------------*/
     817             : 
     818        1533 :         IF( NE_32( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old ) ), IVAS_ERR_OK ) )
     819             :         {
     820           0 :             return error;
     821             :         }
     822             : 
     823             :         /*-----------------------------------------------------------------*
     824             :          * floating-point output audio buffers
     825             :          *-----------------------------------------------------------------*/
     826             : 
     827        1533 :         nchan_out_buff = ivas_get_nchan_buffers_dec_fx( st_ivas, -1, -1 );
     828        1533 :         IF( NE_32( ( error = ivas_output_buff_dec_fx( st_ivas->p_output_fx, nchan_out_buff_old, nchan_out_buff ) ), IVAS_ERR_OK ) )
     829             :         {
     830           0 :             return error;
     831             :         }
     832             :     }
     833             : 
     834        1534 :     return IVAS_ERR_OK;
     835             : }
     836             : 
     837             : 
     838             : /*--------------------------------------------------------------------------*
     839             :  * ivas_set_surplus_brate_dec()
     840             :  *
     841             :  * set bit-rate surplus in combined format coding
     842             :  *--------------------------------------------------------------------------*/
     843        6529 : void ivas_set_surplus_brate_dec(
     844             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
     845             :     Word32 *ism_total_brate  /* i/o: ISM total bitrate      */
     846             : )
     847             : {
     848             :     Word16 n, bits_ism, bits_element[MAX_NUM_OBJECTS];
     849             :     Word32 ism_total_brate_ref, element_brate[MAX_NUM_OBJECTS];
     850             : 
     851        6529 :     *ism_total_brate = 0;
     852        6529 :     move32();
     853             : 
     854        6529 :     test();
     855        6529 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     856             :     {
     857        3727 :         *ism_total_brate = ivas_interformat_brate_fx( st_ivas->ism_mode, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
     858        3727 :         move32();
     859             : 
     860        3727 :         st_ivas->hCPE[0]->brate_surplus = L_sub( st_ivas->hSCE[0]->element_brate, *ism_total_brate );
     861        3727 :         move32();
     862             : 
     863             :         /* set 'st->total_brate'; there are no meta-data in ISM_MASA_MODE_PARAM_ONE_OBJ mode */
     864        3727 :         st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
     865        3727 :         move32();
     866             : 
     867        3727 :         st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
     868        3727 :         move16();
     869        3727 :         if ( EQ_16( st_ivas->hIsmMetaData[0]->ism_imp, ISM_NO_META ) )
     870             :         {
     871           0 :             st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
     872           0 :             move16();
     873             :         }
     874             :     }
     875        2802 :     ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
     876             :     {
     877             :         Word16 brate_limit_flag, ism_imp[MAX_NUM_OBJECTS], tmp;
     878             : 
     879       10277 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     880             :         {
     881        7475 :             ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
     882        7475 :             move16();
     883             :         }
     884             : 
     885        2802 :         brate_limit_flag = calculate_brate_limit_flag_fx( ism_imp, st_ivas->nchan_ism );
     886             : 
     887        2802 :         ism_total_brate_ref = 0;
     888        2802 :         move32();
     889       10277 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     890             :         {
     891        7475 :             ism_total_brate_ref = L_add( ism_total_brate_ref, st_ivas->hSCE[n]->element_brate );
     892             :         }
     893             : 
     894             :         /* bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC ); */
     895        2802 :         bits_ism = extract_l( Mpy_32_32( ism_total_brate_ref, ONE_BY_FRAMES_PER_SEC_Q31 ) );
     896             : 
     897        2802 :         tmp = 0;
     898        2802 :         move16();
     899        2802 :         IF( bits_ism != 0 )
     900             :         {
     901        2802 :             tmp = idiv1616( bits_ism, st_ivas->nchan_ism );
     902             :         }
     903        2802 :         set16_fx( bits_element, tmp, st_ivas->nchan_ism );
     904        2802 :         bits_element[st_ivas->nchan_ism - 1] = add( bits_element[st_ivas->nchan_ism - 1], bits_ism % st_ivas->nchan_ism );
     905        2802 :         move16();
     906        2802 :         bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
     907             : 
     908        2802 :         *ism_total_brate = 0;
     909        2802 :         move32();
     910       10277 :         FOR( n = 0; n < st_ivas->nchan_ism; n++ )
     911             :         {
     912        7475 :             st_ivas->hSCE[n]->element_brate = element_brate[n];
     913        7475 :             move32();
     914             : 
     915        7475 :             *ism_total_brate = L_add( *ism_total_brate, ivas_interformat_brate_fx( ISM_MASA_MODE_DISC, st_ivas->nchan_ism, st_ivas->hSCE[n]->element_brate, st_ivas->hIsmMetaData[n]->ism_imp, brate_limit_flag ) );
     916        7475 :             move32();
     917             : 
     918        7475 :             test();
     919        7475 :             test();
     920        7475 :             IF( GT_16( ism_imp[n], 1 ) && EQ_16( st_ivas->flag_omasa_brate, 1 ) && brate_limit_flag >= 0 )
     921             :             {
     922         445 :                 *ism_total_brate = L_sub( *ism_total_brate, ADJUST_ISM_BRATE_NEG );
     923         445 :                 move32();
     924             :             }
     925             : 
     926        7475 :             test();
     927        7475 :             test();
     928        7475 :             test();
     929        7475 :             IF( EQ_16( brate_limit_flag, -1 ) && GE_16( ism_imp[n], 1 ) && GE_16( st_ivas->nchan_ism, 3 ) && GT_32( L_sub( ism_total_brate_ref, *ism_total_brate ), IVAS_48k ) )
     930             :             {
     931           0 :                 *ism_total_brate = L_add( *ism_total_brate, ADJUST_ISM_BRATE_POS );
     932           0 :                 move32();
     933             :             }
     934             :         }
     935        2802 :         st_ivas->hCPE[0]->brate_surplus = L_sub( ism_total_brate_ref, *ism_total_brate );
     936        2802 :         move32();
     937             : 
     938             :         /* 'st->total_brate' is set in ivas_ism_config */
     939             :     }
     940             :     ELSE
     941             :     {
     942           0 :         st_ivas->hCPE[0]->brate_surplus = 0;
     943           0 :         move32();
     944             :     }
     945             : 
     946        6529 :     return;
     947             : }
     948             : 
     949             : 
     950             : /*--------------------------------------------------------------------------*
     951             :  * ivas_omasa_ism_metadata_dec()
     952             :  *
     953             :  * decode ISM metadata in OMASA format
     954             :  *--------------------------------------------------------------------------*/
     955             : 
     956        6529 : ivas_error ivas_omasa_ism_metadata_dec_fx(
     957             :     Decoder_Struct *st_ivas,            /* i/o: IVAS decoder structure            */
     958             :     const Word32 ism_total_brate,       /* i  : ISM total bitrate                 */
     959             :     Word16 *nchan_ism,                  /* o  : number of ISM separated channels  */
     960             :     Word16 *nchan_transport_ism,        /* o  : number of ISM TCs                 */
     961             :     const Word16 dirac_bs_md_write_idx, /* i  : DirAC bitstream write index       */
     962             :     Word16 nb_bits_metadata[]           /* o  : number of ISM metadata bits       */
     963             : )
     964             : {
     965             :     Word16 n, block;
     966             :     Word16 azimuth_ism, elevation_ism, meta_write_index;
     967             :     ivas_error error;
     968             : 
     969             :     /* set ISM parameters */
     970        6529 :     *nchan_ism = st_ivas->nchan_ism;
     971        6529 :     move16();
     972        6529 :     *nchan_transport_ism = st_ivas->nchan_ism;
     973        6529 :     move16();
     974             : 
     975        6529 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     976             :     {
     977        2065 :         *nchan_ism = 1;
     978        2065 :         move16();
     979        2065 :         *nchan_transport_ism = 1;
     980        2065 :         move16();
     981             :     }
     982        4464 :     ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
     983             :     {
     984        1662 :         *nchan_ism = 0;
     985        1662 :         move16();
     986        1662 :         *nchan_transport_ism = 1;
     987        1662 :         move16();
     988             :     }
     989             : 
     990        6529 :     test();
     991        6529 :     test();
     992        6529 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
     993             :     {
     994             :         /* decode ISM metadata */
     995        4867 :         IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
     996             :                                                        nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ),
     997             :                    IVAS_ERR_OK ) )
     998             :         {
     999           0 :             return error;
    1000             :         }
    1001             : 
    1002        4867 :         IF( st_ivas->hDirAC != NULL )
    1003             :         {
    1004        3592 :             IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
    1005             :             {
    1006        6462 :                 FOR( n = 0; n < st_ivas->nchan_ism; n++ )
    1007             :                 {
    1008             :                     // azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
    1009             :                     // elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
    1010        4679 :                     azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->azimuth_fx /*Q22*/ ), 22 ) ); // Q0
    1011        4679 :                     if ( st_ivas->hIsmMetaData[n]->azimuth_fx < 0 )
    1012             :                     {
    1013        2465 :                         azimuth_ism = negate( azimuth_ism );
    1014             :                     }
    1015        4679 :                     elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->elevation_fx /*Q22*/ ), 22 ) ); // Q0
    1016        4679 :                     if ( st_ivas->hIsmMetaData[n]->elevation_fx < 0 )
    1017             :                     {
    1018        1487 :                         elevation_ism = negate( elevation_ism );
    1019             :                     }
    1020             : 
    1021       23395 :                     FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
    1022             :                     {
    1023       18716 :                         meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
    1024       18716 :                         move16();
    1025       18716 :                         st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
    1026       18716 :                         move16();
    1027       18716 :                         st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
    1028       18716 :                         move16();
    1029             :                     }
    1030             :                 }
    1031             :             }
    1032             :             ELSE /* ISM_MASA_MODE_MASA_ONE_OBJ */
    1033             :             {
    1034        1809 :                 azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->azimuth_fx ), 22 ) );
    1035        1809 :                 if ( st_ivas->hIsmMetaData[0]->azimuth_fx < 0 )
    1036             :                 {
    1037         982 :                     azimuth_ism = negate( azimuth_ism );
    1038             :                 }
    1039        1809 :                 elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->elevation_fx ), 22 ) );
    1040        1809 :                 if ( st_ivas->hIsmMetaData[0]->elevation_fx < 0 )
    1041             :                 {
    1042         566 :                     elevation_ism = negate( elevation_ism );
    1043             :                 }
    1044             : 
    1045        9045 :                 FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
    1046             :                 {
    1047        7236 :                     meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
    1048        7236 :                     move16();
    1049        7236 :                     st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
    1050        7236 :                     move16();
    1051        7236 :                     st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
    1052        7236 :                     move16();
    1053             :                 }
    1054             :             }
    1055             :         }
    1056        1275 :         ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_EXTERNAL ) )
    1057             :         {
    1058          36 :             azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->azimuth_fx ), 22 ) );
    1059          36 :             if ( st_ivas->hIsmMetaData[0]->azimuth_fx < 0 )
    1060             :             {
    1061          19 :                 azimuth_ism = negate( azimuth_ism );
    1062             :             }
    1063          36 :             elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->elevation_fx ), 22 ) );
    1064          36 :             if ( st_ivas->hIsmMetaData[0]->elevation_fx < 0 )
    1065             :             {
    1066           3 :                 elevation_ism = negate( elevation_ism );
    1067             :             }
    1068             : 
    1069         108 :             FOR( block = 0; block < 2; block++ )
    1070             :             {
    1071          72 :                 st_ivas->hMasaIsmData->azimuth_separated_ism[block] = st_ivas->hMasaIsmData->azimuth_separated_ism[add( block, 2 )];
    1072          72 :                 st_ivas->hMasaIsmData->elevation_separated_ism[block] = st_ivas->hMasaIsmData->elevation_separated_ism[add( block, 2 )];
    1073          72 :                 move16();
    1074          72 :                 move16();
    1075             :             }
    1076         108 :             FOR( block = 2; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
    1077             :             {
    1078          72 :                 st_ivas->hMasaIsmData->azimuth_separated_ism[block] = azimuth_ism;
    1079          72 :                 st_ivas->hMasaIsmData->elevation_separated_ism[block] = elevation_ism;
    1080          72 :                 move16();
    1081          72 :                 move16();
    1082             :             }
    1083             :         }
    1084             :     }
    1085             : 
    1086        6529 :     return IVAS_ERR_OK;
    1087             : }
    1088             : 
    1089             : /*--------------------------------------------------------------------------*
    1090             :  * ivas_omasa_dirac_rend_jbm_fx()
    1091             :  *
    1092             :  * Rendering in OMASA format for JBM
    1093             :  *--------------------------------------------------------------------------*/
    1094             : 
    1095        2735 : void ivas_omasa_dirac_rend_jbm_fx(
    1096             :     Decoder_Struct *st_ivas,      /* i/o: IVAS decoder handle                      */
    1097             :     const UWord16 nSamplesAsked,  /* i  : number of samples requested              */
    1098             :     UWord16 *nSamplesRendered,    /* o  : number of samples rendered               */
    1099             :     UWord16 *nSamplesAvailable,   /* o  : number of samples still to render        */
    1100             :     const Word16 nchan_transport, /* i  : number of transport channels             */
    1101             :     Word32 *output_f[]            /* o  : rendered time signal                     Q11*/
    1102             : )
    1103             : {
    1104             :     Word16 subframes_rendered;
    1105             :     Word16 slots_rendered;
    1106             :     Word16 n;
    1107             :     Word32 data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
    1108             : 
    1109        2735 :     test();
    1110        2735 :     IF( !st_ivas->hDecoderConfig->Opt_tsm )
    1111             :     {
    1112        1800 :         *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available );
    1113             : 
    1114             : 
    1115        1800 :         test();
    1116        1800 :         IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
    1117             :         {
    1118        1050 :             Copy32( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered );
    1119             :         }
    1120             :         ELSE
    1121             :         {
    1122        2474 :             FOR( n = 0; n < st_ivas->nchan_ism; n++ )
    1123             :             {
    1124        1724 :                 Copy32( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered );
    1125             :             }
    1126             :         }
    1127             :     }
    1128             : 
    1129        2735 :     subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
    1130        2735 :     move16();
    1131        2735 :     slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
    1132        2735 :     move16();
    1133             : 
    1134        2735 :     ivas_dirac_dec_render_fx( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f );
    1135             : 
    1136       13675 :     FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
    1137             :     {
    1138       10940 :         scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, -1 ); // Q30 -> Q29
    1139             :     }
    1140             : 
    1141        2735 :     ivas_omasa_separate_object_render_jbm_fx( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered );
    1142             : 
    1143       13675 :     FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
    1144             :     {
    1145       10940 :         scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, 1 ); // Q29 -> Q30
    1146             :     }
    1147             : 
    1148        2735 :     return;
    1149             : }
    1150             : 
    1151             : 
    1152             : /*--------------------------------------------------------------------------*
    1153             :  * ivas_omasa_dirac_td_binaural_render()
    1154             :  *
    1155             :  * Binaural rendering in OMASA format for JBM
    1156             :  *--------------------------------------------------------------------------*/
    1157             : 
    1158         129 : ivas_error ivas_omasa_dirac_td_binaural_jbm_fx(
    1159             :     Decoder_Struct *st_ivas,      /* i/o: IVAS decoder handle                      */
    1160             :     const UWord16 nSamplesAsked,  /* i  : number of samples requested              */
    1161             :     UWord16 *nSamplesRendered,    /* o  : number of samples rendered               */
    1162             :     UWord16 *nSamplesAvailable,   /* o  : number of samples still to render        */
    1163             :     const Word16 nchan_transport, /* i  : number of transport channels             */
    1164             :     Word32 *output_fx[]           /* o  : rendered time signal                     Q11*/
    1165             : )
    1166             : {
    1167             :     Word16 n;
    1168             :     ivas_error error;
    1169             :     Word32 *p_sepobj_fx[BINAURAL_CHANNELS]; // Q11
    1170             :     Word32 data_separated_objects_fx[BINAURAL_CHANNELS][L_FRAME48k];
    1171             :     Word16 slot_idx_start;
    1172             : 
    1173         129 :     slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
    1174         129 :     move16();
    1175             : 
    1176         387 :     FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
    1177             :     {
    1178         258 :         p_sepobj_fx[n] = &data_separated_objects_fx[n][0];
    1179             :     }
    1180             : 
    1181             :     /* Delay the object signals to match the CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */
    1182             : 
    1183         129 :     ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_fx );
    1184             : 
    1185             :     /* reset combined orientation access index before calling the td renderer */
    1186         129 :     ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
    1187             : 
    1188         129 :     IF( EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_16( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
    1189           0 :     {
    1190             :         Word16 slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots;
    1191             :         Word32 Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX];
    1192             :         Word32 Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX];
    1193             :         Word32 *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */
    1194           0 :         Word16 q_cldfb, q_in = 11;
    1195           0 :         move16();
    1196             : 
    1197           0 :         FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); n++ )
    1198             :         {
    1199           0 :             p_rend_obj[n] = &output_fx[n][0];
    1200           0 :             move32();
    1201             :         }
    1202             : 
    1203           0 :         num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels;
    1204           0 :         move16();
    1205           0 :         nchan_transport_orig = st_ivas->nchan_transport;
    1206           0 :         move16();
    1207           0 :         st_ivas->nchan_transport = st_ivas->nchan_ism;
    1208           0 :         move16();
    1209             : 
    1210           0 :         IF( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_rend_obj, *nSamplesRendered ) ) != IVAS_ERR_OK ) /* objects are read from st_ivas->hTcBuffer->tc[2..(1+n_isms)] */
    1211             :         {
    1212           0 :             return error;
    1213             :         }
    1214             : 
    1215           0 :         st_ivas->nchan_transport = nchan_transport_orig;
    1216           0 :         move16();
    1217           0 :         cldfb_slots = *nSamplesRendered / num_cldfb_bands;
    1218             : 
    1219           0 :         FOR( n = 0; n < i_mult( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses, BINAURAL_CHANNELS ); ++n )
    1220             :         {
    1221           0 :             q_cldfb = q_in;
    1222           0 :             Scale_sig32( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->cldfb_state_fx,
    1223           0 :                          sub( st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->p_filter_length, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->no_channels ),
    1224           0 :                          sub( q_cldfb, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state ) );
    1225           0 :             st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n]->Q_cldfb_state = q_cldfb;
    1226           0 :             FOR( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ )
    1227             :             {
    1228           0 :                 q_cldfb = q_in;
    1229           0 :                 cldfbAnalysis_ts_fx_fixed_q( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n], &q_cldfb );
    1230             : 
    1231           0 :                 Scale_sig32( Cldfb_RealBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) );
    1232           0 :                 Scale_sig32( Cldfb_ImagBuffer, num_cldfb_bands, sub( Q6, q_cldfb ) );
    1233             :                 /* note: this intentionally differs from OSBA by: no scaling by 0.5 */
    1234           0 :                 v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands );
    1235           0 :                 v_add_fx( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural_fx[n][slot_idx_start + slot_idx], num_cldfb_bands );
    1236             :             }
    1237             :         }
    1238             :     }
    1239             :     else
    1240             :     {
    1241         129 :         IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
    1242             :         {
    1243           0 :             return error;
    1244             :         }
    1245             : 
    1246         387 :         FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
    1247             :         {
    1248         258 :             v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered );
    1249             :         }
    1250             :     }
    1251             : 
    1252         129 :     return IVAS_ERR_OK;
    1253             : }
    1254             : 
    1255             : 
    1256             : /*--------------------------------------------------------------------------*
    1257             :  * ivas_omasa_rearrange_channels()
    1258             :  *
    1259             :  * in case of external rendering, rearrange the channels order
    1260             :  *--------------------------------------------------------------------------*/
    1261             : 
    1262         753 : void ivas_omasa_rearrange_channels_fx(
    1263             :     Word32 *output[],                 /* o  : output synthesis signal         Q11*/
    1264             :     const Word16 nchan_transport_ism, /* o  : number of ISM TCs               */
    1265             :     const Word16 output_frame         /* i  : output frame length per channel */
    1266             : )
    1267             : {
    1268             :     Word16 n;
    1269             :     Word32 tmp_buff[CPE_CHANNELS][L_FRAME48k]; // Q11
    1270             : 
    1271         753 :     Copy32( output[0], tmp_buff[0], output_frame );
    1272         753 :     Copy32( output[1], tmp_buff[1], output_frame );
    1273             : 
    1274        2865 :     FOR( n = 0; n < nchan_transport_ism; n++ )
    1275             :     {
    1276        2112 :         Copy32( output[CPE_CHANNELS + n], output[n], output_frame );
    1277             :     }
    1278         753 :     Copy32( tmp_buff[0], output[n], output_frame );
    1279         753 :     Copy32( tmp_buff[1], output[add( n, 1 )], output_frame );
    1280             : 
    1281         753 :     return;
    1282             : }
    1283             : 
    1284             : 
    1285             : /*-------------------------------------------------------------------------*
    1286             :  * ivas_omasa_combine_separate_ism_with_masa_open_fx()
    1287             :  *
    1288             :  * Open structures, reserve memory, and init values.
    1289             :  *-------------------------------------------------------------------------*/
    1290             : 
    1291          18 : ivas_error ivas_omasa_combine_separate_ism_with_masa_open_fx(
    1292             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
    1293             : )
    1294             : {
    1295             :     Word16 i;
    1296             :     Word16 *tmp;
    1297             : 
    1298          18 :     st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) );
    1299          18 :     move32();
    1300             : 
    1301          18 :     IF( st_ivas->hIsmRendererData == NULL )
    1302             :     {
    1303           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
    1304             :     }
    1305             : 
    1306          90 :     FOR( i = 0; i < MAX_NUM_OBJECTS; i++ )
    1307             :     {
    1308          72 :         set_zero_fx( st_ivas->hIsmRendererData->prev_gains_fx[i], MAX_OUTPUT_CHANNELS );
    1309             :     }
    1310             : 
    1311          18 :     test();
    1312          18 :     test();
    1313          18 :     IF( EQ_32( st_ivas->hDecoderConfig->output_Fs, 16000 ) ||
    1314             :         EQ_32( st_ivas->hDecoderConfig->output_Fs, 32000 ) ||
    1315             :         EQ_32( st_ivas->hDecoderConfig->output_Fs, 48000 ) )
    1316             :     {
    1317          18 :         IF( EQ_32( st_ivas->hDecoderConfig->output_Fs, 16000 ) )
    1318             :         {
    1319           0 :             st_ivas->hIsmRendererData->interpolator_len = 80;
    1320           0 :             tmp = interpolator_table_16k_q15;
    1321             :         }
    1322          18 :         ELSE IF( EQ_32( st_ivas->hDecoderConfig->output_Fs, 32000 ) )
    1323             :         {
    1324           0 :             st_ivas->hIsmRendererData->interpolator_len = 160;
    1325           0 :             tmp = interpolator_table_32k_q15;
    1326             :         }
    1327             :         ELSE
    1328             :         {
    1329          18 :             st_ivas->hIsmRendererData->interpolator_len = 240;
    1330          18 :             tmp = interpolator_table_48k_q15;
    1331             :         }
    1332          18 :         move16();
    1333          18 :         move32();
    1334             : 
    1335          18 :         st_ivas->hIsmRendererData->interpolator_fx = (Word16 *) malloc( sizeof( Word16 ) * st_ivas->hIsmRendererData->interpolator_len );
    1336             : 
    1337          18 :         IF( st_ivas->hIsmRendererData->interpolator_fx == NULL )
    1338             :         {
    1339           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM renderer interpolator\n" ) );
    1340             :         }
    1341             : 
    1342        4338 :         FOR( i = 0; i < st_ivas->hIsmRendererData->interpolator_len; i++ )
    1343             :         {
    1344        4320 :             st_ivas->hIsmRendererData->interpolator_fx[i] = tmp[i];
    1345        4320 :             move16();
    1346             :         }
    1347             :     }
    1348             :     ELSE
    1349             :     {
    1350           0 :         return ( IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Unsupported output sample rate\n" ) );
    1351             :     }
    1352             : 
    1353          18 :     return IVAS_ERR_OK;
    1354             : }
    1355             : 
    1356             : 
    1357             : /*--------------------------------------------------------------------------*
    1358             :  * ivas_omasa_combine_separate_ism_with_masa_fx()
    1359             :  *
    1360             :  * in case of external rendering, combine separated ISM signal with MASA stream
    1361             :  *--------------------------------------------------------------------------*/
    1362             : 
    1363          36 : void ivas_omasa_combine_separate_ism_with_masa_fx(
    1364             :     Decoder_Struct *st_ivas,  /* i/o: IVAS decoder handle             */
    1365             :     Word32 *output[],         /* i/o: output synthesis signal         */
    1366             :     Word16 *output_q,         /* i/o: output Q value                  */
    1367             :     const Word16 nchan_ism,   /* i  : number of ISMs                  */
    1368             :     const Word16 output_frame /* i  : output frame length per channel */
    1369             : )
    1370             : {
    1371             :     Word16 n, sf, band, k;
    1372             :     MASA_DECODER_EXT_OUT_META_HANDLE masaMetaHandle;
    1373             :     MASA_DECODER_EXT_OUT_META_HANDLE ismMetaHandle;
    1374             :     MASA_DECODER_EXT_OUT_META ismMeta;
    1375             :     Word32 inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1376             :     Word32 inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1377             :     UWord16 directionIndex;
    1378             :     Word16 nchan_in;
    1379             :     Word16 nBins;
    1380             :     Word16 slot;
    1381             :     Word16 mrange[2], brange[2];
    1382             :     Word16 processing_len, offset;
    1383             : 
    1384             :     Word32 old_panning_gains_fx[2];
    1385             :     Word32 new_panning_gains_fx[2];
    1386             : 
    1387             :     Word16 inRe_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1388             :     Word16 inIm_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1389             :     Word16 out_exp[MASA_MAX_TRANSPORT_CHANNELS + 1][L_FRAME48k];
    1390             : 
    1391             :     Word16 eneMasa_exp[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
    1392             :     Word32 eneMasa_frac[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
    1393             :     Word16 eneIsm_exp[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
    1394             :     Word32 eneIsm_frac[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
    1395             : 
    1396             :     Word16 old_panning_gains_q15_fx[2];
    1397             :     Word16 new_panning_gains_q15_fx[2];
    1398             : 
    1399             :     Word16 exp;
    1400             : 
    1401          36 :     masaMetaHandle = st_ivas->hMasa->data.extOutMeta;
    1402          36 :     ismMetaHandle = &ismMeta;
    1403          36 :     move32();
    1404          36 :     move32();
    1405             : 
    1406             :     /* Compute CLDFB analysis */
    1407          36 :     nchan_in = add( st_ivas->nchan_transport, 1 );
    1408          36 :     nBins = mult( output_frame, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ); // Q15
    1409         612 :     FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
    1410             :     {
    1411        2304 :         FOR( n = 0; n < nchan_in; n++ )
    1412             :         {
    1413        1728 :             Word16 in_q = *output_q;
    1414        1728 :             move16();
    1415             : 
    1416        1728 :             cldfbAnalysis_ts_fx_var_q( &( output[n][L_mult0( nBins, slot )] ),
    1417        1728 :                                        inRe[n][slot],
    1418        1728 :                                        inIm[n][slot],
    1419             :                                        nBins, st_ivas->cldfbAnaDec[n], &in_q );
    1420             : 
    1421             :             /* Assign input exponent */
    1422        1728 :             exp = sub( Q31, in_q );
    1423        1728 :             set16_fx( inRe_exp[n][slot], exp, nBins );
    1424        1728 :             set16_fx( inIm_exp[n][slot], exp, nBins );
    1425             :         }
    1426             :     }
    1427             : 
    1428             :     /* Convert output to exponent+mantissa representation */
    1429          36 :     exp = sub( Q31, *output_q );
    1430         144 :     FOR( n = 0; n < add( MASA_MAX_TRANSPORT_CHANNELS, 1 ); n++ )
    1431             :     {
    1432         108 :         set16_fx( out_exp[n], exp, output_frame );
    1433             :     }
    1434             : 
    1435         180 :     FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1436             :     {
    1437         144 :         set16_fx( eneMasa_exp[sf], 0, MASA_FREQUENCY_BANDS );
    1438         144 :         set32_fx( eneMasa_frac[sf], 0, MASA_FREQUENCY_BANDS );
    1439             : 
    1440         144 :         set16_fx( eneIsm_exp[sf], 0, MASA_FREQUENCY_BANDS );
    1441         144 :         set32_fx( eneIsm_frac[sf], 0, MASA_FREQUENCY_BANDS );
    1442             :     }
    1443             : 
    1444             :     /* Determine energies */
    1445         180 :     FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1446             :     {
    1447         144 :         mrange[0] = st_ivas->hMasa->config.block_grouping[sf];
    1448         144 :         mrange[1] = st_ivas->hMasa->config.block_grouping[add( sf, 1 )];
    1449         144 :         move16();
    1450         144 :         move16();
    1451             : 
    1452         720 :         FOR( slot = mrange[0]; slot < mrange[1]; slot++ )
    1453             :         {
    1454       14400 :             FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
    1455             :             {
    1456       13824 :                 brange[0] = st_ivas->hMasa->config.band_grouping[band];
    1457       13824 :                 brange[1] = st_ivas->hMasa->config.band_grouping[add( band, 1 )];
    1458       13824 :                 move16();
    1459       13824 :                 move16();
    1460             : 
    1461       13824 :                 IF( GT_16( brange[1], nBins ) )
    1462             :                 {
    1463           0 :                     brange[1] = nBins;
    1464           0 :                     move16();
    1465             :                 }
    1466             : 
    1467       13824 :                 Word16 len = sub( brange[1], brange[0] );
    1468             : 
    1469       41472 :                 FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
    1470             :                 {
    1471       27648 :                     sample_energy_acc_fx( &inRe[n][slot][brange[0]],
    1472       27648 :                                           &inRe_exp[n][slot][brange[0]],
    1473       27648 :                                           &inIm[n][slot][brange[0]],
    1474       27648 :                                           &inIm_exp[n][slot][brange[0]],
    1475       27648 :                                           &eneMasa_frac[sf][band],
    1476       27648 :                                           &eneMasa_exp[sf][band],
    1477             :                                           len );
    1478             :                 }
    1479             : 
    1480       13824 :                 sample_energy_acc_fx( &inRe[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
    1481       13824 :                                       &inRe_exp[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
    1482       13824 :                                       &inIm[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
    1483       13824 :                                       &inIm_exp[MASA_MAX_TRANSPORT_CHANNELS][slot][brange[0]],
    1484       13824 :                                       &eneIsm_frac[sf][band],
    1485       13824 :                                       &eneIsm_exp[sf][band],
    1486             :                                       len );
    1487             :             }
    1488             :         }
    1489             :     }
    1490             : 
    1491             :     /* Determine MASA metadata for the object */
    1492          36 :     ismMetaHandle->descriptiveMeta.numberOfDirections = 0u;
    1493          36 :     move16();
    1494             : 
    1495         180 :     FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1496             :     {
    1497             :         Word32 ele, azi;
    1498             : 
    1499         144 :         ele = st_ivas->hMasaIsmData->elevation_separated_ism[sf];
    1500         144 :         azi = st_ivas->hMasaIsmData->azimuth_separated_ism[sf];
    1501             : 
    1502         144 :         directionIndex = index_theta_phi_16_fx( &ele, &azi, st_ivas->hMasa->data.sph_grid16 );
    1503             : 
    1504        3600 :         FOR( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
    1505             :         {
    1506        3456 :             ismMetaHandle->directionIndex[0][sf][band] = directionIndex;
    1507        3456 :             ismMetaHandle->directToTotalRatio[0][sf][band] = UINT8_MAX;
    1508        3456 :             ismMetaHandle->spreadCoherence[0][sf][band] = 0;
    1509        3456 :             ismMetaHandle->surroundCoherence[sf][band] = 0;
    1510        3456 :             ismMetaHandle->diffuseToTotalRatio[sf][band] = 0;
    1511        3456 :             move16();
    1512        3456 :             move16();
    1513        3456 :             move16();
    1514        3456 :             move16();
    1515        3456 :             move16();
    1516             :         }
    1517             :     }
    1518             : 
    1519             :     /* Merge MASA metadatas */
    1520          36 :     ivas_prerend_merge_masa_metadata_fx( masaMetaHandle, masaMetaHandle,
    1521             :                                          IVAS_REND_AUDIO_CONFIG_TYPE_MASA,
    1522             :                                          eneMasa_frac, eneMasa_exp, ismMetaHandle, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED,
    1523             :                                          eneIsm_frac, eneIsm_exp );
    1524             : 
    1525             :     /* Mix the separated object audio signal to the MASA audio signals */
    1526          36 :     ivas_get_stereo_panning_gains_fx( st_ivas->hMasaIsmData->azimuth_separated_ism[0],
    1527          36 :                                       st_ivas->hMasaIsmData->elevation_separated_ism[0], old_panning_gains_q15_fx );
    1528          36 :     ivas_get_stereo_panning_gains_fx( st_ivas->hMasaIsmData->azimuth_separated_ism[2],
    1529          36 :                                       st_ivas->hMasaIsmData->elevation_separated_ism[2], new_panning_gains_q15_fx );
    1530             : 
    1531             :     /* Subsequent processing in Q31 format */
    1532         108 :     FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
    1533             :     {
    1534          72 :         new_panning_gains_fx[n] = L_shl( new_panning_gains_q15_fx[n], Q16 );
    1535          72 :         old_panning_gains_fx[n] = L_shl( old_panning_gains_q15_fx[n], Q16 );
    1536             :     }
    1537             : 
    1538          36 :     processing_len = shr( output_frame, 1 );
    1539         108 :     FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
    1540             :     {
    1541          72 :         v_multc_acc_exp_mantissa_fx( output[MASA_MAX_TRANSPORT_CHANNELS],
    1542             :                                      out_exp[MASA_MAX_TRANSPORT_CHANNELS],
    1543             :                                      old_panning_gains_fx[n],
    1544          72 :                                      output[n],
    1545          72 :                                      out_exp[n],
    1546             :                                      processing_len );
    1547             :     }
    1548          36 :     offset = processing_len;
    1549          36 :     move16();
    1550             : 
    1551          36 :     processing_len = shr( output_frame, 2 ); /*  divide by MAX_PARAM_SPATIAL_SUBFRAMES; */
    1552         108 :     FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
    1553             :     {
    1554             :         Word32 mantissa;
    1555             : 
    1556             :         /* k == 0->gain == old_panning_gains[n] */
    1557             :         /* output[n][offset] += gain * output[MASA_MAX_TRANSPORT_CHANNELS][offset]; */
    1558          72 :         mantissa = mult32_mantissa_fx( output[MASA_MAX_TRANSPORT_CHANNELS][offset],
    1559             :                                        old_panning_gains_fx[n],
    1560          72 :                                        out_exp[MASA_MAX_TRANSPORT_CHANNELS][offset], &exp );
    1561             : 
    1562         144 :         output[n][offset] = BASOP_Util_Add_Mant32Exp( output[n][offset], out_exp[n][offset],
    1563          72 :                                                       mantissa, exp, &out_exp[n][offset] );
    1564          72 :         move32();
    1565          72 :         move32();
    1566             : 
    1567       17280 :         FOR( k = 1; k < processing_len; k++ )
    1568             :         {
    1569       17208 :             Word16 index = add( k, offset );
    1570             : 
    1571       17208 :             Word32 g1_fx = L_shl( st_ivas->hIsmRendererData->interpolator_fx[k], Q16 );
    1572             : 
    1573             :             /* 1.0f - g1 */
    1574       17208 :             Word32 g2_fx = L_sub( MAX_32, L_sub( g1_fx, 1 ) );
    1575             : 
    1576             :             /* g1 *new_panning_gains[n] + g2 *old_panning_gains[n] */
    1577       17208 :             Word32 gain_k = W_extract_h( W_add( W_mult_32_32( g1_fx, new_panning_gains_fx[n] ),
    1578             :                                                 W_mult_32_32( g2_fx, old_panning_gains_fx[n] ) ) );
    1579             : 
    1580             :             /* output[n][k + offset] += gain_k * output[MASA_MAX_TRANSPORT_CHANNELS][k + offset]; */
    1581       17208 :             mantissa = mult32_mantissa_fx( output[MASA_MAX_TRANSPORT_CHANNELS][index], gain_k,
    1582       17208 :                                            out_exp[MASA_MAX_TRANSPORT_CHANNELS][index], &exp );
    1583       34416 :             output[n][index] = BASOP_Util_Add_Mant32Exp( output[n][index], out_exp[n][index],
    1584       17208 :                                                          mantissa, exp, &out_exp[n][index] );
    1585       17208 :             move32();
    1586       17208 :             move32();
    1587             :         }
    1588             :     }
    1589          36 :     offset = add( offset, processing_len );
    1590             : 
    1591         108 :     FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
    1592             :     {
    1593          72 :         v_multc_acc_exp_mantissa_fx( &output[MASA_MAX_TRANSPORT_CHANNELS][offset],
    1594          72 :                                      &out_exp[MASA_MAX_TRANSPORT_CHANNELS][offset],
    1595             :                                      new_panning_gains_fx[n],
    1596          72 :                                      &output[n][offset],
    1597          72 :                                      &out_exp[n][offset],
    1598             :                                      processing_len );
    1599             :     }
    1600             : 
    1601             :     /* Convert output from exponent+mantissa representation to Q11 */
    1602         108 :     FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
    1603             :     {
    1604          72 :         mantissa_exp_to_qvalue( &out_exp[n][0], &output[n][0], Q20, output_frame );
    1605             :     }
    1606             : 
    1607             :     /* Zero output object channels */
    1608         180 :     FOR( n = 0; n < nchan_ism; n++ )
    1609             :     {
    1610         144 :         set_zero_fx( output[add( MASA_MAX_TRANSPORT_CHANNELS, n )], output_frame );
    1611             :     }
    1612             : 
    1613          36 :     return;
    1614             : }
    1615             : 
    1616             : 
    1617             : /*-------------------------------------------------------------------------*
    1618             :  * ivas_omasa_objects_delay_open()
    1619             :  *
    1620             :  * Open structures, reserve memory, and init values for dela buffers of objects.
    1621             :  *-------------------------------------------------------------------------*/
    1622             : 
    1623         569 : ivas_error ivas_omasa_objects_delay_open_fx(
    1624             :     Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
    1625             : )
    1626             : {
    1627             :     Word16 i;
    1628             :     Word32 size;
    1629             : 
    1630         569 :     test();
    1631         569 :     IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
    1632             :     {
    1633         341 :         st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
    1634         341 :         move16();
    1635             :     }
    1636             :     ELSE
    1637             :     {
    1638         228 :         st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
    1639         228 :         move16();
    1640             :     }
    1641             : 
    1642         569 :     st_ivas->hMasaIsmData->delayBuffer_size = extract_l( Mult_32_16( st_ivas->hDecoderConfig->output_Fs,
    1643             :                                                                      OMASA_DELAYFRAMES_PER_SEC_Q15 ) );
    1644             : 
    1645         569 :     size = L_mult0( st_ivas->hMasaIsmData->delayBuffer_nchan, sizeof( Word16 * ) );
    1646         569 :     st_ivas->hMasaIsmData->delayBuffer_fx = (Word32 **) malloc( size );
    1647         569 :     move32();
    1648             : 
    1649         569 :     IF( st_ivas->hMasaIsmData->delayBuffer_fx == NULL )
    1650             :     {
    1651           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
    1652             :     }
    1653             : 
    1654         569 :     size = L_mult0( st_ivas->hMasaIsmData->delayBuffer_size, sizeof( Word32 ) );
    1655        1694 :     FOR( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
    1656             :     {
    1657        1125 :         st_ivas->hMasaIsmData->delayBuffer_fx[i] = (Word32 *) malloc( size );
    1658        1125 :         move32();
    1659             : 
    1660        1125 :         IF( st_ivas->hMasaIsmData->delayBuffer_fx[i] == NULL )
    1661             :         {
    1662           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
    1663             :         }
    1664        1125 :         set_zero_fx( st_ivas->hMasaIsmData->delayBuffer_fx[i], st_ivas->hMasaIsmData->delayBuffer_size );
    1665             :     }
    1666             : 
    1667         569 :     return IVAS_ERR_OK;
    1668             : }
    1669             : 
    1670             : 
    1671             : /*--------------------------------------------------------------------------*
    1672             :  * ivas_omasa_render_objects_from_mix()
    1673             :  *
    1674             :  * In case of external rendering, render objects from the transport signal
    1675             :  * mix containing MASA audio and object audio.
    1676             :  *--------------------------------------------------------------------------*/
    1677             : 
    1678          40 : void ivas_omasa_render_objects_from_mix_fx(
    1679             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder handle             */
    1680             :     Word32 *output[],          /* o  : output synthesis signal         */
    1681             :     const Word16 nchan_ism,    /* i  : number of ISMs                  */
    1682             :     const Word16 output_frame, /* i  : output frame length per channel */
    1683             :     Word16 *output_q           /* i/o: output Q value                  */
    1684             : )
    1685             : {
    1686             :     Word16 n, m, i;
    1687             :     MASA_ISM_EXT_DATA_HANDLE hExtData;
    1688             :     Word32 separated_object[L_FRAME48k];
    1689             :     Word32 rendered_objects[MAX_NUM_OBJECTS][L_FRAME48k];
    1690             :     Word16 coding_delay;
    1691             :     Word32 inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1692             :     Word32 inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1693             :     Word32 outRe[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1694             :     Word32 outIm[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1695             :     Word16 slot;
    1696             :     Word16 sf;
    1697             :     Word16 bin;
    1698             :     Word16 nchan_transport;
    1699             :     Word16 nBins;
    1700             : 
    1701             :     Word16 inRe_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1702             :     Word16 inIm_exp[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1703             :     Word16 outRe_exp[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1704             :     Word16 outIm_exp[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1705             : 
    1706             :     Word16 transport_energy_exp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1707             :     Word32 transport_energy_frac[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
    1708             : 
    1709             :     /* Create slot to metadata map */
    1710          40 :     slot = 0;
    1711          40 :     move16();
    1712         200 :     FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
    1713             :     {
    1714             :         Word16 index;
    1715             : 
    1716         800 :         FOR( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ )
    1717             :         {
    1718         640 :             st_ivas->hSpatParamRendCom->render_to_md_map[slot] = st_ivas->hSpatParamRendCom->dirac_read_idx;
    1719         640 :             move16();
    1720         640 :             slot = add( slot, 1 );
    1721             :         }
    1722             : 
    1723         160 :         index = add( st_ivas->hSpatParamRendCom->dirac_read_idx, 1 );
    1724         160 :         IF( GE_16( index, st_ivas->hSpatParamRendCom->dirac_md_buffer_length ) )
    1725             :         {
    1726          20 :             index = 0;
    1727          20 :             move16();
    1728             :         }
    1729         160 :         st_ivas->hSpatParamRendCom->dirac_read_idx = index;
    1730         160 :         move16();
    1731             :     }
    1732             : 
    1733             :     /* Move separated object signal and object channels */
    1734          40 :     mvl2l( output[CPE_CHANNELS], separated_object, output_frame );
    1735         200 :     FOR( n = 0; n < nchan_ism; n++ )
    1736             :     {
    1737         160 :         set_zero_fx( output[CPE_CHANNELS + n], output_frame );
    1738             :     }
    1739             : 
    1740             :     /* Delay the separated object signal by the CLDFB delay */
    1741          40 :     delay_signal32_fx( separated_object, output_frame, st_ivas->hMasaIsmData->delayBuffer_fx[0],
    1742          40 :                        st_ivas->hMasaIsmData->delayBuffer_size );
    1743             : 
    1744             :     /* Set object metadata to the ism struct */
    1745         200 :     FOR( n = 0; n < nchan_ism; n++ )
    1746             :     {
    1747             :         // Q0 -> Q22
    1748         160 :         Word32 azi = L_shl( st_ivas->hMasaIsmData->azimuth_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx], Q22 );
    1749         160 :         Word32 ele = L_shl( st_ivas->hMasaIsmData->elevation_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx], Q22 );
    1750             : 
    1751         160 :         st_ivas->hIsmMetaData[n]->azimuth_fx = azi;
    1752         160 :         st_ivas->hIsmMetaData[n]->elevation_fx = ele;
    1753         160 :         move16();
    1754         160 :         move16();
    1755             :     }
    1756             : 
    1757             :     /* Move the separated object signal to the correct output channel */
    1758          40 :     hExtData = st_ivas->hMasaIsmData->hExtData;
    1759          40 :     move32();
    1760          40 :     coding_delay = mult( output_frame, MULT_17_DIV_20_Q15 ); /* Q15: 17 ms of coding and CLDFB delay */
    1761          40 :     mvl2l( separated_object, output[add( CPE_CHANNELS, hExtData->prev_idx_separated_ism )], coding_delay );
    1762          80 :     mvl2l( &separated_object[coding_delay],
    1763          40 :            &output[add( CPE_CHANNELS, st_ivas->hMasaIsmData->idx_separated_ism )][coding_delay],
    1764          40 :            sub( output_frame, coding_delay ) );
    1765             : 
    1766             :     /* Compute CLDFB analysis */
    1767          40 :     nchan_transport = st_ivas->nchan_transport;
    1768          40 :     move16();
    1769          40 :     nBins = mult( output_frame, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ); // Q15
    1770             : 
    1771         680 :     FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
    1772             :     {
    1773        1920 :         FOR( n = 0; n < nchan_transport; n++ )
    1774             :         {
    1775        1280 :             Word16 in_q = *output_q;
    1776        1280 :             move16();
    1777             : 
    1778        1280 :             cldfbAnalysis_ts_fx_var_q( &( output[n][L_mult0( nBins, slot )] ),
    1779        1280 :                                        inRe[n][slot],
    1780        1280 :                                        inIm[n][slot],
    1781             :                                        nBins, st_ivas->cldfbAnaDec[n], &in_q );
    1782             : 
    1783             :             /* Assign input exponent */
    1784        1280 :             Word16 exp = sub( Q31, in_q );
    1785        1280 :             set16_fx( inRe_exp[n][slot], exp, nBins );
    1786        1280 :             set16_fx( inIm_exp[n][slot], exp, nBins );
    1787             :         }
    1788             :     }
    1789             : 
    1790             :     /* Create prototype signals */
    1791         200 :     for ( n = 0; n < nchan_ism; n++ )
    1792             :     {
    1793             :         Word32 panning_gains_fx[2];
    1794             :         Word16 new_panning_gains_fx[2];
    1795             :         Word16 azimuth_fx, elevation_fx;
    1796             : 
    1797             :         // Q22 -> Q0
    1798         160 :         azimuth_fx = extract_l( L_shr( st_ivas->hIsmMetaData[n]->azimuth_fx, Q22 ) );
    1799         160 :         elevation_fx = extract_l( L_shr( st_ivas->hIsmMetaData[n]->elevation_fx, Q22 ) );
    1800         160 :         ivas_get_stereo_panning_gains_fx( azimuth_fx, elevation_fx, new_panning_gains_fx );
    1801             : 
    1802         160 :         Word16 interpValInc = 0;
    1803         160 :         move16();
    1804             : 
    1805             :         // Represents (1.0f - interpVal) value
    1806         160 :         Word16 interpValDec = extract_l( L_sub( -MIN16B, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 ) );
    1807             : 
    1808        2560 :         FOR( slot = 0; slot < sub( CLDFB_NO_COL_MAX, 1 ); slot++ )
    1809             :         {
    1810        2400 :             interpValInc = add( interpValInc, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 );
    1811             : 
    1812        7200 :             FOR( m = 0; m < 2; m++ )
    1813             :             {
    1814        4800 :                 Word32 prev_gain = hExtData->prev_panning_gains[n][m];
    1815        4800 :                 move32();
    1816             : 
    1817        4800 :                 Word32 new_gain = L_shl( new_panning_gains_fx[m], 16 ); // Q15 -> Q31
    1818             : 
    1819        4800 :                 panning_gains_fx[m] = L_add( Mpy_32_16( extract_h( prev_gain ), extract_l( prev_gain ),
    1820             :                                                         interpValDec ),
    1821        4800 :                                              Mpy_32_16( extract_h( new_gain ), extract_l( new_gain ),
    1822             :                                                         interpValInc ) );
    1823             :             }
    1824             : 
    1825        2400 :             interpValDec = sub( interpValDec, MULT_1_DIV_CLDFB_NO_COL_MAX_Q15 );
    1826             : 
    1827        2400 :             v_multc_exp_mantissa_fx( inRe[0][slot], inRe_exp[0][slot], panning_gains_fx[0],
    1828        2400 :                                      outRe[n][slot], outRe_exp[n][slot], nBins );
    1829        2400 :             v_multc_exp_mantissa_fx( inIm[0][slot], inIm_exp[0][slot], panning_gains_fx[0],
    1830        2400 :                                      outIm[n][slot], outIm_exp[n][slot], nBins );
    1831             : 
    1832        2400 :             v_multc_acc_exp_mantissa_fx( inRe[1][slot], inRe_exp[1][slot], panning_gains_fx[1],
    1833        2400 :                                          outRe[n][slot], outRe_exp[n][slot], nBins );
    1834        2400 :             v_multc_acc_exp_mantissa_fx( inIm[1][slot], inIm_exp[1][slot], panning_gains_fx[1],
    1835        2400 :                                          outIm[n][slot], outIm_exp[n][slot], nBins );
    1836             :         }
    1837             : 
    1838             :         // Special case where (1.0f - interpVal) = 0 and interpVal = 1
    1839         480 :         FOR( m = 0; m < 2; m++ )
    1840             :         {
    1841         320 :             panning_gains_fx[m] = L_shl( new_panning_gains_fx[m], 16 ); // Q15 -> Q31
    1842             :         }
    1843             : 
    1844         160 :         v_multc_exp_mantissa_fx( inRe[0][slot], inRe_exp[0][slot], panning_gains_fx[0],
    1845         160 :                                  outRe[n][slot], outRe_exp[n][slot], nBins );
    1846         160 :         v_multc_exp_mantissa_fx( inIm[0][slot], inIm_exp[0][slot], panning_gains_fx[0],
    1847         160 :                                  outIm[n][slot], outIm_exp[n][slot], nBins );
    1848             : 
    1849         160 :         v_multc_acc_exp_mantissa_fx( inRe[1][slot], inRe_exp[1][slot], panning_gains_fx[1],
    1850         160 :                                      outRe[n][slot], outRe_exp[n][slot], nBins );
    1851         160 :         v_multc_acc_exp_mantissa_fx( inIm[1][slot], inIm_exp[1][slot], panning_gains_fx[1],
    1852         160 :                                      outIm[n][slot], outIm_exp[n][slot], nBins );
    1853             : 
    1854         480 :         FOR( m = 0; m < 2; m++ )
    1855             :         {
    1856         320 :             hExtData->prev_panning_gains[n][m] = panning_gains_fx[m];
    1857         320 :             move32();
    1858             :         }
    1859             :     }
    1860             : 
    1861             :     /* Determine transport energy */
    1862         680 :     FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
    1863             :     {
    1864         640 :         set_zero_fx( &transport_energy_frac[slot][0], nBins );
    1865         640 :         set16_zero_fx( &transport_energy_exp[slot][0], nBins );
    1866             :     }
    1867         120 :     FOR( n = 0; n < CPE_CHANNELS; n++ )
    1868             :     {
    1869        1360 :         FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
    1870             :         {
    1871       78080 :             FOR( bin = 0; bin < nBins; bin++ )
    1872             :             {
    1873             :                 Word16 exp;
    1874             : 
    1875             :                 // energy = re^2 + im^2
    1876       76800 :                 Word32 mantissa = sample_energy_fx( inRe[n][slot][bin], inRe_exp[n][slot][bin],
    1877       76800 :                                                     inIm[n][slot][bin], inIm_exp[n][slot][bin], &exp );
    1878       76800 :                 move32();
    1879             : 
    1880             :                 // Accumulate energy
    1881      153600 :                 transport_energy_frac[slot][bin] = BASOP_Util_Add_Mant32Exp( transport_energy_frac[slot][bin],
    1882       76800 :                                                                              transport_energy_exp[slot][bin],
    1883             :                                                                              mantissa,
    1884             :                                                                              exp,
    1885       76800 :                                                                              &transport_energy_exp[slot][bin] );
    1886       76800 :                 move32();
    1887             :             }
    1888             :         }
    1889             :     }
    1890             : 
    1891             :     /* Determine temporally smoothed energies and determine gains using them */
    1892         200 :     FOR( n = 0; n < nchan_ism; n++ )
    1893             :     {
    1894        2720 :         FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
    1895             :         {
    1896        2560 :             Word16 md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
    1897        2560 :             move16();
    1898             : 
    1899      156160 :             FOR( bin = 0; bin < nBins; bin++ )
    1900             :             {
    1901             :                 Word16 exp, exp_mult, proto_e, target_e;
    1902             :                 Word32 mantissa, proto_m, target_m;
    1903             : 
    1904             :                 Word32 ism_target_energy_frac;
    1905             :                 Word16 ism_target_energy_exp;
    1906             : 
    1907             :                 Word32 ism_proto_energy_frac;
    1908             :                 Word16 ism_proto_energy_exp;
    1909             : 
    1910             :                 // r1 = transport_energy[slot][bin] * st_ivas->hMasaIsmData->energy_ratio_ism[n][md_idx][bin]
    1911      153600 :                 ism_target_energy_frac = mult32_mantissa_fx( transport_energy_frac[slot][bin],
    1912      153600 :                                                              st_ivas->hMasaIsmData->energy_ratio_ism_fx[n][md_idx][bin],
    1913      153600 :                                                              add( transport_energy_exp[slot][bin], 1 ),
    1914             :                                                              &ism_target_energy_exp );
    1915      153600 :                 move32();
    1916             : 
    1917             :                 // r2 = r1 * (1.0 - EXT_RENDER_IIR_FAC)
    1918      153600 :                 ism_target_energy_frac = mult32_mantissa_fx( ism_target_energy_frac,
    1919             :                                                              ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
    1920             :                                                              ism_target_energy_exp,
    1921             :                                                              &ism_target_energy_exp );
    1922      153600 :                 move32();
    1923             : 
    1924             :                 // r3 = re^2 + im^2
    1925      153600 :                 mantissa = sample_energy_fx( outRe[n][slot][bin],
    1926      153600 :                                              outRe_exp[n][slot][bin],
    1927             :                                              outIm[n][slot][bin],
    1928      153600 :                                              outIm_exp[n][slot][bin],
    1929             :                                              &exp );
    1930      153600 :                 move32();
    1931             : 
    1932             :                 // r4 = r3 * (1 - EXT_RENDER_IIR_FAC)
    1933      153600 :                 ism_proto_energy_frac = mult32_mantissa_fx( mantissa, ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
    1934             :                                                             exp, &ism_proto_energy_exp );
    1935      153600 :                 move32();
    1936             : 
    1937             : 
    1938             :                 // r5 = ism_render_proto_energy[n][bin] * EXT_RENDER_IIR_FAC
    1939      153600 :                 proto_m = mult32_mantissa_fx( hExtData->ism_render_proto_energy_frac[n][bin], EXT_RENDER_IIR_FAC_Q31,
    1940      153600 :                                               hExtData->ism_render_proto_energy_exp[n][bin], &proto_e );
    1941      153600 :                 move32();
    1942             : 
    1943             :                 // r6 = r5 + r4
    1944      153600 :                 proto_m = BASOP_Util_Add_Mant32Exp( proto_m, proto_e,
    1945             :                                                     ism_proto_energy_frac,
    1946             :                                                     ism_proto_energy_exp,
    1947             :                                                     &proto_e );
    1948      153600 :                 move32();
    1949             : 
    1950             :                 // r7 = ism_render_target_energy[n][bin] * EXT_RENDER_IIR_FAC
    1951      153600 :                 target_m = mult32_mantissa_fx( hExtData->ism_render_target_energy_frac[n][bin], EXT_RENDER_IIR_FAC_Q31,
    1952      153600 :                                                hExtData->ism_render_target_energy_exp[n][bin], &target_e );
    1953      153600 :                 move32();
    1954             : 
    1955             :                 // r8 = r7 + r2
    1956      153600 :                 target_m = BASOP_Util_Add_Mant32Exp( target_m, target_e,
    1957             :                                                      ism_target_energy_frac,
    1958             :                                                      ism_target_energy_exp,
    1959             :                                                      &target_e );
    1960      153600 :                 move32();
    1961             : 
    1962      153600 :                 hExtData->ism_render_proto_energy_frac[n][bin] = proto_m;
    1963      153600 :                 hExtData->ism_render_proto_energy_exp[n][bin] = proto_e;
    1964      153600 :                 move32();
    1965      153600 :                 move16();
    1966             : 
    1967      153600 :                 hExtData->ism_render_target_energy_frac[n][bin] = target_m;
    1968      153600 :                 hExtData->ism_render_target_energy_exp[n][bin] = target_e;
    1969      153600 :                 move32();
    1970      153600 :                 move16();
    1971             : 
    1972             :                 // r9 = sqrt(r8 / r6)
    1973      153600 :                 mantissa = get_processing_gain_fx( proto_m, proto_e, target_m, target_e, &exp );
    1974      153600 :                 move32();
    1975             : 
    1976             :                 // outRe[n][slot][bin] *= r9
    1977      153600 :                 exp_mult = add( exp, outRe_exp[n][slot][bin] );
    1978      307200 :                 outRe[n][slot][bin] = mult32_mantissa_fx( outRe[n][slot][bin], mantissa, exp_mult,
    1979      153600 :                                                           &outRe_exp[n][slot][bin] );
    1980      153600 :                 move32();
    1981             : 
    1982             :                 // outIm[n][slot][bin] *= r9
    1983      153600 :                 exp_mult = add( exp, outIm_exp[n][slot][bin] );
    1984      307200 :                 outIm[n][slot][bin] = mult32_mantissa_fx( outIm[n][slot][bin], mantissa, exp_mult,
    1985      153600 :                                                           &outIm_exp[n][slot][bin] );
    1986      153600 :                 move32();
    1987             :             }
    1988             :         }
    1989             :     }
    1990             : 
    1991         680 :     FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
    1992             :     {
    1993         640 :         Word16 md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
    1994         640 :         move16();
    1995             : 
    1996       39040 :         FOR( bin = 0; bin < nBins; bin++ )
    1997             :         {
    1998             :             Word16 exp, proto_e, target_e, transport_exp;
    1999             :             Word32 mantissa, proto_m, target_m, transport_mantissa;
    2000             : 
    2001             :             Word32 masa_target_energy_frac;
    2002             :             Word16 masa_target_energy_exp;
    2003             : 
    2004             :             // r1 = transport_energy[slot][bin] * hExtData->masa_render_masa_to_total[md_idx][bin]
    2005       38400 :             masa_target_energy_frac = mult32_mantissa_fx( transport_energy_frac[slot][bin],
    2006             :                                                           hExtData->masa_render_masa_to_total[md_idx][bin],
    2007       38400 :                                                           add( transport_energy_exp[slot][bin], 1 ),
    2008             :                                                           &masa_target_energy_exp );
    2009       38400 :             move32();
    2010             : 
    2011             :             // r2 = r1 * EXT_RENDER_IIR_FAC
    2012       38400 :             masa_target_energy_frac = mult32_mantissa_fx( masa_target_energy_frac,
    2013             :                                                           ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
    2014             :                                                           masa_target_energy_exp,
    2015             :                                                           &masa_target_energy_exp );
    2016       38400 :             move32();
    2017             : 
    2018             :             // r3 = masa_render_proto_energy[bin] * EXT_RENDER_IIR_FAC
    2019       38400 :             proto_m = mult32_mantissa_fx( hExtData->masa_render_proto_energy_frac[bin], EXT_RENDER_IIR_FAC_Q31,
    2020       38400 :                                           hExtData->masa_render_proto_energy_exp[bin], &proto_e );
    2021       38400 :             move32();
    2022             : 
    2023             :             // r4 = transport_energy[slot][bin] * EXT_RENDER_IIR_FAC
    2024       38400 :             transport_mantissa = mult32_mantissa_fx( transport_energy_frac[slot][bin],
    2025             :                                                      ONEMINUX_EXT_RENDER_IIR_FAC_Q31,
    2026       38400 :                                                      transport_energy_exp[slot][bin], &transport_exp );
    2027       38400 :             move32();
    2028             : 
    2029             :             // r5 = r3 + r4
    2030       38400 :             proto_m = BASOP_Util_Add_Mant32Exp( proto_m, proto_e,
    2031             :                                                 transport_mantissa,
    2032             :                                                 transport_exp,
    2033             :                                                 &proto_e );
    2034       38400 :             move32();
    2035             : 
    2036             :             // r6 =  masa_render_target_energy[bin] * EXT_RENDER_IIR_FAC
    2037       38400 :             target_m = mult32_mantissa_fx( hExtData->masa_render_target_energy_frac[bin], EXT_RENDER_IIR_FAC_Q31,
    2038       38400 :                                            hExtData->masa_render_target_energy_exp[bin], &target_e );
    2039       38400 :             move32();
    2040             : 
    2041             :             // r7 = r6 + r2
    2042       38400 :             target_m = BASOP_Util_Add_Mant32Exp( target_m, target_e,
    2043             :                                                  masa_target_energy_frac,
    2044             :                                                  masa_target_energy_exp,
    2045             :                                                  &target_e );
    2046       38400 :             move32();
    2047             : 
    2048       38400 :             hExtData->masa_render_proto_energy_frac[bin] = proto_m;
    2049       38400 :             hExtData->masa_render_proto_energy_exp[bin] = proto_e;
    2050       38400 :             move16();
    2051       38400 :             move32();
    2052             : 
    2053       38400 :             hExtData->masa_render_target_energy_frac[bin] = target_m;
    2054       38400 :             hExtData->masa_render_target_energy_exp[bin] = target_e;
    2055       38400 :             move16();
    2056       38400 :             move32();
    2057             : 
    2058             :             // r8 = sqrt(r7 / r5)
    2059       38400 :             mantissa = get_processing_gain_fx( proto_m, proto_e, target_m, target_e, &exp );
    2060       38400 :             move32();
    2061             : 
    2062      115200 :             FOR( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
    2063             :             {
    2064             :                 Word16 exp_mult;
    2065             : 
    2066             :                 // inRe[n][slot][bin] *= r8
    2067       76800 :                 exp_mult = add( exp, inRe_exp[n][slot][bin] );
    2068      153600 :                 inRe[n][slot][bin] = mult32_mantissa_fx( inRe[n][slot][bin], mantissa, exp_mult,
    2069       76800 :                                                          &inRe_exp[n][slot][bin] );
    2070       76800 :                 move32();
    2071             : 
    2072             :                 // inIm[n][slot][bin] *= r8
    2073       76800 :                 exp_mult = add( exp, inIm_exp[n][slot][bin] );
    2074      153600 :                 inIm[n][slot][bin] = mult32_mantissa_fx( inIm[n][slot][bin], mantissa, exp_mult,
    2075       76800 :                                                          &inIm_exp[n][slot][bin] );
    2076       76800 :                 move32();
    2077             :             }
    2078             :         }
    2079             :     }
    2080             : 
    2081          40 :     *output_q = Q11;
    2082             : 
    2083             :     /* Compute CLDFB synthesis */
    2084         680 :     FOR( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
    2085             :     {
    2086             :         Word32 *outSlotRePr, *outSlotImPr;
    2087         640 :         Word32 index = L_mult0( nBins, slot );
    2088             : 
    2089        1920 :         FOR( n = 0; n < nchan_transport; n++ )
    2090             :         {
    2091        1280 :             outSlotRePr = &( inRe[n][slot][0] );
    2092        1280 :             outSlotImPr = &( inIm[n][slot][0] );
    2093        1280 :             move32();
    2094        1280 :             move32();
    2095             : 
    2096       78080 :             FOR( bin = 0; bin < nBins; bin++ )
    2097             :             {
    2098       76800 :                 inRe_exp[n][slot][bin] = sub( inRe_exp[n][slot][bin], Q2 );
    2099       76800 :                 inIm_exp[n][slot][bin] = sub( inIm_exp[n][slot][bin], Q2 );
    2100             :             }
    2101             : 
    2102        1280 :             mantissa_exp_to_qvalue( &inRe_exp[n][slot][0], &inRe[n][slot][0], Q20, nBins );
    2103        1280 :             mantissa_exp_to_qvalue( &inIm_exp[n][slot][0], &inIm[n][slot][0], Q20, nBins );
    2104             : 
    2105        1280 :             cldfbSynthesis_ivas_fx( &outSlotRePr, &outSlotImPr, &output[n][index],
    2106             :                                     nBins, Q2, 1, st_ivas->cldfbSynDec[n] );
    2107             :         }
    2108             : 
    2109        3200 :         FOR( n = 0; n < nchan_ism; n++ )
    2110             :         {
    2111        2560 :             Word32 index2 = add( n, CPE_CHANNELS );
    2112             : 
    2113        2560 :             outSlotRePr = &( outRe[n][slot][0] );
    2114        2560 :             outSlotImPr = &( outIm[n][slot][0] );
    2115        2560 :             move32();
    2116        2560 :             move32();
    2117             : 
    2118        2560 :             mantissa_exp_to_qvalue( &outRe_exp[n][slot][0], &outRe[n][slot][0], Q20, nBins );
    2119        2560 :             mantissa_exp_to_qvalue( &outIm_exp[n][slot][0], &outIm[n][slot][0], Q20, nBins );
    2120             : 
    2121        2560 :             cldfbSynthesis_ivas_fx( &outSlotRePr, &outSlotImPr, &rendered_objects[n][index],
    2122             :                                     nBins, 0, 1, st_ivas->cldfbSynDec[index2] );
    2123             :         }
    2124             :     }
    2125             : 
    2126             :     /* Combine the rendered objects with the separated objects */
    2127         200 :     FOR( n = 0; n < nchan_ism; n++ )
    2128             :     {
    2129         160 :         Word16 index = add( CPE_CHANNELS, n );
    2130         160 :         v_add_32( output[index], rendered_objects[n], output[index], output_frame );
    2131             :     }
    2132             : 
    2133          40 :     hExtData->prev_idx_separated_ism = st_ivas->hMasaIsmData->idx_separated_ism;
    2134          40 :     move16();
    2135             : 
    2136          40 :     return;
    2137             : }

Generated by: LCOV version 1.14