LCOV - code coverage report
Current view: top level - lib_dec - ivas_omasa_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ b9bfbe380d1c207f5198ba67a82398b3d313550e Lines: 779 867 89.9 %
Date: 2025-11-16 02:22:47 Functions: 19 20 95.0 %

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

Generated by: LCOV version 1.14