LCOV - code coverage report
Current view: top level - lib_rend - ivas_dirac_rend_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ da9cc8ead0679b4682d329fdff98cf1616159273 Lines: 2184 2353 92.8 %
Date: 2025-10-13 22:24:20 Functions: 23 23 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "cnst.h"
      38             : #include "prot_fx.h"
      39             : #include "ivas_prot_rend_fx.h"
      40             : #include "ivas_cnst.h"
      41             : #include "ivas_rom_rend.h"
      42             : #include "wmc_auto.h"
      43             : #include "ivas_prot_fx.h"
      44             : #include "ivas_rom_binaural_crend_head.h"
      45             : 
      46             : 
      47             : /*-------------------------------------------------------------------------
      48             :  * ivas_dirac_allocate_parameters()
      49             :  *
      50             :  * Allocate and initialize DirAC parameters
      51             :  *-------------------------------------------------------------------------*/
      52             : 
      53        1089 : ivas_error ivas_dirac_allocate_parameters_fx(
      54             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */
      55             :     const Word16 params_flag                              /* i  : set of parameters flag    */
      56             : )
      57             : {
      58             :     Word16 i;
      59             : 
      60        1089 :     IF( EQ_16( params_flag, 1 ) )
      61             :     {
      62         676 :         IF( ( hSpatParamRendCom->azimuth = (Word16 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word16 * ) ) ) == NULL )
      63             :         {
      64           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
      65             :         }
      66             : 
      67         676 :         IF( ( hSpatParamRendCom->elevation = (Word16 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word16 * ) ) ) == NULL )
      68             :         {
      69           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
      70             :         }
      71             : 
      72         676 :         IF( ( hSpatParamRendCom->diffuseness_vector_fx = (Word32 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word32 * ) ) ) == NULL )
      73             :         {
      74           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
      75             :         }
      76             : 
      77         676 :         IF( ( hSpatParamRendCom->energy_ratio1_fx = (Word32 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word32 * ) ) ) == NULL )
      78             :         {
      79           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
      80             :         }
      81             : 
      82         676 :         IF( ( hSpatParamRendCom->spreadCoherence_fx = (Word16 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word16 * ) ) ) == NULL )
      83             :         {
      84           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
      85             :         }
      86             : 
      87         676 :         IF( ( hSpatParamRendCom->surroundingCoherence_fx = (Word16 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word16 * ) ) ) == NULL )
      88             :         {
      89           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
      90             :         }
      91             : 
      92        3972 :         FOR( i = 0; i < hSpatParamRendCom->dirac_md_buffer_length; i++ )
      93             :         {
      94        3296 :             IF( ( hSpatParamRendCom->azimuth[i] = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL )
      95             :             {
      96           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
      97             :             }
      98        3296 :             set16_fx( hSpatParamRendCom->azimuth[i], 0, hSpatParamRendCom->num_freq_bands );
      99             : 
     100        3296 :             IF( ( hSpatParamRendCom->elevation[i] = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL )
     101             :             {
     102           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     103             :             }
     104        3296 :             set16_fx( hSpatParamRendCom->elevation[i], 0, hSpatParamRendCom->num_freq_bands );
     105             : 
     106        3296 :             IF( ( hSpatParamRendCom->diffuseness_vector_fx[i] = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     107             :             {
     108           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     109             :             }
     110        3296 :             set32_fx( hSpatParamRendCom->diffuseness_vector_fx[i], ONE_IN_Q30, hSpatParamRendCom->num_freq_bands ); // q30
     111             : 
     112        3296 :             IF( ( hSpatParamRendCom->energy_ratio1_fx[i] = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     113             :             {
     114           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     115             :             }
     116        3296 :             set32_fx( hSpatParamRendCom->energy_ratio1_fx[i], 0, hSpatParamRendCom->num_freq_bands );
     117             : 
     118        3296 :             IF( ( hSpatParamRendCom->spreadCoherence_fx[i] = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL )
     119             :             {
     120           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     121             :             }
     122        3296 :             set16_fx( hSpatParamRendCom->spreadCoherence_fx[i], 0, hSpatParamRendCom->num_freq_bands );
     123             : 
     124        3296 :             IF( ( hSpatParamRendCom->surroundingCoherence_fx[i] = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL )
     125             :             {
     126           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     127             :             }
     128        3296 :             set16_fx( hSpatParamRendCom->surroundingCoherence_fx[i], 0, hSpatParamRendCom->num_freq_bands );
     129             :         }
     130             :     }
     131         413 :     ELSE IF( EQ_16( params_flag, 2 ) )
     132             :     {
     133         413 :         IF( ( hSpatParamRendCom->azimuth2 = (Word16 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word16 * ) ) ) == NULL )
     134             :         {
     135           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     136             :         }
     137             : 
     138         413 :         IF( ( hSpatParamRendCom->elevation2 = (Word16 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word16 * ) ) ) == NULL )
     139             :         {
     140           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     141             :         }
     142             : 
     143         413 :         IF( ( hSpatParamRendCom->energy_ratio2_fx = (Word32 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word32 * ) ) ) == NULL )
     144             :         {
     145           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     146             :         }
     147             : 
     148         413 :         IF( ( hSpatParamRendCom->spreadCoherence2_fx = (Word16 **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( Word16 * ) ) ) == NULL )
     149             :         {
     150           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     151             :         }
     152             : 
     153        2603 :         FOR( i = 0; i < hSpatParamRendCom->dirac_md_buffer_length; i++ )
     154             :         {
     155        2190 :             IF( ( hSpatParamRendCom->azimuth2[i] = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL )
     156             :             {
     157           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     158             :             }
     159        2190 :             set16_fx( hSpatParamRendCom->azimuth2[i], 0, hSpatParamRendCom->num_freq_bands );
     160             : 
     161        2190 :             IF( ( hSpatParamRendCom->elevation2[i] = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL )
     162             :             {
     163           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     164             :             }
     165        2190 :             set16_fx( hSpatParamRendCom->elevation2[i], 0, hSpatParamRendCom->num_freq_bands );
     166             : 
     167        2190 :             IF( ( hSpatParamRendCom->energy_ratio2_fx[i] = (Word32 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word32 ) ) ) == NULL )
     168             :             {
     169           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     170             :             }
     171        2190 :             set32_fx( hSpatParamRendCom->energy_ratio2_fx[i], 0, hSpatParamRendCom->num_freq_bands );
     172             : 
     173        2190 :             IF( ( hSpatParamRendCom->spreadCoherence2_fx[i] = (Word16 *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( Word16 ) ) ) == NULL )
     174             :             {
     175           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
     176             :             }
     177        2190 :             set16_fx( hSpatParamRendCom->spreadCoherence2_fx[i], 0, hSpatParamRendCom->num_freq_bands );
     178             :         }
     179             :     }
     180             : 
     181        1089 :     return IVAS_ERR_OK;
     182             : }
     183             : 
     184             : 
     185             : /*-------------------------------------------------------------------------
     186             :  * ivas_spat_hSpatParamRendCom_config()
     187             :  *
     188             :  *
     189             :  *-------------------------------------------------------------------------*/
     190             : 
     191        4533 : ivas_error ivas_spat_hSpatParamRendCom_config_fx(
     192             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, /* i/o: IVAS decoder structure  */
     193             :     const DIRAC_CONFIG_FLAG flag_config_inp,                   /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
     194             :     const Word16 dec_param_estim_flag,
     195             :     const IVAS_FORMAT ivas_format,
     196             :     const MC_MODE mc_mode,
     197             :     const Word32 output_Fs,
     198             :     const Word16 hodirac_flag,
     199             :     const Word16 masa_ext_rend_flag )
     200             : {
     201             :     ivas_error error;
     202             :     Word16 map_idx;
     203             :     DIRAC_CONFIG_FLAG flag_config;
     204             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
     205             : 
     206        4533 :     IF( EQ_32( flag_config_inp, DIRAC_RECONFIGURE_MODE ) )
     207        1116 :     flag_config = DIRAC_RECONFIGURE;
     208             :     ELSE
     209        3417 :         flag_config = flag_config_inp;
     210        4533 :     move32();
     211        4533 :     error = IVAS_ERR_OK;
     212        4533 :     move32();
     213             : 
     214        4533 :     hSpatParamRendCom = NULL;
     215             : 
     216        4533 :     IF( EQ_32( flag_config, DIRAC_RECONFIGURE ) )
     217             :     {
     218        3955 :         hSpatParamRendCom = *hSpatParamRendCom_out;
     219             :     }
     220         578 :     ELSE IF( flag_config == DIRAC_OPEN )
     221             :     {
     222             :         /*-----------------------------------------------------------------*
     223             :          * prepare library opening
     224             :          *-----------------------------------------------------------------*/
     225             : 
     226         578 :         IF( ( hSpatParamRendCom = (SPAT_PARAM_REND_COMMON_DATA_HANDLE) malloc( sizeof( SPAT_PARAM_REND_COMMON_DATA ) ) ) == NULL )
     227             :         {
     228           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC meta\n" ) );
     229             :         }
     230             : 
     231         578 :         *hSpatParamRendCom_out = hSpatParamRendCom;
     232             :     }
     233             : 
     234        4533 :     IF( EQ_32( flag_config, DIRAC_OPEN ) )
     235             :     {
     236             :         /* hSpatParamRendCom->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX ); */
     237         578 :         hSpatParamRendCom->slot_size = extract_l( Mpy_32_32( output_Fs, 2684355 /* 1 / ( FRAMES_PER_SEC * CLDFB_NO_COL_MAX) in Q31 */ ) ); // Q0+Q31-Q31=>Q0
     238         578 :         move16();
     239         578 :         set16_fx( hSpatParamRendCom->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
     240         578 :         set16_fx( hSpatParamRendCom->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS );
     241         578 :         hSpatParamRendCom->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS;
     242         578 :         move16();
     243         578 :         hSpatParamRendCom->subframes_rendered = 0;
     244         578 :         move16();
     245         578 :         hSpatParamRendCom->slots_rendered = 0;
     246         578 :         move16();
     247         578 :         hSpatParamRendCom->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME;
     248         578 :         move16();
     249             :         /* hSpatParamRendCom->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ); */
     250         578 :         hSpatParamRendCom->num_freq_bands = extract_l( Mpy_32_32( output_Fs, 2684355 /* INV_CLDFB_BANDWIDTH in Q31 */ ) ); // 0+31-31=>0
     251         578 :         move16();
     252         578 :         hSpatParamRendCom->numSimultaneousDirections = 0;
     253         578 :         move16();
     254         578 :         hSpatParamRendCom->numParametricDirections = 0;
     255         578 :         move16();
     256         578 :         hSpatParamRendCom->numIsmDirections = 0;
     257         578 :         move16();
     258             :     }
     259             : 
     260             :     /*-----------------------------------------------------------------*
     261             :      * set input parameters
     262             :      *-----------------------------------------------------------------*/
     263             : 
     264        4533 :     test();
     265        4533 :     test();
     266        4533 :     IF( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && EQ_32( flag_config, DIRAC_RECONFIGURE ) )
     267             :     {
     268        1116 :         test();
     269        1116 :         test();
     270        1116 :         IF( hodirac_flag && hSpatParamRendCom->azimuth2 == NULL )
     271             :         {
     272          89 :             IF( NE_32( ( error = ivas_dirac_allocate_parameters_fx( hSpatParamRendCom, 2 ) ), IVAS_ERR_OK ) )
     273             :             {
     274           0 :                 return error;
     275             :             }
     276             :         }
     277        1027 :         ELSE IF( !hodirac_flag && hSpatParamRendCom->azimuth2 != NULL )
     278             :         {
     279          81 :             ivas_dirac_deallocate_parameters_fx( hSpatParamRendCom, 2 );
     280             :         }
     281             :     }
     282             : 
     283        4533 :     IF( flag_config == DIRAC_OPEN )
     284             :     {
     285         578 :         hSpatParamRendCom->dirac_md_buffer_length = 0;
     286         578 :         move16();
     287         578 :         hSpatParamRendCom->dirac_bs_md_write_idx = 0;
     288         578 :         move16();
     289         578 :         hSpatParamRendCom->dirac_read_idx = 0;
     290         578 :         move16();
     291         578 :         test();
     292         578 :         test();
     293         578 :         IF( EQ_32( mc_mode, MC_MODE_MCMASA ) || EQ_16( masa_ext_rend_flag, 1 ) )
     294             :         {
     295         282 :             hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES;
     296         282 :             move16();
     297             : 
     298         282 :             set16_fx( hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
     299        1410 :             FOR( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ )
     300             :             {
     301        1128 :                 hSpatParamRendCom->render_to_md_map[map_idx] = map_idx;
     302        1128 :                 move16();
     303             :             }
     304             :         }
     305         296 :         ELSE IF( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) )
     306             :         {
     307         159 :             hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR;
     308         159 :             move16();
     309         159 :             hSpatParamRendCom->dirac_bs_md_write_idx = DELAY_MASA_PARAM_DEC_SFR;
     310         159 :             move16();
     311             : 
     312         159 :             set16_fx( hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
     313         795 :             FOR( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ )
     314             :             {
     315         636 :                 hSpatParamRendCom->render_to_md_map[map_idx] = map_idx;
     316         636 :                 move16();
     317             :             }
     318             :         }
     319             :         ELSE
     320             :         {
     321             :             Word16 num_slots_in_subfr, tmp;
     322         137 :             tmp = 1;
     323         137 :             move16();
     324         137 :             IF( dec_param_estim_flag )
     325          68 :             num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES;
     326             :             ELSE
     327          69 :                 num_slots_in_subfr = 1;
     328         137 :             move16();
     329         137 :             hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_DIRAC_PARAM_DEC_SFR;
     330         137 :             move16();
     331         137 :             hSpatParamRendCom->dirac_bs_md_write_idx = DELAY_DIRAC_PARAM_DEC_SFR;
     332         137 :             move16();
     333         137 :             hSpatParamRendCom->dirac_read_idx = 0;
     334         137 :             move16();
     335             : 
     336         137 :             set16_fx( hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
     337             : 
     338         137 :             if ( EQ_16( num_slots_in_subfr, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ) )
     339             :             {
     340          68 :                 tmp = 2;
     341          68 :                 move16();
     342             :             }
     343             : 
     344        1501 :             FOR( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS * num_slots_in_subfr; map_idx++ )
     345             :             {
     346        1364 :                 hSpatParamRendCom->render_to_md_map[map_idx] = add( hSpatParamRendCom->dirac_read_idx, shr( map_idx, tmp ) );
     347        1364 :                 move16();
     348             :             }
     349             :         }
     350             : 
     351         578 :         IF( NE_32( ( error = ivas_dirac_allocate_parameters_fx( hSpatParamRendCom, 1 ) ), IVAS_ERR_OK ) )
     352             :         {
     353           0 :             return error;
     354             :         }
     355             : 
     356         578 :         test();
     357         578 :         test();
     358         578 :         test();
     359         578 :         test();
     360         578 :         IF( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) || ( ( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) && hodirac_flag ) )
     361             :         {
     362         226 :             IF( NE_32( ( error = ivas_dirac_allocate_parameters_fx( hSpatParamRendCom, 2 ) ), IVAS_ERR_OK ) )
     363             :             {
     364           0 :                 return error;
     365             :             }
     366             :         }
     367             :         ELSE
     368             :         {
     369         352 :             hSpatParamRendCom->azimuth2 = NULL;
     370         352 :             hSpatParamRendCom->elevation2 = NULL;
     371         352 :             hSpatParamRendCom->energy_ratio2_fx = NULL;
     372         352 :             hSpatParamRendCom->spreadCoherence2_fx = NULL;
     373             :         }
     374             :     }
     375             : 
     376        4533 :     return error;
     377             : }
     378             : 
     379             : 
     380             : /*-------------------------------------------------------------------------
     381             :  * ivas_spat_hSpatParamRendCom_close()
     382             :  *
     383             :  *
     384             :  *-------------------------------------------------------------------------*/
     385             : 
     386        1725 : void ivas_spat_hSpatParamRendCom_close_fx(
     387             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out )
     388             : {
     389        1725 :     test();
     390        1725 :     IF( hSpatParamRendCom_out == NULL || *hSpatParamRendCom_out == NULL )
     391             :     {
     392        1147 :         return;
     393             :     }
     394         578 :     ivas_dirac_deallocate_parameters_fx( *hSpatParamRendCom_out, 1 );
     395         578 :     ivas_dirac_deallocate_parameters_fx( *hSpatParamRendCom_out, 2 );
     396             : 
     397         578 :     free( *hSpatParamRendCom_out );
     398         578 :     *hSpatParamRendCom_out = NULL;
     399             : 
     400         578 :     return;
     401             : }
     402             : 
     403             : 
     404             : /*-------------------------------------------------------------------------
     405             :  * ivas_dirac_rend_close()
     406             :  *
     407             :  *
     408             :  *-------------------------------------------------------------------------*/
     409             : 
     410        3934 : void ivas_dirac_rend_close_fx(
     411             :     DIRAC_REND_HANDLE *hDirACRend_out )
     412             : {
     413             :     Word16 i, j;
     414             :     DIRAC_REND_HANDLE hDirACRend;
     415             : 
     416        3934 :     test();
     417        3934 :     IF( hDirACRend_out == NULL || *hDirACRend_out == NULL )
     418             :     {
     419        3496 :         return;
     420             :     }
     421             : 
     422         438 :     hDirACRend = *hDirACRend_out;
     423             : 
     424             :     /* close Output synthesis sub-module */
     425         438 :     ivas_dirac_dec_output_synthesis_close_fx( hDirACRend );
     426             : 
     427             :     /* close Decorrelator sub-module */
     428         438 :     IF( hDirACRend->proto_signal_decorr_on )
     429             :     {
     430         378 :         ivas_dirac_dec_decorr_close_fx( &hDirACRend->h_freq_domain_decorr_ap_params, &hDirACRend->h_freq_domain_decorr_ap_state );
     431             :     }
     432             : 
     433             :     /* Params */
     434             : 
     435             :     /* free frequency axis buffer */
     436         438 :     IF( hDirACRend->frequency_axis_fx != NULL )
     437             :     {
     438         438 :         free( hDirACRend->frequency_axis_fx );
     439         438 :         hDirACRend->frequency_axis_fx = NULL;
     440             :     }
     441             : 
     442         438 :     IF( hDirACRend->diffuse_response_function_fx != NULL )
     443             :     {
     444         438 :         free( hDirACRend->diffuse_response_function_fx );
     445         438 :         hDirACRend->diffuse_response_function_fx = NULL;
     446             :     }
     447             : 
     448         438 :     IF( hDirACRend->hoa_encoder_fx != NULL )
     449             :     {
     450          15 :         free( hDirACRend->hoa_encoder_fx );
     451          15 :         hDirACRend->hoa_encoder_fx = NULL;
     452             :     }
     453             : 
     454         438 :     IF( hDirACRend->hoa_encoder_fx != NULL )
     455             :     {
     456           0 :         free( hDirACRend->hoa_encoder_fx );
     457           0 :         hDirACRend->hoa_encoder_fx = NULL;
     458             :     }
     459             : 
     460             :     /* prototype indexing */
     461         438 :     IF( hDirACRend->proto_index_dir != NULL )
     462             :     {
     463         438 :         free( hDirACRend->proto_index_dir );
     464         438 :         hDirACRend->proto_index_dir = NULL;
     465             :     }
     466             : 
     467         438 :     IF( hDirACRend->proto_index_diff != NULL )
     468             :     {
     469         438 :         free( hDirACRend->proto_index_diff );
     470         438 :         hDirACRend->proto_index_dir = NULL;
     471             :     }
     472             : 
     473             :     /* States */
     474             : 
     475             :     /* free prototype signal buffers */
     476         438 :     IF( hDirACRend->proto_frame_f_fx != NULL )
     477             :     {
     478         226 :         free( hDirACRend->proto_frame_f_fx );
     479         226 :         hDirACRend->proto_frame_f_fx = NULL;
     480             :     }
     481             : 
     482             : 
     483        1752 :     FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
     484             :     {
     485       43362 :         FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
     486             :         {
     487       42048 :             IF( hDirACRend->buffer_intensity_real_fx[i][j] != NULL )
     488             :             {
     489       15456 :                 free( hDirACRend->buffer_intensity_real_fx[i][j] );
     490       15456 :                 hDirACRend->buffer_intensity_real_fx[i][j] = NULL;
     491             :             }
     492             :         }
     493             :     }
     494         438 :     IF( hDirACRend->buffer_energy_fx != NULL )
     495             :     {
     496         161 :         free( hDirACRend->buffer_energy_fx );
     497         161 :         hDirACRend->buffer_energy_fx = NULL;
     498             :     }
     499             : 
     500         438 :     IF( hDirACRend->masa_stereo_type_detect != NULL )
     501             :     {
     502          66 :         free( hDirACRend->masa_stereo_type_detect );
     503          66 :         hDirACRend->masa_stereo_type_detect = NULL;
     504             :     }
     505             : 
     506         438 :     ivas_dirac_free_mem_fx( &( hDirACRend->stack_mem ) );
     507             : 
     508         438 :     free( *hDirACRend_out );
     509         438 :     *hDirACRend_out = NULL;
     510             : 
     511         438 :     return;
     512             : }
     513             : 
     514             : 
     515             : /*-------------------------------------------------------------------------
     516             :  * ivas_dirac_deallocate_parameters()
     517             :  *
     518             :  * Deallocate DirAC parameters
     519             :  *-------------------------------------------------------------------------*/
     520             : 
     521        1433 : void ivas_dirac_deallocate_parameters_fx(
     522             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering  */
     523             :     const Word16 params_flag                              /* i  : set of parameters flag                        */
     524             : )
     525             : {
     526             :     Word16 i;
     527             :     Word16 md_buffer_length;
     528             : 
     529        1433 :     IF( hSpatParamRendCom == NULL )
     530             :     {
     531           0 :         return;
     532             :     }
     533             : 
     534        1433 :     md_buffer_length = hSpatParamRendCom->dirac_md_buffer_length;
     535        1433 :     move16();
     536             : 
     537        1433 :     IF( EQ_16( params_flag, 1 ) )
     538             :     {
     539         676 :         IF( hSpatParamRendCom->azimuth != NULL )
     540             :         {
     541        3972 :             FOR( i = 0; i < md_buffer_length; i++ )
     542             :             {
     543        3296 :                 IF( hSpatParamRendCom->azimuth[i] != NULL )
     544             :                 {
     545        3296 :                     free( hSpatParamRendCom->azimuth[i] );
     546        3296 :                     hSpatParamRendCom->azimuth[i] = NULL;
     547             :                 }
     548             :             }
     549             : 
     550         676 :             free( hSpatParamRendCom->azimuth );
     551         676 :             hSpatParamRendCom->azimuth = NULL;
     552             :         }
     553             : 
     554         676 :         IF( hSpatParamRendCom->elevation != NULL )
     555             :         {
     556        3972 :             FOR( i = 0; i < md_buffer_length; i++ )
     557             :             {
     558        3296 :                 IF( hSpatParamRendCom->elevation[i] != NULL )
     559             :                 {
     560        3296 :                     free( hSpatParamRendCom->elevation[i] );
     561        3296 :                     hSpatParamRendCom->elevation[i] = NULL;
     562             :                 }
     563             :             }
     564             : 
     565         676 :             free( hSpatParamRendCom->elevation );
     566         676 :             hSpatParamRendCom->elevation = NULL;
     567             :         }
     568             : 
     569         676 :         IF( hSpatParamRendCom->energy_ratio1_fx != NULL )
     570             :         {
     571        3972 :             FOR( i = 0; i < md_buffer_length; i++ )
     572             :             {
     573        3296 :                 IF( hSpatParamRendCom->energy_ratio1_fx[i] != NULL )
     574             :                 {
     575        3296 :                     free( hSpatParamRendCom->energy_ratio1_fx[i] );
     576        3296 :                     hSpatParamRendCom->energy_ratio1_fx[i] = NULL;
     577             :                 }
     578             :             }
     579         676 :             free( hSpatParamRendCom->energy_ratio1_fx );
     580         676 :             hSpatParamRendCom->energy_ratio1_fx = NULL;
     581             :         }
     582             : 
     583         676 :         IF( hSpatParamRendCom->diffuseness_vector_fx != NULL )
     584             :         {
     585        3972 :             FOR( i = 0; i < md_buffer_length; i++ )
     586             :             {
     587        3296 :                 IF( hSpatParamRendCom->diffuseness_vector_fx[i] != NULL )
     588             :                 {
     589        3296 :                     free( hSpatParamRendCom->diffuseness_vector_fx[i] );
     590        3296 :                     hSpatParamRendCom->diffuseness_vector_fx[i] = NULL;
     591             :                 }
     592             :             }
     593             : 
     594         676 :             free( hSpatParamRendCom->diffuseness_vector_fx );
     595         676 :             hSpatParamRendCom->diffuseness_vector_fx = NULL;
     596             :         }
     597             : 
     598         676 :         IF( hSpatParamRendCom->spreadCoherence_fx != NULL )
     599             :         {
     600        3972 :             FOR( i = 0; i < md_buffer_length; i++ )
     601             :             {
     602        3296 :                 IF( hSpatParamRendCom->spreadCoherence_fx[i] != NULL )
     603             :                 {
     604        3296 :                     free( hSpatParamRendCom->spreadCoherence_fx[i] );
     605        3296 :                     hSpatParamRendCom->spreadCoherence_fx[i] = NULL;
     606             :                 }
     607             :             }
     608         676 :             free( hSpatParamRendCom->spreadCoherence_fx );
     609         676 :             hSpatParamRendCom->spreadCoherence_fx = NULL;
     610             :         }
     611             : 
     612         676 :         IF( hSpatParamRendCom->surroundingCoherence_fx != NULL )
     613             :         {
     614        3972 :             FOR( i = 0; i < md_buffer_length; i++ )
     615             :             {
     616        3296 :                 IF( hSpatParamRendCom->surroundingCoherence_fx[i] != NULL )
     617             :                 {
     618        3296 :                     free( hSpatParamRendCom->surroundingCoherence_fx[i] );
     619        3296 :                     hSpatParamRendCom->surroundingCoherence_fx[i] = NULL;
     620             :                 }
     621             :             }
     622         676 :             free( hSpatParamRendCom->surroundingCoherence_fx );
     623         676 :             hSpatParamRendCom->surroundingCoherence_fx = NULL;
     624             :         }
     625             :     }
     626         757 :     ELSE IF( EQ_16( params_flag, 2 ) )
     627             :     {
     628         757 :         IF( hSpatParamRendCom->azimuth2 != NULL )
     629             :         {
     630        2603 :             FOR( i = 0; i < md_buffer_length; i++ )
     631             :             {
     632        2190 :                 IF( hSpatParamRendCom->azimuth2[i] != NULL )
     633             :                 {
     634        2190 :                     free( hSpatParamRendCom->azimuth2[i] );
     635        2190 :                     hSpatParamRendCom->azimuth2[i] = NULL;
     636             :                 }
     637             :             }
     638         413 :             free( hSpatParamRendCom->azimuth2 );
     639         413 :             hSpatParamRendCom->azimuth2 = NULL;
     640             :         }
     641             : 
     642         757 :         IF( hSpatParamRendCom->elevation2 != NULL )
     643             :         {
     644        2603 :             FOR( i = 0; i < md_buffer_length; i++ )
     645             :             {
     646        2190 :                 IF( hSpatParamRendCom->elevation2[i] != NULL )
     647             :                 {
     648        2190 :                     free( hSpatParamRendCom->elevation2[i] );
     649        2190 :                     hSpatParamRendCom->elevation2[i] = NULL;
     650             :                 }
     651             :             }
     652         413 :             free( hSpatParamRendCom->elevation2 );
     653         413 :             hSpatParamRendCom->elevation2 = NULL;
     654             :         }
     655             : 
     656         757 :         IF( hSpatParamRendCom->energy_ratio2_fx != NULL )
     657             :         {
     658        2603 :             FOR( i = 0; i < md_buffer_length; i++ )
     659             :             {
     660        2190 :                 IF( hSpatParamRendCom->energy_ratio2_fx[i] != NULL )
     661             :                 {
     662        2190 :                     free( hSpatParamRendCom->energy_ratio2_fx[i] );
     663        2190 :                     hSpatParamRendCom->energy_ratio2_fx[i] = NULL;
     664             :                 }
     665             :             }
     666         413 :             free( hSpatParamRendCom->energy_ratio2_fx );
     667         413 :             hSpatParamRendCom->energy_ratio2_fx = NULL;
     668             :         }
     669             : 
     670         757 :         IF( hSpatParamRendCom->spreadCoherence2_fx != NULL )
     671             :         {
     672        2603 :             FOR( i = 0; i < md_buffer_length; i++ )
     673             :             {
     674        2190 :                 IF( hSpatParamRendCom->spreadCoherence2_fx[i] != NULL )
     675             :                 {
     676        2190 :                     free( hSpatParamRendCom->spreadCoherence2_fx[i] );
     677        2190 :                     hSpatParamRendCom->spreadCoherence2_fx[i] = NULL;
     678             :                 }
     679             :             }
     680         413 :             free( hSpatParamRendCom->spreadCoherence2_fx );
     681         413 :             hSpatParamRendCom->spreadCoherence2_fx = NULL;
     682             :         }
     683             :     }
     684             : 
     685        1433 :     return;
     686             : }
     687             : 
     688             : 
     689             : /*-------------------------------------------------------------------------
     690             :  * ivas_dirac_alloc_mem()
     691             :  *
     692             :  * Allocate stack memory for DirAC renderer
     693             :  *------------------------------------------------------------------------*/
     694             : 
     695        2280 : ivas_error ivas_dirac_alloc_mem_fx(
     696             :     DIRAC_REND_HANDLE hDirACRend,
     697             :     const RENDERER_TYPE renderer_type,
     698             :     const Word16 num_freq_bands,
     699             :     DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem,
     700             :     const Word16 hodirac_flag )
     701             : {
     702             :     Word16 num_freq_bands_diff, size;
     703             :     Word16 size_ho;
     704             :     Word16 size_pf;
     705             :     Word16 num_outputs_dir, num_outputs_diff;
     706             :     Word16 num_protos_dir;
     707             : 
     708        2280 :     num_protos_dir = hDirACRend->num_protos_dir;
     709        2280 :     move16();
     710             : 
     711        2280 :     num_freq_bands_diff = hDirACRend->h_output_synthesis_psd_params.max_band_decorr;
     712        2280 :     move16();
     713             : 
     714        2280 :     num_outputs_dir = hDirACRend->num_outputs_dir;
     715        2280 :     move16();
     716        2280 :     num_outputs_diff = hDirACRend->num_outputs_diff;
     717        2280 :     move16();
     718             : 
     719        2280 :     size = imult1616( num_freq_bands, num_outputs_dir );
     720        2280 :     IF( hodirac_flag )
     721             :     {
     722         112 :         size_ho = imult1616( size, DIRAC_HO_NUMSECTORS );
     723         112 :         size_pf = imult1616( num_freq_bands, DIRAC_HO_NUMSECTORS );
     724             :     }
     725             :     ELSE
     726             :     {
     727        2168 :         size_ho = size;
     728        2168 :         move16();
     729        2168 :         size_pf = num_freq_bands;
     730        2168 :         move16();
     731             :     }
     732             : 
     733             :     /* PSD related buffers */
     734        2280 :     hDirAC_mem->cy_auto_dir_smooth_fx = NULL;
     735        2280 :     hDirAC_mem->proto_power_smooth_fx = NULL;
     736        2280 :     hDirAC_mem->proto_power_diff_smooth_fx = NULL;
     737        2280 :     hDirAC_mem->direct_responses_square_fx = NULL;
     738        2280 :     hDirAC_mem->frame_dec_f_fx = NULL;
     739        2280 :     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     740             :     {
     741        1421 :         IF( ( hDirAC_mem->cy_auto_dir_smooth_fx = (Word32 *) malloc( sizeof( Word32 ) * size ) ) == NULL )
     742             :         {
     743           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     744             :         }
     745        1421 :         set_zero_fx( hDirAC_mem->cy_auto_dir_smooth_fx, size );
     746        1421 :         hDirACRend->h_output_synthesis_psd_state.cy_auto_dir_smooth_len = size;
     747        1421 :         move16();
     748             : 
     749        1421 :         IF( ( hDirAC_mem->proto_power_smooth_fx = (Word32 *) malloc( sizeof( Word32 ) * size ) ) == NULL )
     750             :         {
     751           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     752             :         }
     753        1421 :         set_zero_fx( hDirAC_mem->proto_power_smooth_fx, size );
     754        1421 :         hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len = size;
     755        1421 :         move16();
     756             : 
     757        1421 :         IF( ( hDirAC_mem->proto_power_diff_smooth_fx = (Word32 *) malloc( sizeof( Word32 ) * size ) ) == NULL )
     758             :         {
     759           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     760             :         }
     761        1421 :         set_zero_fx( hDirAC_mem->proto_power_diff_smooth_fx, size );
     762        1421 :         hDirAC_mem->proto_power_diff_smooth_len = size;
     763        1421 :         move16();
     764        1421 :         hDirAC_mem->proto_power_diff_smooth_q = Q31;
     765        1421 :         move16();
     766             : 
     767        1421 :         IF( ( hDirAC_mem->direct_responses_square_fx = (Word32 *) malloc( sizeof( Word32 ) * size ) ) == NULL )
     768             :         {
     769           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     770             :         }
     771        1421 :         set32_fx( hDirAC_mem->direct_responses_square_fx, 0, size );
     772        1421 :         test();
     773        1421 :         test();
     774        1421 :         test();
     775        1421 :         IF( hDirACRend->proto_signal_decorr_on && ( NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) ) )
     776             :         {
     777        1264 :             IF( ( hDirAC_mem->frame_dec_f_fx = (Word32 *) malloc( sizeof( Word32 ) * 2 * num_outputs_diff * num_freq_bands ) ) == NULL )
     778             :             {
     779           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     780             :             }
     781        1264 :             set_zero_fx( hDirAC_mem->frame_dec_f_fx, 2 * num_outputs_diff * num_freq_bands );
     782        1264 :             hDirAC_mem->frame_dec_f_len = imult1616( imult1616( 2, num_outputs_diff ), num_freq_bands );
     783             :         }
     784             :     }
     785        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx = hDirAC_mem->proto_power_smooth_fx;
     786        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = Q31;
     787        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = Q31;
     788        2280 :     move16();
     789        2280 :     move16();
     790        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = Q31;
     791        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = Q31;
     792        2280 :     move16();
     793        2280 :     move16();
     794        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx = hDirAC_mem->proto_power_diff_smooth_fx;
     795        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = hDirAC_mem->proto_power_diff_smooth_q;
     796        2280 :     move16();
     797        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len = hDirAC_mem->proto_power_diff_smooth_len;
     798        2280 :     move16();
     799        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = Q31;
     800        2280 :     move16();
     801        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = Q31;
     802        2280 :     move16();
     803        2280 :     hDirACRend->h_output_synthesis_psd_state.cy_auto_dir_smooth_fx = hDirAC_mem->cy_auto_dir_smooth_fx;
     804        2280 :     hDirACRend->h_output_synthesis_psd_state.q_cy_auto_dir_smooth = 0;
     805        2280 :     move16();
     806        2280 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx = hDirAC_mem->direct_responses_square_fx;
     807        2280 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = Q31;
     808        2280 :     move16();
     809        2280 :     move16();
     810             : 
     811             :     /* Target and smoothed nrg factors/gains */
     812        2280 :     IF( ( hDirAC_mem->cy_cross_dir_smooth_fx = (Word32 *) malloc( sizeof( Word32 ) * size_ho ) ) == NULL )
     813             :     {
     814           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     815             :     }
     816        2280 :     hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_len = size_ho;
     817        2280 :     move16();
     818        2280 :     set_zero_fx( hDirAC_mem->cy_cross_dir_smooth_fx, size_ho );
     819             : 
     820        2280 :     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     821             :     {
     822        1421 :         IF( ( hDirAC_mem->cy_auto_diff_smooth_fx = (Word32 *) malloc( sizeof( Word32 ) * size ) ) == NULL )
     823             :         {
     824           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     825             :         }
     826        1421 :         set_zero_fx( hDirAC_mem->cy_auto_diff_smooth_fx, size );
     827        1421 :         hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_len = size;
     828        1421 :         move16();
     829             :     }
     830             :     ELSE
     831             :     {
     832         859 :         IF( ( hDirAC_mem->cy_auto_diff_smooth_fx = (Word32 *) malloc( sizeof( Word32 ) * num_outputs_diff * num_freq_bands_diff ) ) == NULL )
     833             :         {
     834           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     835             :         }
     836         859 :         set_zero_fx( hDirAC_mem->cy_auto_diff_smooth_fx, imult1616( num_outputs_diff, num_freq_bands_diff ) );
     837         859 :         hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_len = imult1616( num_outputs_diff, num_freq_bands_diff );
     838             :     }
     839        2280 :     hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_fx = hDirAC_mem->cy_cross_dir_smooth_fx;
     840        2280 :     hDirACRend->h_output_synthesis_psd_state.q_cy_cross_dir_smooth = 31;
     841        2280 :     move16();
     842        2280 :     hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_fx = hDirAC_mem->cy_auto_diff_smooth_fx;
     843        2280 :     hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth = 0;
     844        2280 :     move16();
     845             : 
     846             :     /*Responses (gains/factors)*/
     847        2280 :     IF( ( hDirAC_mem->direct_responses_fx = (Word32 *) malloc( sizeof( Word32 ) * size_ho ) ) == NULL )
     848             :     {
     849           0 :         return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     850             :     }
     851        2280 :     set32_fx( hDirAC_mem->direct_responses_fx, 0, size );
     852             : 
     853             : 
     854        2280 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_fx = hDirAC_mem->direct_responses_fx;
     855        2280 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_q = Q31;
     856        2280 :     move16();
     857             : 
     858             :     /* Prototypes */
     859        2280 :     hDirAC_mem->proto_direct_buffer_f_fx = NULL;
     860        2280 :     hDirAC_mem->proto_diffuse_buffer_f_fx = NULL;
     861        2280 :     test();
     862        2280 :     test();
     863        2280 :     IF( NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) )
     864             :     {
     865        2280 :         IF( ( hDirAC_mem->proto_direct_buffer_f_fx = (Word32 *) malloc( sizeof( Word32 ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * num_protos_dir * num_freq_bands ) ) == NULL )
     866             :         {
     867           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     868             :         }
     869        2280 :         hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_protos_dir ), num_freq_bands );
     870        2280 :         set_zero_fx( hDirAC_mem->proto_direct_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len );
     871        2280 :         move16();
     872        2280 :         hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = Q31;
     873        2280 :         move16();
     874             : 
     875        2280 :         IF( hDirACRend->proto_signal_decorr_on )
     876             :         {
     877        2123 :             IF( EQ_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
     878             :             {
     879         414 :                 IF( ( hDirAC_mem->proto_diffuse_buffer_f_fx = (Word32 *) malloc( sizeof( Word32 ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * size ) ) == NULL )
     880             :                 {
     881           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     882             :                 }
     883         414 :                 hDirAC_mem->proto_diffuse_buffer_f_len = imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, size );
     884         414 :                 move16();
     885             :             }
     886             :             ELSE
     887             :             {
     888        1709 :                 IF( ( hDirAC_mem->proto_diffuse_buffer_f_fx = (Word32 *) malloc( sizeof( Word32 ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * num_outputs_diff * num_freq_bands ) ) == NULL )
     889             :                 {
     890           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     891             :                 }
     892        1709 :                 hDirAC_mem->proto_diffuse_buffer_f_len = imult1616( imult1616( 2 * MAX_PARAM_SPATIAL_SUBFRAMES, num_outputs_diff ), num_freq_bands );
     893             :             }
     894        2123 :             set_zero_fx( hDirAC_mem->proto_diffuse_buffer_f_fx, hDirAC_mem->proto_diffuse_buffer_f_len );
     895             :         }
     896             :     }
     897        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx = hDirAC_mem->proto_direct_buffer_f_fx;
     898        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx = hDirAC_mem->proto_diffuse_buffer_f_fx;
     899        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len = hDirAC_mem->proto_diffuse_buffer_f_len;
     900        2280 :     move16();
     901        2280 :     hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q = Q31;
     902        2280 :     move16();
     903             : 
     904             :     /* Gains/power factors*/
     905        2280 :     hDirAC_mem->direct_power_factor_fx = NULL;
     906        2280 :     hDirAC_mem->diffuse_power_factor_fx = NULL;
     907             : 
     908        2280 :     test();
     909        2280 :     test();
     910        2280 :     IF( NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) )
     911             :     {
     912        2280 :         IF( ( hDirAC_mem->direct_power_factor_fx = (Word32 *) malloc( sizeof( Word32 ) * size_pf ) ) == NULL )
     913             :         {
     914           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     915             :         }
     916        2280 :         IF( ( hDirAC_mem->diffuse_power_factor_fx = (Word32 *) malloc( sizeof( Word32 ) * size_pf ) ) == NULL )
     917             :         {
     918           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     919             :         }
     920             :     }
     921             : 
     922        2280 :     hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx = hDirAC_mem->direct_power_factor_fx;
     923        2280 :     hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx = hDirAC_mem->diffuse_power_factor_fx;
     924        2280 :     hDirACRend->h_output_synthesis_psd_state.diff_dir_power_factor_len = size_pf;
     925        2280 :     set_zero_fx( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx, size_pf );
     926        2280 :     set_zero_fx( hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx, size_pf );
     927        2280 :     hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q = Q31;
     928        2280 :     move16();
     929        2280 :     hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q = Q31;
     930        2280 :     move16();
     931             : 
     932        2280 :     hDirAC_mem->reference_power_fx = NULL;
     933        2280 :     hDirAC_mem->onset_filter_fx = NULL;
     934        2280 :     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
     935             :     {
     936        1421 :         test();
     937        1421 :         test();
     938        1421 :         IF( NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC ) && NE_32( renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) && NE_32( renderer_type, RENDERER_STEREO_PARAMETRIC ) )
     939             :         {
     940        1421 :             IF( ( hDirAC_mem->reference_power_fx = (Word32 *) malloc( sizeof( Word32 ) * 2 * num_freq_bands ) ) == NULL )
     941             :             {
     942           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     943             :             }
     944             : 
     945        1421 :             hDirAC_mem->reference_power_len = imult1616( 2, num_freq_bands );
     946        1421 :             move16();
     947        1421 :             hDirAC_mem->reference_power_q[0] = Q31;
     948        1421 :             hDirAC_mem->reference_power_q[1] = Q31;
     949        1421 :             move16();
     950        1421 :             move16();
     951        1421 :             hDirAC_mem->reference_power_smooth_q[0] = Q31;
     952        1421 :             hDirAC_mem->reference_power_smooth_q[1] = Q31;
     953        1421 :             move16();
     954        1421 :             move16();
     955        1421 :             IF( hDirACRend->proto_signal_decorr_on )
     956             :             {
     957        1264 :                 IF( ( hDirAC_mem->onset_filter_fx = (Word32 *) malloc( sizeof( Word32 ) * num_outputs_diff * num_freq_bands ) ) == NULL )
     958             :                 {
     959           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     960             :                 }
     961        1264 :                 set_zero_fx( hDirAC_mem->onset_filter_fx, imult1616( num_outputs_diff, num_freq_bands ) );
     962             :             }
     963             :         }
     964             :     }
     965             :     ELSE
     966             :     {
     967         859 :         IF( GT_16( num_protos_dir, 2 ) )
     968             :         {
     969         850 :             IF( ( hDirAC_mem->reference_power_fx = (Word32 *) malloc( sizeof( Word32 ) * 5 * num_freq_bands ) ) == NULL )
     970             :             {
     971           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     972             :             }
     973             : 
     974         850 :             hDirAC_mem->reference_power_len = imult1616( 5, num_freq_bands );
     975         850 :             set16_fx( hDirAC_mem->reference_power_q, Q31, 2 );
     976             :         }
     977             : 
     978         859 :         IF( hDirACRend->proto_signal_decorr_on )
     979             :         {
     980         859 :             IF( ( hDirAC_mem->onset_filter_fx = (Word32 *) malloc( sizeof( Word32 ) * 2 * num_freq_bands ) ) == NULL )
     981             :             {
     982           0 :                 return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
     983             :             }
     984         859 :             set_zero_fx( hDirAC_mem->onset_filter_fx, imult1616( 2, num_freq_bands ) );
     985             :         }
     986             :     }
     987             : 
     988        2280 :     return IVAS_ERR_OK;
     989             : }
     990             : 
     991             : 
     992             : /*-------------------------------------------------------------------------
     993             :  * ivas_dirac_free_mem()
     994             :  *
     995             :  *
     996             :  *-------------------------------------------------------------------------*/
     997             : 
     998        2280 : void ivas_dirac_free_mem_fx(
     999             :     DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem )
    1000             : {
    1001        2280 :     IF( hDirAC_mem->cy_auto_dir_smooth_fx != NULL )
    1002             :     {
    1003        1421 :         free( hDirAC_mem->cy_auto_dir_smooth_fx );
    1004             :     }
    1005        2280 :     IF( hDirAC_mem->proto_power_smooth_fx != NULL )
    1006             :     {
    1007        1421 :         free( hDirAC_mem->proto_power_smooth_fx );
    1008             :     }
    1009        2280 :     IF( hDirAC_mem->proto_power_diff_smooth_fx != NULL )
    1010             :     {
    1011        1421 :         free( hDirAC_mem->proto_power_diff_smooth_fx );
    1012             :     }
    1013        2280 :     IF( hDirAC_mem->direct_responses_square_fx != NULL )
    1014             :     {
    1015        1421 :         free( hDirAC_mem->direct_responses_square_fx );
    1016             :     }
    1017        2280 :     IF( hDirAC_mem->frame_dec_f_fx != NULL )
    1018             :     {
    1019        1264 :         free( hDirAC_mem->frame_dec_f_fx );
    1020             :     }
    1021        2280 :     IF( hDirAC_mem->cy_cross_dir_smooth_fx != NULL )
    1022             :     {
    1023        2280 :         free( hDirAC_mem->cy_cross_dir_smooth_fx );
    1024             :     }
    1025        2280 :     IF( hDirAC_mem->cy_auto_diff_smooth_fx != NULL )
    1026             :     {
    1027        2280 :         free( hDirAC_mem->cy_auto_diff_smooth_fx );
    1028             :     }
    1029        2280 :     IF( hDirAC_mem->direct_responses_fx != NULL )
    1030             :     {
    1031        2280 :         free( hDirAC_mem->direct_responses_fx );
    1032             :     }
    1033        2280 :     IF( hDirAC_mem->proto_direct_buffer_f_fx != NULL )
    1034             :     {
    1035        2280 :         free( hDirAC_mem->proto_direct_buffer_f_fx );
    1036             :     }
    1037        2280 :     IF( hDirAC_mem->proto_diffuse_buffer_f_fx != NULL )
    1038             :     {
    1039        2123 :         free( hDirAC_mem->proto_diffuse_buffer_f_fx );
    1040             :     }
    1041        2280 :     IF( hDirAC_mem->direct_power_factor_fx != NULL )
    1042             :     {
    1043        2280 :         free( hDirAC_mem->direct_power_factor_fx );
    1044             :     }
    1045        2280 :     IF( hDirAC_mem->diffuse_power_factor_fx != NULL )
    1046             :     {
    1047        2280 :         free( hDirAC_mem->diffuse_power_factor_fx );
    1048             :     }
    1049        2280 :     IF( hDirAC_mem->reference_power_fx != NULL )
    1050             :     {
    1051        2271 :         free( hDirAC_mem->reference_power_fx );
    1052             :     }
    1053        2280 :     IF( hDirAC_mem->onset_filter_fx != NULL )
    1054             :     {
    1055        2123 :         free( hDirAC_mem->onset_filter_fx );
    1056             :     }
    1057             : 
    1058        2280 :     return;
    1059             : }
    1060             : 
    1061             : 
    1062             : /*-------------------------------------------------------------------------
    1063             :  * compute_hoa_encoder_mtx()
    1064             :  *
    1065             :  *
    1066             :  *------------------------------------------------------------------------*/
    1067             : 
    1068         430 : void compute_hoa_encoder_mtx_fx(
    1069             :     const Word32 *azimuth,   /*q22*/
    1070             :     const Word32 *elevation, /*q22*/
    1071             :     Word32 *response_fx,     /*q31*/
    1072             :     const Word16 num_responses,
    1073             :     const Word16 ambisonics_order )
    1074             : {
    1075             :     Word16 k, num_sh;
    1076             : 
    1077         430 :     num_sh = ivas_sba_get_nchan_fx( ambisonics_order, 0 );
    1078        3856 :     FOR( k = 0; k < num_responses; k++ )
    1079             :     {
    1080        3426 :         ivas_dirac_dec_get_response_fx( shr( extract_h( azimuth[k] ), Q22 - Q16 ), shr( extract_h( elevation[k] ), Q22 - Q16 ), &response_fx[k * num_sh], ambisonics_order, Q31 ); /* Q31 */
    1081             :     }
    1082             : 
    1083         430 :     return;
    1084             : }
    1085             : 
    1086             : 
    1087             : /*-------------------------------------------------------------------------
    1088             :  * ivas_dirac_dec_get_frequency_axis()
    1089             :  *
    1090             :  * DirAC decoding initialization
    1091             :  *------------------------------------------------------------------------*/
    1092             : 
    1093        1641 : void ivas_dirac_dec_get_frequency_axis_fx(
    1094             :     Word16 *frequency_axis, /* Q0 */
    1095             :     const Word32 output_Fs,
    1096             :     const Word16 num_freq_bands )
    1097             : {
    1098             :     Word16 k, const_part, scale;
    1099             :     /* calc cldfb frequency axis */
    1100             : 
    1101        1641 :     const_part = BASOP_Util_Divide3216_Scale( output_Fs, shl( num_freq_bands, 1 ), &scale ); // 15-(scale+31-15)=>-1-scale
    1102        1641 :     const_part = shr( const_part, sub( -1, scale ) );                                        // q(-1-scale)->q0
    1103       83021 :     FOR( k = 0; k < num_freq_bands; k++ )
    1104             :     {
    1105             :         /* frequency_axis[k] = ((float)k + 0.5f) * const_part; */
    1106       81380 :         frequency_axis[k] = add( i_mult( k, const_part ), shr( const_part, 1 ) ); /*q0*/
    1107       81380 :         move16();
    1108             :     }
    1109             : 
    1110        1641 :     return;
    1111             : }
    1112             : 
    1113             : 
    1114             : /*-------------------------------------------------------------------------
    1115             :  * initDiffuseResponses()
    1116             :  *
    1117             :  *
    1118             :  *-------------------------------------------------------------------------*/
    1119             : 
    1120        2280 : void initDiffuseResponses_fx(
    1121             :     Word16 *diffuse_response_function_fx, /*q15*/
    1122             :     const Word16 num_channels,
    1123             :     const AUDIO_CONFIG output_config,
    1124             :     const IVAS_OUTPUT_SETUP hOutSetup,
    1125             :     const Word16 ambisonics_order,
    1126             :     const IVAS_FORMAT ivas_format,
    1127             :     Word16 *num_ele_spk_no_diffuse_rendering,
    1128             :     const AUDIO_CONFIG transport_config )
    1129             : {
    1130             :     Word16 i, l, k, idx, num_horizontal_speakers;
    1131        2280 :     *num_ele_spk_no_diffuse_rendering = 0;
    1132             : 
    1133             :     Word16 var1, exp_var1, res;
    1134             : 
    1135        2280 :     test();
    1136        2280 :     test();
    1137        2280 :     IF( EQ_32( output_config, IVAS_AUDIO_CONFIG_MONO ) )
    1138             :     {
    1139         111 :         diffuse_response_function_fx[0] = MAX16B; /*1 q15*/
    1140         111 :         move16();
    1141         111 :         diffuse_response_function_fx[1] = 18918 /*inv_sqrt(3.0f) oin Q15*/;
    1142         111 :         move16();
    1143             :     }
    1144        2169 :     ELSE IF( !( EQ_32( output_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( output_config, IVAS_AUDIO_CONFIG_HOA3 ) ) )
    1145             :     {
    1146             :         /* set diffuse response function */
    1147         896 :         test();
    1148         896 :         test();
    1149         896 :         test();
    1150         896 :         test();
    1151         896 :         test();
    1152         896 :         test();
    1153         896 :         test();
    1154         896 :         test();
    1155         896 :         test();
    1156         896 :         test();
    1157         896 :         test();
    1158         896 :         test();
    1159         896 :         test();
    1160         896 :         test();
    1161         896 :         test();
    1162         896 :         test();
    1163         896 :         test();
    1164         896 :         test();
    1165         896 :         test();
    1166         896 :         test();
    1167         896 :         test();
    1168         896 :         IF( EQ_32( ivas_format, MC_FORMAT ) && ( EQ_32( transport_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( transport_config, IVAS_AUDIO_CONFIG_7_1 ) ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) )
    1169             :         {
    1170           0 :             num_horizontal_speakers = sub( num_channels, NUM_ELEVATED_SPEAKERS );
    1171           0 :             Copy( diffuse_response_CICP6_fx, diffuse_response_function_fx, num_horizontal_speakers ); // q15
    1172           0 :             set16_fx( &diffuse_response_function_fx[num_horizontal_speakers], 0, NUM_ELEVATED_SPEAKERS );
    1173           0 :             *num_ele_spk_no_diffuse_rendering = NUM_ELEVATED_SPEAKERS;
    1174           0 :             move16();
    1175             :         }
    1176         896 :         ELSE IF( EQ_32( ivas_format, MC_FORMAT ) && ( EQ_32( transport_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( transport_config, IVAS_AUDIO_CONFIG_7_1 ) ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_7_1_4 ) )
    1177             :         {
    1178          79 :             num_horizontal_speakers = sub( num_channels, NUM_ELEVATED_SPEAKERS );
    1179          79 :             exp_var1 = 15;
    1180          79 :             move16();
    1181          79 :             var1 = ISqrt16( num_horizontal_speakers, &exp_var1 );                    // q=15-exp_var1
    1182          79 :             var1 = shr( var1, negate( exp_var1 ) );                                  // Q15
    1183          79 :             set16_fx( diffuse_response_function_fx, var1, num_horizontal_speakers ); // q15
    1184          79 :             set16_fx( &diffuse_response_function_fx[num_horizontal_speakers], 0, NUM_ELEVATED_SPEAKERS );
    1185          79 :             *num_ele_spk_no_diffuse_rendering = NUM_ELEVATED_SPEAKERS;
    1186          79 :             move16();
    1187             :         }
    1188         817 :         ELSE IF( ( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) || EQ_32( ivas_format, MC_FORMAT ) ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1 ) && EQ_16( num_channels, 5 ) )
    1189             :         {
    1190         101 :             Copy( diffuse_response_CICP6_fx, diffuse_response_function_fx, num_channels ); // q15
    1191             :         }
    1192         716 :         ELSE IF( ( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) || EQ_32( ivas_format, MC_FORMAT ) ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_2 ) && EQ_16( num_channels, 7 ) )
    1193             :         {
    1194         202 :             Copy( diffuse_response_CICP14_fx, diffuse_response_function_fx, num_channels ); // q15
    1195             :         }
    1196         514 :         ELSE IF( ( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) || EQ_32( ivas_format, MC_FORMAT ) ) && ( EQ_32( output_config, IVAS_AUDIO_CONFIG_5_1_4 ) ) && EQ_16( num_channels, 9 ) )
    1197             :         {
    1198         220 :             Copy( diffuse_response_CICP16_fx, diffuse_response_function_fx, num_channels ); // q15
    1199             :         }
    1200         294 :         ELSE IF( ( EQ_32( ivas_format, MASA_FORMAT ) || EQ_32( ivas_format, MASA_ISM_FORMAT ) || EQ_32( ivas_format, MC_FORMAT ) ) && EQ_32( output_config, IVAS_AUDIO_CONFIG_LS_CUSTOM ) )
    1201             :         {
    1202           0 :             IF( EQ_32( transport_config, IVAS_AUDIO_CONFIG_5_1 ) || EQ_32( transport_config, IVAS_AUDIO_CONFIG_7_1 ) )
    1203             :             {
    1204             :                 /* Detect loudspeakers with elevation */
    1205           0 :                 num_horizontal_speakers = 0;
    1206           0 :                 move16();
    1207           0 :                 FOR( i = 0; i < num_channels; i++ )
    1208             :                 {
    1209           0 :                     IF( LE_32( L_abs( hOutSetup.ls_elevation_fx[i] /*q22*/ ), 20971520 /*5 in Q22*/ ) )
    1210             :                     {
    1211           0 :                         num_horizontal_speakers = add( num_horizontal_speakers, 1 );
    1212           0 :                         diffuse_response_function_fx[i] = MAX16B; // q15
    1213           0 :                         move16();
    1214             :                     }
    1215             :                     ELSE
    1216             :                     {
    1217           0 :                         *num_ele_spk_no_diffuse_rendering = add( *num_ele_spk_no_diffuse_rendering, 1 );
    1218           0 :                         move16();
    1219           0 :                         diffuse_response_function_fx[i] = 0;
    1220           0 :                         move16();
    1221             :                     }
    1222             :                 }
    1223             :                 /* Diffuse only to horizontal plane IF enough loudspeakers */
    1224           0 :                 IF( GT_16( num_horizontal_speakers, 2 ) )
    1225             :                 {
    1226           0 :                     exp_var1 = 15;
    1227           0 :                     move16();
    1228           0 :                     Word16 num_horizontal_speakers_isq = ISqrt16( num_horizontal_speakers, &exp_var1 );   // q15-exp_var1
    1229           0 :                     num_horizontal_speakers_isq = shr( num_horizontal_speakers_isq, negate( exp_var1 ) ); // q15
    1230           0 :                     assert( 0 );
    1231             :                     /*No stream hitting*/
    1232             :                     FOR( i = 0; i < num_channels; i++ )
    1233             :                     {
    1234             :                         diffuse_response_function_fx[i] = mult( diffuse_response_function_fx[i], num_horizontal_speakers_isq ); // q15
    1235             :                         move16();
    1236             :                     }
    1237             :                 }
    1238             :                 ELSE
    1239             :                 {
    1240           0 :                     var1 = num_channels, exp_var1 = 15;
    1241           0 :                     move16();
    1242           0 :                     move16();
    1243           0 :                     res = ISqrt16( var1, &exp_var1 );                            // q=15-exp_var1
    1244           0 :                     res = shr( res, negate( exp_var1 ) );                        // q=15
    1245           0 :                     set16_fx( diffuse_response_function_fx, res, num_channels ); // q15
    1246           0 :                     *num_ele_spk_no_diffuse_rendering = 0;
    1247           0 :                     move16();
    1248             :                 }
    1249             :             }
    1250             :             ELSE
    1251             :             {
    1252           0 :                 var1 = num_channels, exp_var1 = 15;
    1253           0 :                 move16();
    1254           0 :                 move16();
    1255           0 :                 res = ISqrt16( var1, &exp_var1 );                            // q=15-exp_var1
    1256           0 :                 res = shr( res, negate( exp_var1 ) );                        // q15
    1257           0 :                 set16_fx( diffuse_response_function_fx, res, num_channels ); // q15
    1258             :             }
    1259             :         }
    1260             :         ELSE
    1261             :         {
    1262         294 :             var1 = num_channels, exp_var1 = 15;
    1263         294 :             move16();
    1264         294 :             move16();
    1265         294 :             res = ISqrt16( var1, &exp_var1 );                            // q(15-exp_var1)
    1266         294 :             res = shr( res, negate( exp_var1 ) );                        // q15
    1267         294 :             set16_fx( diffuse_response_function_fx, res, num_channels ); // q15
    1268             :         }
    1269             :     }
    1270             :     ELSE
    1271             :     {
    1272        1273 :         idx = 0;
    1273        1273 :         move16();
    1274             :         Word16 j;
    1275        5627 :         FOR( l = 0; l <= ambisonics_order; l++ )
    1276             :         {
    1277        4354 :             j = add( imult1616( 2, l ), 1 );
    1278       20170 :             FOR( k = 0; k < j; k++ )
    1279             :             {
    1280       15816 :                 var1 = j, exp_var1 = 15;
    1281       15816 :                 move16();
    1282       15816 :                 move16();
    1283       15816 :                 res = ISqrt16( var1, &exp_var1 );                                   // q(15-exp_var1)
    1284       15816 :                 diffuse_response_function_fx[idx] = shr( res, negate( exp_var1 ) ); // q15
    1285       15816 :                 idx = idx + 1;
    1286             :             }
    1287             :         }
    1288             :     }
    1289             : 
    1290        2280 :     return;
    1291             : }
    1292             : 
    1293             : 
    1294             : /*-------------------------------------------------------------------------
    1295             :  * protoSignalComputation_shd()
    1296             :  *
    1297             :  *
    1298             :  *-------------------------------------------------------------------------*/
    1299             : 
    1300      951931 : void protoSignalComputation_shd_fx(
    1301             :     Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*Q(q_cldfb)*/
    1302             :     Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*Q(q_cldfb)*/
    1303             :     Word32 *proto_direct_buffer_f_fx,                                           /*Q(proto_direct_buffer_f_q)*/
    1304             :     Word16 *proto_direct_buffer_f_q,
    1305             :     Word32 *proto_diffuse_buffer_f_fx, /*Q(proto_diffuse_buffer_f_q)*/
    1306             :     Word16 *proto_diffuse_buffer_f_q,
    1307             :     Word32 *reference_power_fx, /*Q(reference_power_q)*/
    1308             :     Word16 *reference_power_q,
    1309             :     const Word16 slot_index,
    1310             :     const Word16 num_inputs,
    1311             :     const Word16 num_outputs_diff,
    1312             :     const Word16 num_freq_bands,
    1313             :     Word32 *p_Rmat_fx, /* Q30 */
    1314             :     Word16 q_cldfb )
    1315             : {
    1316             :     Word16 l, k;
    1317             :     Word16 Rmat_k[4];
    1318             :     Word32 *p_proto_direct_buffer_fx;
    1319             :     Word32 *p_proto_diffuse_buffer_fx;
    1320             :     Word32 re1, im1;
    1321             :     Word32 re2, im2;
    1322             :     Word32 re3, im3;
    1323             :     Word32 *p_k_fx[4];
    1324             :     Word16 min_q_shift, q_shift;
    1325             :     Word16 idx, idx1;
    1326             : 
    1327      951931 :     k = 0; /* to avoid compilation warning */
    1328      951931 :     move16();
    1329             : 
    1330      951931 :     min_q_shift = Q31;
    1331      951931 :     move16();
    1332      951931 :     q_shift = Q31;
    1333      951931 :     move16();
    1334             : 
    1335      951931 :     p_proto_direct_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( slot_index, 2 ), i_mult( num_freq_bands, num_inputs ) );         /*proto_direct_buffer_f_q*/
    1336      951931 :     p_proto_diffuse_buffer_fx = proto_diffuse_buffer_f_fx + i_mult( i_mult( slot_index, 2 ), i_mult( num_freq_bands, num_outputs_diff ) ); /*proto_diffuse_buffer_f_q*/
    1337             : 
    1338      951931 :     IF( EQ_16( num_inputs, 1 ) )
    1339             :     {
    1340     2989244 :         FOR( l = 0; l < num_freq_bands; l++ )
    1341             :         {
    1342     2940240 :             p_proto_direct_buffer_fx[2 * l] = RealBuffer_fx[0][0][l]; /*Q(q_cldfb)*/
    1343     2940240 :             move32();
    1344     2940240 :             p_proto_direct_buffer_fx[2 * l + 1] = ImagBuffer_fx[0][0][l]; /*Q(q_cldfb)*/
    1345     2940240 :             move32();
    1346             :         }
    1347       49004 :         *proto_direct_buffer_f_q = q_cldfb;
    1348       49004 :         move16();
    1349             :     }
    1350      902927 :     ELSE IF( EQ_16( num_inputs, 2 ) )
    1351             :     {
    1352           0 :         IF( p_Rmat_fx != 0 )
    1353             :         {
    1354           0 :             assert( EQ_16( num_inputs, 4 ) && "This code block should never be run with num_inputs != 4!" );
    1355             : 
    1356           0 :             FOR( l = 0; l < num_freq_bands; l++ )
    1357             :             {
    1358           0 :                 re1 = L_add( RealBuffer_fx[0][0][l], RealBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1359           0 :                 im1 = L_add( ImagBuffer_fx[0][0][l], ImagBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1360             : 
    1361           0 :                 re2 = L_sub( RealBuffer_fx[0][0][l], RealBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1362           0 :                 im2 = L_sub( ImagBuffer_fx[0][0][l], ImagBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1363             : 
    1364           0 :                 p_proto_direct_buffer_fx[2 * l] = re1; /*Q(q_cldfb)*/
    1365           0 :                 move32();
    1366           0 :                 p_proto_direct_buffer_fx[2 * l + 1] = im1; /*Q(q_cldfb)*/
    1367           0 :                 move32();
    1368           0 :                 p_proto_direct_buffer_fx[2 * ( num_freq_bands + l )] = L_shl( Mpy_32_32( p_Rmat_fx[0], re2 ), Q1 ); // left shift is done to maintain constant Q factor for p_proto_direct_buffer_fx =>Q(q_cldfb)
    1369           0 :                 move32();
    1370           0 :                 p_proto_direct_buffer_fx[2 * ( num_freq_bands + l ) + 1] = L_shl( Mpy_32_32( p_Rmat_fx[0], im2 ), Q1 ); // left shift is done to maintain constant Q factor for p_proto_direct_buffer_fx => Q(q_cldfb)
    1371           0 :                 move32();
    1372             :             }
    1373           0 :             *proto_direct_buffer_f_q = q_cldfb;
    1374           0 :             move16();
    1375             :         }
    1376             :         ELSE
    1377             :         {
    1378           0 :             FOR( l = 0; l < num_freq_bands; l++ )
    1379             :             {
    1380           0 :                 re1 = L_add( RealBuffer_fx[0][0][l], RealBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1381           0 :                 im1 = L_add( ImagBuffer_fx[0][0][l], ImagBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1382             : 
    1383           0 :                 p_proto_direct_buffer_fx[2 * l] = re1; /*Q(q_cldfb)*/
    1384           0 :                 move32();
    1385           0 :                 p_proto_direct_buffer_fx[2 * l + 1] = im1; /*Q(q_cldfb)*/
    1386           0 :                 move32();
    1387           0 :                 p_proto_direct_buffer_fx[2 * num_freq_bands + 2 * l] = L_sub( RealBuffer_fx[0][0][l], RealBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1388           0 :                 move32();
    1389           0 :                 p_proto_direct_buffer_fx[2 * num_freq_bands + 2 * l + 1] = L_sub( ImagBuffer_fx[0][0][l], ImagBuffer_fx[1][0][l] ); /*Q(q_cldfb)*/
    1390           0 :                 move32();
    1391             :             }
    1392             :         }
    1393           0 :         *proto_direct_buffer_f_q = q_cldfb;
    1394           0 :         move16();
    1395             :     }
    1396      902927 :     ELSE IF( GE_16( num_inputs, 4 ) )
    1397             :     {
    1398      902927 :         p_k_fx[0] = p_proto_direct_buffer_fx;                               /*Q(proto_direct_buffer_f_q)*/
    1399      902927 :         p_k_fx[1] = p_proto_direct_buffer_fx + i_mult( 2, num_freq_bands ); /*Q(proto_direct_buffer_f_q)*/
    1400      902927 :         p_k_fx[2] = p_proto_direct_buffer_fx + i_mult( 4, num_freq_bands ); /*Q(proto_direct_buffer_f_q)*/
    1401      902927 :         p_k_fx[3] = p_proto_direct_buffer_fx + i_mult( 6, num_freq_bands ); /*Q(proto_direct_buffer_f_q)*/
    1402             : 
    1403      902927 :         Rmat_k[0] = 0;
    1404      902927 :         move16();
    1405      902927 :         Rmat_k[1] = 1;
    1406      902927 :         move16();
    1407      902927 :         Rmat_k[2] = 2;
    1408      902927 :         move16();
    1409      902927 :         Rmat_k[3] = 0;
    1410      902927 :         move16();
    1411             : 
    1412             :         /* calculate the minimum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */
    1413     4514635 :         FOR( k = 0; k < 4; k++ )
    1414             :         {
    1415     3611708 :             q_shift = L_norm_arr( RealBuffer_fx[k][0], num_freq_bands );
    1416     3611708 :             min_q_shift = s_min( min_q_shift, q_shift );
    1417     3611708 :             q_shift = L_norm_arr( ImagBuffer_fx[k][0], num_freq_bands );
    1418     3611708 :             min_q_shift = s_min( min_q_shift, q_shift );
    1419             :         }
    1420             : 
    1421      902927 :         min_q_shift = sub( min_q_shift, 4 ); /* 4 is for guard bits*/
    1422             : 
    1423      902927 :         IF( p_Rmat_fx != 0 )
    1424             :         {
    1425      147200 :             assert( EQ_16( num_inputs, 4 ) && "This code block should never be run with num_inputs != 4!" );
    1426             : 
    1427     5779200 :             FOR( l = 0; l < num_freq_bands; l++ )
    1428             :             {
    1429     5632000 :                 *p_k_fx[0] = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1430     5632000 :                 move32();
    1431     5632000 :                 reference_power_fx[l + num_freq_bands] = Mpy_32_32( *p_k_fx[0], *p_k_fx[0] ); /*2*Q(q_cldfb+min_q_shift)-31*/
    1432     5632000 :                 move32();
    1433     5632000 :                 p_k_fx[0]++;
    1434             : 
    1435     5632000 :                 *p_k_fx[0] = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1436     5632000 :                 move32();
    1437     5632000 :                 reference_power_fx[l + num_freq_bands] = Madd_32_32( reference_power_fx[l + num_freq_bands], *p_k_fx[0], *p_k_fx[0] ); /*2*Q(q_cldfb+min_q_shift)-31*/
    1438     5632000 :                 move32();
    1439     5632000 :                 p_k_fx[0]++;
    1440             : 
    1441     5632000 :                 reference_power_fx[l] = L_shr( reference_power_fx[l + num_freq_bands], 1 ); /*2*Q(q_cldfb+min_q_shift)-31-1*/
    1442     5632000 :                 move32();
    1443             : 
    1444     5632000 :                 re1 = L_shl( RealBuffer_fx[1][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1445     5632000 :                 re2 = L_shl( RealBuffer_fx[2][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1446     5632000 :                 re3 = L_shl( RealBuffer_fx[3][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1447     5632000 :                 im1 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1448     5632000 :                 im2 = L_shl( ImagBuffer_fx[2][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1449     5632000 :                 im3 = L_shl( ImagBuffer_fx[3][0][l], min_q_shift ); /*Q(q_cldfb+min_q_shift)*/
    1450             : 
    1451    22528000 :                 FOR( k = 1; k < 4; k++ )
    1452             :                 {
    1453    16896000 :                     idx = i_mult( 3, Rmat_k[k] );
    1454    16896000 :                     idx1 = add( l, i_mult( add( k, 1 ), num_freq_bands ) );
    1455             : 
    1456    16896000 :                     *p_k_fx[k] = Madd_32_32( Madd_32_32( Mpy_32_32( p_Rmat_fx[idx + 1], re1 ), p_Rmat_fx[idx + 2], re2 ), p_Rmat_fx[idx], re3 ); /*Q(30 + q_cldfb+min_q_shift-31)=>Q(q_cldfb+min_q_shift-1)*/
    1457    16896000 :                     move32();
    1458    16896000 :                     *p_k_fx[k] = L_shl( *p_k_fx[k], Q1 ); // left shift is done to maintain constant Q factor for p_k_fx Q(q_cldfb+min_q_shift)
    1459    16896000 :                     move32();
    1460    16896000 :                     reference_power_fx[idx1] = Mpy_32_32( *p_k_fx[k], *p_k_fx[k] ); // Q(2*(q_cldfb + min_q_shift)-31)
    1461    16896000 :                     move32();
    1462    16896000 :                     p_k_fx[k]++;
    1463             : 
    1464    16896000 :                     *p_k_fx[k] = Madd_32_32( Madd_32_32( Mpy_32_32( p_Rmat_fx[idx + 1], im1 ), p_Rmat_fx[idx + 2], im2 ), p_Rmat_fx[idx], im3 ); /*Q(q_cldfb+min_q_shift-1)*/
    1465    16896000 :                     move32();
    1466    16896000 :                     *p_k_fx[k] = L_shl( *p_k_fx[k], Q1 ); // left shift is done to maintain constant Q factor Q(q_cldfb+min_q_shift)
    1467    16896000 :                     move32();
    1468    16896000 :                     reference_power_fx[idx1] = Mpy_32_32( *p_k_fx[k], *p_k_fx[k] ); // Q(2*(q_cldfb + min_q_shift)-31)
    1469    16896000 :                     move32();
    1470    16896000 :                     p_k_fx[k]++;
    1471             : 
    1472    16896000 :                     reference_power_fx[l] = L_add( reference_power_fx[l], L_shr( reference_power_fx[idx1], 1 ) ); /*2*Q(q_cldfb+min_q_shift)-31-1*/
    1473    16896000 :                     move32();
    1474             :                 }
    1475             : 
    1476     5632000 :                 *proto_direct_buffer_f_q = add( q_cldfb, min_q_shift );
    1477     5632000 :                 move16();
    1478     5632000 :                 Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    1479     5632000 :                 reference_power_q[qidx] = sub( add( *proto_direct_buffer_f_q, *proto_direct_buffer_f_q ), 31 );
    1480     5632000 :                 move16();
    1481             : 
    1482     5632000 :                 Word16 shift = sub( *proto_direct_buffer_f_q, q_cldfb );
    1483    22528000 :                 FOR( k = 1; k < 4; k++ )
    1484             :                 {
    1485    16896000 :                     RealBuffer_fx[k][0][l] = L_shr( p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l )], shift ); // proto_direct_buffer_f_q -> q_cldfb
    1486    16896000 :                     move32();
    1487    16896000 :                     ImagBuffer_fx[k][0][l] = L_shr( p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l ) + 1], shift ); // proto_direct_buffer_f_q -> q_cldfb
    1488    16896000 :                     move32();
    1489             :                 }
    1490             :             }
    1491             :         }
    1492             :         ELSE
    1493             :         {
    1494      755727 :             set_zero_fx( reference_power_fx, num_freq_bands );
    1495     3778635 :             FOR( k = 0; k < 4; k++ )
    1496             :             {
    1497   171708828 :                 FOR( l = 0; l < num_freq_bands; l++ )
    1498             :                 {
    1499   168685920 :                     p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l )] = RealBuffer_fx[k][0][l]; // q_cldfb
    1500   168685920 :                     move32();
    1501   168685920 :                     p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l ) + 1] = ImagBuffer_fx[k][0][l]; // q_cldfb
    1502   168685920 :                     move32();
    1503             : 
    1504   168685920 :                     re1 = L_shl( RealBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift
    1505   168685920 :                     im1 = L_shl( ImagBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift
    1506             : 
    1507   168685920 :                     reference_power_fx[l + ( k + 1 ) * num_freq_bands] = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31
    1508   168685920 :                     move32();
    1509   168685920 :                     reference_power_fx[l] = L_add( reference_power_fx[l], L_shr( reference_power_fx[l + ( k + 1 ) * num_freq_bands], 1 ) ); // 2*(q_cldfb+min_q_shift)-31-1
    1510   168685920 :                     move32();
    1511             :                 }
    1512             :             }
    1513      755727 :             *proto_direct_buffer_f_q = q_cldfb;
    1514      755727 :             move16();
    1515      755727 :             reference_power_q[0] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 );
    1516      755727 :             reference_power_q[1] = reference_power_q[0];
    1517      755727 :             move16();
    1518      755727 :             move16();
    1519             :         }
    1520             : 
    1521             :         /* Additional transport channels = planar SBA components of degree higher than 1*/
    1522     2325263 :         FOR( ; k < num_inputs; k++ )
    1523             :         {
    1524    84944896 :             FOR( l = 0; l < num_freq_bands; l++ )
    1525             :             {
    1526    83522560 :                 p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l )] = RealBuffer_fx[k][0][l]; // q_cldfb
    1527    83522560 :                 move32();
    1528    83522560 :                 p_proto_direct_buffer_fx[2 * ( k * num_freq_bands + l ) + 1] = ImagBuffer_fx[k][0][l]; // q_cldfb
    1529    83522560 :                 move32();
    1530             :             }
    1531             :         }
    1532             :     }
    1533             : 
    1534             : 
    1535             :     /*Copy direct to diffuse proto*/
    1536      951931 :     Copy32( p_proto_direct_buffer_fx, p_proto_diffuse_buffer_fx, i_mult( i_mult( 2, num_freq_bands ), s_min( num_outputs_diff, num_inputs ) ) ); /*proto_diffuse_buffer_f_q -> proto_direct_buffer_f_q*/
    1537      951931 :     *proto_diffuse_buffer_f_q = *proto_direct_buffer_f_q;
    1538      951931 :     move16();
    1539             : 
    1540      951931 :     IF( EQ_16( num_inputs, 1 ) )
    1541             :     {
    1542             :         /* Add comfort noise addition (CNA) to diffuse proto only*/
    1543     2989244 :         FOR( l = 0; l < num_freq_bands; l++ )
    1544             :         {
    1545     2940240 :             p_proto_diffuse_buffer_fx[2 * l] = L_add( p_proto_diffuse_buffer_fx[2 * l], RealBuffer_fx[1][0][l] ); // q_cldfb
    1546     2940240 :             move32();
    1547     2940240 :             p_proto_diffuse_buffer_fx[2 * l + 1] = L_add( p_proto_diffuse_buffer_fx[2 * l + 1], ImagBuffer_fx[1][0][l] ); // q_cldfb
    1548     2940240 :             move32();
    1549             :         }
    1550             :     }
    1551             : 
    1552      951931 :     return;
    1553             : }
    1554             : 
    1555             : 
    1556             : /*-------------------------------------------------------------------------
    1557             :  * protoSignalComputation1()
    1558             :  *
    1559             :  *
    1560             :  *-------------------------------------------------------------------------*/
    1561             : 
    1562      136295 : void protoSignalComputation1_fx(
    1563             :     Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    1564             :     Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    1565             :     Word32 *proto_frame_f_fx,                                                   /*proto_frame_f_q*/
    1566             :     Word16 *proto_frame_f_q,
    1567             :     Word32 *proto_direct_buffer_f_fx, /*proto_direct_buffer_f_q*/
    1568             :     Word16 *proto_direct_buffer_f_q,
    1569             :     Word32 *reference_power_fx, /*reference_power_q*/
    1570             :     Word16 *reference_power_q,
    1571             :     Word32 *proto_power_smooth_fx, /*proto_power_smooth_q*/
    1572             :     Word16 *proto_power_smooth_q,
    1573             :     const Word16 slot_index,
    1574             :     const Word16 num_outputs_diff,
    1575             :     const Word16 num_freq_bands,
    1576             :     Word16 q_cldfb )
    1577             : {
    1578             :     Word16 l, k, idx;
    1579             :     Word32 *p_proto_buffer_fx;
    1580             :     Word16 proto_power_smooth_fx_q[2], min_q_shift, q_shift;
    1581             :     Word32 re, im;
    1582             : 
    1583      136295 :     min_q_shift = Q31;
    1584      136295 :     move16();
    1585      136295 :     q_shift = Q31;
    1586      136295 :     move16();
    1587             : 
    1588      136295 :     p_proto_buffer_fx = proto_direct_buffer_f_fx + ( slot_index * ( 2 * num_freq_bands ) ); /*proto_direct_buffer_f_q*/
    1589             : 
    1590             :     /* calculate the maximum shift possible for the bufferS RealBuffer_fx and  ImagBuffer_fx*/
    1591      136295 :     q_shift = L_norm_arr( RealBuffer_fx[0][0], num_freq_bands );
    1592      136295 :     min_q_shift = s_min( q_shift, min_q_shift );
    1593      136295 :     q_shift = L_norm_arr( ImagBuffer_fx[0][0], num_freq_bands );
    1594      136295 :     min_q_shift = s_min( q_shift, min_q_shift );
    1595             : 
    1596      136295 :     min_q_shift = sub( min_q_shift, find_guarded_bits_fx( 2 ) );
    1597             : 
    1598             :     /* calculate the maximum shift possible for the buffer proto_power_smooth_fx */
    1599      136295 :     q_shift = getScaleFactor32( proto_power_smooth_fx, num_freq_bands );
    1600      136295 :     q_shift = sub( q_shift, find_guarded_bits_fx( 2 ) );
    1601             : 
    1602      136295 :     Scale_sig32( proto_power_smooth_fx, num_freq_bands, q_shift ); /*proto_power_smooth_q+q_shift*/
    1603      136295 :     proto_power_smooth_q[0] = add( proto_power_smooth_q[0], q_shift );
    1604      136295 :     proto_power_smooth_q[1] = add( proto_power_smooth_q[1], q_shift );
    1605      136295 :     proto_power_smooth_fx_q[0] = proto_power_smooth_q[0];
    1606      136295 :     proto_power_smooth_fx_q[1] = proto_power_smooth_q[1];
    1607      136295 :     move16();
    1608      136295 :     move16();
    1609             : 
    1610     7952795 :     FOR( l = 0; l < num_freq_bands; l++ )
    1611             :     {
    1612     7816500 :         Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    1613     7816500 :         re = L_shl( RealBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift
    1614     7816500 :         im = L_shl( ImagBuffer_fx[0][0][l], min_q_shift ); // q_cldfb+min_q_shift
    1615             : 
    1616     7816500 :         reference_power_fx[l] = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31
    1617     7816500 :         move32();
    1618     7816500 :         reference_power_q[qidx] = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 );
    1619     7816500 :         move16();
    1620             : 
    1621     7816500 :         IF( LT_16( reference_power_q[qidx], proto_power_smooth_q[qidx] ) )
    1622             :         {
    1623     4627780 :             proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( proto_power_smooth_q[qidx], reference_power_q[qidx] ) ), reference_power_fx[l] ); // reference_power_q
    1624     4627780 :             move32();
    1625     4627780 :             proto_power_smooth_fx_q[qidx] = reference_power_q[qidx];
    1626     4627780 :             move16();
    1627             :         }
    1628             :         ELSE
    1629             :         {
    1630     3188720 :             proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( reference_power_fx[l], sub( reference_power_q[qidx], proto_power_smooth_q[qidx] ) ) ); // proto_power_smooth_q
    1631     3188720 :             move32();
    1632     3188720 :             proto_power_smooth_fx_q[qidx] = proto_power_smooth_q[qidx];
    1633     3188720 :             move16();
    1634             :         }
    1635             : 
    1636     7816500 :         idx = 2 * l;
    1637     7816500 :         p_proto_buffer_fx[idx] = RealBuffer_fx[0][0][l]; // q_cldfb
    1638     7816500 :         move32();
    1639     7816500 :         p_proto_buffer_fx[idx + 1] = ImagBuffer_fx[0][0][l]; // q_cldfb
    1640     7816500 :         move32();
    1641             : 
    1642    15633000 :         FOR( k = 0; k < num_outputs_diff; k++ )
    1643             :         {
    1644     7816500 :             idx = add( i_mult( i_mult( 2, k ), num_freq_bands ), i_mult( 2, l ) );
    1645     7816500 :             proto_frame_f_fx[idx] = RealBuffer_fx[0][0][l]; // q_cldfb
    1646     7816500 :             move32();
    1647     7816500 :             proto_frame_f_fx[idx + 1] = ImagBuffer_fx[0][0][l]; // q_cldfb
    1648     7816500 :             move32();
    1649             :         }
    1650             :     }
    1651             : 
    1652      136295 :     *proto_frame_f_q = q_cldfb;
    1653      136295 :     move16();
    1654      136295 :     *proto_direct_buffer_f_q = q_cldfb;
    1655      136295 :     move16();
    1656      136295 :     proto_power_smooth_q[0] = proto_power_smooth_fx_q[0];
    1657      136295 :     proto_power_smooth_q[1] = proto_power_smooth_fx_q[1];
    1658      136295 :     move16();
    1659      136295 :     move16();
    1660             : 
    1661      136295 :     return;
    1662             : }
    1663             : 
    1664             : 
    1665             : /*-------------------------------------------------------------------------
    1666             :  * protoSignalComputation2()
    1667             :  *
    1668             :  *
    1669             :  *-------------------------------------------------------------------------*/
    1670             : 
    1671      176435 : void protoSignalComputation2_fx(
    1672             :     Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    1673             :     Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    1674             :     Word32 *proto_frame_f_fx,                                                   /*q_proto_frame_f*/
    1675             :     Word16 *q_proto_frame_f,
    1676             :     Word32 *proto_direct_buffer_f_fx, /*q_proto_direct_buffer_f*/
    1677             :     Word16 *q_proto_direct_buffer_f,
    1678             :     Word32 *reference_power_fx, /*q_reference_power*/
    1679             :     Word16 *q_reference_power,
    1680             :     Word32 *proto_power_smooth_fx, /*q_proto_power_smooth*/
    1681             :     Word16 *q_proto_power_smooth,
    1682             :     const Word16 isloudspeaker,
    1683             :     const Word16 slot_index,
    1684             :     const Word16 num_freq_bands,
    1685             :     MASA_STEREO_TYPE_DETECT *stereo_type_detect,
    1686             :     Word16 q_cldfb )
    1687             : {
    1688             :     Word16 l;
    1689             :     Word16 dipole_freq_range[2];
    1690             :     Word32 *p_proto_buffer_fx;
    1691             :     Word32 Real_aux_fx, Imag_aux_fx, re_aux, im_aux;
    1692             :     Word32 re1, im1, re2, im2;
    1693             :     Word32 RealSubtract_fx, ImagSubtract_fx;
    1694             :     Word32 left_bb_power_fx, right_bb_power_fx, total_bb_power_fx, lr_bb_power_fx;
    1695             :     Word32 left_hi_power_fx, right_hi_power_fx, total_hi_power_fx, lr_hi_power_fx;
    1696             :     Word32 sum_power_fx, Left_power_fx, Right_power_fx, Total_power_fx;
    1697             :     Word16 q_lr_bb_power, q_lr_hi_power;
    1698             :     Word32 lr_total_bb_ratio_fx, lr_total_hi_ratio_fx;
    1699             :     Word32 min_sum_total_ratio_fx, min_sum_total_ratio_db_fx;
    1700             :     Word32 sum_total_ratio_fx[MASA_SUM_FREQ_RANGE_BINS];
    1701             :     Word16 exp_sum_total_ratio_fx[MASA_SUM_FREQ_RANGE_BINS];
    1702      176435 :     Word16 q_sum_total_ratio = 0;
    1703      176435 :     move16();
    1704             :     Word32 a_fx, b_fx, a2_fx, b2_fx;
    1705             :     Word16 interpolatorSpaced_fx, interpolatorDmx_fx;
    1706             :     Word32 tempSpaced_fx, tempDmx_fx;
    1707             :     Word16 q_shift, min_q_shift[2], exp, q_temp[2];
    1708             :     Word32 temp;
    1709             :     Word64 W_tmp1, W_tmp2, W_tmp3;
    1710             :     Word64 reference_power_64fx[CLDFB_NO_CHANNELS_MAX];
    1711             :     Word16 q_reference_power_64fx;
    1712             :     Word16 head_room, q_Left_Right_power;
    1713      176435 :     Word16 num_proto = 3;
    1714             :     /* Calculate maximum possible shift for the buffers RealBuffer_fx and ImagBuffer_fx */
    1715      176435 :     min_q_shift[0] = Q31;
    1716      176435 :     min_q_shift[1] = Q31;
    1717      176435 :     move16();
    1718      176435 :     move16();
    1719      176435 :     q_sum_total_ratio = 0;
    1720      176435 :     move16();
    1721      176435 :     exp = 0;
    1722      176435 :     move16();
    1723      176435 :     interpolatorSpaced_fx = 0;
    1724      176435 :     move16();
    1725      176435 :     interpolatorDmx_fx = MAX16B;
    1726      176435 :     move16();
    1727             : 
    1728             :     /* Calculate the max shift possible for the buffers RealBuffer_fx and ImagBuffer_fx */
    1729      529305 :     FOR( l = 0; l < 2; l++ )
    1730             :     {
    1731      352870 :         q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) ) );
    1732      352870 :         min_q_shift[0] = s_min( min_q_shift[0], q_shift );
    1733      352870 :         q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ), L_norm_arr( ImagBuffer_fx[l][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) );
    1734      352870 :         min_q_shift[1] = s_min( min_q_shift[1], q_shift );
    1735             : #if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF )
    1736             : #error MASA_SUM_FREQ_RANGE_BINS if greater than CLDFB_NO_CHANNELS_HALF, this does not work
    1737             : #endif
    1738      352870 :         q_shift = s_min( L_norm_arr( RealBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ), L_norm_arr( ImagBuffer_fx[l][0], s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) );
    1739             :     }
    1740             : 
    1741      176435 :     min_q_shift[0] = sub( min_q_shift[0], 2 ); // guard bits
    1742      176435 :     min_q_shift[1] = sub( min_q_shift[1], 2 ); // guard bits
    1743             : 
    1744             :     /* Upscaling of the buffer proto_power_smooth_fx */
    1745      176435 :     IF( isloudspeaker )
    1746             :     {
    1747       95232 :         num_proto = 3;
    1748       95232 :         q_shift = L_norm_arr( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) );
    1749       95232 :         q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    1750       95232 :         q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    1751       95232 :         scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) );                                   // q_proto_power_smooth+q_shift-1
    1752       95232 :         scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) );                  // q_proto_power_smooth+q_shift-1
    1753       95232 :         scale_sig32( proto_power_smooth_fx + num_freq_bands + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1
    1754             :     }
    1755             :     ELSE
    1756             :     {
    1757       81203 :         num_proto = 2;
    1758       81203 :         q_shift = L_norm_arr( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) );
    1759       81203 :         q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    1760       81203 :         scale_sig32( proto_power_smooth_fx, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) );                  // q_proto_power_smooth+q_shift-1
    1761       81203 :         scale_sig32( proto_power_smooth_fx + num_freq_bands, s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1
    1762             :     }
    1763      176435 :     q_proto_power_smooth[0] = add( q_proto_power_smooth[0], sub( q_shift, 1 ) );
    1764      176435 :     move16();
    1765      176435 :     IF( isloudspeaker )
    1766             :     {
    1767       95232 :         q_shift = L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    1768       95232 :         q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) );
    1769       95232 :         q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) );
    1770       95232 :         scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) );                                   // q_proto_power_smooth+q_shift-1
    1771       95232 :         scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) );                  // q_proto_power_smooth+q_shift-1
    1772       95232 :         scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1
    1773             :     }
    1774             :     ELSE
    1775             :     {
    1776       81203 :         q_shift = L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    1777       81203 :         q_shift = s_min( q_shift, L_norm_arr( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) ) );
    1778       81203 :         scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) );                  // q_proto_power_smooth+q_shift-1
    1779       81203 :         scale_sig32( proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + num_freq_bands, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( q_shift, 1 ) ); // q_proto_power_smooth+q_shift-1
    1780             :     }
    1781      176435 :     q_proto_power_smooth[1] = add( q_proto_power_smooth[1], sub( q_shift, 1 ) );
    1782      176435 :     move16();
    1783             : 
    1784      176435 :     IF( isloudspeaker )
    1785             :     {
    1786       95232 :         p_proto_buffer_fx = proto_direct_buffer_f_fx + i_mult( i_mult( i_mult( slot_index, 2 ), num_freq_bands ), 3 ); // q_proto_direct_buffer_f
    1787             : 
    1788       95232 :         q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 );
    1789       95232 :         q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 );
    1790             : 
    1791     5703552 :         FOR( l = 0; l < num_freq_bands; l++ )
    1792             :         {
    1793     5608320 :             Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    1794             : 
    1795     5608320 :             re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1796     5608320 :             im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1797     5608320 :             re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1798     5608320 :             im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1799             : 
    1800     5608320 :             Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift
    1801     5608320 :             Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift
    1802             : 
    1803             :             // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 );
    1804     5608320 :             W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift)
    1805             :             // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 );
    1806     5608320 :             W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift)
    1807             : 
    1808             : 
    1809             :             // reference_power_fx[l] = L_add( Left_power_fx, Right_power_fx );
    1810     5608320 :             reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift)
    1811     5608320 :             move64();
    1812             : 
    1813     5608320 :             temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31
    1814             : 
    1815     5608320 :             IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    1816             :             {
    1817     4391240 :                 proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    1818     4391240 :                 move32();
    1819             :             }
    1820             :             ELSE
    1821             :             {
    1822     1217080 :                 proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    1823     1217080 :                 move32();
    1824             :             }
    1825             : 
    1826     5608320 :             p_proto_buffer_fx[2 * l] = Real_aux_fx; // q_cldfb+min_q_shift
    1827     5608320 :             move32();
    1828     5608320 :             p_proto_buffer_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+min_q_shift
    1829     5608320 :             move32();
    1830             : 
    1831     5608320 :             temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31
    1832             : 
    1833     5608320 :             IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    1834             :             {
    1835     4391240 :                 proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    1836     4391240 :                 move32();
    1837             :             }
    1838             :             ELSE
    1839             :             {
    1840     1217080 :                 proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    1841     1217080 :                 move32();
    1842             :             }
    1843             : 
    1844     5608320 :             p_proto_buffer_fx[2 * ( num_freq_bands + l )] = re1; // q_cldfb+min_q_shift
    1845     5608320 :             move32();
    1846     5608320 :             p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = im1; // q_cldfb+min_q_shift
    1847     5608320 :             move32();
    1848             : 
    1849     5608320 :             temp = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 ); // 2*(q_cldfb+min_q_shift)-31
    1850     5608320 :             IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    1851             :             {
    1852     4391240 :                 proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    1853     4391240 :                 move32();
    1854             :             }
    1855             :             ELSE
    1856             :             {
    1857     1217080 :                 proto_power_smooth_fx[l + ( 2 * num_freq_bands )] = L_add( proto_power_smooth_fx[l + ( 2 * num_freq_bands )], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    1858     1217080 :                 move32();
    1859             :             }
    1860             : 
    1861     5608320 :             p_proto_buffer_fx[4 * num_freq_bands + 2 * l] = re2; // q_cldfb+min_q_shift
    1862     5608320 :             move32();
    1863     5608320 :             p_proto_buffer_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+min_q_shift
    1864     5608320 :             move32();
    1865             : 
    1866     5608320 :             proto_frame_f_fx[2 * l] = Real_aux_fx; // q_cldfb+min_q_shift
    1867     5608320 :             move32();
    1868     5608320 :             proto_frame_f_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+min_q_shift
    1869     5608320 :             move32();
    1870             : 
    1871     5608320 :             proto_frame_f_fx[2 * num_freq_bands + 2 * l] = re1; // q_cldfb+min_q_shift
    1872     5608320 :             move32();
    1873     5608320 :             proto_frame_f_fx[2 * num_freq_bands + 2 * l + 1] = im1; // q_cldfb+min_q_shift
    1874     5608320 :             move32();
    1875     5608320 :             proto_frame_f_fx[4 * num_freq_bands + 2 * l] = re2; // q_cldfb+min_q_shift
    1876     5608320 :             move32();
    1877     5608320 :             proto_frame_f_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+min_q_shift
    1878     5608320 :             move32();
    1879             :         }
    1880             :     }
    1881       81203 :     ELSE IF( stereo_type_detect != NULL )
    1882             :     {
    1883       61947 :         p_proto_buffer_fx = proto_direct_buffer_f_fx + ( slot_index * 4 * num_freq_bands ); // q_proto_direct_buffer_f
    1884             : 
    1885       61947 :         left_bb_power_fx = 0;
    1886       61947 :         move32();
    1887       61947 :         right_bb_power_fx = 0;
    1888       61947 :         move32();
    1889       61947 :         total_bb_power_fx = 0;
    1890       61947 :         move32();
    1891             : 
    1892       61947 :         left_hi_power_fx = 0;
    1893       61947 :         move32();
    1894       61947 :         right_hi_power_fx = 0;
    1895       61947 :         move32();
    1896       61947 :         total_hi_power_fx = 0;
    1897       61947 :         move32();
    1898             : 
    1899       61947 :         dipole_freq_range[0] = stereo_type_detect->dipole_freq_range[0];
    1900       61947 :         move16();
    1901       61947 :         dipole_freq_range[1] = stereo_type_detect->dipole_freq_range[1];
    1902       61947 :         move16();
    1903             : 
    1904       61947 :         a_fx = 21474836; /*0.01 in Q31*/ /* Temporal smoothing coefficient */
    1905       61947 :         move32();
    1906       61947 :         b_fx = L_sub( ONE_IN_Q31, a_fx ); /* Temporal smoothing coefficient q31*/
    1907       61947 :         move32();
    1908       61947 :         a2_fx = 214748365; /*0.1 in Q31*/ /* Temporal smoothing coefficient */
    1909       61947 :         move32();
    1910       61947 :         b2_fx = L_sub( ONE_IN_Q31, a2_fx ); /* Temporal smoothing coefficient */
    1911             : 
    1912       61947 :         IF( stereo_type_detect->interpolator > 0 )
    1913             :         {
    1914          30 :             IF( EQ_16( stereo_type_detect->type_change_direction, MASA_STEREO_SPACED_MICS ) )
    1915             :             {
    1916             :                 /* interpolatorSpaced = ( (float) ( stereo_type_detect->interpolator ) ) / ( (float) MASA_STEREO_INTERPOLATION_SLOTS ); */
    1917          30 :                 interpolatorSpaced_fx = i_mult_sat( stereo_type_detect->interpolator, 2048 /* 1 / MASA_STEREO_INTERPOLATION_SLOTS in Q15 */ ); /* Q15 */
    1918          30 :                 interpolatorDmx_fx = sub( MAX16B, interpolatorSpaced_fx );                                                                     /* Q15 */
    1919             :             }
    1920             :             ELSE
    1921             :             {
    1922             :                 /* interpolatorDmx = ( (float) ( stereo_type_detect->interpolator ) ) / ( (float) MASA_STEREO_INTERPOLATION_SLOTS ); */
    1923           0 :                 interpolatorDmx_fx = i_mult_sat( stereo_type_detect->interpolator, 2048 /* 1 / MASA_STEREO_INTERPOLATION_SLOTS in Q15 */ ); /* Q15 */
    1924           0 :                 interpolatorSpaced_fx = sub( MAX16B, interpolatorDmx_fx );                                                                  /* Q15 */
    1925             :             }
    1926             :         }
    1927             : 
    1928             :         Word16 total_shift[2];
    1929             :         /* total_shift shift required to get common Q of sum power values */
    1930       61947 :         total_shift[0] = shl( s_max( 0, sub( min_q_shift[0], min_q_shift[1] ) ), 1 );
    1931       61947 :         total_shift[1] = shl( s_max( 0, sub( min_q_shift[1], min_q_shift[0] ) ), 1 );
    1932       61947 :         min_q_shift[0] = sub( min_q_shift[0], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) );
    1933       61947 :         min_q_shift[1] = sub( min_q_shift[1], idiv1616( find_guarded_bits_fx( num_freq_bands ), 2 ) );
    1934       61947 :         q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 );
    1935       61947 :         q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 );
    1936             : 
    1937       61947 :         head_room = 63;
    1938       61947 :         move16();
    1939     3338547 :         FOR( l = 0; l < num_freq_bands; l++ )
    1940             :         {
    1941     3276600 :             Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    1942     3276600 :             re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1943     3276600 :             im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1944     3276600 :             re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1945     3276600 :             im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1946             : 
    1947     3276600 :             W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) );
    1948     3276600 :             W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) );
    1949             : 
    1950     3276600 :             head_room = s_min( head_room, W_norm( W_add( W_tmp1, W_tmp2 ) ) );
    1951             :         }
    1952       61947 :         head_room = sub( head_room, find_guarded_bits_fx( num_freq_bands ) );
    1953             : 
    1954             : #if ( MASA_SUM_FREQ_RANGE_BINS > CLDFB_NO_CHANNELS_HALF )
    1955             : #error MASA_SUM_FREQ_RANGE_BINS must be less than CLDFB_NO_CHANNELS_HALF
    1956             : #endif
    1957       61947 :         q_Left_Right_power = add( shl( add( q_cldfb, min_q_shift[0] ), 1 ), sub( head_room, 32 ) );
    1958       61947 :         Word16 exp_left_hi_power = 0, exp_right_hi_power = 0, exp_total_hi_power = 0, exp_temppp;
    1959       61947 :         move16();
    1960       61947 :         move16();
    1961       61947 :         move16();
    1962     3338547 :         FOR( l = 0; l < num_freq_bands; l++ )
    1963             :         {
    1964     3276600 :             Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    1965     3276600 :             re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1966     3276600 :             im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1967     3276600 :             re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1968     3276600 :             im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+min_q_shift
    1969             : 
    1970             :             /* Compute sum signal */
    1971     3276600 :             Real_aux_fx = L_add( re1, re2 ); // q_cldfb+min_q_shift
    1972     3276600 :             Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+min_q_shift
    1973             : 
    1974             :             /* Compute reference power */
    1975             :             // Left_power_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 );
    1976     3276600 :             W_tmp1 = W_add( W_mult0_32_32( re1, re1 ), W_mult0_32_32( im1, im1 ) ); // 2*(q_cldfb+min_q_shift)
    1977     3276600 :             Left_power_fx = W_extract_h( W_shl( W_tmp1, head_room ) );              // q_Left_Right_power
    1978             : 
    1979             :             // Right_power_fx = Madd_32_32( Mpy_32_32( re2, re2 ), im2, im2 );
    1980     3276600 :             W_tmp2 = W_add( W_mult0_32_32( re2, re2 ), W_mult0_32_32( im2, im2 ) ); // 2*(q_cldfb+min_q_shift)
    1981     3276600 :             Right_power_fx = W_extract_h( W_shl( W_tmp2, head_room ) );             // q_Left_Right_power
    1982             : 
    1983             :             // reference_power_fx[l] = L_add( Left_power_fx, Right_power_fx );
    1984     3276600 :             reference_power_64fx[l] = W_add( W_tmp1, W_tmp2 ); // 2*(q_cldfb+min_q_shift)
    1985     3276600 :             move64();
    1986             : 
    1987     3276600 :             Left_power_fx = L_shr( Left_power_fx, total_shift[qidx] );
    1988     3276600 :             Right_power_fx = L_shr( Right_power_fx, total_shift[qidx] );
    1989     3276600 :             left_bb_power_fx = L_add( left_bb_power_fx, Left_power_fx );    // q_Left_Right_power
    1990     3276600 :             right_bb_power_fx = L_add( right_bb_power_fx, Right_power_fx ); // q_Left_Right_power
    1991             :             // total_bb_power_fx = L_add( total_bb_power_fx, reference_power_fx[l] );
    1992     3276600 :             total_bb_power_fx = L_add( total_bb_power_fx, W_extract_h( W_shl( reference_power_64fx[l], sub( head_room, total_shift[qidx] ) ) ) ); // q_Left_Right_power
    1993     3276600 :             IF( GT_16( l, MASA_HI_FREQ_START_BIN ) )
    1994             :             {
    1995     2347395 :                 W_tmp1 = W_add( W_mult0_32_32( RealBuffer_fx[0][0][l], RealBuffer_fx[0][0][l] ), W_mult0_32_32( ImagBuffer_fx[0][0][l], ImagBuffer_fx[0][0][l] ) );
    1996     2347395 :                 q_shift = W_norm( W_tmp1 );
    1997     2347395 :                 Left_power_fx = W_extract_h( W_shl( W_tmp1, q_shift ) );
    1998     2347395 :                 exp_temppp = sub( 31, sub( add( shl( q_cldfb, 1 ), q_shift ), 32 ) );
    1999             : 
    2000     2347395 :                 left_hi_power_fx = BASOP_Util_Add_Mant32Exp( left_hi_power_fx, exp_left_hi_power, Left_power_fx, exp_temppp, &exp_left_hi_power ); // exp:exp_left_hi_power
    2001             : 
    2002     2347395 :                 W_tmp2 = W_add( W_mult0_32_32( RealBuffer_fx[1][0][l], RealBuffer_fx[1][0][l] ), W_mult0_32_32( ImagBuffer_fx[1][0][l], ImagBuffer_fx[1][0][l] ) );
    2003     2347395 :                 q_shift = W_norm( W_tmp2 );
    2004     2347395 :                 Right_power_fx = W_extract_h( W_shl( W_tmp2, q_shift ) );
    2005     2347395 :                 exp_temppp = sub( 31, sub( add( shl( q_cldfb, 1 ), q_shift ), 32 ) );
    2006             : 
    2007     2347395 :                 right_hi_power_fx = BASOP_Util_Add_Mant32Exp( right_hi_power_fx, exp_right_hi_power, Right_power_fx, exp_temppp, &exp_right_hi_power ); // exp:exp_right_hi_power
    2008             : 
    2009     2347395 :                 W_tmp2 = W_add( W_tmp1, W_tmp2 );
    2010     2347395 :                 q_shift = W_norm( W_tmp2 );
    2011     2347395 :                 Total_power_fx = W_extract_h( W_shl( W_tmp2, q_shift ) );
    2012     2347395 :                 exp_temppp = sub( 31, sub( add( shl( q_cldfb, 1 ), q_shift ), 32 ) );
    2013             : 
    2014     2347395 :                 total_hi_power_fx = BASOP_Util_Add_Mant32Exp( total_hi_power_fx, exp_total_hi_power, Total_power_fx, exp_temppp, &exp_total_hi_power ); // exp:exp_total_hi_power
    2015             :             }
    2016             : 
    2017     3276600 :             IF( LT_16( l, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) ) )
    2018             :             {
    2019     1524675 :                 re_aux = L_add( L_shr( RealBuffer_fx[0][0][l], 1 ), L_shr( RealBuffer_fx[1][0][l], 1 ) );
    2020     1524675 :                 im_aux = L_add( L_shr( ImagBuffer_fx[0][0][l], 1 ), L_shr( ImagBuffer_fx[1][0][l], 1 ) );
    2021             : 
    2022     1524675 :                 W_tmp3 = W_add( W_mult0_32_32( re_aux, re_aux ), W_mult0_32_32( im_aux, im_aux ) );
    2023     1524675 :                 q_shift = W_norm( W_tmp3 );
    2024     1524675 :                 sum_power_fx = W_extract_h( W_shl( W_tmp3, q_shift ) );
    2025     1524675 :                 exp_temppp = sub( 31, sub( add( shl( sub( q_cldfb, 1 ), 1 ), q_shift ), 32 ) );
    2026             : 
    2027     1524675 :                 stereo_type_detect->sum_power_fx[l] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, sum_power_fx ), exp_temppp, Mpy_32_32( b_fx, stereo_type_detect->sum_power_fx[l] ), stereo_type_detect->exp_sum_power[l], &stereo_type_detect->exp_sum_power[l] );
    2028     1524675 :                 move32();
    2029     1524675 :                 W_tmp1 = W_add( W_mult0_32_32( RealBuffer_fx[0][0][l], RealBuffer_fx[0][0][l] ), W_mult0_32_32( ImagBuffer_fx[0][0][l], ImagBuffer_fx[0][0][l] ) );
    2030     1524675 :                 W_tmp2 = W_add( W_mult0_32_32( RealBuffer_fx[1][0][l], RealBuffer_fx[1][0][l] ), W_mult0_32_32( ImagBuffer_fx[1][0][l], ImagBuffer_fx[1][0][l] ) );
    2031             : 
    2032     1524675 :                 W_tmp2 = W_add( W_tmp1, W_tmp2 );
    2033     1524675 :                 q_shift = W_norm( W_tmp2 );
    2034     1524675 :                 Total_power_fx = W_extract_h( W_shl( W_tmp2, q_shift ) );
    2035     1524675 :                 exp_temppp = sub( 31, sub( add( shl( q_cldfb, 1 ), q_shift ), 32 ) );
    2036             : 
    2037     1524675 :                 stereo_type_detect->total_power_fx[l] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, Total_power_fx ), exp_temppp, Mpy_32_32( b_fx, stereo_type_detect->total_power_fx[l] ), stereo_type_detect->exp_total_power[l], &stereo_type_detect->exp_total_power[l] );
    2038     1524675 :                 move32();
    2039             : 
    2040     1524675 :                 test();
    2041     1524675 :                 IF( ( stereo_type_detect->sum_power_fx[l] == 0 ) && ( stereo_type_detect->total_power_fx[l] == 0 ) )
    2042             :                 {
    2043         152 :                     sum_total_ratio_fx[l] = MAX_32; // q15
    2044         152 :                     move32();
    2045         152 :                     exp_sum_total_ratio_fx[l] = 16;
    2046         152 :                     move16();
    2047             :                 }
    2048     1524523 :                 ELSE IF( stereo_type_detect->total_power_fx[l] == 0 )
    2049             :                 {
    2050           0 :                     sum_total_ratio_fx[l] = MAX_32; // q15
    2051           0 :                     move32();
    2052           0 :                     exp_sum_total_ratio_fx[l] = 16;
    2053           0 :                     move16();
    2054             :                 }
    2055             :                 ELSE
    2056             :                 {
    2057     1524523 :                     sum_total_ratio_fx[l] = BASOP_Util_Divide3232_Scale_newton( stereo_type_detect->sum_power_fx[l], stereo_type_detect->total_power_fx[l], &exp ); // 15-(exp+s_min( stereo_type_detect->q_total_power, q_temp )-s_min( stereo_type_detect->q_sum_power, q_temp2 ))
    2058     1524523 :                     move32();
    2059     1524523 :                     exp_sum_total_ratio_fx[l] = add( exp, sub( stereo_type_detect->exp_sum_power[l], stereo_type_detect->exp_total_power[l] ) );
    2060     1524523 :                     move16();
    2061             :                 }
    2062     1524675 :                 q_sum_total_ratio = s_max( q_sum_total_ratio, exp_sum_total_ratio_fx[l] );
    2063             :             }
    2064             : 
    2065     3276600 :             IF( l == 0 )
    2066             :             {
    2067       61947 :                 RealSubtract_fx = L_sub( re1, re2 ); // q_cldfb+min_q_shift
    2068       61947 :                 ImagSubtract_fx = L_sub( im1, im2 ); // q_cldfb+min_q_shift
    2069             : 
    2070       61947 :                 temp = Madd_32_32( Mpy_32_32( RealSubtract_fx, RealSubtract_fx ), ImagSubtract_fx, ImagSubtract_fx ); // 2*(q_cldfb+min_q_shift)-31
    2071       61947 :                 assert( qidx == 0 );
    2072       61947 :                 IF( LT_16( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) )
    2073             :                 {
    2074       23670 :                     stereo_type_detect->subtract_power_y_fx = L_add( L_shr( stereo_type_detect->subtract_power_y_fx, sub( stereo_type_detect->q_subtract_power_y, q_temp[qidx] ) ), temp ); // q_temp
    2075       23670 :                     move32();
    2076       23670 :                     stereo_type_detect->q_subtract_power_y = q_temp[qidx];
    2077       23670 :                     move16();
    2078             :                 }
    2079             :                 ELSE
    2080             :                 {
    2081       38277 :                     stereo_type_detect->subtract_power_y_fx = L_add( stereo_type_detect->subtract_power_y_fx, L_shr( temp, sub( q_temp[qidx], stereo_type_detect->q_subtract_power_y ) ) ); // stereo_type_detect->q_subtract_power_y
    2082       38277 :                     move32();
    2083             :                 }
    2084             :             }
    2085             : 
    2086             :             /* Compute protos (and their power) for direct sound rendering */
    2087             : 
    2088             :             /* W prototype */
    2089     3276600 :             IF( stereo_type_detect->interpolator > 0 )
    2090             :             {
    2091        1800 :                 IF( L_or( LT_16( l, sub( dipole_freq_range[1], 1 ) ), GE_16( l, MASA_SUM_PROTO_START_BIN ) ) )
    2092             :                 {
    2093        1650 :                     Real_aux_fx = Madd_32_16( Mpy_32_16_1( Real_aux_fx, shr( interpolatorSpaced_fx, 1 ) ), Real_aux_fx, interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2094        1650 :                     Imag_aux_fx = Madd_32_16( Mpy_32_16_1( Imag_aux_fx, shr( interpolatorSpaced_fx, 1 ) ), Imag_aux_fx, interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2095             : 
    2096        1650 :                     temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift) -31
    2097        1650 :                     IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2098             :                     {
    2099        1650 :                         proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2100        1650 :                         move32();
    2101             :                     }
    2102             :                     ELSE
    2103             :                     {
    2104           0 :                         proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2105           0 :                         move32();
    2106             :                     }
    2107             : 
    2108        1650 :                     p_proto_buffer_fx[2 * l] = Real_aux_fx; // q_cldfb+min_q_shift
    2109        1650 :                     move32();
    2110        1650 :                     p_proto_buffer_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+min_q_shift
    2111        1650 :                     move32();
    2112             :                 }
    2113             :                 ELSE
    2114             :                 {
    2115         150 :                     tempSpaced_fx = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 );                              // 2*(q_cldfb+min_q_shift)-31
    2116         150 :                     tempDmx_fx = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31
    2117             : 
    2118         150 :                     temp = Madd_32_16( Mpy_32_16_1( tempSpaced_fx, interpolatorSpaced_fx ), tempDmx_fx, interpolatorDmx_fx ); // 2*(q_cldfb+min_q_shift)-31
    2119         150 :                     IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2120             :                     {
    2121         150 :                         proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2122         150 :                         move32();
    2123             :                     }
    2124             :                     ELSE
    2125             :                     {
    2126           0 :                         proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2127           0 :                         move32();
    2128             :                     }
    2129             : 
    2130         150 :                     p_proto_buffer_fx[2 * l] = Madd_32_16( Mpy_32_16_1( re1, interpolatorSpaced_fx ), Real_aux_fx, interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2131         150 :                     move32();
    2132         150 :                     p_proto_buffer_fx[2 * l + 1] = Madd_32_16( Mpy_32_16_1( im1, interpolatorSpaced_fx ), Imag_aux_fx, interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2133         150 :                     move32();
    2134             :                 }
    2135             :             }
    2136     3274800 :             ELSE IF( EQ_16( stereo_type_detect->masa_stereo_type, MASA_STEREO_SPACED_MICS ) )
    2137             :             {
    2138      526080 :                 IF( L_or( LT_16( l, sub( dipole_freq_range[1], 1 ) ), GE_16( l, MASA_SUM_PROTO_START_BIN ) ) )
    2139             :                 {
    2140      482240 :                     Real_aux_fx = L_shr( Real_aux_fx, 1 );                                                // q_cldfb+min_q_shift
    2141      482240 :                     Imag_aux_fx = L_shr( Imag_aux_fx, 1 );                                                // q_cldfb+min_q_shift
    2142      482240 :                     temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31
    2143      482240 :                     IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2144             :                     {
    2145      482240 :                         proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2146      482240 :                         move32();
    2147             :                     }
    2148             :                     ELSE
    2149             :                     {
    2150           0 :                         proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2151           0 :                         move32();
    2152             :                     }
    2153             : 
    2154      482240 :                     p_proto_buffer_fx[2 * l] = Real_aux_fx; // q_cldfb+min_q_shift
    2155      482240 :                     move32();
    2156      482240 :                     p_proto_buffer_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+min_q_shift
    2157      482240 :                     move32();
    2158             :                 }
    2159             :                 ELSE
    2160             :                 {
    2161       43840 :                     temp = Madd_32_32( Mpy_32_32( re1, re1 ), im1, im1 ); // 2*(q_cldfb+min_q_shift)-31
    2162       43840 :                     IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2163             :                     {
    2164       43840 :                         proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2165       43840 :                         move32();
    2166             :                     }
    2167             :                     ELSE
    2168             :                     {
    2169           0 :                         proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2170           0 :                         move32();
    2171             :                     }
    2172             : 
    2173       43840 :                     p_proto_buffer_fx[2 * l] = re1; // q_cldfb+min_q_shift
    2174       43840 :                     move32();
    2175       43840 :                     p_proto_buffer_fx[2 * l + 1] = im1; // q_cldfb+min_q_shift
    2176       43840 :                     move32();
    2177             :                 }
    2178             :             }
    2179             :             ELSE
    2180             :             {
    2181     2748720 :                 temp = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx ); // 2*(q_cldfb+min_q_shift)-31
    2182     2748720 :                 IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2183             :                 {
    2184     2748260 :                     proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2185     2748260 :                     move32();
    2186             :                 }
    2187             :                 ELSE
    2188             :                 {
    2189         460 :                     proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2190         460 :                     move32();
    2191             :                 }
    2192             : 
    2193     2748720 :                 p_proto_buffer_fx[2 * l] = Real_aux_fx; // q_cldfb+min_q_shift
    2194     2748720 :                 move32();
    2195     2748720 :                 p_proto_buffer_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+min_q_shift
    2196     2748720 :                 move32();
    2197             :             }
    2198             : 
    2199             :             /* Y prototype */
    2200     3276600 :             IF( stereo_type_detect->interpolator > 0 )
    2201             :             {
    2202        1800 :                 IF( LT_16( l, dipole_freq_range[0] ) )
    2203             :                 {
    2204          30 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l )] = Madd_32_16( Mpy_32_16_1( p_proto_buffer_fx[2 * l], interpolatorSpaced_fx ), L_sub( re1, re2 ), interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2205          30 :                     move32();
    2206          30 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = Madd_32_16( Mpy_32_16_1( p_proto_buffer_fx[2 * l + 1], interpolatorSpaced_fx ), L_sub( im1, im2 ), interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2207          30 :                     move32();
    2208             :                 }
    2209        1770 :                 ELSE IF( LT_16( l, dipole_freq_range[1] ) )
    2210             :                 {
    2211          60 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l )] = Madd_32_16( Mpy_32_16_1( L_sub( im1, im2 ), interpolatorSpaced_fx ), L_sub( re1, re2 ), interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2212          60 :                     move32();
    2213          60 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = Madd_32_16( Mpy_32_16_1( -L_sub( re1, re2 ), interpolatorSpaced_fx ), L_sub( im1, im2 ), interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2214          60 :                     move32();
    2215             :                 }
    2216             :                 ELSE
    2217             :                 {
    2218        1710 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l )] = Madd_32_16( Mpy_32_16_1( p_proto_buffer_fx[2 * l], interpolatorSpaced_fx ), L_sub( re1, re2 ), interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2219        1710 :                     move32();
    2220        1710 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = Madd_32_16( Mpy_32_16_1( p_proto_buffer_fx[2 * l + 1], interpolatorSpaced_fx ), L_sub( im1, im2 ), interpolatorDmx_fx ); // q_cldfb+min_q_shift
    2221        1710 :                     move32();
    2222             :                 }
    2223             : 
    2224        1800 :                 temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31
    2225        1800 :                 IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2226             :                 {
    2227        1800 :                     proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2228        1800 :                     move32();
    2229             :                 }
    2230             :                 ELSE
    2231             :                 {
    2232           0 :                     proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2233           0 :                     move32();
    2234             :                 }
    2235             :             }
    2236     3274800 :             ELSE IF( EQ_16( stereo_type_detect->masa_stereo_type, MASA_STEREO_SPACED_MICS ) )
    2237             :             {
    2238      526080 :                 IF( LT_16( l, dipole_freq_range[0] ) ) /* proto = W */
    2239             :                 {
    2240        8768 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l )] = p_proto_buffer_fx[2 * l]; // q_cldfb+min_q_shift
    2241        8768 :                     move32();
    2242        8768 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = p_proto_buffer_fx[2 * l + 1]; // q_cldfb+min_q_shift
    2243        8768 :                     move32();
    2244        8768 :                     proto_power_smooth_fx[l + num_freq_bands] = proto_power_smooth_fx[l];
    2245        8768 :                     move32();
    2246             :                 }
    2247      517312 :                 ELSE IF( LT_16( l, dipole_freq_range[1] ) ) /* proto = -i * (x1-x2) * eq */
    2248             :                 {
    2249       17536 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l )] = L_sub( im1, im2 ); // q_cldfb+min_q_shift
    2250       17536 :                     move32();
    2251       17536 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = -L_sub( re1, re2 ); // q_cldfb+min_q_shift
    2252       17536 :                     move32();
    2253             : 
    2254       17536 :                     temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31
    2255       17536 :                     IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2256             :                     {
    2257       17536 :                         proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2258       17536 :                         move32();
    2259             :                     }
    2260             :                     ELSE
    2261             :                     {
    2262           0 :                         proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2263           0 :                         move32();
    2264             :                     }
    2265             :                 }
    2266             :                 ELSE /* proto = W */
    2267             :                 {
    2268      499776 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l )] = p_proto_buffer_fx[2 * l]; // q_cldfb+min_q_shift
    2269      499776 :                     move32();
    2270      499776 :                     p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = p_proto_buffer_fx[2 * l + 1]; // q_cldfb+min_q_shift
    2271      499776 :                     move32();
    2272      499776 :                     proto_power_smooth_fx[l + num_freq_bands] = proto_power_smooth_fx[l]; // min( q_temp, *q_proto_power_smooth )
    2273      499776 :                     move32();
    2274             :                 }
    2275             :             }
    2276             :             ELSE
    2277             :             {
    2278     2748720 :                 p_proto_buffer_fx[2 * ( num_freq_bands + l )] = L_sub( re1, re2 ); // q_cldfb+min_q_shift
    2279     2748720 :                 move32();
    2280     2748720 :                 p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = L_sub( im1, im2 ); // q_cldfb+min_q_shift
    2281     2748720 :                 move32();
    2282             : 
    2283     2748720 :                 temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // 2*(q_cldfb+min_q_shift)-31
    2284     2748720 :                 IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2285             :                 {
    2286     2748260 :                     proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2287     2748260 :                     move32();
    2288             :                 }
    2289             :                 ELSE
    2290             :                 {
    2291         460 :                     proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2292         460 :                     move32();
    2293             :                 }
    2294             :             }
    2295             : 
    2296             :             /* Compute protos for decorrelation */
    2297     3276600 :             proto_frame_f_fx[2 * l] = Real_aux_fx; // q_cldfb+min_q_shift
    2298     3276600 :             move32();
    2299     3276600 :             proto_frame_f_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+min_q_shift
    2300     3276600 :             move32();
    2301     3276600 :             proto_frame_f_fx[2 * num_freq_bands + 2 * l] = re1; // q_cldfb+min_q_shift
    2302     3276600 :             move32();
    2303     3276600 :             proto_frame_f_fx[2 * num_freq_bands + 2 * l + 1] = im1; // q_cldfb+min_q_shift
    2304     3276600 :             move32();
    2305     3276600 :             proto_frame_f_fx[4 * num_freq_bands + 2 * l] = re2; // q_cldfb+min_q_shift
    2306     3276600 :             move32();
    2307     3276600 :             proto_frame_f_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+min_q_shift
    2308     3276600 :             move32();
    2309             :         }
    2310             : 
    2311       61947 :         IF( stereo_type_detect->interpolator > 0 )
    2312             :         {
    2313          30 :             stereo_type_detect->interpolator++;
    2314          30 :             IF( EQ_16( stereo_type_detect->interpolator, MASA_STEREO_INTERPOLATION_SLOTS ) )
    2315             :             {
    2316           2 :                 stereo_type_detect->interpolator = 0;
    2317           2 :                 move16();
    2318           2 :                 stereo_type_detect->current_stereo_type = stereo_type_detect->type_change_direction;
    2319           2 :                 move32();
    2320             :             }
    2321             :         }
    2322             : 
    2323       61947 :         temp = Mpy_32_32( a_fx, left_bb_power_fx ); // q_Left_Right_power
    2324       61947 :         IF( LT_16( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) )
    2325             :         {
    2326         586 :             stereo_type_detect->left_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->left_bb_power_fx ), sub( stereo_type_detect->q_left_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power
    2327         586 :             move32();
    2328         586 :             stereo_type_detect->q_left_bb_power = q_Left_Right_power;
    2329         586 :             move16();
    2330             :         }
    2331             :         ELSE
    2332             :         {
    2333       61361 :             stereo_type_detect->left_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_left_bb_power ) ), b_fx, stereo_type_detect->left_bb_power_fx ); // stereo_type_detect->q_left_bb_power
    2334       61361 :             move32();
    2335             :         }
    2336             : 
    2337       61947 :         temp = Mpy_32_32( a_fx, right_bb_power_fx ); // q_Left_Right_power
    2338       61947 :         IF( LT_16( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) )
    2339             :         {
    2340         586 :             stereo_type_detect->right_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->right_bb_power_fx ), sub( stereo_type_detect->q_right_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power
    2341         586 :             move32();
    2342         586 :             stereo_type_detect->q_right_bb_power = q_Left_Right_power;
    2343         586 :             move16();
    2344             :         }
    2345             :         ELSE
    2346             :         {
    2347       61361 :             stereo_type_detect->right_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_right_bb_power ) ), b_fx, stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power
    2348       61361 :             move32();
    2349             :         }
    2350             : 
    2351       61947 :         temp = Mpy_32_32( a_fx, total_bb_power_fx ); // q_Left_Right_power
    2352       61947 :         IF( LT_16( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) )
    2353             :         {
    2354         586 :             stereo_type_detect->total_bb_power_fx = L_add( temp, L_shr( Mpy_32_32( b_fx, stereo_type_detect->total_bb_power_fx ), sub( stereo_type_detect->q_total_bb_power, q_Left_Right_power ) ) ); // q_Left_Right_power
    2355         586 :             move32();
    2356         586 :             stereo_type_detect->q_total_bb_power = q_Left_Right_power;
    2357         586 :             move16();
    2358             :         }
    2359             :         ELSE
    2360             :         {
    2361       61361 :             stereo_type_detect->total_bb_power_fx = Madd_32_32( L_shr( temp, sub( q_Left_Right_power, stereo_type_detect->q_total_bb_power ) ), b_fx, stereo_type_detect->total_bb_power_fx ); // stereo_type_detect->q_total_bb_power
    2362       61361 :             move32();
    2363             :         }
    2364             : 
    2365       61947 :         IF( LT_16( stereo_type_detect->q_left_bb_power, stereo_type_detect->q_right_bb_power ) )
    2366             :         {
    2367           0 :             lr_bb_power_fx = L_min( stereo_type_detect->left_bb_power_fx, L_shr( stereo_type_detect->right_bb_power_fx, sub( stereo_type_detect->q_right_bb_power, stereo_type_detect->q_left_bb_power ) ) ); // stereo_type_detect->q_left_bb_power
    2368           0 :             move32();
    2369           0 :             q_lr_bb_power = stereo_type_detect->q_left_bb_power;
    2370           0 :             move16();
    2371             :         }
    2372             :         ELSE
    2373             :         {
    2374       61947 :             lr_bb_power_fx = L_min( L_shr( stereo_type_detect->left_bb_power_fx, sub( stereo_type_detect->q_left_bb_power, stereo_type_detect->q_right_bb_power ) ), stereo_type_detect->right_bb_power_fx ); // stereo_type_detect->q_right_bb_power
    2375       61947 :             move32();
    2376       61947 :             q_lr_bb_power = stereo_type_detect->q_right_bb_power;
    2377       61947 :             move16();
    2378             :         }
    2379       61947 :         q_lr_bb_power = sub( q_lr_bb_power, 1 );                                                                                       /* = (lr_bb_power_fx * 2) */
    2380       61947 :         temp = BASOP_Util_Divide3232_Scale_newton( lr_bb_power_fx, L_add( stereo_type_detect->total_bb_power_fx, EPSILON_FX ), &exp ); // Q(31-(exp+stereo_type_detect->q_total_bb_power-q_lr_bb_power))
    2381       61947 :         exp = sub( 31, add( sub( 31, exp ), sub( q_lr_bb_power, stereo_type_detect->q_total_bb_power ) ) );
    2382       61947 :         temp = BASOP_Util_Log2( temp ); // q25
    2383       61947 :         IF( NE_32( temp, MIN_32 ) )
    2384             :         {
    2385       61940 :             temp = Mpy_32_32( L_add( L_shl( exp, Q25 ), temp ), LOG10_2_Q31 ); // Q25
    2386             :         }
    2387             :         // 20480 = 10 in Q11
    2388       61947 :         lr_total_bb_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21
    2389             : 
    2390       61947 :         stereo_type_detect->left_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, left_hi_power_fx ), exp_left_hi_power, Mpy_32_32( b2_fx, stereo_type_detect->left_hi_power_fx ), sub( 31, stereo_type_detect->q_left_hi_power ), &stereo_type_detect->q_left_hi_power );
    2391       61947 :         move32();
    2392       61947 :         stereo_type_detect->q_left_hi_power = sub( 31, stereo_type_detect->q_left_hi_power );
    2393       61947 :         move16();
    2394             : 
    2395       61947 :         stereo_type_detect->right_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, right_hi_power_fx ), exp_right_hi_power, Mpy_32_32( b2_fx, stereo_type_detect->right_hi_power_fx ), sub( 31, stereo_type_detect->q_right_hi_power ), &stereo_type_detect->q_right_hi_power );
    2396       61947 :         move32();
    2397       61947 :         stereo_type_detect->q_right_hi_power = sub( 31, stereo_type_detect->q_right_hi_power );
    2398       61947 :         move16();
    2399       61947 :         stereo_type_detect->total_hi_power_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a2_fx, total_hi_power_fx ), exp_total_hi_power, Mpy_32_32( b2_fx, stereo_type_detect->total_hi_power_fx ), sub( 31, stereo_type_detect->q_total_hi_power ), &stereo_type_detect->q_total_hi_power );
    2400       61947 :         move32();
    2401       61947 :         stereo_type_detect->q_total_hi_power = sub( 31, stereo_type_detect->q_total_hi_power );
    2402       61947 :         move16();
    2403             : 
    2404       61947 :         IF( LT_16( stereo_type_detect->q_left_hi_power, stereo_type_detect->q_right_hi_power ) )
    2405             :         {
    2406       22653 :             lr_hi_power_fx = L_min( stereo_type_detect->left_hi_power_fx, L_shr( stereo_type_detect->right_hi_power_fx, sub( stereo_type_detect->q_right_hi_power, stereo_type_detect->q_left_hi_power ) ) ); // stereo_type_detect->q_left_hi_power
    2407       22653 :             move32();
    2408       22653 :             q_lr_hi_power = stereo_type_detect->q_left_hi_power;
    2409             :         }
    2410             :         ELSE
    2411             :         {
    2412       39294 :             lr_hi_power_fx = L_min( L_shr( stereo_type_detect->left_hi_power_fx, sub( stereo_type_detect->q_left_hi_power, stereo_type_detect->q_right_hi_power ) ), stereo_type_detect->right_hi_power_fx ); // stereo_type_detect->q_right_hi_power
    2413       39294 :             move32();
    2414       39294 :             q_lr_hi_power = stereo_type_detect->q_right_hi_power;
    2415             :         }
    2416       61947 :         q_lr_hi_power = sub( q_lr_hi_power, 1 );                                                                                       /* = (q_lr_hi_power * 2) */
    2417       61947 :         temp = BASOP_Util_Divide3232_Scale_newton( lr_hi_power_fx, L_add( stereo_type_detect->total_hi_power_fx, EPSILON_FX ), &exp ); // Q=31-(exp+ stereo_type_detect->q_total_hi_power-q_lr_hi_power)
    2418       61947 :         exp = sub( 31, add( sub( 31, exp ), sub( q_lr_hi_power, stereo_type_detect->q_total_hi_power ) ) );
    2419       61947 :         temp = BASOP_Util_Log2( temp ); // q25
    2420       61947 :         IF( NE_32( temp, MIN_32 ) )
    2421             :         {
    2422       61940 :             temp = Mpy_32_32( L_add( L_shl( exp, Q25 ), temp ), LOG10_2_Q31 ); // Q25
    2423             :         }
    2424             :         // 20480 = 10 in Q11
    2425       61947 :         lr_total_hi_ratio_fx = Mpy_32_16_1( temp, 20480 ); // Q21
    2426             : 
    2427     1586622 :         FOR( Word16 i = 0; i < s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ); i++ )
    2428             :         {
    2429     1524675 :             sum_total_ratio_fx[i] = L_shl( sum_total_ratio_fx[i], sub( exp_sum_total_ratio_fx[i], q_sum_total_ratio ) );
    2430     1524675 :             move32();
    2431             :         }
    2432             : 
    2433       61947 :         minimum_l( sum_total_ratio_fx, s_min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ), &min_sum_total_ratio_fx ); // q_sum_total_ratio
    2434       61947 :         exp = q_sum_total_ratio;
    2435       61947 :         move16();
    2436       61947 :         temp = BASOP_Util_Log2( min_sum_total_ratio_fx ); // q25
    2437       61947 :         IF( NE_32( temp, MIN_32 ) )
    2438             :         {
    2439       61946 :             temp = Mpy_32_32( L_add( L_shl( exp, Q25 ), temp ), LOG10_2_Q31 ); // Q25
    2440             :         }
    2441             :         // 20480 = 10 in Q11
    2442       61947 :         min_sum_total_ratio_db_fx = Mpy_32_16_1( temp, 20480 ); // Q21
    2443             : 
    2444       61947 :         stereo_type_detect->lr_total_bb_ratio_db_fx = lr_total_bb_ratio_fx; // Q21
    2445       61947 :         move32();
    2446       61947 :         stereo_type_detect->lr_total_hi_ratio_db_fx = lr_total_hi_ratio_fx; // Q21
    2447       61947 :         move32();
    2448       61947 :         stereo_type_detect->min_sum_total_ratio_db_fx = min_sum_total_ratio_db_fx; // Q21
    2449       61947 :         move32();
    2450             : 
    2451       61947 :         ivas_masa_stereotype_detection_fx( stereo_type_detect );
    2452             :     }
    2453             :     ELSE
    2454             :     {
    2455       19256 :         p_proto_buffer_fx = proto_direct_buffer_f_fx + ( slot_index * num_freq_bands * 4 ); // q_proto_direct_buffer_f
    2456             : 
    2457       19256 :         q_temp[0] = sub( add( add( q_cldfb, min_q_shift[0] ), add( q_cldfb, min_q_shift[0] ) ), 31 );
    2458       19256 :         q_temp[1] = sub( add( add( q_cldfb, min_q_shift[1] ), add( q_cldfb, min_q_shift[1] ) ), 31 );
    2459             : 
    2460     1078616 :         FOR( l = 0; l < num_freq_bands; l++ )
    2461             :         {
    2462     1059360 :             Word16 qidx = s_min( 1, s_max( 0, sub( l, CLDFB_NO_CHANNELS_HALF - 1 ) ) );
    2463     1059360 :             re1 = L_shl( RealBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift
    2464     1059360 :             re2 = L_shl( RealBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift
    2465     1059360 :             im1 = L_shl( ImagBuffer_fx[0][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift
    2466     1059360 :             im2 = L_shl( ImagBuffer_fx[1][0][l], min_q_shift[qidx] ); // q_cldfb+ min_q_shift
    2467             : 
    2468     1059360 :             Real_aux_fx = L_add( re1, re2 ); // q_cldfb+ min_q_shift
    2469     1059360 :             Imag_aux_fx = L_add( im1, im2 ); // q_cldfb+ min_q_shift
    2470             : 
    2471             :             // reference_power_fx[l] = Madd_32_32( Mpy_32_32( Real_aux_fx, Real_aux_fx ), Imag_aux_fx, Imag_aux_fx );
    2472     1059360 :             reference_power_64fx[l] = W_add( W_mult0_32_32( Real_aux_fx, Real_aux_fx ), W_mult0_32_32( Imag_aux_fx, Imag_aux_fx ) ); // q_temp
    2473     1059360 :             move64();
    2474             : 
    2475     1059360 :             IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2476             :             {
    2477      741280 :                 proto_power_smooth_fx[l] = L_add( L_shr( proto_power_smooth_fx[l], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), W_extract_l( W_shr( reference_power_64fx[l], 31 ) ) ); // q_temp
    2478      741280 :                 move32();
    2479             :             }
    2480             :             ELSE
    2481             :             {
    2482      318080 :                 proto_power_smooth_fx[l] = L_add( proto_power_smooth_fx[l], L_shr( W_extract_l( W_shr( reference_power_64fx[l], 31 ) ), sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2483      318080 :                 move32();
    2484             :             }
    2485             : 
    2486     1059360 :             p_proto_buffer_fx[2 * l] = Real_aux_fx; // q_cldfb+ min_q_shift
    2487     1059360 :             move32();
    2488     1059360 :             p_proto_buffer_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+ min_q_shift
    2489     1059360 :             move32();
    2490             : 
    2491     1059360 :             p_proto_buffer_fx[2 * ( num_freq_bands + l )] = L_sub( re1, re2 ); // q_cldfb+ min_q_shift
    2492     1059360 :             move32();
    2493     1059360 :             p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] = L_sub( im1, im2 ); // q_cldfb+ min_q_shift
    2494     1059360 :             move32();
    2495             : 
    2496     1059360 :             temp = Madd_32_32( Mpy_32_32( p_proto_buffer_fx[2 * ( num_freq_bands + l )], p_proto_buffer_fx[2 * ( num_freq_bands + l )] ), p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1], p_proto_buffer_fx[2 * ( num_freq_bands + l ) + 1] ); // q_temp
    2497     1059360 :             IF( LT_16( q_temp[qidx], q_proto_power_smooth[qidx] ) )
    2498             :             {
    2499      741280 :                 proto_power_smooth_fx[l + num_freq_bands] = L_add( L_shr( proto_power_smooth_fx[l + num_freq_bands], sub( q_proto_power_smooth[qidx], q_temp[qidx] ) ), temp ); // q_temp
    2500      741280 :                 move32();
    2501             :             }
    2502             :             ELSE
    2503             :             {
    2504      318080 :                 proto_power_smooth_fx[l + num_freq_bands] = L_add( proto_power_smooth_fx[l + num_freq_bands], L_shr( temp, sub( q_temp[qidx], q_proto_power_smooth[qidx] ) ) ); // q_proto_power_smooth
    2505      318080 :                 move32();
    2506             :             }
    2507             : 
    2508     1059360 :             proto_frame_f_fx[2 * l] = Real_aux_fx; // q_cldfb+ min_q_shift
    2509     1059360 :             move32();
    2510     1059360 :             proto_frame_f_fx[2 * l + 1] = Imag_aux_fx; // q_cldfb+ min_q_shift
    2511     1059360 :             move32();
    2512             : 
    2513     1059360 :             proto_frame_f_fx[2 * num_freq_bands + 2 * l] = re1; // q_cldfb+ min_q_shift
    2514     1059360 :             move32();
    2515     1059360 :             proto_frame_f_fx[2 * num_freq_bands + 2 * l + 1] = im1; // q_cldfb+ min_q_shift
    2516     1059360 :             move32();
    2517     1059360 :             proto_frame_f_fx[4 * num_freq_bands + 2 * l] = re2; // q_cldfb+ min_q_shift
    2518     1059360 :             move32();
    2519     1059360 :             proto_frame_f_fx[4 * num_freq_bands + 2 * l + 1] = im2; // q_cldfb+ min_q_shift
    2520     1059360 :             move32();
    2521             :         }
    2522             :     }
    2523      176435 :     q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[0] ), 1 );
    2524             : 
    2525      176435 :     Word16 norm_shift = 63;
    2526      176435 :     move16();
    2527     5397485 :     FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
    2528             :     {
    2529     5221050 :         IF( reference_power_64fx[l] )
    2530             :         {
    2531     5219735 :             norm_shift = s_min( norm_shift, W_norm( reference_power_64fx[l] ) );
    2532             :         }
    2533             :     }
    2534     5397485 :     FOR( l = 0; l < s_min( num_freq_bands, CLDFB_NO_CHANNELS_HALF ); l++ )
    2535             :     {
    2536     5221050 :         reference_power_fx[l] = W_extract_h( W_shl( reference_power_64fx[l], norm_shift ) ); // q_reference_power_64fx+norm_shift-32
    2537     5221050 :         move32();
    2538             :     }
    2539      176435 :     q_reference_power[0] = sub( add( q_reference_power_64fx, norm_shift ), 32 );
    2540      176435 :     move16();
    2541             : 
    2542      176435 :     q_reference_power_64fx = shl( add( q_cldfb, min_q_shift[1] ), 1 );
    2543      176435 :     norm_shift = 63;
    2544      176435 :     move16();
    2545     4899665 :     FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2546             :     {
    2547     4723230 :         IF( reference_power_64fx[l] )
    2548             :         {
    2549     4721977 :             norm_shift = s_min( norm_shift, W_norm( reference_power_64fx[l] ) );
    2550             :         }
    2551             :     }
    2552     4899665 :     FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2553             :     {
    2554     4723230 :         reference_power_fx[l] = W_extract_h( W_shl( reference_power_64fx[l], norm_shift ) ); // q_reference_power_64fx+norm_shift-32
    2555     4723230 :         move32();
    2556             :     }
    2557      176435 :     q_reference_power[1] = sub( add( q_reference_power_64fx, norm_shift ), 32 );
    2558      176435 :     move16();
    2559             : 
    2560      176435 :     IF( GT_16( min_q_shift[0], min_q_shift[1] ) )
    2561             :     {
    2562          38 :         FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands )
    2563             :         {
    2564          28 :             Scale_sig32( proto_frame_f_fx + shl( l, 1 ), shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) );
    2565             :         }
    2566          10 :         *q_proto_frame_f = add( q_cldfb, min_q_shift[1] );
    2567          10 :         move16();
    2568             :     }
    2569             :     ELSE
    2570             :     {
    2571      624499 :         FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands )
    2572             :         {
    2573      448074 :             Scale_sig32( proto_frame_f_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) );
    2574             :         }
    2575      176425 :         *q_proto_frame_f = add( q_cldfb, min_q_shift[0] );
    2576      176425 :         move16();
    2577             :     }
    2578      176435 :     IF( GT_16( min_q_shift[0], min_q_shift[1] ) )
    2579             :     {
    2580          38 :         FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands )
    2581             :         {
    2582          28 :             Scale_sig32( p_proto_buffer_fx + shl( l, 1 ), shl( s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ), 1 ), sub( min_q_shift[1], min_q_shift[0] ) );
    2583             :         }
    2584          10 :         *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[1] );
    2585          10 :         move16();
    2586             :     }
    2587             :     ELSE
    2588             :     {
    2589      624499 :         FOR( l = 0; l < i_mult( num_proto, num_freq_bands ); l += num_freq_bands )
    2590             :         {
    2591      448074 :             Scale_sig32( p_proto_buffer_fx + shl( add( l, CLDFB_NO_CHANNELS_HALF ), 1 ), shl( s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), 1 ), sub( min_q_shift[0], min_q_shift[1] ) );
    2592             :         }
    2593      176425 :         *q_proto_direct_buffer_f = add( q_cldfb, min_q_shift[0] );
    2594      176425 :         move16();
    2595             :     }
    2596      176435 :     q_proto_power_smooth[0] = s_min( q_proto_power_smooth[0], q_temp[0] );
    2597      176435 :     q_proto_power_smooth[1] = s_min( q_proto_power_smooth[1], q_temp[1] );
    2598      176435 :     move16();
    2599      176435 :     move16();
    2600             : 
    2601      176435 :     return;
    2602             : }
    2603             : 
    2604             : 
    2605             : /*-------------------------------------------------------------------------
    2606             :  * protoSignalComputation4()
    2607             :  *
    2608             :  *
    2609             :  *-------------------------------------------------------------------------*/
    2610             : 
    2611       56000 : void protoSignalComputation4_fx(
    2612             :     Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    2613             :     Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    2614             :     Word32 *proto_frame_f_fx,                                                   /*proto_frame_f_q*/
    2615             :     Word16 *proto_frame_f_q,
    2616             :     Word32 *proto_direct_buffer_f_fx, /*proto_direct_buffer_f_q*/
    2617             :     Word16 *proto_direct_buffer_f_q,
    2618             :     Word32 *reference_power_fx, /*reference_power_q*/
    2619             :     Word16 *reference_power_q,
    2620             :     Word32 *proto_power_smooth_fx, /*proto_power_smooth_q*/
    2621             :     Word16 *proto_power_smooth_q,
    2622             :     const Word16 slot_index,
    2623             :     const Word16 num_outputs_diff,
    2624             :     const Word16 num_freq_bands,
    2625             :     const Word32 *mtx_hoa_decoder, /*q29*/
    2626             :     const Word16 nchan_transport,
    2627             :     const Word16 *sba_map_tc_ind,
    2628             :     Word16 q_cldfb )
    2629             : {
    2630             :     Word16 k, l, idx, idx2;
    2631             :     Word16 n, offset;
    2632             :     Word32 sq_tmp_fx;
    2633             :     Word32 *p_proto_buffer_fx;
    2634             :     Word16 min_q_shift, q_shift;
    2635             : #ifndef FIX_1985_SBA_714_HF_LOSS
    2636             :     Word16 min_q_shift2, q_shift2;
    2637             : #endif
    2638             :     Word32 re, im;
    2639             :     Word16 proto_power_smooth_fx_q, sq_tmp_q;
    2640             : #ifdef FIX_1985_SBA_714_HF_LOSS
    2641             :     Word64 ref_pow64[CLDFB_NO_CHANNELS_MAX], re64;
    2642             :     Word16 sf1, sf2;
    2643             : #endif
    2644             : 
    2645             : #ifdef FIX_1985_SBA_714_HF_LOSS
    2646     3416000 :     FOR( l = 0; l < num_freq_bands; l++ )
    2647             :     {
    2648     3360000 :         re64 = W_mult_32_32( RealBuffer_fx[0][0][l], RealBuffer_fx[0][0][l] );
    2649     3360000 :         re64 = W_mac_32_32( re64, ImagBuffer_fx[0][0][l], ImagBuffer_fx[0][0][l] );
    2650     3360000 :         ref_pow64[l] = W_shr( re64, 1 ); // 2*q_cldfb +1
    2651     3360000 :         move64();
    2652             :     }
    2653      224000 :     FOR( k = 1; k < 4; k++ )
    2654             :     {
    2655    10248000 :         FOR( l = 0; l < num_freq_bands; l++ )
    2656             :         {
    2657    10080000 :             re64 = W_mult_32_32( RealBuffer_fx[k][0][l], RealBuffer_fx[k][0][l] );
    2658    10080000 :             re64 = W_mac_32_32( re64, ImagBuffer_fx[k][0][l], ImagBuffer_fx[k][0][l] );
    2659    10080000 :             ref_pow64[l] = W_add( ref_pow64[l], W_shr( re64, 1 ) ); // 2*q_cldfb +1
    2660    10080000 :             move64();
    2661             :         }
    2662             :     }
    2663       56000 :     sf1 = W_norm_arr( ref_pow64, s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) );
    2664     1736000 :     FOR( l = 0; l < s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ); l++ )
    2665             :     {
    2666     1680000 :         reference_power_fx[l] = W_extract_h( W_shl( ref_pow64[l], sf1 ) );
    2667             :     }
    2668       56000 :     reference_power_q[0] = sub( add( shl( q_cldfb, 1 ), sf1 ), 31 );
    2669             : 
    2670       56000 :     sf2 = W_norm_arr( &ref_pow64[CLDFB_NO_CHANNELS_HALF], s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    2671     1736000 :     FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2672             :     {
    2673     1680000 :         reference_power_fx[l] = W_extract_h( W_shl( ref_pow64[l], sf2 ) );
    2674             :     }
    2675       56000 :     reference_power_q[1] = sub( add( shl( q_cldfb, 1 ), sf2 ), 31 );
    2676             : #else
    2677             :     min_q_shift = Q31;
    2678             :     move16();
    2679             :     q_shift = Q31;
    2680             :     move16();
    2681             :     min_q_shift2 = Q31;
    2682             :     move16();
    2683             :     q_shift2 = Q31;
    2684             :     move16();
    2685             :     sq_tmp_q = 0;
    2686             :     move16();
    2687             : 
    2688             :     set_zero_fx( reference_power_fx, num_freq_bands );
    2689             : 
    2690             :     /* calculate the shift possible for both RealBuffer_fx and ImagBuffer_fx buffers*/
    2691             :     FOR( k = 0; k < s_max( 4, nchan_transport ); k++ )
    2692             :     {
    2693             :         q_shift = L_norm_arr( RealBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) );
    2694             :         min_q_shift = s_min( q_shift, min_q_shift );
    2695             :         q_shift = L_norm_arr( ImagBuffer_fx[k][0], s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ) );
    2696             :         min_q_shift = s_min( q_shift, min_q_shift );
    2697             :         q_shift2 = L_norm_arr( RealBuffer_fx[k][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    2698             :         min_q_shift2 = s_min( q_shift2, min_q_shift2 );
    2699             :         q_shift2 = L_norm_arr( ImagBuffer_fx[k][0] + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ) );
    2700             :         min_q_shift2 = s_min( q_shift2, min_q_shift2 );
    2701             :     }
    2702             :     q_shift = min_q_shift;
    2703             :     min_q_shift = sub( min_q_shift, find_guarded_bits_fx( i_mult( 2, 4 ) ) );
    2704             :     q_shift2 = min_q_shift2;
    2705             :     min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( i_mult( 2, 4 ) ) );
    2706             : 
    2707             :     FOR( k = 0; k < 4; k++ )
    2708             :     {
    2709             :         FOR( l = 0; l < s_min( CLDFB_NO_CHANNELS_HALF, num_freq_bands ); l++ )
    2710             :         {
    2711             :             re = L_shl( RealBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift
    2712             :             im = L_shl( ImagBuffer_fx[k][0][l], min_q_shift ); // q_cldfb+min_q_shift
    2713             : 
    2714             :             sq_tmp_fx = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31
    2715             : 
    2716             :             reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31
    2717             :             move32();
    2718             :         }
    2719             :         FOR( l = CLDFB_NO_CHANNELS_HALF; l < num_freq_bands; l++ )
    2720             :         {
    2721             :             re = L_shl( RealBuffer_fx[k][0][l], min_q_shift2 ); // q_cldfb+min_q_shift
    2722             :             im = L_shl( ImagBuffer_fx[k][0][l], min_q_shift2 ); // q_cldfb+min_q_shift
    2723             : 
    2724             :             sq_tmp_fx = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31
    2725             : 
    2726             :             reference_power_fx[l] = Madd_32_16( reference_power_fx[l], sq_tmp_fx, 16384 /*0.5 in Q15*/ ); // 2*(q_cldfb+min_q_shift)-31
    2727             :             move32();
    2728             :         }
    2729             :     }
    2730             :     sq_tmp_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 );
    2731             :     reference_power_q[0] = sq_tmp_q;
    2732             :     move16();
    2733             :     sq_tmp_q = sub( add( add( q_cldfb, min_q_shift2 ), add( q_cldfb, min_q_shift2 ) ), 31 );
    2734             :     reference_power_q[1] = sq_tmp_q;
    2735             :     move16();
    2736             : #endif
    2737             : 
    2738             : #ifdef FIX_1985_SBA_714_HF_LOSS
    2739       56000 :     min_q_shift = Q31;
    2740             :     /* calculate the shift possible for both RealBuffer_fx and ImagBuffer_fx buffers*/
    2741      287040 :     FOR( k = 0; k < s_max( 4, nchan_transport ); k++ )
    2742             :     {
    2743      231040 :         q_shift = L_norm_arr( RealBuffer_fx[k][0], num_freq_bands );
    2744      231040 :         min_q_shift = s_min( q_shift, min_q_shift );
    2745      231040 :         q_shift = L_norm_arr( ImagBuffer_fx[k][0], num_freq_bands );
    2746      231040 :         min_q_shift = s_min( q_shift, min_q_shift );
    2747             :     }
    2748       56000 :     min_q_shift = sub( min_q_shift, find_guarded_bits_fx( 2 ) );
    2749             : #else
    2750             :     min_q_shift = sub( s_min( q_shift, q_shift2 ), find_guarded_bits_fx( 2 ) );
    2751             : #endif
    2752             : 
    2753             :     /*For decorrelated diffuseness*/
    2754      592000 :     FOR( l = 0; l < num_outputs_diff; l++ )
    2755             :     {
    2756    32696000 :         FOR( k = 0; k < num_freq_bands; k++ )
    2757             :         {
    2758    32160000 :             idx = add( i_mult( i_mult( 2, l ), num_freq_bands ), i_mult( 2, k ) );
    2759    32160000 :             proto_frame_f_fx[idx] = 0;
    2760    32160000 :             move32();
    2761    32160000 :             proto_frame_f_fx[idx + 1] = 0;
    2762    32160000 :             move32();
    2763   165446400 :             FOR( n = 0; n < nchan_transport; n++ )
    2764             :             {
    2765   133286400 :                 idx2 = add( i_mult( l, 16 ), sba_map_tc_ind[n] );
    2766             : 
    2767   133286400 :                 re = L_shl( RealBuffer_fx[n][0][k], min_q_shift ); // q_cldfb+min_q_shift
    2768   133286400 :                 im = L_shl( ImagBuffer_fx[n][0][k], min_q_shift ); // q_cldfb+min_q_shift
    2769             : 
    2770   133286400 :                 proto_frame_f_fx[idx] = Madd_32_32( proto_frame_f_fx[idx], re, mtx_hoa_decoder[idx2] ); // q_cldfb+min_q_shift+29-31 => q_cldfb+min_q_shift-2
    2771   133286400 :                 move32();
    2772   133286400 :                 proto_frame_f_fx[idx + 1] = Madd_32_32( proto_frame_f_fx[idx + 1], im, mtx_hoa_decoder[idx2] ); // q_cldfb+min_q_shift-2
    2773   133286400 :                 move32();
    2774             :             }
    2775             :         }
    2776             :     }
    2777       56000 :     *proto_frame_f_q = sub( add( add( min_q_shift, q_cldfb ), Q29 ), 31 );
    2778       56000 :     move16();
    2779             : 
    2780             :     /* calculate the shift possible to up scale the buffer proto_power_smooth_fx*/
    2781       56000 :     min_q_shift = getScaleFactor32( proto_power_smooth_fx, i_mult( num_outputs_diff, num_freq_bands ) );
    2782       56000 :     min_q_shift = sub( min_q_shift, find_guarded_bits_fx( 2 ) );
    2783             : 
    2784       56000 :     Scale_sig32( proto_power_smooth_fx, i_mult( num_outputs_diff, num_freq_bands ), min_q_shift ); // proto_power_smooth_q+min_q_shift
    2785       56000 :     *proto_power_smooth_q = add( *proto_power_smooth_q, min_q_shift );
    2786       56000 :     move16();
    2787       56000 :     proto_power_smooth_fx_q = *proto_power_smooth_q;
    2788       56000 :     move16();
    2789             : 
    2790             :     /* calculate the shift possible to up scale the values of the buffer proto_frame_f_fx*/
    2791       56000 :     min_q_shift = getScaleFactor32( proto_frame_f_fx, i_mult( 2, i_mult( num_outputs_diff, num_freq_bands ) ) );
    2792       56000 :     min_q_shift = sub( min_q_shift, find_guarded_bits_fx( 2 ) );
    2793             : 
    2794       56000 :     Scale_sig32( proto_frame_f_fx, i_mult( 2, i_mult( num_outputs_diff, num_freq_bands ) ), min_q_shift ); // proto_frame_f_q+min_q_shift
    2795       56000 :     *proto_frame_f_q = add( *proto_frame_f_q, min_q_shift );
    2796       56000 :     move16();
    2797             : 
    2798       56000 :     offset = i_mult( i_mult( slot_index, 2 ), i_mult( num_freq_bands, num_outputs_diff ) );
    2799       56000 :     p_proto_buffer_fx = proto_direct_buffer_f_fx + offset; // proto_direct_buffer_f_q
    2800             : 
    2801      592000 :     FOR( k = 0; k < num_outputs_diff; k++ )
    2802             :     {
    2803    32696000 :         FOR( l = 0; l < num_freq_bands; l++ )
    2804             :         {
    2805    32160000 :             idx = 2 * ( k * num_freq_bands + l );
    2806             : 
    2807    32160000 :             sq_tmp_fx = Madd_32_32( Mpy_32_32( proto_frame_f_fx[idx], proto_frame_f_fx[idx] ), proto_frame_f_fx[idx + 1], proto_frame_f_fx[idx + 1] ); // 2*(proto_frame_f_q)-31
    2808    32160000 :             sq_tmp_q = sub( add( *proto_frame_f_q, *proto_frame_f_q ), 31 );
    2809    32160000 :             proto_power_smooth_fx_q = s_min( *proto_power_smooth_q, sq_tmp_q );
    2810             : 
    2811    32160000 :             proto_power_smooth_fx[l + ( k * num_freq_bands )] = L_add( L_shr( proto_power_smooth_fx[l + ( k * num_freq_bands )], sub( *proto_power_smooth_q, proto_power_smooth_fx_q ) ), L_shr( sq_tmp_fx, sub( sq_tmp_q, proto_power_smooth_fx_q ) ) ); // proto_power_smooth_fx_q
    2812    32160000 :             p_proto_buffer_fx[idx] = proto_frame_f_fx[idx];                                                                                                                                                                                               // proto_frame_f_q
    2813    32160000 :             move32();
    2814    32160000 :             p_proto_buffer_fx[idx + 1] = proto_frame_f_fx[idx + 1]; // proto_frame_f_q
    2815    32160000 :             move32();
    2816             :         }
    2817             :     }
    2818             : 
    2819       56000 :     *proto_direct_buffer_f_q = *proto_frame_f_q;
    2820       56000 :     move16();
    2821       56000 :     proto_power_smooth_q[0] = proto_power_smooth_fx_q;
    2822       56000 :     proto_power_smooth_q[1] = proto_power_smooth_fx_q;
    2823       56000 :     move16();
    2824       56000 :     move16();
    2825             : 
    2826       56000 :     return;
    2827             : }
    2828             : 
    2829             : 
    2830             : /*-------------------------------------------------------------------------
    2831             :  * ivas_dirac_dec_compute_diffuse_proto()
    2832             :  *
    2833             :  * Compute diffuse prototype buffer and smooth power, only for decorrelated bands
    2834             :  *------------------------------------------------------------------------*/
    2835             : 
    2836      333951 : void ivas_dirac_dec_compute_diffuse_proto_fx(
    2837             :     DIRAC_REND_HANDLE hDirACRend,
    2838             :     const Word16 num_freq_bands,
    2839             :     const Word16 slot_idx /* i  : slot index         */
    2840             : )
    2841             : {
    2842             :     Word16 k, l;
    2843             :     Word16 num_freq_bands_diff;
    2844             :     DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
    2845             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
    2846             :     Word16 m;
    2847             : 
    2848             :     Word32 *proto_frame_dec_f_fx;
    2849             :     Word32 *p_diff_buffer_fx, *p_diff_buffer_1_fx;
    2850             :     Word32 *p_proto_diff_fx, *p_power_smooth_fx;
    2851             :     Word32 *p_hoa_enc_fx;
    2852             : 
    2853      333951 :     proto_frame_dec_f_fx = hDirACRend->proto_frame_dec_f_fx; // hDirACRend->proto_frame_dec_f_q
    2854      333951 :     h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
    2855      333951 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
    2856             : 
    2857      333951 :     num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
    2858      333951 :     move16();
    2859             : 
    2860      333951 :     IF( num_freq_bands_diff == 0 )
    2861             :     {
    2862       56000 :         return;
    2863             :     }
    2864             : 
    2865      277951 :     p_diff_buffer_fx = h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx + ( ( ( slot_idx * num_freq_bands_diff ) << 1 ) * hDirACRend->hOutSetup.nchan_out_woLFE ); // proto_diffuse_buffer_f_q
    2866      277951 :     p_diff_buffer_1_fx = p_diff_buffer_fx + 1;
    2867      277951 :     p_power_smooth_fx = h_dirac_output_synthesis_state->proto_power_diff_smooth_fx; // h_dirac_output_synthesis_state->proto_power_diff_smooth_q
    2868             : 
    2869      277951 :     Word16 diffuse_start = imult1616( slot_idx, shl( imult1616( num_freq_bands_diff, hDirACRend->hOutSetup.nchan_out_woLFE ), 1 ) );
    2870             :     Word16 diff_e, smooth_e, proto_e, max_e;
    2871             :     Word32 diff_square, diff_square_1, diff_square_sum;
    2872             :     Word16 diff_square_e;
    2873             :     Word16 old_diff_e;
    2874      277951 :     diff_e = sub( 31, h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q );
    2875      277951 :     old_diff_e = diff_e;
    2876      277951 :     move16();
    2877      277951 :     smooth_e = sub( 31, h_dirac_output_synthesis_state->proto_power_diff_smooth_q );
    2878      277951 :     proto_e = sub( 31, hDirACRend->proto_frame_dec_f_q );
    2879             : 
    2880      277951 :     IF( NE_32( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
    2881             :     {
    2882      213811 :         diff_square_e = add( shl( proto_e, 1 ), 1 );
    2883      213811 :         max_e = add( s_max( diff_square_e, smooth_e ), 1 );
    2884      213811 :         Scale_sig32( p_power_smooth_fx, h_dirac_output_synthesis_state->proto_power_diff_smooth_len, sub( smooth_e, max_e ) ); // 31-max_e
    2885     1721088 :         FOR( k = 0; k < hDirACRend->hOutSetup.nchan_out_woLFE; k++ )
    2886             :         {
    2887     1507277 :             p_proto_diff_fx = proto_frame_dec_f_fx + shl( imult1616( k, num_freq_bands ), 1 ); // hDirACRend->proto_frame_dec_f_q
    2888    24116432 :             FOR( l = 0; l < num_freq_bands_diff; l++ )
    2889             :             {
    2890    22609155 :                 *p_diff_buffer_fx = *( p_proto_diff_fx++ ); // hDirACRend->proto_frame_dec_f_q
    2891    22609155 :                 move32();
    2892    22609155 :                 *p_diff_buffer_1_fx = *( p_proto_diff_fx++ ); // hDirACRend->proto_frame_dec_f_q
    2893    22609155 :                 move32();
    2894             : 
    2895    22609155 :                 diff_square = L_shr( Mpy_32_32( *p_diff_buffer_fx, *p_diff_buffer_fx ), 1 );       // 2 * proto_e + 1
    2896    22609155 :                 diff_square_1 = L_shr( Mpy_32_32( *p_diff_buffer_1_fx, *p_diff_buffer_1_fx ), 1 ); // 2 * proto_e + 1
    2897    22609155 :                 diff_square_sum = L_add( diff_square, diff_square_1 );                             // Q(31- diff_square_e)
    2898    22609155 :                 diff_square_sum = L_shr( diff_square_sum, sub( max_e, diff_square_e ) );           // Q(31-max_e)
    2899    22609155 :                 *p_power_smooth_fx = L_add( *p_power_smooth_fx, diff_square_sum );                 // Q(31-max_e)
    2900    22609155 :                 move32();
    2901             : 
    2902    22609155 :                 p_power_smooth_fx++;
    2903    22609155 :                 p_diff_buffer_fx += 2;
    2904    22609155 :                 p_diff_buffer_1_fx += 2;
    2905             :             }
    2906             :         }
    2907      213811 :         diff_e = proto_e;
    2908      213811 :         move16();
    2909             :     }
    2910             :     ELSE
    2911             :     {
    2912             :         /*DIRAC_SYNTHESIS_PSD_SHD: Virtual LS->HOA encoding*/
    2913       64140 :         Word16 gb = find_guarded_bits_fx( hDirACRend->num_outputs_diff );
    2914       64140 :         diff_square_e = add( shl( add( proto_e, gb ), 1 ), 1 );
    2915       64140 :         max_e = add( s_max( diff_square_e, smooth_e ), 1 );
    2916       64140 :         Scale_sig32( p_power_smooth_fx, h_dirac_output_synthesis_state->proto_power_diff_smooth_len, sub( smooth_e, max_e ) ); // 31-max_e
    2917      587100 :         FOR( k = 0; k < hDirACRend->hOutSetup.nchan_out_woLFE; k++ )
    2918             :         {
    2919     8367360 :             FOR( l = 0; l < num_freq_bands_diff; l++ )
    2920             :             {
    2921     7844400 :                 p_hoa_enc_fx = hDirACRend->hoa_encoder_fx + k;        // q31
    2922     7844400 :                 p_proto_diff_fx = proto_frame_dec_f_fx + shl( l, 1 ); // hDirACRend->proto_frame_dec_f_q
    2923             : 
    2924     7844400 :                 *p_diff_buffer_fx = 0;
    2925     7844400 :                 move32();
    2926     7844400 :                 *p_diff_buffer_1_fx = 0;
    2927     7844400 :                 move32();
    2928             : 
    2929             :                 /*LS to HOA*/
    2930    70599600 :                 FOR( m = 0; m < hDirACRend->num_outputs_diff; m++ )
    2931             :                 {
    2932    62755200 :                     *p_diff_buffer_fx = L_add( *p_diff_buffer_fx, L_shr( Mpy_32_32( *p_hoa_enc_fx, *p_proto_diff_fx ), gb ) ); // hDirACRend->proto_frame_dec_f_q-gb
    2933    62755200 :                     move32();
    2934    62755200 :                     *p_diff_buffer_1_fx = L_add( *p_diff_buffer_1_fx, L_shr( Mpy_32_32( *p_hoa_enc_fx, *( p_proto_diff_fx + 1 ) ), gb ) ); // hDirACRend->proto_frame_dec_f_q-gb
    2935    62755200 :                     move32();
    2936    62755200 :                     p_hoa_enc_fx += hDirACRend->hOutSetup.nchan_out_woLFE;
    2937    62755200 :                     p_proto_diff_fx += shl( num_freq_bands, 1 );
    2938             :                 }
    2939             : 
    2940     7844400 :                 diff_square = L_shr( Mpy_32_32( *p_diff_buffer_fx, *p_diff_buffer_fx ), 1 );       // 2*( proto_e + gb) + 1
    2941     7844400 :                 diff_square_1 = L_shr( Mpy_32_32( *p_diff_buffer_1_fx, *p_diff_buffer_1_fx ), 1 ); // 2*( proto_e + gb) + 1
    2942     7844400 :                 diff_square_sum = L_add( diff_square, diff_square_1 );                             // 2*( proto_e + gb) + 1
    2943     7844400 :                 diff_square_sum = L_shr( diff_square_sum, sub( max_e, diff_square_e ) );           // 31-max_e
    2944     7844400 :                 *p_power_smooth_fx = L_add( *p_power_smooth_fx, diff_square_sum );                 // 31-max_e
    2945     7844400 :                 move32();
    2946             : 
    2947     7844400 :                 p_power_smooth_fx++;
    2948             : 
    2949     7844400 :                 p_diff_buffer_fx += 2;
    2950     7844400 :                 p_diff_buffer_1_fx += 2;
    2951             :             }
    2952             :         }
    2953       64140 :         diff_e = add( proto_e, gb );
    2954             :     }
    2955      277951 :     h_dirac_output_synthesis_state->proto_power_diff_smooth_q = sub( 31, max_e );
    2956      277951 :     move16();
    2957             : 
    2958      277951 :     Word16 new_diff_e = s_max( diff_e, old_diff_e );
    2959      277951 :     Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx, diffuse_start, sub( old_diff_e, new_diff_e ) ); // 31-new_diff_e
    2960      277951 :     Scale_sig32( h_dirac_output_synthesis_state->proto_diffuse_buffer_f_fx + diffuse_start,
    2961      277951 :                  i_mult( shl( num_freq_bands_diff, 1 ), hDirACRend->hOutSetup.nchan_out_woLFE ), sub( diff_e, new_diff_e ) ); // 31-new_diff_e
    2962      277951 :     h_dirac_output_synthesis_state->proto_diffuse_buffer_f_q = sub( 31, new_diff_e );
    2963      277951 :     move16();
    2964             : 
    2965      277951 :     return;
    2966             : }
    2967             : 
    2968             : 
    2969             : /*-------------------------------------------------------------------------
    2970             :  * computeDirectionAngles()
    2971             :  *
    2972             :  *------------------------------------------------------------------------*/
    2973             : 
    2974      746303 : void computeDirectionAngles_fx(
    2975             :     Word32 *intensity_real_x_fx, /*q_intensity_real*/
    2976             :     Word32 *intensity_real_y_fx, /*q_intensity_real*/
    2977             :     Word32 *intensity_real_z_fx, /*q_intensity_real*/
    2978             :     Word16 q_intensity_real,
    2979             :     const Word16 num_frequency_bands,
    2980             :     Word16 *azimuth,
    2981             :     Word16 *elevation )
    2982             : {
    2983             :     Word16 k;
    2984             :     Word32 intensityNorm;
    2985             :     Word32 x, y, z, radius;
    2986             :     Word32 temp;
    2987             :     Word16 res, q_intensityNorm, exp, q_temp;
    2988             :     Word16 q_x, q_y, q_z, exp1, exp2, exp3, q_tmp1, q_tmp2;
    2989             :     Word32 x_re, y_re, z_re, tmp1, tmp2;
    2990             : 
    2991      746303 :     exp = 0;
    2992      746303 :     move16();
    2993             : 
    2994     8955636 :     FOR( k = 0; k < num_frequency_bands; ++k )
    2995             :     {
    2996     8209333 :         exp1 = norm_l( intensity_real_x_fx[k] );
    2997     8209333 :         exp2 = norm_l( intensity_real_y_fx[k] );
    2998     8209333 :         exp3 = norm_l( intensity_real_z_fx[k] );
    2999     8209333 :         x_re = L_shl( intensity_real_x_fx[k], exp1 ); /*q_intensity_real+exp1*/
    3000     8209333 :         y_re = L_shl( intensity_real_y_fx[k], exp2 ); /*q_intensity_real+exp2*/
    3001     8209333 :         z_re = L_shl( intensity_real_z_fx[k], exp3 ); /*q_intensity_real+exp3*/
    3002             : 
    3003     8209333 :         tmp1 = Mpy_32_32( x_re, x_re ); /*2*(q_intensity_real+exp1)-31*/
    3004     8209333 :         q_tmp1 = sub( add( add( q_intensity_real, exp1 ), add( q_intensity_real, exp1 ) ), 31 );
    3005     8209333 :         tmp2 = Mpy_32_32( y_re, y_re ); /*2*(q_intensity_real+exp2)-31*/
    3006     8209333 :         q_tmp2 = sub( add( add( q_intensity_real, exp2 ), add( q_intensity_real, exp2 ) ), 31 );
    3007             : 
    3008     8209333 :         temp = BASOP_Util_Add_Mant32Exp( tmp1, sub( 31, q_tmp1 ), tmp2, sub( 31, q_tmp2 ), &exp ); // 31-exp
    3009             : 
    3010     8209333 :         tmp2 = Mpy_32_32( z_re, z_re ); /*2*(q_intensity_real+exp3)-31*/
    3011     8209333 :         q_tmp2 = sub( add( add( q_intensity_real, exp3 ), add( q_intensity_real, exp3 ) ), 31 );
    3012             : 
    3013     8209333 :         intensityNorm = BASOP_Util_Add_Mant32Exp( temp, exp, tmp2, sub( 31, q_tmp2 ), &exp ); // 31-exp
    3014     8209333 :         q_intensityNorm = sub( 31, exp );
    3015             : 
    3016     8209333 :         IF( LE_32( intensityNorm, EPSILON_FX ) )
    3017             :         {
    3018       24502 :             intensityNorm = ONE_IN_Q30; // q30
    3019       24502 :             move32();
    3020       24502 :             x = ONE_IN_Q30; // q30
    3021       24502 :             move32();
    3022       24502 :             q_x = Q30;
    3023       24502 :             move16();
    3024       24502 :             y = 0;
    3025       24502 :             move32();
    3026       24502 :             q_y = Q30;
    3027       24502 :             move16();
    3028       24502 :             z = 0;
    3029       24502 :             move32();
    3030       24502 :             q_z = Q30;
    3031       24502 :             move16();
    3032             :         }
    3033             :         ELSE
    3034             :         {
    3035     8184831 :             temp = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q30, intensityNorm, &exp ); // Q=31-(exp-(30-q_intensityNorm))
    3036     8184831 :             exp = sub( exp, sub( Q30, q_intensityNorm ) );
    3037     8184831 :             temp = Sqrt32( temp, &exp ); // Q=31-exp
    3038     8184831 :             q_temp = sub( 31, exp );
    3039             : 
    3040     8184831 :             x = Mpy_32_32( x_re, temp ); /*Q=q_intensity_real+exp1+q_temp-31*/
    3041     8184831 :             q_x = sub( add( add( q_intensity_real, exp1 ), q_temp ), 31 );
    3042     8184831 :             y = Mpy_32_32( y_re, temp ); /*Q=q_intensity_real+exp2+q_temp-31*/
    3043     8184831 :             q_y = sub( add( add( q_intensity_real, exp2 ), q_temp ), 31 );
    3044     8184831 :             z = Mpy_32_32( z_re, temp ); /*Q=q_intensity_real+exp3+q_temp-31*/
    3045     8184831 :             q_z = sub( add( add( q_intensity_real, exp3 ), q_temp ), 31 );
    3046             :         }
    3047             : 
    3048     8209333 :         tmp1 = Mpy_32_32( x, x ); /*Q=2*q_x-31*/
    3049     8209333 :         q_tmp1 = sub( add( q_x, q_x ), 31 );
    3050             : 
    3051     8209333 :         tmp2 = Mpy_32_32( y, y ); /*Q=2*q_y-31*/
    3052     8209333 :         q_tmp2 = sub( add( q_y, q_y ), 31 );
    3053             : 
    3054     8209333 :         temp = BASOP_Util_Add_Mant32Exp( tmp1, sub( 31, q_tmp1 ), tmp2, sub( 31, q_tmp2 ), &exp ); // Q=31-exp
    3055     8209333 :         radius = Sqrt32( temp, &exp );                                                             // Q=31-exp
    3056             : 
    3057     8209333 :         res = BASOP_util_atan2( y, x, sub( sub( 31, q_y ), sub( 31, q_x ) ) );                                                          /* Q13 */
    3058     8209333 :         res = add( s_max( -23040 /*-180 q7*/, s_min( 23040 /*180 q7*/, mult( res, _180_OVER_PI_Q9 /*180/pi q9*/ ) ) ), 64 /*0.5 q7*/ ); /* Q7 */
    3059     8209333 :         azimuth[k] = shr( abs_s( res ), Q7 );                                                                                           /* Q0 */
    3060     8209333 :         move16();
    3061     8209333 :         IF( res < 0 )
    3062             :         {
    3063     5033099 :             azimuth[k] = negate( azimuth[k] );
    3064     5033099 :             move16();
    3065             :         }
    3066             : 
    3067     8209333 :         res = BASOP_util_atan2( z, radius, sub( sub( 31, q_z ), exp ) );                                                               /* Q13 */
    3068     8209333 :         res = add( s_max( -11520 /*-90 q7*/, s_min( 23040 /*180 q7*/, mult( res, _180_OVER_PI_Q9 /*180/pi q9*/ ) ) ), 64 /*0.5 q7*/ ); /* Q7 */
    3069     8209333 :         elevation[k] = shr( abs_s( res ), Q7 );                                                                                        /* Q0 */
    3070     8209333 :         move16();
    3071     8209333 :         IF( res < 0 )
    3072             :         {
    3073     4067342 :             elevation[k] = negate( elevation[k] );
    3074     4067342 :             move16();
    3075             :         }
    3076             :     }
    3077             : 
    3078      746303 :     return;
    3079             : }
    3080             : 
    3081             : 
    3082             : /*-------------------------------------------------------------------------
    3083             :  * ivas_masa_init_stereotype_detection()
    3084             :  *
    3085             :  * Initialize stereo transport signal type detection
    3086             :  *------------------------------------------------------------------------*/
    3087             : 
    3088         144 : void ivas_masa_init_stereotype_detection_fx(
    3089             :     MASA_STEREO_TYPE_DETECT *stereo_type_detect )
    3090             : {
    3091         144 :     stereo_type_detect->masa_stereo_type = MASA_STEREO_DOWNMIX;
    3092         144 :     move32();
    3093         144 :     stereo_type_detect->current_stereo_type = MASA_STEREO_DOWNMIX;
    3094         144 :     move32();
    3095         144 :     stereo_type_detect->type_change_direction = MASA_STEREO_DOWNMIX;
    3096         144 :     move32();
    3097             : 
    3098         144 :     stereo_type_detect->counter = 0;
    3099         144 :     move16();
    3100         144 :     stereo_type_detect->interpolator = 0;
    3101         144 :     move16();
    3102             : 
    3103         144 :     stereo_type_detect->dipole_freq_range[0] = 1;
    3104         144 :     move16();
    3105         144 :     stereo_type_detect->dipole_freq_range[1] = 3;
    3106         144 :     move16();
    3107             : 
    3108         144 :     stereo_type_detect->left_bb_power_fx = 0; /* Broadband estimates */
    3109         144 :     move32();
    3110         144 :     stereo_type_detect->q_left_bb_power = Q31;
    3111         144 :     move16();
    3112         144 :     stereo_type_detect->right_bb_power_fx = 0;
    3113         144 :     move32();
    3114         144 :     stereo_type_detect->q_right_bb_power = Q31;
    3115         144 :     move16();
    3116         144 :     stereo_type_detect->total_bb_power_fx = 0;
    3117         144 :     move32();
    3118         144 :     stereo_type_detect->q_total_bb_power = Q31;
    3119         144 :     move16();
    3120             : 
    3121         144 :     stereo_type_detect->left_hi_power_fx = 0; /* High-frequency estimates */
    3122         144 :     move32();
    3123         144 :     stereo_type_detect->q_left_hi_power = Q31;
    3124         144 :     move16();
    3125         144 :     stereo_type_detect->right_hi_power_fx = 0;
    3126         144 :     move32();
    3127         144 :     stereo_type_detect->q_right_hi_power = Q31;
    3128         144 :     move16();
    3129         144 :     stereo_type_detect->total_hi_power_fx = 0;
    3130         144 :     move32();
    3131         144 :     stereo_type_detect->q_total_hi_power = Q31;
    3132         144 :     move16();
    3133             : 
    3134         144 :     set32_fx( stereo_type_detect->sum_power_fx, 0, MASA_SUM_FREQ_RANGE_BINS );
    3135         144 :     set32_fx( stereo_type_detect->total_power_fx, 0, MASA_SUM_FREQ_RANGE_BINS );
    3136             : 
    3137         144 :     set16_fx( stereo_type_detect->exp_sum_power, 0, MASA_SUM_FREQ_RANGE_BINS );
    3138         144 :     set16_fx( stereo_type_detect->exp_total_power, 0, MASA_SUM_FREQ_RANGE_BINS );
    3139             : 
    3140         144 :     stereo_type_detect->subtract_power_y_fx = 0;
    3141         144 :     move32();
    3142         144 :     stereo_type_detect->q_subtract_power_y = Q31;
    3143         144 :     move16();
    3144         144 :     stereo_type_detect->subtract_power_y_smooth_fx = 0;
    3145         144 :     move32();
    3146         144 :     stereo_type_detect->q_subtract_power_y_smooth = Q31;
    3147         144 :     move16();
    3148         144 :     stereo_type_detect->target_power_y_smooth_fx = 0;
    3149         144 :     move32();
    3150         144 :     stereo_type_detect->q_target_power_y_smooth = 31;
    3151         144 :     move16();
    3152             : 
    3153         144 :     stereo_type_detect->lr_total_bb_ratio_db_fx = 0;
    3154         144 :     move32();
    3155         144 :     stereo_type_detect->lr_total_hi_ratio_db_fx = 0;
    3156         144 :     move32();
    3157         144 :     stereo_type_detect->min_sum_total_ratio_db_fx = 0;
    3158         144 :     move32();
    3159         144 :     stereo_type_detect->subtract_target_ratio_db_fx = 0;
    3160         144 :     move32();
    3161             : 
    3162         144 :     return;
    3163             : }
    3164             : 
    3165             : 
    3166             : /*-------------------------------------------------------------------------
    3167             :  * ivas_masa_stereotype_detection()
    3168             :  *
    3169             :  * Detect the type of the transport audio signals
    3170             :  *------------------------------------------------------------------------*/
    3171             : 
    3172       61947 : void ivas_masa_stereotype_detection_fx(
    3173             :     MASA_STEREO_TYPE_DETECT *stereo_type_detect )
    3174             : {
    3175             :     Word32 lr_total_bb_ratio_db_fx;
    3176             :     Word32 lr_total_hi_ratio_db_fx;
    3177             :     Word32 min_sum_total_ratio_db_fx;
    3178             :     Word32 subtract_target_ratio_db_fx;
    3179             :     Word32 change_to_spaced_fx;
    3180             :     Word16 change_to_spaced_selection;
    3181             :     Word32 change_to_downmix_fx;
    3182             :     Word32 change_to_downmix2_fx;
    3183             :     Word16 change_to_downmix_selection;
    3184             :     Word32 subtract_temp_fx;
    3185             :     Word32 min_sum_temp_fx;
    3186             :     Word32 lr_total_bb_temp_fx;
    3187             :     Word32 lr_total_hi_temp_fx;
    3188             :     Word32 temp;
    3189             : 
    3190       61947 :     lr_total_bb_ratio_db_fx = stereo_type_detect->lr_total_bb_ratio_db_fx; // q21
    3191       61947 :     move32();
    3192       61947 :     lr_total_hi_ratio_db_fx = stereo_type_detect->lr_total_hi_ratio_db_fx; // q21
    3193       61947 :     move32();
    3194       61947 :     min_sum_total_ratio_db_fx = stereo_type_detect->min_sum_total_ratio_db_fx; // q21
    3195       61947 :     move32();
    3196       61947 :     subtract_target_ratio_db_fx = stereo_type_detect->subtract_target_ratio_db_fx; // q21
    3197       61947 :     move32();
    3198             : 
    3199             :     /* Determine if the determined features match the spaced mic type */
    3200       61947 :     change_to_spaced_selection = 0;
    3201       61947 :     move16();
    3202       61947 :     IF( LT_32( subtract_target_ratio_db_fx, -THREE_Q21 /*-3 q21*/ ) )
    3203             :     {
    3204             :         /* subtract_temp = ( -subtract_target_ratio_db - 3.0f ) / 3.0f; */
    3205       19626 :         temp = L_sub( L_shr( -subtract_target_ratio_db_fx, 1 ), L_shr( THREE_Q21, 1 ) ); // q20
    3206       19626 :         subtract_temp_fx = Mpy_32_32( temp, 715827883 /* 1 / 3.0f in Q31 */ );           // q20
    3207       19626 :         subtract_temp_fx = L_shl( subtract_temp_fx, 1 );                                 /* Q21 */
    3208             : 
    3209             :         /* min_sum_temp = max( -min_sum_total_ratio_db / 6.0f, 0.0f ); */
    3210       19626 :         min_sum_temp_fx = Mpy_32_32_r( -min_sum_total_ratio_db_fx, 357913941 /* 1 / 6.0f in Q31 */ ); /* Q21 */
    3211       19626 :         min_sum_temp_fx = L_max( min_sum_temp_fx, 0 );                                                /*q21*/
    3212             : 
    3213             :         /* lr_total_bb_temp = lr_total_bb_ratio_db / 6.0f; */
    3214       19626 :         lr_total_bb_temp_fx = Mpy_32_32_r( lr_total_bb_ratio_db_fx, 357913941 /* 1 / 6.0f in Q31 */ ); /* Q21 */
    3215             : 
    3216       19626 :         change_to_spaced_fx = L_add( L_add( subtract_temp_fx, min_sum_temp_fx ), lr_total_bb_temp_fx ); /* Q21 */
    3217             : 
    3218       19626 :         IF( GE_32( change_to_spaced_fx, ONE_IN_Q21 ) )
    3219             :         {
    3220       10505 :             change_to_spaced_selection = 1;
    3221       10505 :             move16();
    3222             :         }
    3223             :     }
    3224             : 
    3225             :     /* Determine if the determined features match the downmix type, according to a metric */
    3226       61947 :     change_to_downmix_selection = 0;
    3227       61947 :     move16();
    3228       61947 :     IF( subtract_target_ratio_db_fx > 0 )
    3229             :     {
    3230             :         /* subtract_temp = subtract_target_ratio_db / 3.0f; */
    3231       25564 :         subtract_temp_fx = Mpy_32_32( subtract_target_ratio_db_fx, 715827883 /* 1 / 3.0f in Q31 */ ); /* Q21 */
    3232             : 
    3233             :         /* min_sum_temp = ( min_sum_total_ratio_db + 1.0f ) / 6.0f; */
    3234       25564 :         min_sum_temp_fx = Mpy_32_32_r( L_add( min_sum_total_ratio_db_fx, ONE_IN_Q21 ), 357913941 /* 1 / 6.0f in Q31 */ ); /* Q21 */
    3235             : 
    3236             :         /* lr_total_bb_temp = -lr_total_bb_ratio_db / 6.0f; */
    3237       25564 :         lr_total_bb_temp_fx = Mpy_32_32_r( -lr_total_bb_ratio_db_fx, 357913941 /* 1 / 6.0f in Q31 */ ); /* Q21 */
    3238             : 
    3239       25564 :         change_to_downmix_fx = L_add( L_add( subtract_temp_fx, min_sum_temp_fx ), lr_total_bb_temp_fx ); /* Q21 */
    3240             : 
    3241       25564 :         IF( GE_32( change_to_downmix_fx, ONE_IN_Q21 /*1 q21*/ ) )
    3242             :         {
    3243       11526 :             change_to_downmix_selection = 1;
    3244       11526 :             move16();
    3245             :         }
    3246             :     }
    3247             : 
    3248             :     /* Determine if the determined features match the downmix type, according to another metric */
    3249       61947 :     IF( LT_32( lr_total_hi_ratio_db_fx, -25165824 ) ) // 25165824 = 12.0 in Q21
    3250             :     {
    3251             :         /* subtract_temp = ( subtract_target_ratio_db + 4.0f ) / 3.0f; */
    3252         324 :         subtract_temp_fx = Mpy_32_32( L_add( subtract_target_ratio_db_fx, 8388608 /* 4.0 in Q21 */ ), 715827883 /* 1 / 3.0f in Q31 */ );
    3253             : 
    3254             :         /* min_sum_temp = min_sum_total_ratio_db / 6.0f; */
    3255         324 :         min_sum_temp_fx = Mpy_32_32_r( min_sum_total_ratio_db_fx, 357913941 /* 1 / 6.0f in Q31 */ );
    3256             : 
    3257             :         /* lr_total_hi_temp = ( -lr_total_hi_ratio_db - 12.0f ) / 3.0f; */
    3258         324 :         lr_total_hi_temp_fx = Mpy_32_32( L_sub( -lr_total_hi_ratio_db_fx, 25165824 /* 12.0 in Q21 */ ), 715827883 /* 1 / 3.0f in Q31 */ );
    3259             : 
    3260         324 :         change_to_downmix2_fx = L_add( L_add( subtract_temp_fx, min_sum_temp_fx ), lr_total_hi_temp_fx ); // Q21
    3261             : 
    3262         324 :         IF( GE_32( change_to_downmix2_fx, ONE_IN_Q21 /*1 q21*/ ) )
    3263             :         {
    3264         303 :             change_to_downmix_selection = 1;
    3265         303 :             move16();
    3266             :         }
    3267             :     }
    3268             : 
    3269       61947 :     IF( LT_16( stereo_type_detect->counter, 400 ) )
    3270             :     {
    3271       19563 :         stereo_type_detect->counter++;
    3272             :     }
    3273             :     ELSE
    3274             :     {
    3275       42384 :         IF( EQ_16( change_to_spaced_selection, 1 ) )
    3276             :         {
    3277        8800 :             stereo_type_detect->masa_stereo_type = MASA_STEREO_SPACED_MICS;
    3278        8800 :             move32();
    3279             :         }
    3280       33584 :         ELSE IF( EQ_16( change_to_downmix_selection, 1 ) )
    3281             :         {
    3282        6656 :             stereo_type_detect->masa_stereo_type = MASA_STEREO_DOWNMIX;
    3283        6656 :             move32();
    3284             :         }
    3285             :     }
    3286             : 
    3287       61947 :     IF( stereo_type_detect->interpolator == 0 )
    3288             :     {
    3289       61919 :         IF( NE_16( stereo_type_detect->current_stereo_type, stereo_type_detect->masa_stereo_type ) )
    3290             :         {
    3291           2 :             stereo_type_detect->interpolator = 1;
    3292           2 :             move16();
    3293           2 :             stereo_type_detect->type_change_direction = stereo_type_detect->masa_stereo_type;
    3294           2 :             move32();
    3295             :         }
    3296             :     }
    3297             : 
    3298       61947 :     return;
    3299             : }
    3300             : 
    3301             : 
    3302             : /*-------------------------------------------------------------------------
    3303             :  * computeIntensityVector_dec()
    3304             :  *
    3305             :  *
    3306             :  *------------------------------------------------------------------------*/
    3307             : 
    3308      746303 : void computeIntensityVector_dec_fx(
    3309             :     Word32 Cldfb_RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    3310             :     Word32 Cldfb_ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    3311             :     Word16 q_cldfb,
    3312             :     const Word16 num_frequency_bands,
    3313             :     Word32 *intensity_real_x_fx, /*q_intensity_real*/
    3314             :     Word32 *intensity_real_y_fx, /*q_intensity_real*/
    3315             :     Word32 *intensity_real_z_fx, /*q_intensity_real*/
    3316             :     Word16 *q_intensity_real )
    3317             : {
    3318             :     /*
    3319             :      * W = a + ib; Y = c + id
    3320             :      * real(W*Y') = ac + bd
    3321             :      */
    3322             :     Word16 i;
    3323             :     Word32 re1, re2, im1, im2;
    3324             :     Word16 min_q_shift;
    3325             : 
    3326      746303 :     min_q_shift = Q31;
    3327      746303 :     move32();
    3328             :     /* calculate the max possible shift for the buffers Cldfb_RealBuffer_fx and Cldfb_ImagBuffer_fx*/
    3329     3731515 :     FOR( i = 0; i < 4; i++ )
    3330             :     {
    3331     2985212 :         min_q_shift = s_min( min_q_shift, s_min( L_norm_arr( Cldfb_RealBuffer_fx[i][0], num_frequency_bands ), L_norm_arr( Cldfb_ImagBuffer_fx[i][0], num_frequency_bands ) ) );
    3332             :     }
    3333             : 
    3334      746303 :     min_q_shift = sub( min_q_shift, 1 ); // guard bits
    3335             : 
    3336     8955636 :     FOR( i = 0; i < num_frequency_bands; ++i )
    3337             :     {
    3338     8209333 :         re1 = L_shl( Cldfb_RealBuffer_fx[0][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3339     8209333 :         im1 = L_shl( Cldfb_ImagBuffer_fx[0][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3340     8209333 :         re2 = L_shl( Cldfb_RealBuffer_fx[3][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3341     8209333 :         im2 = L_shl( Cldfb_ImagBuffer_fx[3][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3342             : 
    3343     8209333 :         intensity_real_x_fx[i] = Madd_32_32( Mpy_32_32( re2, re1 ), im2, im1 ); /*2*(q_cldfb+min_q_shift)-31*/
    3344     8209333 :         move32();
    3345             : 
    3346     8209333 :         re2 = L_shl( Cldfb_RealBuffer_fx[1][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3347     8209333 :         im2 = L_shl( Cldfb_ImagBuffer_fx[1][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3348             : 
    3349     8209333 :         intensity_real_y_fx[i] = Madd_32_32( Mpy_32_32( re2, re1 ), im2, im1 ); /*2*(q_cldfb+min_q_shift)-31*/
    3350     8209333 :         move32();
    3351             : 
    3352     8209333 :         re2 = L_shl( Cldfb_RealBuffer_fx[2][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3353     8209333 :         im2 = L_shl( Cldfb_ImagBuffer_fx[2][0][i], min_q_shift ); /*q_cldfb+min_q_shift*/
    3354             : 
    3355     8209333 :         intensity_real_z_fx[i] = Madd_32_32( Mpy_32_32( re2, re1 ), im2, im1 ); /*2*(q_cldfb+min_q_shift)-31*/
    3356     8209333 :         move32();
    3357             :     }
    3358             : 
    3359      746303 :     *q_intensity_real = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 );
    3360      746303 :     move16();
    3361             : 
    3362      746303 :     return;
    3363             : }
    3364             : 
    3365             : 
    3366             : /*-------------------------------------------------------------------------
    3367             :  * ivas_lfe_synth_with_cldfb()
    3368             :  *
    3369             :  *
    3370             :  *------------------------------------------------------------------------*/
    3371             : 
    3372       26560 : void ivas_lfe_synth_with_cldfb_fx(
    3373             :     MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth,
    3374             :     Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],  /*q_cldfb*/
    3375             :     Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],  /*q_cldfb*/
    3376             :     Word32 RealBufferLfe_fx[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    3377             :     Word32 ImagBufferLfe_fx[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /*q_cldfb*/
    3378             :     const Word16 slot_index,
    3379             :     const Word16 subframe_index,
    3380             :     const Word16 nchan_transport,
    3381             :     Word16 q_cldfb )
    3382             : {
    3383             :     Word16 i;
    3384             : 
    3385             :     Word16 lfeGain_fx, transportGain_fx;
    3386             :     Word32 protoLfeReal_fx, protoLfeImag_fx;
    3387             :     Word32 transportEne_fx, protoLfeEne_fx, targetEneLfe_fx, targetEneTrans_fx;
    3388             :     Word16 transportEne_q, protoLfeEne_q, targetEneLfe_q, targetEneTrans_q;
    3389       26560 :     Word16 temp, temp_q = 0;
    3390             :     Word16 transportGain_q_fx, lfeGain_q_fx;
    3391             :     Word16 exp, min_q_shift;
    3392             :     Word32 re, im;
    3393       26560 :     move16(); // temp_q
    3394             : 
    3395       26560 :     exp = Q31;
    3396       26560 :     move16();
    3397       26560 :     min_q_shift = Q31;
    3398       26560 :     move16();
    3399             : 
    3400       26560 :     set_zero_fx( RealBufferLfe_fx[slot_index], CLDFB_NO_CHANNELS_MAX );
    3401       26560 :     set_zero_fx( ImagBufferLfe_fx[slot_index], CLDFB_NO_CHANNELS_MAX );
    3402             : 
    3403       54240 :     FOR( i = 0; i < nchan_transport; i++ )
    3404             :     {
    3405       27680 :         IF( RealBuffer_fx[i][0][0] )
    3406             :         {
    3407       27660 :             exp = norm_l( RealBuffer_fx[i][0][0] );
    3408             :         }
    3409       27680 :         min_q_shift = s_min( min_q_shift, exp );
    3410       27680 :         IF( ImagBuffer_fx[i][0][0] )
    3411             :         {
    3412       27664 :             exp = norm_l( ImagBuffer_fx[i][0][0] );
    3413             :         }
    3414       27680 :         min_q_shift = s_min( min_q_shift, exp );
    3415             :     }
    3416       26560 :     min_q_shift = sub( sub( min_q_shift, find_guarded_bits_fx( nchan_transport ) ), 1 );
    3417             : 
    3418       26560 :     re = L_shl( RealBuffer_fx[0][0][0], min_q_shift ); // q_cldfb+min_q_shift
    3419       26560 :     im = L_shl( ImagBuffer_fx[0][0][0], min_q_shift ); // q_cldfb+min_q_shift
    3420             : 
    3421       26560 :     protoLfeReal_fx = re; // q_cldfb+min_q_shift
    3422       26560 :     move32();
    3423       26560 :     protoLfeImag_fx = im; // q_cldfb+min_q_shift
    3424       26560 :     move32();
    3425       26560 :     transportEne_fx = Madd_32_32( Mpy_32_32( re, re ), im, im ); // 2*(q_cldfb+min_q_shift)-31
    3426       27680 :     FOR( i = 1; i < nchan_transport; i++ )
    3427             :     {
    3428        1120 :         re = L_shl( RealBuffer_fx[i][0][0], min_q_shift ); // q_cldfb+min_q_shift
    3429        1120 :         im = L_shl( ImagBuffer_fx[i][0][0], min_q_shift ); // q_cldfb+min_q_shift
    3430             : 
    3431        1120 :         protoLfeReal_fx = L_add( protoLfeReal_fx, re );                                        // q_cldfb+min_q_shift
    3432        1120 :         protoLfeImag_fx = L_add( protoLfeImag_fx, im );                                        // q_cldfb+min_q_shift
    3433        1120 :         transportEne_fx = L_add( transportEne_fx, Madd_32_32( Mpy_32_32( re, re ), im, im ) ); // 2*(q_cldfb+min_q_shift)-31
    3434             :     }
    3435       26560 :     transportEne_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 );
    3436             : 
    3437       26560 :     protoLfeEne_fx = Madd_32_32( Mpy_32_32( protoLfeReal_fx, protoLfeReal_fx ), protoLfeImag_fx, protoLfeImag_fx ); // 2*(q_cldfb+min_q_shift)-31
    3438       26560 :     protoLfeEne_q = sub( add( add( q_cldfb, min_q_shift ), add( q_cldfb, min_q_shift ) ), 31 );
    3439             : 
    3440       26560 :     targetEneLfe_fx = Mpy_32_16_1( transportEne_fx, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ); // targetEneLfe_q+14-15
    3441       26560 :     targetEneLfe_q = sub( add( transportEne_q, Q14 ), 15 );
    3442             : 
    3443       26560 :     temp = s_max( sub( ONE_IN_Q14 /*1 q14*/, hMasaLfeSynth->lfeToTotalEnergyRatio_fx[subframe_index] ), 164 /*0.01 in Q14*/ ); // q14
    3444       26560 :     targetEneTrans_fx = Mpy_32_16_1( transportEne_fx, temp );                                                                  /*transportEne_q+Q14 -15*/
    3445       26560 :     targetEneTrans_q = sub( add( transportEne_q, Q14 ), 15 );
    3446             : 
    3447       26560 :     hMasaLfeSynth->transportEneSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->transportEneSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); // hMasaLfeSynth->transportEneSmooth_q+15-15
    3448       26560 :     move32();
    3449       26560 :     hMasaLfeSynth->protoLfeEneSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->protoLfeEneSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); // hMasaLfeSynth->protoLfeEneSmooth_q+15-15
    3450       26560 :     move32();
    3451       26560 :     hMasaLfeSynth->targetEneLfeSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneLfeSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); // hMasaLfeSynth->targetEneLfeSmooth_q+15-15
    3452       26560 :     move32();
    3453       26560 :     hMasaLfeSynth->targetEneTransSmooth_fx = Mpy_32_16_1( hMasaLfeSynth->targetEneTransSmooth_fx, MCMASA_LFE_SYNTH_ALPHA_Q15 ); // hMasaLfeSynth->targetEneTransSmooth_q+15-15
    3454       26560 :     move32();
    3455             : 
    3456       26560 :     hMasaLfeSynth->transportEneSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->transportEneSmooth_fx, sub( 31, hMasaLfeSynth->transportEneSmooth_q ), transportEne_fx, sub( 31, transportEne_q ), &temp_q ); // 31-temp_q
    3457       26560 :     move32();
    3458       26560 :     hMasaLfeSynth->transportEneSmooth_q = sub( 31, temp_q );
    3459       26560 :     move16();
    3460             : 
    3461       26560 :     hMasaLfeSynth->protoLfeEneSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->protoLfeEneSmooth_fx, sub( 31, hMasaLfeSynth->protoLfeEneSmooth_q ), protoLfeEne_fx, sub( 31, protoLfeEne_q ), &temp_q ); // 31-temp_q
    3462       26560 :     move32();
    3463       26560 :     hMasaLfeSynth->protoLfeEneSmooth_q = sub( 31, temp_q );
    3464       26560 :     move16();
    3465             : 
    3466       26560 :     hMasaLfeSynth->targetEneLfeSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->targetEneLfeSmooth_fx, sub( 31, hMasaLfeSynth->targetEneLfeSmooth_q ), targetEneLfe_fx, sub( 31, targetEneLfe_q ), &temp_q ); // 31-temp_q
    3467       26560 :     move32();
    3468       26560 :     hMasaLfeSynth->targetEneLfeSmooth_q = sub( 31, temp_q );
    3469       26560 :     move16();
    3470             : 
    3471       26560 :     hMasaLfeSynth->targetEneTransSmooth_fx = BASOP_Util_Add_Mant32Exp( hMasaLfeSynth->targetEneTransSmooth_fx, sub( 31, hMasaLfeSynth->targetEneTransSmooth_q ), targetEneTrans_fx, sub( 31, targetEneTrans_q ), &temp_q ); // 31-temp_q
    3472       26560 :     move32();
    3473       26560 :     hMasaLfeSynth->targetEneTransSmooth_q = sub( 31, temp_q );
    3474       26560 :     move16();
    3475             : 
    3476       26560 :     temp = BASOP_Util_Divide3232_Scale( hMasaLfeSynth->targetEneLfeSmooth_fx, L_add( EPSILON_FX, hMasaLfeSynth->protoLfeEneSmooth_fx ), &temp_q ); // 15-(temp_q-(hMasaLfeSynth->targetEneLfeSmooth_q-hMasaLfeSynth->protoLfeEneSmooth_q))
    3477       26560 :     temp_q = add( sub( hMasaLfeSynth->targetEneLfeSmooth_q, hMasaLfeSynth->protoLfeEneSmooth_q ), sub( Q15, temp_q ) );
    3478             : 
    3479       26560 :     exp = sub( Q15, temp_q );
    3480       26560 :     lfeGain_fx = Sqrt16( temp, &exp ); // 15-exp
    3481       26560 :     lfeGain_q_fx = sub( Q15, exp );
    3482             : 
    3483       26560 :     IF( GT_32( L_shr( lfeGain_fx, sub( lfeGain_q_fx, Q14 ) ), ONE_IN_Q14 /*1 q14*/ ) )
    3484             :     {
    3485           0 :         lfeGain_fx = ONE_IN_Q14; /*1 q14*/
    3486           0 :         move16();
    3487           0 :         lfeGain_q_fx = Q14;
    3488           0 :         move16();
    3489             :     }
    3490             : 
    3491       26560 :     temp = BASOP_Util_Divide3232_Scale( hMasaLfeSynth->targetEneTransSmooth_fx, L_add( EPSILON_FX, hMasaLfeSynth->transportEneSmooth_fx ), &temp_q ); // Q=15-(temp_q-(hMasaLfeSynth->targetEneTransSmooth_q-hMasaLfeSynth->transportEneSmooth_q))
    3492       26560 :     temp_q = add( sub( hMasaLfeSynth->targetEneTransSmooth_q, hMasaLfeSynth->transportEneSmooth_q ), sub( Q15, temp_q ) );
    3493             : 
    3494       26560 :     exp = sub( Q15, temp_q );
    3495       26560 :     transportGain_fx = Sqrt16( temp, &exp ); // q=15-exp
    3496       26560 :     transportGain_q_fx = sub( Q15, exp );
    3497             : 
    3498       26560 :     IF( GT_32( L_shr( transportGain_fx, sub( transportGain_q_fx, Q14 ) ), ONE_IN_Q14 /*1 q14*/ ) )
    3499             :     {
    3500           0 :         transportGain_fx = ONE_IN_Q14; /*1 q14*/
    3501           0 :         move16();
    3502           0 :         transportGain_q_fx = Q14;
    3503           0 :         move16();
    3504             :     }
    3505             : 
    3506       26560 :     RealBufferLfe_fx[slot_index][0] = L_shr( Mpy_32_16_1( protoLfeReal_fx, lfeGain_fx ), add( min_q_shift, sub( lfeGain_q_fx, Q15 ) ) ); // q_cldfb
    3507       26560 :     move32();
    3508       26560 :     ImagBufferLfe_fx[slot_index][0] = L_shr( Mpy_32_16_1( protoLfeImag_fx, lfeGain_fx ), add( min_q_shift, sub( lfeGain_q_fx, Q15 ) ) ); // q_cldfb
    3509       26560 :     move32();
    3510             : 
    3511       26560 :     RealBuffer_fx[0][0][0] = L_shr( Mpy_32_16_1( RealBuffer_fx[0][0][0], transportGain_fx ), sub( transportGain_q_fx, Q15 ) ); // Q = q_cldfb
    3512       26560 :     move32();
    3513       26560 :     ImagBuffer_fx[0][0][0] = L_shr( Mpy_32_16_1( ImagBuffer_fx[0][0][0], transportGain_fx ), sub( transportGain_q_fx, Q15 ) ); // Q = q_cldfb
    3514       26560 :     move32();
    3515       27680 :     FOR( i = 1; i < nchan_transport; i++ )
    3516             :     {
    3517        1120 :         RealBuffer_fx[i][0][0] = L_shr( Mpy_32_16_1( RealBuffer_fx[i][0][0], transportGain_fx ), sub( transportGain_q_fx, Q15 ) ); // Q = q_cldfb
    3518        1120 :         move32();
    3519        1120 :         ImagBuffer_fx[i][0][0] = L_shr( Mpy_32_16_1( ImagBuffer_fx[i][0][0], transportGain_fx ), sub( transportGain_q_fx, Q15 ) ); // Q = q_cldfb
    3520        1120 :         move32();
    3521             :     }
    3522             : 
    3523       26560 :     return;
    3524             : }
    3525             : 
    3526             : 
    3527             : /*-------------------------------------------------------------------------
    3528             :  * rotateAziEle_DirAC()
    3529             :  *
    3530             :  * Apply rotation to DirAC DOAs
    3531             :  *------------------------------------------------------------------------*/
    3532             : 
    3533      147200 : void rotateAziEle_DirAC_fx(
    3534             :     Word16 *azi,            /* i/o: array of azimuth values               */
    3535             :     Word16 *ele,            /* i/o: array of elevation values             */
    3536             :     const Word16 band1,     /* i  : bands to work on (lower limit)        */
    3537             :     const Word16 band2,     /* i  : bands to work on (upper bound)        */
    3538             :     const Word32 *p_Rmat_fx /* i  : pointer to real-space rotation matrix q30*/
    3539             : )
    3540             : {
    3541             :     Word16 b;
    3542             :     Word32 dv_0_fx, dv_1_fx, dv_2_fx;
    3543             :     Word32 dv_r_0_fx, dv_r_1_fx, dv_r_2_fx, tmp, w_fx;
    3544             :     Word16 exp, temp;
    3545             :     const Word32 *ptr_sin, *ptr_cos;
    3546             : 
    3547      147200 :     ptr_sin = &sine_table_Q31[180]; // sin[x] = sine_table_Q31[180 + x] q31
    3548      147200 :     ptr_cos = cosine_table_Q31;     // q31
    3549             : 
    3550      147200 :     push_wmops( "rotateAziEle_DirAC" );
    3551             : 
    3552     4160000 :     FOR( b = band1; b < band2; b++ )
    3553             :     {
    3554             :         /*Conversion spherical to cartesian coordinates*/
    3555     4012800 :         IF( GT_16( abs_s( ele[b] ), 180 ) )
    3556             :         {
    3557             :             // cos(180 + x) = -cos(x)
    3558           0 :             w_fx = L_negate( ptr_cos[abs( ele[b] ) - 180] ); // Q31
    3559             :         }
    3560             :         ELSE
    3561             :         {
    3562     4012800 :             w_fx = ptr_cos[abs_s( ele[b] )]; // Q31
    3563     4012800 :             move32();
    3564             :         }
    3565             : 
    3566     4012800 :         IF( GT_16( abs_s( azi[b] ), 180 ) )
    3567             :         {
    3568             :             // cos(180 + x) = -cos(x)
    3569     1909728 :             tmp = L_negate( ptr_cos[abs( azi[b] ) - 180] ); // Q31
    3570             :         }
    3571             :         ELSE
    3572             :         {
    3573     2103072 :             tmp = ptr_cos[abs( azi[b] )]; // Q31
    3574     2103072 :             move32();
    3575             :         }
    3576             : 
    3577     4012800 :         dv_0_fx = Mpy_32_32( w_fx, tmp ); // Q31
    3578             : 
    3579             : 
    3580     4012800 :         IF( GT_16( azi[b], 180 ) )
    3581             :         {
    3582             :             // sin(180 + x) = -sin(x)
    3583     1909728 :             tmp = L_negate( ptr_sin[azi[b] - 180] ); // Q31
    3584     1909728 :             move32();
    3585             :         }
    3586     2103072 :         ELSE IF( LT_16( azi[b], -180 ) )
    3587             :         {
    3588             :             // sin(-(180 + x)) = sin(180 + x) = sinx
    3589           0 :             tmp = ptr_sin[abs( azi[b] ) - 180]; // Q31
    3590           0 :             move32();
    3591             :         }
    3592             :         ELSE
    3593             :         {
    3594     2103072 :             tmp = ptr_sin[azi[b]]; // Q31
    3595     2103072 :             move32();
    3596             :         }
    3597     4012800 :         dv_1_fx = Mpy_32_32( w_fx, tmp ); // Q31
    3598             : 
    3599     4012800 :         IF( GT_16( ele[b], 180 ) )
    3600             :         {
    3601             :             // sin(180 + x) = -sin(x)
    3602           0 :             dv_2_fx = L_negate( ptr_sin[ele[b] - 180] ); // Q31
    3603           0 :             move32();
    3604             :         }
    3605     4012800 :         ELSE IF( LT_16( ele[b], -180 ) )
    3606             :         {
    3607             :             // sin(-(180 + x)) = -sin(180 + x) = sinx
    3608           0 :             dv_2_fx = ptr_sin[abs( ele[b] ) - 180]; // Q31
    3609           0 :             move32();
    3610             :         }
    3611             :         ELSE
    3612             :         {
    3613     4012800 :             dv_2_fx = ptr_sin[ele[b]]; // Q31
    3614     4012800 :             move32();
    3615             :         }
    3616             : 
    3617     4012800 :         dv_r_0_fx = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat_fx[0], Q1 ), dv_0_fx ), L_shr( p_Rmat_fx[1], Q1 ), dv_1_fx ), L_shr( p_Rmat_fx[2], Q1 ), dv_2_fx ); // Q29
    3618     4012800 :         dv_r_1_fx = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat_fx[3], Q1 ), dv_0_fx ), L_shr( p_Rmat_fx[4], Q1 ), dv_1_fx ), L_shr( p_Rmat_fx[5], Q1 ), dv_2_fx ); // Q29
    3619     4012800 :         dv_r_2_fx = Madd_32_32( Madd_32_32( Mpy_32_32( L_shr( p_Rmat_fx[6], Q1 ), dv_0_fx ), L_shr( p_Rmat_fx[7], Q1 ), dv_1_fx ), L_shr( p_Rmat_fx[8], Q1 ), dv_2_fx ); // Q29
    3620             : 
    3621             :         /*Conversion spherical to cartesian coordinates*/
    3622     4012800 :         temp = BASOP_util_atan2( dv_r_1_fx, dv_r_0_fx, 0 ); // Q13
    3623     4012800 :         azi[b] = shr( mult( temp, _180_OVER_PI_Q9 ), 7 );   // Q0;
    3624     4012800 :         move16();
    3625             : 
    3626     4012800 :         tmp = L_add( Mpy_32_32( dv_r_0_fx, dv_r_0_fx ), Mpy_32_32( dv_r_1_fx, dv_r_1_fx ) ); // Q27
    3627     4012800 :         exp = sub( 31, Q27 );
    3628     4012800 :         tmp = Sqrt32( tmp, &exp );                                            // q=31-exp
    3629     4012800 :         temp = BASOP_util_atan2( dv_r_2_fx, tmp, sub( sub( 31, 29 ), exp ) ); // Q13
    3630     4012800 :         ele[b] = shr( mult( temp, _180_OVER_PI_Q9 ), 7 );                     // Q0
    3631     4012800 :         move16();
    3632             :     }
    3633             : 
    3634      147200 :     pop_wmops();
    3635             : 
    3636      147200 :     return;
    3637             : }
    3638             : 
    3639             : 
    3640             : /* A reduced rewrite of the corresponding decoder side function */
    3641       20400 : static void ivas_masa_ext_dirac_render_sf_fx(
    3642             :     MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: IVAS decoder structure                                  */
    3643             :     Word32 *output_f_fx[]              /* i/o: synthesized core-coder transport channels/DirAC output q11*/
    3644             : )
    3645             : {
    3646             :     Word16 i, ch, idx_in, idx_lfe;
    3647             :     DIRAC_REND_HANDLE hDirACRend;
    3648             :     Word16 subframe_idx;
    3649             :     Word16 slot_idx, index_slot;
    3650             :     Word16 slot_idx_start, slot_idx_start_cldfb_synth, md_idx;
    3651             :     Word16 nchan_transport;
    3652             :     Word16 masa_band_mapping[MASA_FREQUENCY_BANDS + 1];
    3653             : 
    3654             :     /* local copies of azi, ele, diffuseness */
    3655             :     Word16 azimuth[CLDFB_NO_CHANNELS_MAX];
    3656             :     Word16 elevation[CLDFB_NO_CHANNELS_MAX];
    3657             : 
    3658             :     Word32 diffuseness_vector_fx[CLDFB_NO_CHANNELS_MAX];
    3659             :     Word32 Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    3660             :     Word32 Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
    3661       20400 :     Word16 q_cldfb = 0;
    3662             :     Word32 surCohRatio_fx[CLDFB_NO_CHANNELS_MAX];
    3663             :     Word16 Q_surCohRatio, surCohRatio_exp[CLDFB_NO_CHANNELS_MAX];
    3664             :     Word32 dirEne_fx;
    3665             :     Word32 surCohEner_fx;
    3666       20400 :     move16();
    3667             : 
    3668      346800 :     FOR( Word16 ii = 0; ii < MAX_OUTPUT_CHANNELS; ii++ )
    3669             :     {
    3670     1632000 :         FOR( Word16 jj = 0; jj < MAX_PARAM_SPATIAL_SUBFRAMES; jj++ )
    3671             :         {
    3672     1305600 :             set_zero_fx( Cldfb_RealBuffer_fx[ii][jj], CLDFB_NO_CHANNELS_MAX );
    3673     1305600 :             set_zero_fx( Cldfb_ImagBuffer_fx[ii][jj], CLDFB_NO_CHANNELS_MAX );
    3674             :         }
    3675             :     }
    3676             : 
    3677             :     DIRAC_DEC_STACK_MEM DirAC_mem;
    3678             : 
    3679       20400 :     Word32 *onset_filter_fx, *onset_filter_subframe_fx, *p_onset_filter_fx = NULL;
    3680             :     Word32 *reference_power_smooth_fx, *reference_power_fix;
    3681             :     UWord16 coherence_flag;
    3682             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    3683             : 
    3684       20400 :     push_wmops( "ivas_masa_ext_dirac_render_sf" );
    3685             : 
    3686             :     /* Initialize aux buffers */
    3687       20400 :     hDirACRend = hMasaExtRend->hDirACRend;
    3688       20400 :     hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom;
    3689       20400 :     nchan_transport = hMasaExtRend->nchan_input;
    3690       20400 :     move16();
    3691             : 
    3692       20400 :     DirAC_mem = hDirACRend->stack_mem;
    3693             : 
    3694       20400 :     onset_filter_fx = DirAC_mem.onset_filter_fx;        // q31
    3695       20400 :     reference_power_fix = DirAC_mem.reference_power_fx; // DirAC_mem.reference_power_q
    3696       20400 :     IF( ( DirAC_mem.reference_power_fx == NULL ) )
    3697             :     {
    3698        3600 :         reference_power_smooth_fx = NULL;
    3699             :     }
    3700             :     ELSE
    3701             :     {
    3702       16800 :         reference_power_smooth_fx = DirAC_mem.reference_power_fx + hSpatParamRendCom->num_freq_bands; // DirAC_mem.reference_power_q
    3703             :     }
    3704       20400 :     IF( ( DirAC_mem.onset_filter_fx == NULL ) )
    3705             :     {
    3706        1200 :         onset_filter_subframe_fx = NULL;
    3707             :     }
    3708             :     ELSE
    3709             :     {
    3710       19200 :         onset_filter_subframe_fx = DirAC_mem.onset_filter_fx + hSpatParamRendCom->num_freq_bands; // q31
    3711             :     }
    3712       20400 :     coherence_flag = 1; /* There is always coherence assumed for ext rend of MASA */
    3713       20400 :     move16();
    3714             :     /* Construct default MASA band mapping */
    3715      530400 :     FOR( i = 0; i < MASA_FREQUENCY_BANDS + 1; i++ )
    3716             :     {
    3717      510000 :         masa_band_mapping[i] = i;
    3718      510000 :         move16();
    3719             :     }
    3720             : 
    3721             :     /* Subframe loop */
    3722       20400 :     slot_idx_start = hSpatParamRendCom->slots_rendered;
    3723       20400 :     move16();
    3724       20400 :     slot_idx_start_cldfb_synth = 0;
    3725       20400 :     move16();
    3726             : 
    3727       20400 :     subframe_idx = hSpatParamRendCom->subframes_rendered;
    3728       20400 :     move16();
    3729       20400 :     md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];
    3730       20400 :     move16();
    3731             : 
    3732             :     DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
    3733       20400 :     h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
    3734             : 
    3735             :     /* copy parameters into local buffers*/
    3736             : 
    3737       20400 :     Copy( hSpatParamRendCom->azimuth[hSpatParamRendCom->render_to_md_map[subframe_idx]], azimuth, hSpatParamRendCom->num_freq_bands );
    3738       20400 :     Copy( hSpatParamRendCom->elevation[hSpatParamRendCom->render_to_md_map[subframe_idx]], elevation, hSpatParamRendCom->num_freq_bands );
    3739       20400 :     Copy32( hSpatParamRendCom->diffuseness_vector_fx[hSpatParamRendCom->render_to_md_map[subframe_idx]], diffuseness_vector_fx, hSpatParamRendCom->num_freq_bands ); // q30
    3740             : 
    3741       20400 :     IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    3742             :     {
    3743       16800 :         set32_fx( reference_power_smooth_fx, 0, hSpatParamRendCom->num_freq_bands );
    3744             :     }
    3745             :     ELSE
    3746             :     {
    3747        3600 :         set32_fx( onset_filter_subframe_fx, 0, hSpatParamRendCom->num_freq_bands );
    3748             :     }
    3749             : 
    3750             :     /* compute response */
    3751       20400 :     IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    3752             :     {
    3753       16800 :         ivas_dirac_dec_compute_power_factors_fx( hSpatParamRendCom->num_freq_bands,
    3754             :                                                  diffuseness_vector_fx,
    3755       16800 :                                                  hDirACRend->h_output_synthesis_psd_params.max_band_decorr,
    3756             :                                                  hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx,
    3757             :                                                  hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx );
    3758             : 
    3759       16800 :         hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q = Q29;
    3760       16800 :         move16();
    3761       16800 :         hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q = Q29;
    3762       16800 :         move16();
    3763             : 
    3764             : 
    3765       16800 :         IF( coherence_flag )
    3766             :         {
    3767       16800 :             Word16 temp_exp = MIN_16;
    3768       16800 :             move16();
    3769     1024800 :             FOR( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ )
    3770             :             {
    3771     1008000 :                 dirEne_fx = hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i]; // 29
    3772     1008000 :                 move32();
    3773     1008000 :                 surCohEner_fx = Mpy_32_16_1( hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx[i], hSpatParamRendCom->surroundingCoherence_fx[md_idx][i] );         // Q.29
    3774     1008000 :                 hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx[i] = L_sub( hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx[i], surCohEner_fx ); // q29
    3775     1008000 :                 move32();
    3776     1008000 :                 hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i] = L_add( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx[i], surCohEner_fx ); // q29
    3777     1008000 :                 move32();
    3778             : 
    3779     1008000 :                 surCohRatio_fx[i] = BASOP_Util_Divide3232_Scale_newton( surCohEner_fx, L_add( L_add( 1, dirEne_fx ), surCohEner_fx ), &surCohRatio_exp[i] ); // 31-surCohRatio_exp
    3780     1008000 :                 move32();
    3781     1008000 :                 temp_exp = s_max( temp_exp, surCohRatio_exp[i] );
    3782             :             }
    3783             : 
    3784     1024800 :             FOR( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ )
    3785             :             {
    3786     1008000 :                 surCohRatio_fx[i] = L_shr( surCohRatio_fx[i], sub( temp_exp, surCohRatio_exp[i] ) ); // 31-temp_exp
    3787     1008000 :                 move32();
    3788             :             }
    3789       16800 :             Q_surCohRatio = sub( 31, temp_exp );
    3790             :         }
    3791             :         ELSE
    3792             :         {
    3793           0 :             set32_fx( surCohRatio_fx, 0, hSpatParamRendCom->num_freq_bands );
    3794           0 :             Q_surCohRatio = 31;
    3795           0 :             move16();
    3796             :         }
    3797             :     }
    3798             :     ELSE
    3799             :     {
    3800        3600 :         ivas_dirac_dec_compute_gain_factors_fx( hSpatParamRendCom->num_freq_bands,
    3801        3600 :                                                 hSpatParamRendCom->diffuseness_vector_fx[md_idx],
    3802             :                                                 hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx,
    3803             :                                                 hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx,
    3804             :                                                 &hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q,
    3805             :                                                 &hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q );
    3806        3600 :         hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q = sub( 31, hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q );
    3807        3600 :         move16();
    3808        3600 :         hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q = sub( 31, hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q );
    3809        3600 :         move16();
    3810        3600 :         IF( coherence_flag )
    3811             :         {
    3812      219600 :             FOR( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ )
    3813             :             {
    3814      216000 :                 surCohRatio_fx[i] = L_deposit_h( hSpatParamRendCom->surroundingCoherence_fx[md_idx][i] ); // q31
    3815      216000 :                 move32();
    3816             :             }
    3817             :         }
    3818             :         ELSE
    3819             :         {
    3820           0 :             set32_fx( surCohRatio_fx, 0, hSpatParamRendCom->num_freq_bands );
    3821             :         }
    3822             : 
    3823        3600 :         Q_surCohRatio = Q31;
    3824        3600 :         move16();
    3825             :     }
    3826             : 
    3827       20400 :     ivas_dirac_dec_compute_directional_responses_fx( hSpatParamRendCom,
    3828             :                                                      hDirACRend,
    3829             :                                                      hMasaExtRend->hVBAPdata,
    3830             :                                                      masa_band_mapping,
    3831             :                                                      NULL,
    3832             :                                                      azimuth,
    3833             :                                                      elevation,
    3834             :                                                      md_idx,
    3835             :                                                      surCohRatio_fx,
    3836             :                                                      Q_surCohRatio,
    3837             :                                                      0 );
    3838             : 
    3839             :     Word16 proto_direct_buffer_f_temp_q[60];
    3840             :     Word16 temp_proto_frame_q;
    3841             : 
    3842      102000 :     FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    3843             :     {
    3844       81600 :         index_slot = add( slot_idx_start, slot_idx );
    3845       81600 :         md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];
    3846       81600 :         move16();
    3847       81600 :         proto_direct_buffer_f_temp_q[slot_idx] = MAX_16;
    3848       81600 :         move16();
    3849             : 
    3850             :         /* CLDFB Analysis*/
    3851      206400 :         FOR( ch = 0; ch < nchan_transport; ch++ )
    3852             :         {
    3853      124800 :             q_cldfb = 11;
    3854      124800 :             move16();
    3855      124800 :             hMasaExtRend->cldfbAnaRend[ch]->Q_cldfb_state = q_cldfb;
    3856      124800 :             move16();
    3857      124800 :             cldfbAnalysis_ts_fx_fixed_q( &( output_f_fx[ch][hSpatParamRendCom->num_freq_bands * index_slot] ),
    3858      124800 :                                          Cldfb_RealBuffer_fx[ch][0],
    3859      124800 :                                          Cldfb_ImagBuffer_fx[ch][0],
    3860      124800 :                                          hSpatParamRendCom->num_freq_bands,
    3861             :                                          hMasaExtRend->cldfbAnaRend[ch], &q_cldfb );
    3862             :         }
    3863             : 
    3864       81600 :         IF( EQ_16( nchan_transport, 1 ) )
    3865             :         {
    3866             :             /* Need to set second CLDFB channel to zero as further processing assumes CNA content in it */
    3867       38400 :             set32_fx( Cldfb_RealBuffer_fx[1][0], 0, hSpatParamRendCom->num_freq_bands );
    3868       38400 :             set32_fx( Cldfb_ImagBuffer_fx[1][0], 0, hSpatParamRendCom->num_freq_bands );
    3869             :         }
    3870             :         /*-----------------------------------------------------------------*
    3871             :          * prototype signal computation
    3872             :          *-----------------------------------------------------------------*/
    3873             : 
    3874       81600 :         IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    3875             :         {
    3876       14400 :             protoSignalComputation_shd_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx,
    3877             :                                            hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx,
    3878             :                                            &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q,
    3879             :                                            hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx,
    3880             :                                            &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q,
    3881             :                                            reference_power_fix, DirAC_mem.reference_power_q, slot_idx, nchan_transport,
    3882       14400 :                                            hDirACRend->num_outputs_diff,
    3883       14400 :                                            hSpatParamRendCom->num_freq_bands,
    3884             :                                            0, q_cldfb );
    3885             : 
    3886       14400 :             proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q;
    3887       14400 :             move16();
    3888             :         }
    3889       67200 :         ELSE IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_MONO ) )
    3890             :         {
    3891        4800 :             protoSignalComputation2_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hDirACRend->proto_frame_f_fx, &hDirACRend->proto_frame_f_q,
    3892             :                                         hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx,
    3893             :                                         &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q,
    3894             :                                         reference_power_fix, DirAC_mem.reference_power_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx,
    3895        4800 :                                         hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q,
    3896        4800 :                                         0, slot_idx, hSpatParamRendCom->num_freq_bands, hDirACRend->masa_stereo_type_detect, q_cldfb );
    3897             : 
    3898        4800 :             proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q;
    3899        4800 :             move16();
    3900        4800 :             IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) )
    3901             :             {
    3902        2784 :                 FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    3903             :                 {
    3904        1392 :                     Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q
    3905             :                 }
    3906        1392 :                 DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0];
    3907        1392 :                 move16();
    3908             :             }
    3909             :             ELSE
    3910             :             {
    3911        3408 :                 Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q
    3912        3408 :                 DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0];
    3913        3408 :                 move16();
    3914             :             }
    3915        4800 :             IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) )
    3916             :             {
    3917        2652 :                 FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    3918             :                 {
    3919        1326 :                     Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q
    3920             :                 }
    3921        1326 :                 DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1];
    3922        1326 :                 move16();
    3923             :             }
    3924             :             ELSE
    3925             :             {
    3926        3474 :                 Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q
    3927        3474 :                 DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1];
    3928        3474 :                 move16();
    3929             :             }
    3930        4800 :             temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 );
    3931        4800 :             Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q
    3932        4800 :             hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q );
    3933        4800 :             move16();
    3934             :         }
    3935             :         ELSE
    3936             :         {
    3937       62400 :             SWITCH( nchan_transport )
    3938             :             {
    3939       38400 :                 case 2:
    3940       38400 :                     protoSignalComputation2_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx,
    3941             :                                                 hDirACRend->proto_frame_f_fx,
    3942             :                                                 &hDirACRend->proto_frame_f_q,
    3943             :                                                 hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx,
    3944             :                                                 &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q,
    3945             :                                                 reference_power_fix, DirAC_mem.reference_power_q,
    3946             :                                                 hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx,
    3947       38400 :                                                 hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q,
    3948       38400 :                                                 hDirACRend->hOutSetup.is_loudspeaker_setup,
    3949             :                                                 slot_idx,
    3950       38400 :                                                 hSpatParamRendCom->num_freq_bands,
    3951             :                                                 hDirACRend->masa_stereo_type_detect, q_cldfb );
    3952             : 
    3953       38400 :                     proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q;
    3954       38400 :                     move16();
    3955       38400 :                     IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) )
    3956             :                     {
    3957       22272 :                         FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    3958             :                         {
    3959       11136 :                             Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q
    3960             :                         }
    3961       11136 :                         DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0];
    3962       11136 :                         move16();
    3963             :                     }
    3964             :                     ELSE
    3965             :                     {
    3966       27264 :                         Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q
    3967       27264 :                         DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0];
    3968       27264 :                         move16();
    3969             :                     }
    3970       38400 :                     IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) )
    3971             :                     {
    3972       21216 :                         FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    3973             :                         {
    3974       10608 :                             Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q
    3975             :                         }
    3976       10608 :                         DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1];
    3977       10608 :                         move16();
    3978             :                     }
    3979             :                     ELSE
    3980             :                     {
    3981       27792 :                         Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q
    3982       27792 :                         DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1];
    3983       27792 :                         move16();
    3984             :                     }
    3985             : 
    3986       38400 :                     temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 );
    3987       38400 :                     Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q
    3988       38400 :                     hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q );
    3989       38400 :                     move16();
    3990             : 
    3991       38400 :                     BREAK;
    3992       24000 :                 case 1:
    3993       24000 :                     protoSignalComputation1_fx( Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx,
    3994             :                                                 hDirACRend->proto_frame_f_fx,
    3995             :                                                 &hDirACRend->proto_frame_f_q,
    3996             :                                                 hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx,
    3997             :                                                 &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q,
    3998             :                                                 reference_power_fix, DirAC_mem.reference_power_q,
    3999             :                                                 hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx,
    4000       24000 :                                                 hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q,
    4001             :                                                 slot_idx,
    4002       24000 :                                                 hDirACRend->num_protos_diff,
    4003       24000 :                                                 hSpatParamRendCom->num_freq_bands, q_cldfb );
    4004             : 
    4005       24000 :                     proto_direct_buffer_f_temp_q[slot_idx] = hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q;
    4006       24000 :                     move16();
    4007             : 
    4008       24000 :                     IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) )
    4009             :                     {
    4010       15420 :                         FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4011             :                         {
    4012        7710 :                             Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q
    4013             :                         }
    4014        7710 :                         DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0];
    4015        7710 :                         move16();
    4016             :                     }
    4017             :                     ELSE
    4018             :                     {
    4019       16290 :                         Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q
    4020       16290 :                         DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0];
    4021       16290 :                         move16();
    4022             :                     }
    4023       24000 :                     IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) )
    4024             :                     {
    4025       15420 :                         FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4026             :                         {
    4027        7710 :                             Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q
    4028             :                         }
    4029        7710 :                         DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1];
    4030        7710 :                         move16();
    4031             :                     }
    4032             :                     ELSE
    4033             :                     {
    4034       16290 :                         Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q
    4035       16290 :                         DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1];
    4036       16290 :                         move16();
    4037             :                     }
    4038             : 
    4039       24000 :                     temp_proto_frame_q = sub( getScaleFactor32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len ), 2 );
    4040       24000 :                     Scale_sig32( hDirACRend->proto_frame_f_fx, hDirACRend->proto_frame_f_len, temp_proto_frame_q ); // hDirACRend->proto_frame_f_q+temp_proto_frame_q
    4041       24000 :                     hDirACRend->proto_frame_f_q = add( hDirACRend->proto_frame_f_q, temp_proto_frame_q );
    4042       24000 :                     move16();
    4043             : 
    4044       24000 :                     BREAK;
    4045           0 :                 default:
    4046           0 :                     return;
    4047             :             }
    4048             :         }
    4049             : 
    4050             :         /*-----------------------------------------------------------------*
    4051             :          * frequency domain decorrelation
    4052             :          *-----------------------------------------------------------------*/
    4053       81600 :         IF( EQ_16( hDirACRend->proto_signal_decorr_on, 1 ) )
    4054             :         {
    4055             :             /* decorrelate prototype frame */
    4056       76800 :             IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    4057             :             {
    4058       28800 :                 ivas_dirac_dec_decorr_process_fx( hSpatParamRendCom->num_freq_bands,
    4059       14400 :                                                   hDirACRend->num_outputs_diff,
    4060       14400 :                                                   hDirACRend->num_protos_diff,
    4061             :                                                   hDirACRend->synthesisConf,
    4062             :                                                   nchan_transport,
    4063       14400 :                                                   hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff,
    4064       14400 :                                                   hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q,
    4065       14400 :                                                   hDirACRend->num_protos_diff,
    4066       14400 :                                                   hDirACRend->proto_index_diff,
    4067       14400 :                                                   hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * s_min( 4, nchan_transport ),
    4068             :                                                   &hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q,
    4069             :                                                   onset_filter_fx,
    4070             :                                                   hDirACRend->h_freq_domain_decorr_ap_params,
    4071             :                                                   hDirACRend->h_freq_domain_decorr_ap_state );
    4072             : 
    4073       14400 :                 v_multc_fixed( onset_filter_fx, 536870912 /* 0.25f in Q31 */, onset_filter_fx, hSpatParamRendCom->num_freq_bands );            /* Q31 */
    4074       14400 :                 v_add_fixed_no_hdrm( onset_filter_fx, onset_filter_subframe_fx, onset_filter_subframe_fx, hSpatParamRendCom->num_freq_bands ); /* Q31 */
    4075       14400 :                 p_onset_filter_fx = onset_filter_subframe_fx;                                                                                  /*q31*/
    4076             :             }
    4077             :             ELSE
    4078             :             {
    4079       62400 :                 set_zero_fx( DirAC_mem.frame_dec_f_fx, DirAC_mem.frame_dec_f_len );
    4080             : 
    4081       62400 :                 ivas_dirac_dec_decorr_process_fx( hSpatParamRendCom->num_freq_bands,
    4082       62400 :                                                   hDirACRend->num_outputs_diff,
    4083       62400 :                                                   hDirACRend->num_protos_diff,
    4084             :                                                   hDirACRend->synthesisConf,
    4085             :                                                   nchan_transport,
    4086       62400 :                                                   hDirACRend->proto_frame_f_fx,
    4087       62400 :                                                   hDirACRend->proto_frame_f_q,
    4088       62400 :                                                   hDirACRend->num_protos_diff,
    4089       62400 :                                                   hDirACRend->proto_index_diff,
    4090             :                                                   DirAC_mem.frame_dec_f_fx,
    4091             :                                                   &DirAC_mem.frame_dec_f_q,
    4092             :                                                   onset_filter_fx,
    4093             :                                                   hDirACRend->h_freq_domain_decorr_ap_params,
    4094             :                                                   hDirACRend->h_freq_domain_decorr_ap_state );
    4095             : 
    4096       62400 :                 hDirACRend->proto_frame_dec_f_fx = DirAC_mem.frame_dec_f_fx; // DirAC_mem.frame_dec_f_q
    4097       62400 :                 hDirACRend->proto_frame_dec_f_q = DirAC_mem.frame_dec_f_q;
    4098       62400 :                 move16();
    4099       62400 :                 p_onset_filter_fx = onset_filter_fx; // q31
    4100             :             }
    4101             :         }
    4102             :         ELSE
    4103             :         {
    4104        4800 :             IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    4105             :             {
    4106           0 :                 set32_fx( onset_filter_subframe_fx, ONE_IN_Q31, hSpatParamRendCom->num_freq_bands ); // q31
    4107           0 :                 p_onset_filter_fx = onset_filter_subframe_fx;                                        // q31
    4108             :             }
    4109             :             ELSE
    4110             :             {
    4111             :                 /* no frequency domain decorrelation: use prototype frame */
    4112        4800 :                 hDirACRend->proto_frame_dec_f_fx = hDirACRend->proto_frame_f_fx; // q31
    4113        4800 :                 hDirACRend->proto_frame_dec_f_q = hDirACRend->proto_frame_f_q;
    4114        4800 :                 p_onset_filter_fx = NULL;
    4115             :             }
    4116             :         }
    4117             : 
    4118             :         /*-----------------------------------------------------------------*
    4119             :          * output synthesis
    4120             :          *-----------------------------------------------------------------*/
    4121             : 
    4122       81600 :         test();
    4123       81600 :         IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_LS ) || EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_PSD_SHD ) )
    4124             :         {
    4125             :             /* Compute diffuse prototypes */
    4126       62400 :             ivas_dirac_dec_compute_diffuse_proto_fx( hDirACRend, hSpatParamRendCom->num_freq_bands, slot_idx );
    4127             :         }
    4128       81600 :         Scale_sig32( h_dirac_output_synthesis_state->diffuse_power_factor_fx, hSpatParamRendCom->num_freq_bands, sub( 31, h_dirac_output_synthesis_state->diffuse_power_factor_q ) ); // q31
    4129       81600 :         h_dirac_output_synthesis_state->diffuse_power_factor_q = Q31;
    4130       81600 :         move16();
    4131             : 
    4132       81600 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx, hSpatParamRendCom->num_freq_bands, sub( 31, hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q ) ); // q31
    4133       81600 :         hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q = Q31;
    4134       81600 :         move16();
    4135             : 
    4136       81600 :         ivas_dirac_dec_output_synthesis_process_slot_fx( reference_power_fix,
    4137             :                                                          DirAC_mem.reference_power_q,
    4138             :                                                          p_onset_filter_fx,
    4139             :                                                          azimuth,
    4140             :                                                          elevation,
    4141       81600 :                                                          hSpatParamRendCom->diffuseness_vector_fx[md_idx],
    4142       81600 :                                                          hSpatParamRendCom->q_diffuseness_vector,
    4143             :                                                          hSpatParamRendCom,
    4144             :                                                          hDirACRend,
    4145             :                                                          hMasaExtRend->hVBAPdata,
    4146             :                                                          hDirACRend->hOutSetup,
    4147             :                                                          nchan_transport,
    4148             :                                                          md_idx,
    4149             :                                                          0,
    4150             :                                                          0 );
    4151             : 
    4152       81600 :         IF( NE_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    4153             :         {
    4154       67200 :             Scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, -1 ); // DirAC_mem.reference_power_q-1
    4155       67200 :             DirAC_mem.reference_power_q[0] = sub( DirAC_mem.reference_power_q[0], 1 );
    4156       67200 :             DirAC_mem.reference_power_q[1] = sub( DirAC_mem.reference_power_q[1], 1 );
    4157       67200 :             move16();
    4158       67200 :             move16();
    4159       67200 :             DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0];
    4160       67200 :             DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1];
    4161       67200 :             move16();
    4162       67200 :             move16();
    4163       67200 :             v_add_fixed_no_hdrm( reference_power_fix, reference_power_smooth_fx, reference_power_smooth_fx, hSpatParamRendCom->num_freq_bands ); // DirAC_mem.reference_power_smooth_q
    4164             :         }
    4165             :     }
    4166             :     /*Rescaling proto_direct_buffer_f*/
    4167       20400 :     Word16 temp = MAX_16;
    4168       20400 :     move16();
    4169             : 
    4170      102000 :     FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    4171             :     {
    4172       81600 :         temp = s_min( temp, proto_direct_buffer_f_temp_q[slot_idx] );
    4173             :     }
    4174             : 
    4175       20400 :     IF( hDirACRend->hOutSetup.is_loudspeaker_setup )
    4176             :     {
    4177       66000 :         FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    4178             :         {
    4179       52800 :             Scale_sig32( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx[( slot_idx * ( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len / hSpatParamRendCom->subframe_nbslots[subframe_idx] ) )], idiv1616( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), sub( temp, proto_direct_buffer_f_temp_q[slot_idx] ) ); // temp
    4180             :         }
    4181             :     }
    4182             :     ELSE
    4183             :     {
    4184       36000 :         FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    4185             :         {
    4186       28800 :             Scale_sig32( &hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx[( slot_idx * ( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len / hSpatParamRendCom->subframe_nbslots[subframe_idx] ) )], idiv1616( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, hSpatParamRendCom->subframe_nbslots[subframe_idx] ), sub( temp, proto_direct_buffer_f_temp_q[slot_idx] ) ); // temp
    4187             :         }
    4188             :     }
    4189       20400 :     hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = temp;
    4190       20400 :     move16();
    4191             : 
    4192             : 
    4193       20400 :     ivas_dirac_dec_output_synthesis_get_interpolator_fx( &hDirACRend->h_output_synthesis_psd_params, hSpatParamRendCom->subframe_nbslots[subframe_idx] );
    4194             : 
    4195             :     /*Memories Scaling*/
    4196       20400 :     Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_power_factor_fx, hSpatParamRendCom->num_freq_bands, sub( 31, hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q ) ); // q31
    4197       20400 :     hDirACRend->h_output_synthesis_psd_state.direct_power_factor_q = Q31;
    4198       20400 :     move16();
    4199       20400 :     Scale_sig32( hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_fx, hSpatParamRendCom->num_freq_bands, sub( 31, hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q ) ); // q31
    4200       20400 :     hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor_q = Q31;
    4201       20400 :     move16();
    4202       20400 :     Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_fx, hDirACRend->num_outputs_dir * hSpatParamRendCom->num_freq_bands, sub( 31, hDirACRend->h_output_synthesis_psd_state.direct_responses_q ) ); // q31
    4203       20400 :     hDirACRend->h_output_synthesis_psd_state.direct_responses_q = Q31;
    4204       20400 :     move16();
    4205             : 
    4206       20400 :     IF( EQ_16( hDirACRend->synthesisConf, DIRAC_SYNTHESIS_GAIN_SHD ) )
    4207             :     {
    4208       38400 :         FOR( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ )
    4209             :         {
    4210      174000 :             FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    4211             :             {
    4212      139200 :                 Scale_sig32( Cldfb_RealBuffer_fx[ch][slot_idx],
    4213      139200 :                              hSpatParamRendCom->num_freq_bands, sub( 6, q_cldfb ) ); // q6
    4214      139200 :                 Scale_sig32( Cldfb_ImagBuffer_fx[ch][slot_idx],
    4215      139200 :                              hSpatParamRendCom->num_freq_bands, sub( 6, q_cldfb ) ); // q6
    4216             :             }
    4217             :         }
    4218        3600 :         q_cldfb = 6;
    4219        3600 :         move16();
    4220             : 
    4221        3600 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_len, sub( 26, hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth ) ); // q26
    4222        3600 :         hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth = Q26;
    4223        3600 :         move16();
    4224             : 
    4225        3600 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_fx, hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_len, sub( 26, hDirACRend->h_output_synthesis_psd_state.q_cy_cross_dir_smooth ) ); // q26
    4226        3600 :         hDirACRend->h_output_synthesis_psd_state.q_cy_cross_dir_smooth = Q26;
    4227        3600 :         move16();
    4228             : 
    4229        3600 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth_prev_len, sub( 26, hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev ) ); // q26
    4230        3600 :         hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev = Q26;
    4231        3600 :         move16();
    4232             : 
    4233        3600 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth_prev_len, sub( 26, hDirACRend->h_output_synthesis_psd_state.q_cy_cross_dir_smooth_prev ) ); // q26
    4234        3600 :         hDirACRend->h_output_synthesis_psd_state.q_cy_cross_dir_smooth_prev = Q26;
    4235        3600 :         move16();
    4236             : 
    4237        3600 :         ivas_dirac_dec_output_synthesis_process_subframe_gain_shd_fx( Cldfb_RealBuffer_fx,
    4238             :                                                                       Cldfb_ImagBuffer_fx,
    4239             :                                                                       hSpatParamRendCom,
    4240             :                                                                       hDirACRend,
    4241             :                                                                       nchan_transport,
    4242        3600 :                                                                       hSpatParamRendCom->subframe_nbslots[subframe_idx],
    4243             :                                                                       p_onset_filter_fx,
    4244             :                                                                       diffuseness_vector_fx,
    4245             :                                                                       0,
    4246             :                                                                       0,
    4247             :                                                                       &hDirACRend->h_output_synthesis_psd_state.q_cy_cross_dir_smooth_prev,
    4248             :                                                                       &hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev );
    4249        3600 :         q_cldfb = -1;
    4250        3600 :         move16();
    4251        3600 :         hDirACRend->h_output_synthesis_psd_state.gains_dir_prev_q = hDirACRend->h_output_synthesis_psd_state.q_cy_cross_dir_smooth_prev;
    4252        3600 :         move16();
    4253        3600 :         hDirACRend->h_output_synthesis_psd_state.gains_diff_prev_q = hDirACRend->h_output_synthesis_psd_state.q_cy_auto_diff_smooth_prev;
    4254        3600 :         move16();
    4255             :     }
    4256             :     ELSE
    4257             :     {
    4258       16800 :         IF( hDirACRend->proto_signal_decorr_on )
    4259             :         {
    4260       15600 :             Word16 new_proto_diffuse_buffer_f_q = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len );
    4261       15600 :             Word16 new_proto_direct_buffer_f_q = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len );
    4262             : 
    4263       15600 :             scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_len, new_proto_diffuse_buffer_f_q ); // hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q + new_proto_diffuse_buffer_f_q
    4264       15600 :             scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_fx, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_len, new_proto_direct_buffer_f_q );    // hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q + new_proto_direct_buffer_f_q
    4265       15600 :             hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q = add( hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f_q, new_proto_direct_buffer_f_q );
    4266       15600 :             move16();
    4267       15600 :             hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q = add( hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f_q, new_proto_diffuse_buffer_f_q );
    4268       15600 :             move16();
    4269             :         }
    4270             : 
    4271       16800 :         Word16 reference_power_temp_q = getScaleFactor32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len );
    4272       16800 :         scale_sig32( DirAC_mem.reference_power_fx, DirAC_mem.reference_power_len, reference_power_temp_q ); /*DirAC_mem.reference_power_q + reference_power_temp_q*/
    4273       16800 :         DirAC_mem.reference_power_q[0] = add( DirAC_mem.reference_power_q[0], reference_power_temp_q );
    4274       16800 :         DirAC_mem.reference_power_q[1] = add( DirAC_mem.reference_power_q[1], reference_power_temp_q );
    4275       16800 :         move16();
    4276       16800 :         DirAC_mem.reference_power_smooth_q[0] = add( DirAC_mem.reference_power_q[0], reference_power_temp_q );
    4277       16800 :         DirAC_mem.reference_power_smooth_q[1] = add( DirAC_mem.reference_power_q[1], reference_power_temp_q );
    4278       16800 :         move16();
    4279             : 
    4280       16800 :         Word16 q_cy_auto_diff_smooth = getScaleFactor32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_len );
    4281       16800 :         Scale_sig32( h_dirac_output_synthesis_state->cy_auto_diff_smooth_fx, h_dirac_output_synthesis_state->cy_auto_diff_smooth_len, q_cy_auto_diff_smooth ); // h_dirac_output_synthesis_state->q_cy_auto_diff_smooth+ q_cy_auto_diff_smooth
    4282       16800 :         h_dirac_output_synthesis_state->q_cy_auto_diff_smooth = add( h_dirac_output_synthesis_state->q_cy_auto_diff_smooth, q_cy_auto_diff_smooth );
    4283       16800 :         move16();
    4284             : 
    4285       16800 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.direct_responses_square_fx, hDirACRend->num_outputs_dir * hSpatParamRendCom->num_freq_bands, sub( 31, hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q ) ); // q31
    4286       16800 :         hDirACRend->h_output_synthesis_psd_state.direct_responses_square_q = Q31;
    4287       16800 :         move16();
    4288       16800 :         Scale_sig32( h_dirac_output_synthesis_state->diffuse_power_factor_fx, hSpatParamRendCom->num_freq_bands, sub( 31, h_dirac_output_synthesis_state->diffuse_power_factor_q ) ); // q31
    4289       16800 :         h_dirac_output_synthesis_state->diffuse_power_factor_q = Q31;
    4290       16800 :         move16();
    4291       16800 :         Scale_sig32( h_dirac_output_synthesis_state->direct_responses_fx, hSpatParamRendCom->num_freq_bands, sub( 31, h_dirac_output_synthesis_state->direct_responses_q ) ); // q31
    4292       16800 :         h_dirac_output_synthesis_state->direct_responses_q = Q31;
    4293       16800 :         move16();
    4294             : 
    4295             :         /*Q-adjustment*/
    4296       16800 :         IF( hDirACRend->masa_stereo_type_detect )
    4297             :         {
    4298        4800 :             hDirACRend->masa_stereo_type_detect->subtract_power_y_smooth_fx = L_shl( hDirACRend->masa_stereo_type_detect->subtract_power_y_smooth_fx, sub( s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y ), hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth ) ); // s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y )
    4299        4800 :             move32();
    4300        4800 :             hDirACRend->masa_stereo_type_detect->subtract_power_y_fx = L_shl( hDirACRend->masa_stereo_type_detect->subtract_power_y_fx, sub( s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y ), hDirACRend->masa_stereo_type_detect->q_subtract_power_y ) ); // s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y )
    4301        4800 :             move32();
    4302             : 
    4303        4800 :             hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth = s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y );
    4304        4800 :             move16();
    4305        4800 :             hDirACRend->masa_stereo_type_detect->q_subtract_power_y = s_min( hDirACRend->masa_stereo_type_detect->q_subtract_power_y_smooth, hDirACRend->masa_stereo_type_detect->q_subtract_power_y );
    4306        4800 :             move16();
    4307             :         }
    4308             : 
    4309      147600 :         FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4310             :         {
    4311      130800 :             Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q )
    4312             :         }
    4313       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] );
    4314       16800 :         move16();
    4315      147600 :         FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4316             :         {
    4317      130800 :             Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q )
    4318             :         }
    4319       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] );
    4320       16800 :         move16();
    4321             : 
    4322       50400 :         FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4323             :         {
    4324       33600 :             Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q )
    4325             :         }
    4326       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[0], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[0] );
    4327       16800 :         move16();
    4328       50400 :         FOR( i = 0; hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4329             :         {
    4330       33600 :             Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1] ), hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q )
    4331             :         }
    4332       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_q[1], hDirACRend->h_output_synthesis_psd_state.proto_power_smooth_prev_q[1] );
    4333       16800 :         move16();
    4334             : 
    4335       16800 :         Word16 proto_power_diff_smooth_prev_temp_q = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len );
    4336       16800 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len, proto_power_diff_smooth_prev_temp_q ); // hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q + proto_power_diff_smooth_prev_temp_q
    4337       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q, proto_power_diff_smooth_prev_temp_q );
    4338       16800 :         move16();
    4339             : 
    4340       16800 :         Word16 proto_power_diff_smooth_temp_q = getScaleFactor32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len );
    4341       16800 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len, proto_power_diff_smooth_temp_q ); // hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q + proto_power_diff_smooth_temp_q
    4342       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = add( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, proto_power_diff_smooth_temp_q );
    4343       16800 :         move16();
    4344             : 
    4345       16800 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q ), hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q )
    4346       16800 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_fx, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_len, sub( s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q ), hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q ) );                // s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q )
    4347       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q );
    4348       16800 :         move16();
    4349       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = s_min( hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q, hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q );
    4350       16800 :         move16();
    4351             : 
    4352       16800 :         Scale_sig32( diffuseness_vector_fx, hSpatParamRendCom->num_freq_bands, 1 );
    4353             : 
    4354             :         /*Buffer rescaling*/
    4355             : 
    4356       16800 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] ) );                                    // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q )
    4357       16800 :         Scale_sig32( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_fx + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q )
    4358       50400 :         FOR( i = 0; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4359             :         {
    4360       33600 :             Scale_sig32( DirAC_mem.reference_power_fx + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] ), DirAC_mem.reference_power_q[0] ) );                                    // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q )
    4361       33600 :             Scale_sig32( DirAC_mem.reference_power_fx + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] ), DirAC_mem.reference_power_q[1] ) ); // s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q, DirAC_mem.reference_power_q )
    4362             :         }
    4363       16800 :         hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] );
    4364       16800 :         move16();
    4365       16800 :         hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] );
    4366       16800 :         move16();
    4367       16800 :         DirAC_mem.reference_power_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] );
    4368       16800 :         move16();
    4369       16800 :         DirAC_mem.reference_power_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] );
    4370       16800 :         move16();
    4371       16800 :         DirAC_mem.reference_power_smooth_q[0] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0], DirAC_mem.reference_power_q[0] );
    4372       16800 :         move16();
    4373       16800 :         DirAC_mem.reference_power_smooth_q[1] = s_min( hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1], DirAC_mem.reference_power_q[1] );
    4374       16800 :         move16();
    4375             : 
    4376       16800 :         ivas_dirac_dec_output_synthesis_process_subframe_psd_ls_fx( Cldfb_RealBuffer_fx,
    4377             :                                                                     Cldfb_ImagBuffer_fx,
    4378             :                                                                     hSpatParamRendCom,
    4379             :                                                                     hDirACRend,
    4380       16800 :                                                                     hSpatParamRendCom->subframe_nbslots[subframe_idx],
    4381             :                                                                     diffuseness_vector_fx,
    4382             :                                                                     reference_power_smooth_fx,
    4383             :                                                                     DirAC_mem.reference_power_smooth_q,
    4384             :                                                                     ONE_IN_Q31,
    4385             :                                                                     0, &q_cldfb );
    4386             : 
    4387       16800 :         hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_prev_q = hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth_q;
    4388       16800 :         move16();
    4389       16800 :         hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[0] = DirAC_mem.reference_power_smooth_q[0];
    4390       16800 :         hDirACRend->h_output_synthesis_psd_state.reference_power_smooth_prev_q[1] = DirAC_mem.reference_power_smooth_q[1];
    4391       16800 :         move16();
    4392       16800 :         IF( LT_16( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) )
    4393             :         {
    4394           0 :             FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4395             :             {
    4396           0 :                 Scale_sig32( reference_power_fix + i, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_q[0], DirAC_mem.reference_power_smooth_q[0] ) ); // DirAC_mem.reference_power_q
    4397             :             }
    4398           0 :             DirAC_mem.reference_power_smooth_q[0] = DirAC_mem.reference_power_q[0];
    4399           0 :             move16();
    4400             :         }
    4401             :         ELSE
    4402             :         {
    4403       16800 :             Scale_sig32( reference_power_fix, s_min( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ), sub( DirAC_mem.reference_power_smooth_q[0], DirAC_mem.reference_power_q[0] ) ); // DirAC_mem.reference_power_smooth_q
    4404       16800 :             DirAC_mem.reference_power_q[0] = DirAC_mem.reference_power_smooth_q[0];
    4405       16800 :             move16();
    4406             :         }
    4407       16800 :         IF( LT_16( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) )
    4408             :         {
    4409           0 :             FOR( i = hSpatParamRendCom->num_freq_bands; DirAC_mem.reference_power_len > i; i = add( i, hSpatParamRendCom->num_freq_bands ) )
    4410             :             {
    4411           0 :                 Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF + i, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_q[1], DirAC_mem.reference_power_smooth_q[1] ) ); // DirAC_mem.reference_power_q
    4412             :             }
    4413           0 :             DirAC_mem.reference_power_smooth_q[1] = DirAC_mem.reference_power_q[1];
    4414           0 :             move16();
    4415             :         }
    4416             :         ELSE
    4417             :         {
    4418       16800 :             Scale_sig32( reference_power_fix + CLDFB_NO_CHANNELS_HALF, s_max( 0, sub( hSpatParamRendCom->num_freq_bands, CLDFB_NO_CHANNELS_HALF ) ), sub( DirAC_mem.reference_power_smooth_q[1], DirAC_mem.reference_power_q[1] ) ); // DirAC_mem.reference_power_smooth_q
    4419       16800 :             DirAC_mem.reference_power_q[1] = DirAC_mem.reference_power_smooth_q[1];
    4420       16800 :             move16();
    4421             :         }
    4422             :     }
    4423             : 
    4424             :     /*-----------------------------------------------------------------*
    4425             :      * CLDFB synthesis (and binaural rendering)
    4426             :      *-----------------------------------------------------------------*/
    4427             : 
    4428       20400 :     index_slot = slot_idx_start_cldfb_synth;
    4429       20400 :     move16();
    4430             : 
    4431             :     {
    4432             :         Word16 outchannels;
    4433             :         Word32 *RealBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES];
    4434             :         Word32 *ImagBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES];
    4435       20400 :         Word16 scale_factor = 31;
    4436       20400 :         move16();
    4437             : 
    4438      186000 :         FOR( ch = 0; ch < hDirACRend->num_outputs_dir; ch++ )
    4439             :         {
    4440      828000 :             FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    4441             :             {
    4442      662400 :                 scale_factor = s_min( scale_factor, L_norm_arr( Cldfb_RealBuffer_fx[ch][slot_idx],
    4443      662400 :                                                                 hSpatParamRendCom->num_freq_bands ) );
    4444      662400 :                 scale_factor = s_min( scale_factor, L_norm_arr( Cldfb_ImagBuffer_fx[ch][slot_idx],
    4445      662400 :                                                                 hSpatParamRendCom->num_freq_bands ) );
    4446             :             }
    4447             :         }
    4448       20400 :         scale_factor = sub( scale_factor, find_guarded_bits_fx( hSpatParamRendCom->num_freq_bands ) ); // guard bits
    4449             : 
    4450      186000 :         FOR( ch = 0; ch < hDirACRend->num_outputs_dir; ch++ )
    4451             :         {
    4452      828000 :             FOR( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
    4453             :             {
    4454      662400 :                 scale_sig32( Cldfb_RealBuffer_fx[ch][slot_idx],
    4455      662400 :                              hSpatParamRendCom->num_freq_bands, scale_factor ); // q_cldfb+scale_factor
    4456      662400 :                 scale_sig32( Cldfb_ImagBuffer_fx[ch][slot_idx],
    4457      662400 :                              hSpatParamRendCom->num_freq_bands, scale_factor ); // q_cldfb+scale_factor
    4458             :             }
    4459             :         }
    4460       20400 :         q_cldfb = add( q_cldfb, scale_factor );
    4461             : 
    4462       20400 :         idx_in = 0;
    4463       20400 :         move16();
    4464       20400 :         idx_lfe = 0;
    4465       20400 :         move16();
    4466             : 
    4467       20400 :         outchannels = add( hDirACRend->hOutSetup.nchan_out_woLFE, hDirACRend->hOutSetup.num_lfe );
    4468             : 
    4469             :         /* Note here that compared to decoder path, there is no separate channel ever for MASA ext rend path */
    4470      196800 :         FOR( ch = 0; ch < outchannels; ch++ )
    4471             :         {
    4472      176400 :             test();
    4473      176400 :             IF( hDirACRend->hOutSetup.num_lfe > 0 && ( EQ_16( hDirACRend->hOutSetup.index_lfe[idx_lfe], ch ) ) )
    4474             :             {
    4475             :                 /* No LFE for MASA rendering */
    4476       12000 :                 set32_fx( &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), 0, imult1616( hSpatParamRendCom->subframe_nbslots[subframe_idx], hSpatParamRendCom->num_freq_bands ) );
    4477             : 
    4478       12000 :                 IF( LT_16( idx_lfe, sub( hDirACRend->hOutSetup.num_lfe, 1 ) ) )
    4479             :                 {
    4480           0 :                     idx_lfe = add( idx_lfe, 1 );
    4481             :                 }
    4482             :             }
    4483             :             ELSE
    4484             :             {
    4485             :                 /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
    4486             :                 /* cldfb_state_fx should be in 1 less q-factor compared to cld buffers for cldfbSynthesis_ivas_fx function */
    4487      164400 :                 Word16 q_out = sub( q_cldfb, 1 );
    4488      164400 :                 Word16 max_shift = L_norm_arr( hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_length );
    4489      164400 :                 IF( GT_16( max_shift, sub( q_out, hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state ) ) )
    4490             :                 {
    4491      164400 :                     scale_sig32( hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_fx, hMasaExtRend->cldfbSynRend[idx_in]->cldfb_state_length, sub( q_out, hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state ) ); // q_out
    4492      164400 :                     hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state = q_out;
    4493      164400 :                     move16();
    4494             :                 }
    4495             :                 ELSE
    4496             :                 {
    4497           0 :                     FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
    4498             :                     {
    4499           0 :                         scale_sig32( Cldfb_RealBuffer_fx[idx_in][i], hSpatParamRendCom->num_freq_bands, sub( hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state, q_out ) );
    4500           0 :                         scale_sig32( Cldfb_ImagBuffer_fx[idx_in][i], hSpatParamRendCom->num_freq_bands, sub( hMasaExtRend->cldfbSynRend[idx_in]->Q_cldfb_state, q_out ) );
    4501             :                     }
    4502             :                 }
    4503      822000 :                 FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
    4504             :                 {
    4505      657600 :                     RealBuffer_fx[i] = Cldfb_RealBuffer_fx[idx_in][i]; // q_cldfb
    4506      657600 :                     ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; // q_cldfb
    4507             :                 }
    4508      164400 :                 Word16 out_size = imult1616( hSpatParamRendCom->num_freq_bands, hSpatParamRendCom->subframe_nbslots[subframe_idx] );
    4509      164400 :                 cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, 0, 0, hMasaExtRend->cldfbSynRend[idx_in] );
    4510      164400 :                 scale_sig32( &( output_f_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), out_size, sub( 11, q_out ) ); // q11
    4511      164400 :                 idx_in++;
    4512             :             }
    4513             :         }
    4514             :     }
    4515       20400 :     hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->subframe_nbslots[subframe_idx], hSpatParamRendCom->slots_rendered );
    4516       20400 :     move16();
    4517       20400 :     hSpatParamRendCom->subframes_rendered++;
    4518             : 
    4519       20400 :     pop_wmops();
    4520             : 
    4521       20400 :     return;
    4522             : }
    4523             : 
    4524             : 
    4525       12750 : void ivas_masa_ext_dirac_render_fx(
    4526             :     MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA renderer structure             */
    4527             :     Word32 *output_f[],                /* i/o: input/output signals in time domain q11*/
    4528             :     const Word16 num_subframes         /* i  : number of subframes to render       */
    4529             : )
    4530             : {
    4531             :     Word16 subframe_idx;
    4532             :     Word32 *output_f_local[MAX_OUTPUT_CHANNELS];
    4533             :     Word16 n, n_samples_sf;
    4534             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
    4535             : 
    4536       12750 :     hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom;
    4537             : 
    4538       12750 :     n_samples_sf = i_mult( JBM_CLDFB_SLOTS_IN_SUBFRAME, hSpatParamRendCom->slot_size );
    4539             : 
    4540      216750 :     FOR( n = 0; n < MAX_OUTPUT_CHANNELS; n++ )
    4541             :     {
    4542      204000 :         output_f_local[n] = output_f[n]; // q11
    4543             :     }
    4544             : 
    4545       12750 :     hSpatParamRendCom->subframes_rendered = hSpatParamRendCom->dirac_read_idx;
    4546       12750 :     move16();
    4547             : 
    4548       33150 :     FOR( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ )
    4549             :     {
    4550       20400 :         hSpatParamRendCom->slots_rendered = 0;
    4551       20400 :         move16();
    4552       20400 :         ivas_masa_ext_dirac_render_sf_fx( hMasaExtRend, output_f_local );
    4553      346800 :         FOR( n = 0; n < MAX_OUTPUT_CHANNELS; n++ )
    4554             :         {
    4555      326400 :             output_f_local[n] += n_samples_sf;
    4556             :         }
    4557             : 
    4558       20400 :         hSpatParamRendCom->dirac_read_idx = add( hSpatParamRendCom->dirac_read_idx, 1 ) % hSpatParamRendCom->dirac_md_buffer_length;
    4559       20400 :         move16();
    4560             :     }
    4561             : 
    4562       12750 :     return;
    4563             : }

Generated by: LCOV version 1.14