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

Generated by: LCOV version 1.14