LCOV - code coverage report
Current view: top level - lib_dec - ivas_spar_decoder_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 906 959 94.5 %
Date: 2025-06-27 02:59:36 Functions: 20 20 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include <math.h>
      35             : #include <assert.h>
      36             : #include "options.h"
      37             : #include "ivas_stat_dec.h"
      38             : #include "prot_fx.h"
      39             : #include "string.h"
      40             : #include "ivas_prot_rend_fx.h"
      41             : #include "rom_com.h"
      42             : #include "ivas_rom_com.h"
      43             : #include "ivas_rom_dec.h"
      44             : #include "ivas_stat_com.h"
      45             : #include "stat_com.h"
      46             : #include "wmc_auto.h"
      47             : #include "ivas_prot_fx.h"
      48             : #ifdef DEBUGGING
      49             : #include "debug.h"
      50             : #endif
      51             : 
      52             : /*-------------------------------------------------------------------*
      53             :  * Local function prototypes
      54             :  *--------------------------------------------------------------------*/
      55             : 
      56             : static ivas_error ivas_spar_dec_MD_fx( Decoder_Struct *st_ivas, Decoder_State *st0 );
      57             : 
      58             : 
      59             : /*-------------------------------------------------------------------------
      60             :  * ivas_spar_dec_open()
      61             :  *
      62             :  * Allocate and initialize SPAR decoder handle and sub-handles
      63             :  *------------------------------------------------------------------------*/
      64             : 
      65        1476 : ivas_error ivas_spar_dec_open_fx(
      66             :     Decoder_Struct *st_ivas,        /* i/o: IVAS decoder handle        */
      67             :     const Word16 spar_reconfig_flag /* i  : SPAR reconfiguration flag  Q0*/
      68             : )
      69             : {
      70             :     SPAR_DEC_HANDLE hSpar;
      71             :     ivas_error error;
      72             :     Word16 sba_order_internal, num_channels_internal;
      73             :     IVAS_FB_CFG *fb_cfg;
      74             :     Word16 i, j, b, active_w_mixing;
      75             :     Word32 output_Fs;
      76             :     Word16 num_decor_chs, map_idx;
      77             : 
      78        1476 :     error = IVAS_ERR_OK;
      79        1476 :     move32();
      80             : 
      81        1476 :     sba_order_internal = s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); /*Q0*/
      82        1476 :     move16();
      83             : 
      84        1476 :     num_channels_internal = ivas_sba_get_nchan_metadata_fx( sba_order_internal, st_ivas->hDecoderConfig->ivas_total_brate ); /*Q0*/
      85             : 
      86        1476 :     hSpar = st_ivas->hSpar;
      87             : 
      88        1476 :     IF( !spar_reconfig_flag )
      89             :     {
      90             :         /* SPAR decoder handle */
      91         273 :         IF( ( hSpar = (SPAR_DEC_HANDLE) malloc( sizeof( SPAR_DEC_DATA ) ) ) == NULL )
      92             :         {
      93           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR decoder" );
      94             :         }
      95             :     }
      96             : 
      97        1476 :     output_Fs = st_ivas->hDecoderConfig->output_Fs; /*Q0*/
      98        1476 :     move32();
      99        1476 :     IF( GT_16( num_channels_internal, ( SBA_HOA2_ORDER + 1 ) * ( SBA_HOA2_ORDER + 1 ) ) )
     100             :     {
     101          71 :         num_decor_chs = IVAS_HBR_MAX_DECOR_CHS; /*Q0*/
     102          71 :         move16();
     103             :     }
     104             :     ELSE
     105             :     {
     106        1405 :         num_decor_chs = sub( num_channels_internal, 1 ); /*Q0*/
     107             :     }
     108             : 
     109             :     /* TD decorr. */
     110        1476 :     test();
     111        1476 :     test();
     112        1476 :     test();
     113        1476 :     test();
     114        1476 :     IF( EQ_32( st_ivas->ivas_format, SBA_FORMAT ) && ( ( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) ) || ( GE_32( st_ivas->hDecoderConfig->ivas_total_brate, IVAS_256k ) && EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) ) ) )
     115             :     {
     116         231 :         hSpar->hTdDecorr = NULL;
     117             :     }
     118             :     ELSE
     119             :     {
     120        1245 :         IF( ( error = ivas_td_decorr_dec_open_fx( &hSpar->hTdDecorr, output_Fs, add( num_decor_chs, 1 ), 1 ) ) != IVAS_ERR_OK )
     121             :         {
     122           0 :             return error;
     123             :         }
     124             :     }
     125             : 
     126             :     /* MD handle */
     127        1476 :     IF( ( error = ivas_spar_md_dec_open( &hSpar->hMdDec, st_ivas->hDecoderConfig, num_channels_internal, sba_order_internal, st_ivas->sid_format, st_ivas->last_active_ivas_total_brate ) ) != IVAS_ERR_OK )
     128             :     {
     129           0 :         return error;
     130             :     }
     131        1476 :     hSpar->hMdDec->td_decorr_flag = 1;
     132        1476 :     move16();
     133        1476 :     if ( hSpar->hTdDecorr )
     134             :     {
     135        1245 :         hSpar->hTdDecorr->ducking_flag = ivas_spar_br_table_consts[hSpar->hMdDec->table_idx].td_ducking; /*Q0*/
     136        1245 :         move16();
     137             :     }
     138             : 
     139             :     /* set FB config. */
     140        1476 :     active_w_mixing = -1;
     141        1476 :     move16();
     142        1476 :     IF( NE_32( ( error = ivas_fb_set_cfg( &fb_cfg, SBA_FORMAT, num_channels_internal, num_channels_internal, active_w_mixing, output_Fs, 0 ) ), IVAS_ERR_OK ) )
     143             :     {
     144           0 :         return error;
     145             :     }
     146        1476 :     fb_cfg->pcm_offset = NS2SA_FX2( output_Fs, DELAY_FB_1_NS + IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ); /*Q0*/
     147        1476 :     move16();
     148        1476 :     fb_cfg->remix_order = remix_order_set[hSpar->hMdDec->spar_md_cfg.remix_unmix_order]; /*Q0*/
     149        1476 :     move16();
     150             : 
     151             :     /* FB mixer handle */
     152        1476 :     IF( NE_32( ( error = ivas_FB_mixer_open_fx( &hSpar->hFbMixer, output_Fs, fb_cfg, spar_reconfig_flag ) ), IVAS_ERR_OK ) )
     153             :     {
     154           0 :         return error;
     155             :     }
     156             : 
     157             :     /* AGC handle */
     158        1476 :     IF( NE_32( ( error = ivas_spar_agc_dec_open_fx( &hSpar->hAgcDec, output_Fs ) ), IVAS_ERR_OK ) )
     159             :     {
     160           0 :         return error;
     161             :     }
     162             : 
     163             :     /* PCA handle */
     164        1476 :     hSpar->hPCA = NULL;
     165        1476 :     test();
     166        1476 :     IF( EQ_32( st_ivas->hDecoderConfig->ivas_total_brate, PCA_BRATE ) && EQ_16( sba_order_internal, 1 ) )
     167             :     {
     168          32 :         IF( ( hSpar->hPCA = (PCA_DEC_STATE *) malloc( sizeof( PCA_DEC_STATE ) ) ) == NULL )
     169             :         {
     170           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for PCA decoder" );
     171             :         }
     172             : 
     173          32 :         ivas_pca_dec_init_fx( hSpar->hPCA );
     174             :     }
     175             : 
     176             :     /* mixer_mat intitialization */
     177        8494 :     FOR( i = 0; i < num_channels_internal; i++ )
     178             :     {
     179       45426 :         FOR( j = 0; j < num_channels_internal; j++ )
     180             :         {
     181      499304 :             FOR( b = 0; b < IVAS_MAX_NUM_BANDS; b++ )
     182             :             {
     183      460896 :                 hSpar->hMdDec->mixer_mat_fx[i][j][b] = 0;
     184      460896 :                 move32();
     185     2765376 :                 FOR( Word16 i_ts = 0; i_ts < ( MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); i_ts++ )
     186             :                 {
     187     2304480 :                     hSpar->hMdDec->mixer_mat_prev_fx[i_ts][i][j][b] = 0;
     188     2304480 :                     move32();
     189             :                 }
     190             :             }
     191             :         }
     192             :     }
     193        1476 :     hSpar->hMdDec->Q_mixer_mat = Q31;
     194        1476 :     move16();
     195        1476 :     hSpar->i_subframe = 0;
     196        1476 :     move16();
     197        1476 :     hSpar->AGC_flag = 0;
     198        1476 :     move16();
     199             : 
     200             :     /*-----------------------------------------------------------------*
     201             :      * Configuration - set SPAR high-level parameters
     202             :      *-----------------------------------------------------------------*/
     203             : 
     204        1476 :     ivas_spar_config_fx( st_ivas->hDecoderConfig->ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, st_ivas->sid_format );
     205             : 
     206        1476 :     SWITCH( sba_order_internal )
     207             :     {
     208        1236 :         case 1:
     209        1236 :             st_ivas->transport_config = IVAS_AUDIO_CONFIG_FOA;
     210        1236 :             move32();
     211        1236 :             BREAK;
     212          55 :         case 2:
     213          55 :             st_ivas->transport_config = IVAS_AUDIO_CONFIG_HOA2;
     214          55 :             move32();
     215          55 :             BREAK;
     216         185 :         case 3:
     217         185 :             st_ivas->transport_config = IVAS_AUDIO_CONFIG_HOA3;
     218         185 :             move32();
     219         185 :             BREAK;
     220             :     }
     221             : 
     222        1476 :     ivas_output_init( &( st_ivas->hTransSetup ), st_ivas->transport_config );
     223             : 
     224        1476 :     set16_fx( hSpar->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
     225        1476 :     set16_fx( hSpar->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS ); /*Q0*/
     226        1476 :     hSpar->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS;                                             /*Q0*/
     227        1476 :     move16();
     228        1476 :     hSpar->subframes_rendered = 0;
     229        1476 :     move16();
     230        1476 :     hSpar->slots_rendered = 0;
     231        1476 :     move16();
     232        1476 :     hSpar->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME; /*Q0*/
     233        1476 :     move16();
     234             : 
     235             :     /* init render timeslot mapping */
     236        1476 :     set16_fx( hSpar->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
     237       25092 :     FOR( map_idx = 0; map_idx < DEFAULT_JBM_CLDFB_TIMESLOTS; map_idx++ )
     238             :     {
     239       23616 :         hSpar->render_to_md_map[map_idx] = map_idx; /*Q0*/
     240       23616 :         move16();
     241             :     }
     242             : 
     243             :     /* allocate transport channels*/
     244        1476 :     IF( st_ivas->hTcBuffer == NULL )
     245             :     {
     246             :         Word16 nchan_to_allocate;
     247             :         Word16 nchan_tc;
     248             :         TC_BUFFER_MODE buffer_mode;
     249             :         Word16 granularity;
     250             : 
     251         273 :         buffer_mode = TC_BUFFER_MODE_RENDERER;
     252         273 :         move32();
     253         273 :         nchan_tc = ivas_jbm_dec_get_num_tc_channels_fx( st_ivas ); /*Q0*/
     254         273 :         nchan_to_allocate = num_channels_internal;                 /*Q0*/
     255         273 :         move16();
     256             : 
     257         273 :         test();
     258         273 :         if ( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
     259             :         {
     260          12 :             nchan_to_allocate = add( nchan_to_allocate, st_ivas->nchan_ism ); /*Q0*/
     261             :         }
     262             : 
     263         273 :         granularity = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); /*Q0*/
     264         273 :         move16();
     265             : 
     266         273 :         test();
     267         273 :         test();
     268         273 :         test();
     269         273 :         IF( ( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) ) )
     270             :         {
     271          14 :             test();
     272          14 :             test();
     273          14 :             IF( ( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) ) )
     274             :             {
     275           1 :                 nchan_tc = add( st_ivas->hDecoderConfig->nchan_out, st_ivas->nchan_ism ); /*Q0*/
     276           1 :                 nchan_to_allocate = nchan_tc;                                             /*Q0*/
     277           1 :                 move16();
     278             :             }
     279             :             ELSE
     280             :             {
     281          13 :                 buffer_mode = TC_BUFFER_MODE_BUFFER;
     282          13 :                 move32();
     283          13 :                 nchan_tc = st_ivas->hDecoderConfig->nchan_out; /*Q0*/
     284          13 :                 move16();
     285          13 :                 nchan_to_allocate = nchan_tc; /*Q0*/
     286          13 :                 move16();
     287             :             }
     288             :         }
     289         259 :         ELSE IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) || EQ_32( st_ivas->renderer_type, RENDERER_STEREO_PARAMETRIC ) )
     290             :         {
     291          47 :             nchan_to_allocate = 2 * BINAURAL_CHANNELS;
     292          47 :             move16();
     293             :         }
     294             : 
     295         273 :         test();
     296         273 :         test();
     297         273 :         test();
     298         273 :         IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && ( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
     299             :         {
     300             :             /* get correct granularity in case of binaural rendering of the discrete objects with the td obj renderer */
     301             :             Word32 quo, rem;
     302           4 :             iDiv_and_mod_32( st_ivas->hDecoderConfig->output_Fs, FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &quo, &rem, 0 );
     303           4 :             granularity = extract_l( quo ); /*Q0*/
     304             :         }
     305             : 
     306         273 :         IF( NE_32( ( error = ivas_jbm_dec_tc_buffer_open_fx( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, granularity ) ), IVAS_ERR_OK ) )
     307             :         {
     308           0 :             return error;
     309             :         }
     310             :     }
     311             : 
     312        1476 :     st_ivas->hSpar = hSpar;
     313             : 
     314        1476 :     return error;
     315             : }
     316             : 
     317             : 
     318             : /*-------------------------------------------------------------------------
     319             :  * ivas_spar_dec_close()
     320             :  *
     321             :  * Deallocate SPAR handle
     322             :  *------------------------------------------------------------------------*/
     323             : 
     324        1807 : void ivas_spar_dec_close_fx(
     325             :     SPAR_DEC_HANDLE *hSpar,         /* i/o: SPAR decoder handle        */
     326             :     const Word32 output_Fs,         /* i  : output sampling rate       Q0*/
     327             :     const Word16 spar_reconfig_flag /* i  : SPAR reconfiguration flag  Q0*/
     328             : )
     329             : {
     330        1807 :     test();
     331        1807 :     IF( hSpar == NULL || *hSpar == NULL )
     332             :     {
     333         331 :         return;
     334             :     }
     335             : 
     336             :     /* MD handle */
     337        1476 :     ivas_spar_md_dec_close( &( *hSpar )->hMdDec );
     338             : 
     339             :     /* TD decorrelator handle */
     340        1476 :     ivas_td_decorr_dec_close( &( *hSpar )->hTdDecorr );
     341             : 
     342             :     /* FB mixer handle */
     343        1476 :     ivas_FB_mixer_close_fx( &( *hSpar )->hFbMixer, output_Fs, spar_reconfig_flag );
     344             : 
     345             :     /* AGC */
     346        1476 :     ivas_spar_agc_dec_close_fx( &( *hSpar )->hAgcDec );
     347             : 
     348             :     /* PCA */
     349        1476 :     IF( ( *hSpar )->hPCA != NULL )
     350             :     {
     351          24 :         free( ( *hSpar )->hPCA );
     352          24 :         ( *hSpar )->hPCA = NULL;
     353             :     }
     354             : 
     355        1476 :     IF( !spar_reconfig_flag )
     356             :     {
     357         273 :         free( ( *hSpar ) );
     358         273 :         ( *hSpar ) = NULL;
     359             :     }
     360             : 
     361        1476 :     return;
     362             : }
     363             : 
     364             : 
     365             : /*-------------------------------------------------------------------*
     366             :  * ivas_spar_dec()
     367             :  *
     368             :  * Principal IVAS SPAR decoder routine
     369             :  *-------------------------------------------------------------------*/
     370             : 
     371      149027 : ivas_error ivas_spar_dec_fx(
     372             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct             */
     373             :     Word16 *nb_bits_read     /* o  : number of MD bits read          Q0*/
     374             : )
     375             : {
     376             :     DECODER_CONFIG_HANDLE hDecoderConfig;
     377             :     Word16 i, nb_bits_read_orig;
     378             :     Decoder_State *st0;
     379             :     Word16 next_bit_pos_orig, last_bit_pos;
     380             :     UWord16 bstr_meta[MAX_BITS_METADATA], *bit_stream_orig;
     381             :     ivas_error error;
     382             :     Word32 quo, rem;
     383             : 
     384      149027 :     push_wmops( "ivas_spar_decode" );
     385      149027 :     error = IVAS_ERR_OK;
     386      149027 :     move32();
     387      149027 :     hDecoderConfig = st_ivas->hDecoderConfig;
     388             : 
     389      149027 :     st0 = NULL;
     390      149027 :     IF( st_ivas->nSCE > 0 )
     391             :     {
     392       41554 :         st0 = st_ivas->hSCE[0]->hCoreCoder[0];
     393             :     }
     394             :     ELSE
     395             :     {
     396      107473 :         st0 = st_ivas->hCPE[0]->hCoreCoder[0];
     397             :     }
     398             : 
     399      149027 :     bit_stream_orig = st0->bit_stream;     /*Q0*/
     400      149027 :     next_bit_pos_orig = st0->next_bit_pos; /*Q0*/
     401      149027 :     move16();
     402             : 
     403      149027 :     IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
     404             :     {
     405       30003 :         iDiv_and_mod_32( hDecoderConfig->ivas_total_brate, FRAMES_PER_SEC, &quo, &rem, 0 );
     406       30003 :         last_bit_pos = sub( extract_l( L_sub( quo, 1 ) ), nb_bits_read[1] ); /*Q0*/
     407             :     }
     408             :     ELSE
     409             :     {
     410      119024 :         *nb_bits_read = 0;
     411      119024 :         move16();
     412      119024 :         last_bit_pos = 0;
     413      119024 :         move16();
     414             :     }
     415             : 
     416             :     /* read DirAC bitstream */
     417      149027 :     IF( st_ivas->hQMetaData != NULL )
     418             :     {
     419      149027 :         ivas_dirac_dec_read_BS_fx( hDecoderConfig->ivas_total_brate, st0, st_ivas->hDirAC, st_ivas->hSpatParamRendCom, st_ivas->hQMetaData, nb_bits_read, last_bit_pos, ivas_get_hodirac_flag_fx( hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ), st_ivas->hSpar->dirac_to_spar_md_bands );
     420             :     }
     421             : 
     422      149027 :     IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
     423             :     {
     424       30003 :         iDiv_and_mod_32( hDecoderConfig->ivas_total_brate, FRAMES_PER_SEC, &quo, &rem, 0 );
     425       30003 :         last_bit_pos = sub( extract_l( L_sub( quo, 1 ) ), nb_bits_read[1] ); /*Q0*/
     426             :     }
     427             :     ELSE
     428             :     {
     429      119024 :         iDiv_and_mod_32( hDecoderConfig->ivas_total_brate, FRAMES_PER_SEC, &quo, &rem, 0 );
     430      119024 :         last_bit_pos = extract_l( L_sub( quo, 1 ) ); /*Q0*/
     431             :     }
     432             : 
     433      149027 :     test();
     434      149027 :     if ( !st0->bfi && EQ_32( hDecoderConfig->ivas_total_brate, IVAS_SID_5k2 ) )
     435             :     {
     436         324 :         last_bit_pos = sub( last_bit_pos, SID_FORMAT_NBITS ); /*Q0*/
     437             :     }
     438      149027 :     nb_bits_read_orig = *nb_bits_read; /*Q0*/
     439      149027 :     move16();
     440      149027 :     last_bit_pos = sub( last_bit_pos, nb_bits_read_orig ); /*Q0*/
     441             : 
     442             :     /* reverse the bitstream for easier reading of indices */
     443   225377204 :     FOR( i = 0; i < s_min( MAX_BITS_METADATA, last_bit_pos ); i++ )
     444             :     {
     445   225228177 :         bstr_meta[i] = st_ivas->bit_stream[( last_bit_pos - i )]; /*Q0*/
     446   225228177 :         move16();
     447             :     }
     448      149027 :     st0->bit_stream = bstr_meta; /*Q0*/
     449      149027 :     st0->next_bit_pos = 0;
     450      149027 :     move16();
     451      149027 :     st0->bits_frame = s_min( MAX_BITS_METADATA, add( last_bit_pos, 1 ) ); /*Q0*/
     452      149027 :     move16();
     453             : 
     454      149027 :     if ( !st0->bfi )
     455             :     {
     456      142968 :         st0->total_brate = hDecoderConfig->ivas_total_brate; /* to avoid BER detect */ /*Q0*/
     457      142968 :         move32();
     458             :     }
     459             : 
     460             :     /*---------------------------------------------------------------------*
     461             :      * Decode SPAR metadata
     462             :      *---------------------------------------------------------------------*/
     463             : 
     464      149027 :     IF( NE_32( ( error = ivas_spar_dec_MD_fx( st_ivas, st0 ) ), IVAS_ERR_OK ) )
     465             :     {
     466           0 :         return error;
     467             :     }
     468             : 
     469      149027 :     *nb_bits_read = add( st0->next_bit_pos, nb_bits_read_orig ); /*Q0*/
     470      149027 :     move16();
     471      149027 :     st0->bit_stream = bit_stream_orig;     /*Q0*/
     472      149027 :     st0->next_bit_pos = next_bit_pos_orig; /*Q0*/
     473      149027 :     move16();
     474             : 
     475      149027 :     test();
     476      149027 :     IF( !st0->bfi && EQ_32( hDecoderConfig->ivas_total_brate, IVAS_SID_5k2 ) )
     477             :     {
     478             :         Word16 zero_pad_bits;
     479         324 :         *nb_bits_read = add( *nb_bits_read, SID_FORMAT_NBITS ); /*Q0*/
     480         324 :         move16();
     481         324 :         zero_pad_bits = sub( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC, *nb_bits_read ); /*Q0*/
     482         324 :         assert( zero_pad_bits <= 1 );
     483         324 :         *nb_bits_read = add( *nb_bits_read, zero_pad_bits ); /*Q0*/
     484         324 :         move16();
     485             :     }
     486             : 
     487      149027 :     pop_wmops();
     488             : 
     489      149027 :     return error;
     490             : }
     491             : 
     492             : 
     493             : /*---------------------------------------------------------------------*
     494             :  * Function ivas_get_spar_table_idx_from_coded_idx()
     495             :  *
     496             :  * Get SPAR table index
     497             :  *---------------------------------------------------------------------*/
     498             : 
     499      140580 : static Word16 ivas_get_spar_table_idx_from_coded_idx(
     500             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate                              Q0*/
     501             :     const Word16 sba_order,        /* i  : Ambisonic (SBA) order                           Q0*/
     502             :     Decoder_State *st0,            /* i/o: decoder state structure - for bitstream handling*/
     503             :     Word16 *bitlen                 /* o  : number of bits                                  Q0*/
     504             : )
     505             : {
     506             :     Word16 table_idx, ind1[IVAS_SPAR_BR_TABLE_LEN];
     507             :     Word16 i, j, ind2;
     508             : 
     509      140580 :     j = 0;
     510      140580 :     move16();
     511     2952180 :     FOR( i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++ )
     512             :     {
     513     2811600 :         ind1[j] = 0;
     514     2811600 :         move16();
     515     2811600 :         test();
     516     2811600 :         IF( EQ_32( ivas_spar_br_table_consts[i].ivas_total_brate, ivas_total_brate ) && EQ_16( ivas_spar_br_table_consts[i].sba_order, sba_order ) )
     517             :         {
     518      140580 :             ind1[j] = i;
     519      140580 :             move16();
     520      140580 :             j = add( j, 1 );
     521             :         }
     522             :     }
     523             : 
     524      140580 :     assert( j > 0 );
     525      140580 :     *bitlen = ivas_get_bits_to_encode( sub( j, 1 ) ); /*Q0*/
     526      140580 :     move16();
     527             : 
     528      140580 :     ind2 = get_next_indice_fx( st0, *bitlen ); /*Q0*/
     529             : 
     530      140580 :     table_idx = ind1[ind2]; /*Q0*/
     531      140580 :     move16();
     532             : 
     533      140580 :     return table_idx;
     534             : }
     535             : 
     536             : 
     537             : /*---------------------------------------------------------------------*
     538             :  * Function ivas_parse_spar_header()
     539             :  *
     540             :  * Get SPAR table index
     541             :  *---------------------------------------------------------------------*/
     542             : 
     543      140580 : static Word16 ivas_parse_spar_header(
     544             :     const Word32 ivas_total_brate, /* i  : IVAS total bitrate                              Q0*/
     545             :     const Word16 sba_order,        /* i  : Ambisonic (SBA) order                           Q0*/
     546             :     Decoder_State *st0,            /* i/o: decoder state structure - for bitstream handling*/
     547             :     Word16 *table_idx /*Q0*/ )
     548             : {
     549             :     Word16 bitlen, bwidth;
     550             : 
     551      140580 :     *table_idx = ivas_get_spar_table_idx_from_coded_idx( ivas_total_brate, sba_order, st0, &bitlen ); /*Q0*/
     552      140580 :     move16();
     553             : 
     554      140580 :     bwidth = ivas_spar_br_table_consts[( *table_idx )].bwidth; /*Q0*/
     555      140580 :     move16();
     556             : 
     557      140580 :     return bwidth;
     558             : }
     559             : 
     560             : 
     561      571920 : static Word16 get_random_number_fx(
     562             :     Word16 *seed )
     563             : {
     564      571920 :     return Random( seed ); /*Q15*/
     565             : }
     566             : 
     567             : 
     568       10944 : static Word32 matrix_det_fx(
     569             :     const Word32 a00, /*Q27*/
     570             :     const Word32 a01, /*Q27*/
     571             :     const Word32 a10, /*Q27*/
     572             :     const Word32 a11  /*Q27*/
     573             : )
     574             : {
     575       10944 :     return L_sub( Mpy_32_32( a00, a11 ), Mpy_32_32( a01, a10 ) ); /*Q23*/
     576             : }
     577             : 
     578             : 
     579         912 : static void matrix_inverse_fx(
     580             :     Word32 in[3][3],  /*Q27*/
     581             :     Word32 out[3][3], /*out_q*/
     582             :     const Word16 size,
     583             :     Word16 *out_q )
     584             : {
     585             :     Word32 det, fac, tmp_32;
     586         912 :     Word32 eps_fx = 1;
     587         912 :     move32();
     588         912 :     Word16 q_fac, shift = 0, tmp_e = 0;
     589         912 :     move16();
     590         912 :     move16();
     591             : 
     592         912 :     IF( EQ_16( size, 1 ) )
     593             :     {
     594           0 :         tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q27, L_max( in[0][0], eps_fx ), &tmp_e ); /*Q: 15 - tmp_e*/
     595           0 :         shift = norm_l( tmp_32 );
     596           0 :         out[0][0] = L_shl( tmp_32, shift ); /*out_q*/
     597           0 :         move32();
     598           0 :         *out_q = add( shift, sub( Q15, tmp_e ) );
     599           0 :         move16();
     600             : 
     601           0 :         return;
     602             :     }
     603         912 :     ELSE IF( EQ_16( size, 2 ) )
     604             :     {
     605           0 :         det = matrix_det_fx( in[0][1], in[0][1], in[1][0], in[1][1] );                    /*Q23*/
     606           0 :         tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q23, L_max( det, eps_fx ), &tmp_e ); /*Q: 15 - tmp_e*/
     607           0 :         shift = norm_l( tmp_32 );
     608           0 :         fac = L_shl( tmp_32, shift ); /*q_fac*/
     609           0 :         q_fac = add( shift, sub( Q15, tmp_e ) );
     610             : 
     611           0 :         out[0][0] = Mpy_32_32( in[1][1], fac ); /*q_fac - 4*/
     612           0 :         move32();
     613           0 :         out[1][0] = Mpy_32_32( in[1][0], L_negate( fac ) ); /*q_fac - 4*/
     614           0 :         move32();
     615             : 
     616           0 :         out[0][1] = Mpy_32_32( in[0][1], L_negate( fac ) ); /*q_fac - 4*/
     617           0 :         move32();
     618           0 :         out[1][1] = Mpy_32_32( in[0][0], fac ); /*q_fac - 4*/
     619           0 :         move32();
     620             : 
     621           0 :         *out_q = add( Q27, sub( q_fac, 31 ) );
     622           0 :         move16();
     623             : 
     624           0 :         return;
     625             :     }
     626             : 
     627         912 :     det = L_add( L_sub( Mpy_32_32( in[0][0], matrix_det_fx( in[1][1], in[1][2], in[2][1], in[2][2] ) ), Mpy_32_32( in[1][0], matrix_det_fx( in[0][1], in[0][2], in[2][1], in[2][2] ) ) ), Mpy_32_32( in[2][0], matrix_det_fx( in[0][1], in[0][2], in[1][1], in[1][2] ) ) ); /*Q19*/
     628         912 :     tmp_32 = BASOP_Util_Divide3232_Scale( ONE_IN_Q19, L_max( det, eps_fx ), &tmp_e );                                                                                                                                                                                       /*Q: 31 - tmp_e*/
     629         912 :     shift = norm_l( tmp_32 );
     630         912 :     fac = L_shl( tmp_32, shift ); /*q_fac*/
     631         912 :     q_fac = add( shift, sub( Q15, tmp_e ) );
     632             : 
     633         912 :     out[0][0] = Mpy_32_32( matrix_det_fx( in[1][1], in[1][2], in[2][1], in[2][2] ), fac ); /*q_fac-8*/
     634         912 :     move32();
     635         912 :     out[1][0] = Mpy_32_32( matrix_det_fx( in[1][0], in[1][2], in[2][0], in[2][2] ), L_negate( fac ) ); /*q_fac-8*/
     636         912 :     move32();
     637         912 :     out[2][0] = Mpy_32_32( matrix_det_fx( in[1][0], in[1][1], in[2][0], in[2][1] ), fac ); /*q_fac-8*/
     638         912 :     move32();
     639             : 
     640         912 :     out[0][1] = Mpy_32_32( matrix_det_fx( in[0][1], in[0][2], in[2][1], in[2][2] ), L_negate( fac ) ); /*q_fac-8*/
     641         912 :     move32();
     642         912 :     out[1][1] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][2], in[2][0], in[2][2] ), fac ); /*q_fac-8*/
     643         912 :     move32();
     644         912 :     out[2][1] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][1], in[2][0], in[2][1] ), L_negate( fac ) ); /*q_fac-8*/
     645         912 :     move32();
     646             : 
     647         912 :     out[0][2] = Mpy_32_32( matrix_det_fx( in[0][1], in[0][2], in[1][1], in[1][2] ), fac ); /*q_fac-8*/
     648         912 :     move32();
     649         912 :     out[1][2] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][2], in[1][0], in[1][2] ), L_negate( fac ) ); /*q_fac-8*/
     650         912 :     move32();
     651         912 :     out[2][2] = Mpy_32_32( matrix_det_fx( in[0][0], in[0][1], in[1][0], in[1][1] ), fac ); /*q_fac-8*/
     652         912 :     move32();
     653             : 
     654         912 :     *out_q = add( Q23, sub( q_fac, 31 ) );
     655         912 :     move16();
     656             : 
     657         912 :     return;
     658             : }
     659             : 
     660             : 
     661             : /*---------------------------------------------------------------------*
     662             :  * Function ivas_spar_get_cldfb_gains()
     663             :  *
     664             :  *
     665             :  *---------------------------------------------------------------------*/
     666             : 
     667         912 : void ivas_spar_get_cldfb_gains_fx(
     668             :     SPAR_DEC_HANDLE hSpar,
     669             :     HANDLE_CLDFB_FILTER_BANK cldfbAnaDec0,
     670             :     HANDLE_CLDFB_FILTER_BANK cldfbSynDec0,
     671             :     const DECODER_CONFIG_HANDLE hDecoderConfig )
     672             : {
     673         912 :     Word32 output_Fs_fx = hDecoderConfig->output_Fs;
     674             :     Word16 *weights_fx;
     675             :     Word16 cf_start_s_fx, cf_len_s_fx;
     676             :     Word32 T_fx[3 * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX - CLDFB_NO_CHANNELS_MAX][3];
     677             :     Word32 Tt_T_fx[3][3];
     678             :     Word32 Tt_T_inv_fx[3][3];
     679             :     Word32 Tt_tgt_fx[3];
     680             :     Word32 ts_inout_fx[CLDFB_NO_CHANNELS_MAX];
     681             :     Word32 ts_re_fx[CLDFB_NO_CHANNELS_MAX];
     682             :     Word32 ts_im_fx[CLDFB_NO_CHANNELS_MAX];
     683             :     Word32 *pp_ts_im_fx[1], *pp_ts_re_fx[1];
     684             :     Word32 tgt_fx[( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX];
     685             :     Word16 pt_len, stride, num_cldfb_bands, decfb_delay;
     686             :     Word16 encfb_delay, cf_start, cf_end, cf_len;
     687             :     Word16 ts, cf_cldfb_start, cf_cldfb_end;
     688             :     Word16 sample, num_cf_slots, num_samples;
     689             :     Word16 seed, split_band, slot_row, slot_col, slot, tmp_idx;
     690             :     Word16 Q_cf_start_s;
     691             :     Word16 Q_cf_len_s;
     692             :     Word16 Q_weights;
     693             : 
     694         912 :     pt_len = cldfbAnaDec0->p_filter_length; /*Q0*/
     695         912 :     move16();
     696         912 :     num_cldfb_bands = cldfbAnaDec0->no_channels; /*Q0*/
     697         912 :     move16();
     698             : 
     699         912 :     stride = NS2SA_FX2( output_Fs_fx, DELAY_CLDFB_NS );            /*Q0*/
     700         912 :     encfb_delay = NS2SA_FX2( output_Fs_fx, IVAS_FB_ENC_DELAY_NS ); /*Q0*/
     701         912 :     decfb_delay = NS2SA_FX2( output_Fs_fx, IVAS_FB_DEC_DELAY_NS ); /*Q0*/
     702             : 
     703         912 :     cf_start = add( sub( hSpar->hFbMixer->cross_fade_start_offset, encfb_delay ), decfb_delay ); /* time domain after CLDFB synthesis*/ /*Q0*/
     704         912 :     cf_end = add( sub( hSpar->hFbMixer->cross_fade_end_offset, encfb_delay ), decfb_delay );                                            /*Q0*/
     705         912 :     cf_len = sub( cf_end, cf_start );
     706         912 :     weights_fx = hSpar->hFbMixer->cldfb_cross_fade_fx;                                                                                                              /*hSpar->hFbMixer->cldfb_cross_fade_q*/
     707         912 :     cf_cldfb_start = shr( extract_l( ceil_fixed( sub( divide1616( sub( cf_start, shr( decfb_delay, 1 ) ), shl( stride, 9 ) ), 32 ), 6 ) ), 6 );                     /*Q0*/
     708         912 :     cf_cldfb_end = shr( divide1616( add( sub( cf_start, shr( decfb_delay, 1 ) ), cf_len ), shl( stride, 9 ) ), 6 ); /*q-factor of stride is 9(as max value is 60)*/ /*Q0*/
     709         912 :     num_cf_slots = add( sub( cf_cldfb_end, cf_cldfb_start ), 1 );                                                                                                   /*Q0*/
     710         912 :     num_samples = add( imult1616( num_cf_slots, stride ), sub( pt_len, stride ) );                                                                                  /*Q0*/
     711         912 :     seed = RANDOM_INITSEED;
     712         912 :     move16();
     713         912 :     split_band = SPAR_DIRAC_SPLIT_START_BAND;
     714         912 :     move16();
     715         912 :     pp_ts_im_fx[0] = ts_im_fx; /*Q22*/
     716         912 :     pp_ts_re_fx[0] = ts_re_fx; /*Q22*/
     717         912 :     set32_fx( tgt_fx, 0, ( 3 - 1 ) * CLDFB_NO_CHANNELS_MAX + 10 * CLDFB_NO_CHANNELS_MAX );
     718         912 :     cf_start_s_fx = divide3232( ( sub( cf_start, shr( decfb_delay, 1 ) ) ), output_Fs_fx );                                            /*Q_cf_start_s*/
     719         912 :     cf_len_s_fx = divide3232( sub( hSpar->hFbMixer->cross_fade_end_offset, hSpar->hFbMixer->cross_fade_start_offset ), output_Fs_fx ); /*Q_cf_len_s*/
     720         912 :     Q_cf_start_s = sub( norm_s( cf_start_s_fx ), 1 );
     721         912 :     Q_cf_len_s = norm_s( cf_len_s_fx );
     722         912 :     Q_weights = add( 15, sub( Q_cf_start_s, Q_cf_len_s ) );
     723       15504 :     FOR( ts = 0; ts < CLDFB_NO_COL_MAX; ts++ )
     724             :     {
     725       14592 :         weights_fx[ts] = divide1616( shl( sub( divide3232( L_mult0( add( shl( ts, 1 ), 1 ), shr( stride, 1 ) ), output_Fs_fx ), cf_start_s_fx ), Q_cf_start_s ), shl( cf_len_s_fx, Q_cf_len_s ) ); /*Q_weights*/
     726       14592 :         move16();
     727       14592 :         weights_fx[ts] = s_max( s_min( weights_fx[ts], shl( 1, Q_weights ) ), 0 ); /*Q_weights*/
     728       14592 :         move16();
     729             :     }
     730         912 :     hSpar->hFbMixer->cldfb_cross_fade_start = cf_cldfb_start; /*Q0*/
     731         912 :     move16();
     732         912 :     hSpar->hFbMixer->cldfb_cross_fade_end = cf_cldfb_end; /*Q0*/
     733         912 :     move16();
     734             : 
     735         912 :     test();
     736         912 :     test();
     737         912 :     test();
     738         912 :     if ( GT_16( num_cf_slots, 3 ) || GT_16( pt_len, 10 * CLDFB_NO_CHANNELS_MAX ) || GT_16( stride, CLDFB_NO_CHANNELS_MAX ) || EQ_16( split_band, IVAS_MAX_NUM_BANDS ) )
     739             :     {
     740           0 :         return;
     741             :     }
     742             : 
     743             :     /* optimization*/
     744             :     /* compute time-domain cross-fade for considered time slots*/
     745         912 :     tmp_idx = sub( cf_start, imult1616( cf_cldfb_start, stride ) ); /*Q0*/
     746      153424 :     FOR( sample = 0; sample < cf_len; sample++ )
     747             :     {
     748      152512 :         tgt_fx[tmp_idx] = L_deposit_h( hSpar->hFbMixer->pFilterbank_cross_fade_fx[sample] ); /*Q31*/
     749      152512 :         move32();
     750      152512 :         tmp_idx = add( tmp_idx, 1 );
     751             :         /* increasing window function */
     752             :     }
     753      344064 :     FOR( ; tmp_idx < num_samples; tmp_idx++ )
     754             :     {
     755             :         /* fill up with ones*/
     756      343152 :         tgt_fx[tmp_idx] = MAX_32; /*Q31*/
     757      343152 :         move32();
     758             :     }
     759      572832 :     FOR( sample = 0; sample < num_samples; sample++ )
     760             :     {
     761             :         /* initialize trasnform matrix with zeros*/
     762      571920 :         T_fx[sample][0] = T_fx[sample][1] = T_fx[sample][2] = 0;
     763      571920 :         move32();
     764      571920 :         move32();
     765      571920 :         move32();
     766             :     }
     767             : 
     768      429852 :     FOR( sample = 0; sample < sub( pt_len, stride ); sample++ )
     769             :     {
     770             :         /* fill internal CLDFB analysis time buffer with data*/
     771      428940 :         Word16 x_fx = get_random_number_fx( &seed );              /*Q15*/
     772      428940 :         cldfbAnaDec0->cldfb_state_fx[sample] = L_shl( x_fx, 12 ); /*Q27*/
     773      428940 :         move32();
     774             :     }
     775         912 :     Word16 q_cldfb = 27;
     776         912 :     move16();
     777         912 :     cldfbAnaDec0->Q_cldfb_state = q_cldfb;
     778         912 :     move16();
     779        3648 :     FOR( slot = 0; slot < num_cf_slots; slot++ )
     780             :     {
     781      145716 :         FOR( sample = 0; sample < stride; sample++ )
     782             :         {
     783      142980 :             Word16 x_fx = get_random_number_fx( &seed ); /*Q15*/
     784      142980 :             ts_inout_fx[sample] = L_shl( x_fx, 12 );     /*Q27*/
     785      142980 :             move32();
     786             :         }
     787             : 
     788        2736 :         cldfbAnalysis_ts_fx_fixed_q( ts_inout_fx, ts_re_fx, ts_im_fx, num_cldfb_bands, cldfbAnaDec0, &q_cldfb );
     789        2736 :         cldfb_reset_memory_fx( cldfbSynDec0 );
     790        2736 :         cldfbSynthesis_ivas_fx( pp_ts_re_fx, pp_ts_im_fx, ts_inout_fx, num_cldfb_bands, 0, 0, cldfbSynDec0 );
     791      145716 :         FOR( sample = 0; sample < stride; sample++ )
     792             :         {
     793      142980 :             T_fx[( ( slot * stride ) + sample )][slot] = ts_inout_fx[sample]; /*Q21*/
     794      142980 :             move32();
     795             :         }
     796        2736 :         tmp_idx = sub( pt_len, 1 ); /*Q0*/
     797     1289556 :         FOR( sample = stride; sample < pt_len; sample++ )
     798             :         {
     799     1286820 :             T_fx[( ( slot * stride ) + sample )][slot] = cldfbSynDec0->cldfb_state_fx[tmp_idx]; /*Q21*/
     800     1286820 :             move32();
     801     1286820 :             tmp_idx = sub( tmp_idx, 1 ); /*Q0*/
     802             :         }
     803             :     }
     804             : 
     805             :     /* target is synthesis output times the cross-fade window*/
     806      572832 :     FOR( sample = 0; sample < num_samples; sample++ )
     807             :     {
     808      571920 :         tgt_fx[sample] = L_shl( Mpy_32_32( tgt_fx[sample], L_add( T_fx[sample][0], L_add( T_fx[sample][1], T_fx[sample][2] ) ) ), 10 ); /*Q31*/
     809      571920 :         move32();
     810             :     }
     811             :     /* compute matrices */
     812        3648 :     FOR( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
     813             :     {
     814        8208 :         FOR( slot_col = slot_row; slot_col < num_cf_slots; slot_col++ )
     815             :         {
     816        5472 :             Tt_T_fx[slot_row][slot_col] = 0;
     817        5472 :             move32();
     818     3436992 :             FOR( sample = 0; sample < num_samples; sample++ )
     819             :             {
     820     3431520 :                 Tt_T_fx[slot_row][slot_col] = L_add( Tt_T_fx[slot_row][slot_col], Mpy_32_32( L_shl( T_fx[sample][slot_row], 8 ), L_shl( T_fx[sample][slot_col], 8 ) ) ); /*Q58-Q31*/
     821     3431520 :                 move32();
     822             :             }
     823             :         }
     824             :     }
     825             : 
     826         912 :     Tt_T_fx[1][0] = Tt_T_fx[0][1]; /*Q27*/
     827         912 :     move32();
     828         912 :     Tt_T_fx[2][0] = Tt_T_fx[0][2]; /*Q27*/
     829         912 :     move32();
     830         912 :     Tt_T_fx[2][1] = Tt_T_fx[1][2]; /*Q27*/
     831         912 :     move32();
     832        3648 :     FOR( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
     833             :     {
     834        2736 :         Tt_tgt_fx[slot_row] = 0;
     835        2736 :         move32();
     836     1718496 :         FOR( sample = 0; sample < num_samples; sample++ )
     837             :         {
     838     1715760 :             Tt_tgt_fx[slot_row] = L_add( Tt_tgt_fx[slot_row], Mpy_32_32( T_fx[sample][slot_row], tgt_fx[sample] ) ); /*Q21*/
     839     1715760 :             move32();
     840             :         }
     841             :     }
     842         912 :     Word16 output_q = 27;
     843         912 :     move16();
     844         912 :     matrix_inverse_fx( Tt_T_fx, Tt_T_inv_fx, num_cf_slots, &output_q );
     845             :     /* compute the optimal coefficients */
     846        3648 :     FOR( slot_row = 0; slot_row < num_cf_slots; slot_row++ )
     847             :     {
     848        2736 :         Word32 tmp = 0;
     849        2736 :         move32();
     850       10944 :         FOR( slot_col = 0; slot_col < num_cf_slots; slot_col++ )
     851             :         {
     852        8208 :             tmp = L_add( tmp, Mpy_32_32( Tt_T_inv_fx[slot_row][slot_col], Tt_tgt_fx[slot_col] ) ); /*output_q-10*/
     853             :         }
     854        2736 :         weights_fx[( cf_cldfb_start + slot_row )] = extract_l( L_shr( L_max( L_min( tmp, L_shl( 1, sub( output_q, 10 ) ) ), 0 ), sub( sub( output_q, 10 ), Q_weights ) ) ); /*Q_weights*/
     855        2736 :         move16();
     856             :     }
     857         912 :     hSpar->hFbMixer->cldfb_cross_fade_q = Q_weights;
     858         912 :     move16();
     859             : 
     860         912 :     cldfb_reset_memory_fx( cldfbSynDec0 );
     861         912 :     cldfb_reset_memory_fx( cldfbAnaDec0 );
     862             : 
     863         912 :     return;
     864             : }
     865    16038504 : Word16 ivas_is_res_channel(
     866             :     const Word16 ch,             /* i  : ch index in WYZX ordering          Q0*/
     867             :     const Word16 nchan_transport /* i  : number of transport channels (1-4) Q0*/
     868             : )
     869             : {
     870    16038504 :     const Word16 rc_map[FOA_CHANNELS][FOA_CHANNELS] = {
     871             :         { 0, 0, 0, 0 },
     872             :         { 0, 1, 0, 0 },
     873             :         { 0, 1, 0, 1 },
     874             :         { 0, 1, 1, 1 }
     875             :     };
     876             : 
     877    16038504 :     if ( GE_16( ch, FOA_CHANNELS ) )
     878             :     {
     879             :         /* never transmitted */
     880     1453448 :         return 0;
     881             :     }
     882    14585056 :     assert( nchan_transport <= FOA_CHANNELS );
     883             : 
     884    14585056 :     return ( rc_map[nchan_transport - 1][ch] ); /*Q0*/
     885             : }
     886             : 
     887             : 
     888             : /*-------------------------------------------------------------------*
     889             :  * ivas_spar_dec_MD()
     890             :  *
     891             :  * IVAS SPAR MD decoder
     892             :  *-------------------------------------------------------------------*/
     893             : 
     894      149027 : static ivas_error ivas_spar_dec_MD_fx(
     895             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle                             */
     896             :     Decoder_State *st0       /* i/o: decoder state structure - for bitstream handling*/
     897             : )
     898             : {
     899             :     Word16 num_channels, table_idx, num_bands_out, bfi, sba_order;
     900             :     Word32 ivas_total_brate;
     901             :     Word16 num_md_sub_frames;
     902             :     ivas_error error;
     903      149027 :     DECODER_CONFIG_HANDLE hDecoderConfig = st_ivas->hDecoderConfig;
     904      149027 :     SPAR_DEC_HANDLE hSpar = st_ivas->hSpar;
     905             : 
     906      149027 :     push_wmops( "ivas_spar_dec_MD" );
     907             : 
     908             :     /*---------------------------------------------------------------------*
     909             :      * Initialization
     910             :      *---------------------------------------------------------------------*/
     911             : 
     912      149027 :     sba_order = s_min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); /*Q0*/
     913      149027 :     bfi = st_ivas->bfi;                                                   /*Q0*/
     914      149027 :     move16();
     915      149027 :     ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; /*Q0*/
     916      149027 :     move32();
     917      149027 :     num_channels = ivas_sba_get_nchan_metadata_fx( sba_order, ivas_total_brate );                                                                 /*Q0*/
     918      149027 :     num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); /*Q0*/
     919             : 
     920      149027 :     num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/
     921      149027 :     move16();
     922             : 
     923      149027 :     test();
     924      149027 :     IF( ( ivas_total_brate > FRAME_NO_DATA ) && !bfi )
     925             :     {
     926      140904 :         IF( GT_32( ivas_total_brate, IVAS_SID_5k2 ) )
     927             :         {
     928      140580 :             ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx );
     929             : 
     930      140580 :             IF( hSpar->hMdDec->spar_hoa_md_flag )
     931             :             {
     932       20813 :                 hSpar->hMdDec->spar_md.num_bands = IVAS_MAX_NUM_BANDS;
     933       20813 :                 move16();
     934             :             }
     935             :             ELSE
     936             :             {
     937      119767 :                 hSpar->hMdDec->spar_md.num_bands = s_min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS ); /*Q0*/
     938      119767 :                 move16();
     939             :             }
     940             : 
     941      140580 :             IF( NE_16( hSpar->hMdDec->table_idx, table_idx ) )
     942             :             {
     943         288 :                 hSpar->hMdDec->table_idx = table_idx; /*Q0*/
     944         288 :                 move16();
     945         288 :                 if ( hSpar->hTdDecorr )
     946             :                 {
     947         258 :                     hSpar->hTdDecorr->ducking_flag = ivas_spar_br_table_consts[table_idx].td_ducking; /*Q0*/
     948         258 :                     move16();
     949             :                 }
     950             : 
     951         288 :                 IF( NE_32( ( error = ivas_spar_md_dec_init( hSpar->hMdDec, hDecoderConfig, num_channels, sba_order ) ), IVAS_ERR_OK ) )
     952             :                 {
     953           0 :                     return error;
     954             :                 }
     955             :             }
     956             :         }
     957             : 
     958             :         /*---------------------------------------------------------------------*
     959             :          * Decode MD
     960             :          *---------------------------------------------------------------------*/
     961             : 
     962      140904 :         ivas_spar_md_dec_process_fx( st_ivas, st0, num_bands_out, sba_order );
     963             : 
     964             :         /*---------------------------------------------------------------------*
     965             :          * read PCA bits
     966             :          *---------------------------------------------------------------------*/
     967             : 
     968      140904 :         IF( hSpar->hPCA != NULL )
     969             :         {
     970        9840 :             ivas_pca_read_bits_fx( st0, hSpar->hPCA );
     971             :         }
     972             : 
     973             :         /*---------------------------------------------------------------------*
     974             :          * Read AGC bits
     975             :          *---------------------------------------------------------------------*/
     976             : 
     977      140904 :         test();
     978      140904 :         test();
     979      140904 :         IF( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && !bfi && hSpar->hMdDec->dtx_vad )
     980             :         {
     981      140347 :             IF( EQ_16( hSpar->hMdDec->spar_md_cfg.nchan_transport, 1 ) )
     982             :             {
     983       37355 :                 hSpar->AGC_flag = get_next_indice_fx( st0, 1 );
     984       37355 :                 move16();
     985             :             }
     986             : 
     987      140347 :             ivas_agc_read_bits_fx( hSpar->hAgcDec, st0, hSpar->hMdDec->spar_md_cfg.nchan_transport, hSpar->AGC_flag );
     988             :         }
     989             : 
     990             :         /*---------------------------------------------------------------------*
     991             :          * MD smoothing
     992             :          *---------------------------------------------------------------------*/
     993             : 
     994      140904 :         test();
     995      140904 :         test();
     996      140904 :         test();
     997      140904 :         IF( EQ_16( st0->m_old_frame_type, ZERO_FRAME ) && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) && ( st0->prev_bfi == 0 ) && EQ_16( hSpar->hMdDec->spar_md_cfg.nchan_transport, 1 ) )
     998             :         {
     999         125 :             ivas_spar_setup_md_smoothing_fx( hSpar->hMdDec, num_bands_out, num_md_sub_frames );
    1000             :         }
    1001             :         ELSE
    1002             :         {
    1003      140779 :             ivas_spar_update_md_hist_fx( hSpar->hMdDec );
    1004             :         }
    1005             :     }
    1006             :     ELSE
    1007             :     {
    1008        8123 :         IF( !bfi )
    1009             :         {
    1010        2064 :             ivas_spar_smooth_md_dtx_fx( hSpar->hMdDec, num_bands_out, num_md_sub_frames );
    1011             :         }
    1012             : 
    1013        8123 :         set16_fx( hSpar->hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS );
    1014             :     }
    1015             : 
    1016      149027 :     pop_wmops();
    1017      149027 :     return IVAS_ERR_OK;
    1018             : }
    1019             : 
    1020             : 
    1021             : /*-------------------------------------------------------------------*
    1022             :  * ivas_spar_get_cldfb_slot_gain()
    1023             :  *
    1024             :  *
    1025             :  *-------------------------------------------------------------------*/
    1026             : 
    1027     2172469 : static Word16 ivas_spar_get_cldfb_slot_gain_fx(
    1028             :     SPAR_DEC_HANDLE hSpar,                      /* i/o: SPAR decoder handle     */
    1029             :     const DECODER_CONFIG_HANDLE hDecoderConfig, /* i  : configuration structure */
    1030             :     const Word16 time_slot_idx,                 /*Q0*/
    1031             :     Word16 *time_slot_idx0,                     /*Q0*/
    1032             :     Word16 *time_slot_idx1,                     /*Q0*/
    1033             :     Word16 *weight_lowfreq_fx                   /*Q15*/
    1034             : )
    1035             : {
    1036             :     Word16 weight_fx;
    1037             :     Word32 encfb_delay_fx, decfb_delay_fx;
    1038             :     Word32 xfade_start_ns_fx;
    1039             :     Word16 xfade_delay_subframes;
    1040             :     Word16 i_hist;
    1041             :     Word16 split_band;
    1042             : 
    1043     2172469 :     *weight_lowfreq_fx = hSpar->hFbMixer->cldfb_cross_fade_fx[time_slot_idx]; /*Q15*/
    1044     2172469 :     move16();
    1045             : 
    1046     2172469 :     encfb_delay_fx = IVAS_FB_ENC_DELAY_NS;
    1047     2172469 :     move32();
    1048     2172469 :     decfb_delay_fx = IVAS_FB_DEC_DELAY_NS;
    1049     2172469 :     move32();
    1050     2172469 :     Word32 one_by_outfs = 0; // Q15
    1051     2172469 :     move32();
    1052     2172469 :     SWITCH( hDecoderConfig->output_Fs )
    1053             :     {
    1054      192000 :         case 16000:
    1055      192000 :             one_by_outfs = 2048000000; /* 1000000000.0f/(output_Fs) in Q15 */
    1056      192000 :             move32();
    1057      192000 :             BREAK;
    1058      948159 :         case 32000:
    1059      948159 :             one_by_outfs = 1024000000; /* 1000000000.0f/(output_Fs) in Q15 */
    1060      948159 :             move32();
    1061      948159 :             BREAK;
    1062     1032310 :         case 48000:
    1063     1032310 :             one_by_outfs = 682666688; /* 1000000000.0f/(output_Fs) in Q15 */
    1064     1032310 :             move32();
    1065     1032310 :             BREAK;
    1066           0 :         default:
    1067           0 :             assert( 0 );
    1068             :     }
    1069             : 
    1070     2172469 :     Word64 fade_start = W_mult0_32_32( one_by_outfs, hSpar->hFbMixer->cross_fade_start_offset ); /*Q15*/
    1071     2172469 :     move64();
    1072     2172469 :     fade_start = W_shr( fade_start, 15 );                                                                                                             /*Q0*/
    1073     2172469 :     xfade_start_ns_fx = L_add( L_sub( W_extract_l( fade_start ), encfb_delay_fx ), L_shr( decfb_delay_fx, 1 ) );                                      /*Q0*/
    1074     2172469 :     xfade_delay_subframes = extract_l( Mpy_32_32( xfade_start_ns_fx, 429 /* 1 / ( FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ) in Q31 -> 429 */ ) ); /*Q0*/
    1075             : 
    1076     2172469 :     i_hist = sub( 4, xfade_delay_subframes ); /*Q0*/
    1077     2172469 :     split_band = SPAR_DIRAC_SPLIT_START_BAND;
    1078     2172469 :     move16();
    1079             : 
    1080     2172469 :     IF( LT_16( split_band, IVAS_MAX_NUM_BANDS ) )
    1081             :     {
    1082     2172469 :         IF( GT_16( hSpar->i_subframe, 3 ) )
    1083             :         {
    1084     2152725 :             Word16 mod_res = time_slot_idx % MAX_PARAM_SPATIAL_SUBFRAMES;
    1085     2152725 :             move16();
    1086     2152725 :             SWITCH( mod_res )
    1087             :             {
    1088      538192 :                 case 0:
    1089      538192 :                     weight_fx = 0;
    1090      538192 :                     move16();
    1091      538192 :                     BREAK;
    1092      538172 :                 case 1:
    1093      538172 :                     weight_fx = 8191; /*0.25f in Q15*/
    1094      538172 :                     move16();
    1095      538172 :                     BREAK;
    1096      538179 :                 case 2:
    1097      538179 :                     weight_fx = 16383; /*0.5f in Q15*/
    1098      538179 :                     move16();
    1099      538179 :                     BREAK;
    1100      538182 :                 case 3:
    1101      538182 :                     weight_fx = 24575; /*0.75f in Q15*/
    1102      538182 :                     move16();
    1103      538182 :                     BREAK;
    1104           0 :                 default:
    1105           0 :                     weight_fx = 0;
    1106           0 :                     move16();
    1107           0 :                     BREAK;
    1108             :             }
    1109             :         }
    1110             :         ELSE
    1111             :         {
    1112       19744 :             weight_fx = 0;
    1113       19744 :             move16();
    1114             :         }
    1115     2172469 :         *time_slot_idx0 = i_hist; /*Q0*/
    1116     2172469 :         move16();
    1117     2172469 :         *time_slot_idx1 = add( i_hist, 1 ); /*Q0*/
    1118     2172469 :         move16();
    1119             :     }
    1120             :     ELSE
    1121             :     {
    1122             :         /* determine cross-fade gain for current frame Parameters*/
    1123           0 :         *time_slot_idx0 = hSpar->hFbMixer->cldfb_cross_fade_start; /*Q0*/
    1124           0 :         move16();
    1125           0 :         *time_slot_idx1 = hSpar->hFbMixer->cldfb_cross_fade_end; /*Q0*/
    1126           0 :         move16();
    1127           0 :         weight_fx = *weight_lowfreq_fx; /*Q15*/
    1128           0 :         move16();
    1129             :     }
    1130             : 
    1131     2172469 :     return weight_fx; /*Q15*/
    1132             : }
    1133             : 
    1134             : 
    1135             : /*-------------------------------------------------------------------*
    1136             :  * ivas_spar_get_parameters()
    1137             :  *
    1138             :  *
    1139             :  *-------------------------------------------------------------------*/
    1140             : 
    1141     2172469 : void ivas_spar_get_parameters_fx(
    1142             :     SPAR_DEC_HANDLE hSpar,                                                    /* i/o: SPAR decoder handle     */
    1143             :     const DECODER_CONFIG_HANDLE hDecoderConfig,                               /* i  : configuration structure */
    1144             :     const Word16 ts,                                                          /*Q0*/
    1145             :     const Word16 num_ch_out,                                                  /*Q0*/
    1146             :     const Word16 num_ch_in,                                                   /*Q0*/
    1147             :     const Word16 num_spar_bands,                                              /*Q0*/
    1148             :     Word32 par_mat_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /*hSpar->hMdDec->Q_mixer_mat*/
    1149             : )
    1150             : {
    1151             :     Word16 spar_band, out_ch, in_ch;
    1152             :     Word16 weight_fx, weight_20ms_fx;
    1153             :     Word16 ts0, ts1, split_band;
    1154             : 
    1155             :     // weight = ivas_spar_get_cldfb_slot_gain(hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms);
    1156     2172469 :     weight_fx = ivas_spar_get_cldfb_slot_gain_fx( hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms_fx ); /*Q15*/
    1157             : 
    1158     2172469 :     split_band = SPAR_DIRAC_SPLIT_START_BAND;
    1159     2172469 :     move16();
    1160     2172469 :     Word16 add_weight_fx = sub( MAX_WORD16, weight_fx );
    1161     2172469 :     Word16 add_weight_20ms_fx = sub( MAX_WORD16, weight_20ms_fx );
    1162             : #ifdef OPT_SBA_DEC_V2_BE
    1163             :     Word16 out_flag[IVAS_MAX_FB_MIXER_OUT_CH];
    1164             : 
    1165     2172469 :     Word32 band_bool = LT_16( split_band, IVAS_MAX_NUM_BANDS );
    1166             : 
    1167    12315793 :     FOR( out_ch = 0; out_ch < num_ch_out; out_ch++ )
    1168             :     {
    1169             :         /* 20ms cross-fade for Transport channels in all frequency bands */
    1170             :         /* sub-frame processing for missing channels in all frequency bands*/
    1171    10143324 :         out_flag[out_ch] = band_bool && ( 0 == ivas_is_res_channel( out_ch, hSpar->hMdDec->spar_md_cfg.nchan_transport ) );
    1172    10143324 :         move16();
    1173             :     }
    1174     2172469 :     Word32 frame_bool = GT_16( hSpar->i_subframe, 3 );
    1175             : 
    1176    12315793 :     FOR( out_ch = 0; out_ch < num_ch_out; out_ch++ )
    1177             :     {
    1178    10143324 :         IF( out_flag[out_ch] )
    1179             :         {
    1180     7051500 :             IF( frame_bool )
    1181             :             {
    1182    89672172 :                 FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
    1183             :                 {
    1184   529455408 :                     FOR( in_ch = 0; in_ch < num_ch_in; in_ch++ )
    1185             :                     {
    1186   446767584 :                         par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ),
    1187   446767584 :                                                                            hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], add_weight_fx );
    1188   446767584 :                         move32();
    1189             :                     }
    1190             :                 }
    1191             :             }
    1192             :             ELSE
    1193             :             {
    1194             : 
    1195             : 
    1196      869328 :                 FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
    1197             :                 {
    1198     5063424 :                     FOR( in_ch = 0; in_ch < num_ch_in; in_ch++ )
    1199             :                     {
    1200             :                         {
    1201     4261248 :                             par_mat_fx[out_ch][in_ch][spar_band] = hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band]; /*hSpar->hMdDec->Q_mixer_mat*/
    1202     4261248 :                             move32();
    1203             :                         }
    1204             :                     }
    1205             :                 }
    1206             :             }
    1207             :         }
    1208             :         ELSE
    1209             :         {
    1210    39785712 :             FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
    1211             :             {
    1212   235793568 :                 FOR( in_ch = 0; in_ch < num_ch_in; in_ch++ )
    1213             :                 {
    1214             :                     /* 20ms Transport channel reconstruction with matching encoder/decoder processing */
    1215   199099680 :                     Word16 prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */
    1216   199099680 :                     move16();
    1217   199099680 :                     par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], add_weight_20ms_fx ),
    1218   199099680 :                                                                        hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ); /*hSpar->hMdDec->Q_mixer_mat*/
    1219   199099680 :                     move32();
    1220             :                 }
    1221             :             }
    1222             :         }
    1223             :     }
    1224             : #else  /* OPT_SBA_DEC_V2_BE */
    1225             :     FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
    1226             :     {
    1227             :         FOR( out_ch = 0; out_ch < num_ch_out; out_ch++ )
    1228             :         {
    1229             :             test();
    1230             :             IF( LT_16( split_band, IVAS_MAX_NUM_BANDS )
    1231             :                 /* 20ms cross-fade for Transport channels in all frequency bands */
    1232             :                 && ( 0 == ivas_is_res_channel( out_ch, hSpar->hMdDec->spar_md_cfg.nchan_transport ) ) /* sub-frame processing for missing channels in all frequency bands*/
    1233             :             )
    1234             :             {
    1235             :                 FOR( in_ch = 0; in_ch < num_ch_in; in_ch++ )
    1236             :                 {
    1237             :                     IF( GT_16( hSpar->i_subframe, 3 ) )
    1238             :                     {
    1239             :                         par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[ts1][out_ch][in_ch][spar_band], weight_fx ),
    1240             :                                                                            hSpar->hMdDec->mixer_mat_prev_fx[ts0][out_ch][in_ch][spar_band], add_weight_fx );
    1241             :                         move32();
    1242             :                     }
    1243             :                     ELSE
    1244             :                     {
    1245             :                         par_mat_fx[out_ch][in_ch][spar_band] = hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band]; /*hSpar->hMdDec->Q_mixer_mat*/
    1246             :                         move32();
    1247             :                     }
    1248             :                 }
    1249             :             }
    1250             :             ELSE
    1251             :             {
    1252             :                 FOR( in_ch = 0; in_ch < num_ch_in; in_ch++ )
    1253             :                 {
    1254             :                     /* 20ms Transport channel reconstruction with matching encoder/decoder processing */
    1255             :                     Word16 prev_idx = SPAR_DIRAC_SPLIT_START_BAND < IVAS_MAX_NUM_BANDS ? 1 : 0; /* if SPAR_DIRAC_SPLIT_START_BAND == IVAS_MAX_NUM_BANDS, then the sub-frame mixer_mat delay line is not active */
    1256             :                     move16();
    1257             :                     par_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( hSpar->hMdDec->mixer_mat_prev_fx[prev_idx][out_ch][in_ch][spar_band], add_weight_20ms_fx ),
    1258             :                                                                        hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][spar_band], weight_20ms_fx ); /*hSpar->hMdDec->Q_mixer_mat*/
    1259             :                     move32();
    1260             :                 }
    1261             :             }
    1262             :         }
    1263             :     }
    1264             : #endif /* OPT_SBA_DEC_V2_BE */
    1265     2172469 :     return;
    1266             : }
    1267             : 
    1268             : 
    1269             : /*-------------------------------------------------------------------*
    1270             :  * ivas_spar_get_skip_mat()
    1271             :  *
    1272             :  *
    1273             :  *-------------------------------------------------------------------*/
    1274             : 
    1275      396216 : static void ivas_spar_get_skip_mat_fx(
    1276             :     SPAR_DEC_HANDLE hSpar,                               /* i/o: SPAR decoder handle */
    1277             :     const Word16 num_ch_out,                             /*Q0*/
    1278             :     const Word16 num_ch_in,                              /*Q0*/
    1279             :     const Word16 num_spar_bands,                         /*Q0*/
    1280             :     Word16 skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*Q0*/
    1281             :     const Word16 num_md_sub_frames                       /*Q0*/
    1282             : )
    1283             : {
    1284             :     Word16 spar_band, out_ch, in_ch;
    1285             :     Word16 i_ts, skip_flag;
    1286             : 
    1287     2344442 :     FOR( out_ch = 0; out_ch < num_ch_out; out_ch++ )
    1288             :     {
    1289    13270150 :         FOR( in_ch = 0; in_ch < num_ch_in; in_ch++ )
    1290             :         {
    1291    11321924 :             skip_mat[out_ch][in_ch] = 1;
    1292    11321924 :             move16();
    1293    11321924 :             skip_flag = 1;
    1294    11321924 :             move16();
    1295    38592786 :             FOR( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ )
    1296             :             {
    1297   362532386 :                 FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
    1298             :                 {
    1299   335261524 :                     IF( hSpar->hMdDec->mixer_mat_prev_fx[1 + i_ts][out_ch][in_ch][spar_band] != 0 )
    1300             :                     {
    1301     4552654 :                         skip_flag = 0;
    1302     4552654 :                         move16();
    1303     4552654 :                         BREAK;
    1304             :                     }
    1305             :                 }
    1306             : 
    1307    31823516 :                 IF( skip_flag == 0 )
    1308             :                 {
    1309     4552654 :                     skip_mat[out_ch][in_ch] = 0;
    1310     4552654 :                     move16();
    1311     4552654 :                     BREAK;
    1312             :                 }
    1313             :             }
    1314             : 
    1315    11321924 :             IF( EQ_16( skip_mat[out_ch][in_ch], 1 ) )
    1316             :             {
    1317    24021734 :                 FOR( i_ts = 0; i_ts < num_md_sub_frames; i_ts++ )
    1318             :                 {
    1319   221706358 :                     FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
    1320             :                     {
    1321   204453894 :                         IF( hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][( spar_band + ( i_ts * IVAS_MAX_NUM_BANDS ) )] != 0 )
    1322             :                         {
    1323       30830 :                             skip_flag = 0;
    1324       30830 :                             move16();
    1325       30830 :                             BREAK;
    1326             :                         }
    1327             :                     }
    1328             : 
    1329    17283294 :                     IF( skip_flag == 0 )
    1330             :                     {
    1331       30830 :                         skip_mat[out_ch][in_ch] = 0;
    1332       30830 :                         move16();
    1333       30830 :                         BREAK;
    1334             :                     }
    1335             :                 }
    1336             :             }
    1337             :         }
    1338             :     }
    1339             : 
    1340      396216 :     return;
    1341             : }
    1342             : 
    1343             : 
    1344        5132 : static void ivas_spar_calc_smooth_facs_fx(
    1345             :     Word32 *cldfb_in_ts_re_fx[CLDFB_NO_COL_MAX], // i q_cldfb
    1346             :     Word32 *cldfb_in_ts_im_fx[CLDFB_NO_COL_MAX], // i q_cldfb
    1347             :     Word16 q_cldfb,
    1348             :     Word16 nbands_spar,           /*Q0*/
    1349             :     const Word16 nSlots,          /*Q0*/
    1350             :     const Word16 isFirstSubframe, /*Q0*/
    1351             :     ivas_fb_bin_to_band_data_t *bin2band,
    1352             :     Word16 *smooth_fac_fx,                                                        // o Q15
    1353             :     Word32 smooth_buf_fx[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1] ) // o Q0
    1354             : {
    1355             :     Word16 b, bin, i, ts;
    1356             :     Word32 subframe_band_nrg_fx[IVAS_MAX_NUM_BANDS];
    1357             :     Word32 smooth_long_avg_fx[IVAS_MAX_NUM_BANDS];
    1358             :     Word32 smooth_short_avg_fx[IVAS_MAX_NUM_BANDS];
    1359             :     Word32 L_temp;
    1360             :     Word16 exp_tmp, q_tmp;
    1361        5132 :     bin = 0;
    1362        5132 :     move16();
    1363       62504 :     FOR( b = 0; b < nbands_spar; b++ )
    1364             :     {
    1365       61584 :         test();
    1366       61584 :         test();
    1367       61584 :         if ( GE_16( bin, CLDFB_NO_CHANNELS_MAX ) || ( ( b > 0 ) && LT_16( bin2band->p_cldfb_map_to_spar_band[bin], bin2band->p_cldfb_map_to_spar_band[bin - 1] ) ) )
    1368             :         {
    1369             :             BREAK;
    1370             :         }
    1371             : 
    1372             :         /* calculate band-wise subframe energies */
    1373       57372 :         subframe_band_nrg_fx[b] = 0;
    1374       57372 :         move32();
    1375      281052 :         WHILE( LT_16( bin, CLDFB_NO_CHANNELS_MAX ) && EQ_16( b, bin2band->p_cldfb_map_to_spar_band[bin] ) )
    1376             :         {
    1377      223680 :             test();
    1378     1118400 :             FOR( ts = 0; ts < nSlots; ts++ )
    1379             :             {
    1380      894720 :                 L_temp = L_add( L_shr( Mpy_32_32( cldfb_in_ts_re_fx[ts][bin], cldfb_in_ts_re_fx[ts][bin] ), 4 ), L_shr( Mpy_32_32( cldfb_in_ts_im_fx[ts][bin], cldfb_in_ts_im_fx[ts][bin] ), 4 ) ); // 2*q_cldfb - 35
    1381      894720 :                 subframe_band_nrg_fx[b] = L_add_sat( subframe_band_nrg_fx[b], L_temp );                                                                                                             // 2*q_cldfb - 35 (saturation reached in 1 orig pytest)
    1382      894720 :                 move32();
    1383             :             }
    1384      223680 :             bin = add( bin, 1 );
    1385             :         }
    1386       57372 :         exp_tmp = sub( 66, shl( q_cldfb, 1 ) );
    1387       57372 :         subframe_band_nrg_fx[b] = Sqrt32( subframe_band_nrg_fx[b], &exp_tmp );
    1388       57372 :         move32();
    1389       57372 :         q_tmp = sub( 31, exp_tmp );
    1390       57372 :         test();
    1391       57372 :         IF( isFirstSubframe && LT_16( nSlots, MAX_PARAM_SPATIAL_SUBFRAMES ) )
    1392             :         {
    1393             :             /* fill up to full 5ms subframe */
    1394           0 :             smooth_buf_fx[b][0] = L_add( smooth_buf_fx[b][0], L_shr( subframe_band_nrg_fx[b], q_tmp ) ); // Q0
    1395           0 :             move32();
    1396             :         }
    1397             :         ELSE
    1398             :         {
    1399       57372 :             smooth_buf_fx[b][0] = L_shr( subframe_band_nrg_fx[b], q_tmp ); // Q0
    1400       57372 :             move32();
    1401             :         }
    1402             :         /* calculate short and long energy averages */
    1403       57372 :         smooth_short_avg_fx[b] = 0;
    1404       57372 :         move32();
    1405      401604 :         FOR( i = 0; i < 2 * SBA_DIRAC_NRG_SMOOTH_SHORT; i++ )
    1406             :         {
    1407      344232 :             smooth_short_avg_fx[b] = L_add( smooth_short_avg_fx[b], smooth_buf_fx[b][i] ); // Q0
    1408      344232 :             move32();
    1409             :         }
    1410             : 
    1411       57372 :         smooth_long_avg_fx[b] = smooth_short_avg_fx[b]; // Q0
    1412       57372 :         move32();
    1413      860580 :         FOR( i = 2 * SBA_DIRAC_NRG_SMOOTH_SHORT; i < 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i++ )
    1414             :         {
    1415      803208 :             smooth_long_avg_fx[b] = L_add( smooth_long_avg_fx[b], smooth_buf_fx[b][i] ); // Q0
    1416      803208 :             move32();
    1417             :         }
    1418       57372 :         smooth_short_avg_fx[b] = Mpy_32_32( smooth_short_avg_fx[b], 357913941 /*(1/6 in Q31)*/ ); // Q0
    1419       57372 :         move32();
    1420       57372 :         smooth_long_avg_fx[b] = Mpy_32_32( smooth_long_avg_fx[b], 107374182 /*(1/20 in Q31)*/ ); // Q0
    1421       57372 :         move32();
    1422             : 
    1423             :         /* calculate smoothing factor based on energy averages */
    1424             :         /* reduce factor for higher short-term energy */
    1425       57372 :         IF( smooth_long_avg_fx[b] <= 0 )
    1426             :         {
    1427       23101 :             smooth_fac_fx[b] = 0;
    1428       23101 :             move16();
    1429             :         }
    1430       34271 :         ELSE IF( GE_32( smooth_long_avg_fx[b], smooth_short_avg_fx[b] ) )
    1431             :         {
    1432       17923 :             smooth_fac_fx[b] = MAX_16; // 1.0f in Q15
    1433       17923 :             move16();
    1434             :         }
    1435             :         ELSE
    1436             :         {
    1437       16348 :             smooth_fac_fx[b] = divide3232( smooth_long_avg_fx[b], smooth_short_avg_fx[b] ); // Q15
    1438       16348 :             move16();
    1439             :         }
    1440             : 
    1441             :         /* map factor to range [0;1] */
    1442       57372 :         smooth_fac_fx[b] = shl( mult_r( s_max( 0, sub( smooth_fac_fx[b], 9830 ) ), 23405 /*Q14*/ ), 1 ); // Q15
    1443       57372 :         move16();
    1444             : 
    1445             :         /* compress factor (higher compression in lowest bands) */
    1446       57372 :         IF( LT_16( b, 2 ) )
    1447             :         {
    1448       10264 :             exp_tmp = 0;
    1449       10264 :             move16();
    1450       10264 :             smooth_fac_fx[b] = Sqrt16( smooth_fac_fx[b], &exp_tmp );
    1451       10264 :             move16();
    1452       10264 :             smooth_fac_fx[b] = Sqrt16( smooth_fac_fx[b], &exp_tmp );
    1453       10264 :             move16();
    1454       10264 :             smooth_fac_fx[b] = shl( smooth_fac_fx[b], exp_tmp ); // Q15
    1455       10264 :             move16();
    1456             :         }
    1457             :         ELSE
    1458             :         {
    1459       47108 :             exp_tmp = 0;
    1460       47108 :             move16();
    1461       47108 :             smooth_fac_fx[b] = Sqrt16( smooth_fac_fx[b], &exp_tmp );
    1462       47108 :             move16();
    1463       47108 :             smooth_fac_fx[b] = shl( smooth_fac_fx[b], exp_tmp ); // Q15
    1464       47108 :             move16();
    1465             :         }
    1466             : 
    1467             :         /* apply upper bounds depending on band */
    1468       57372 :         smooth_fac_fx[b] = s_max( min_smooth_gains1_fx[b], s_min( max_smooth_gains2_fx[b], smooth_fac_fx[b] ) ); /*Q15*/
    1469       57372 :         move16();
    1470             :     }
    1471             : 
    1472             :     /* only update if we collected a full 5ms worth of energies for the buffer */
    1473        5132 :     test();
    1474        5132 :     IF( isFirstSubframe || EQ_16( nSlots, MAX_PARAM_SPATIAL_SUBFRAMES ) )
    1475             :     {
    1476       66716 :         FOR( b = 0; b < nbands_spar; b++ )
    1477             :         {
    1478     1293264 :             FOR( i = 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i > 0; i-- )
    1479             :             {
    1480     1231680 :                 smooth_buf_fx[b][i] = smooth_buf_fx[b][i - 1]; /*Q0*/
    1481     1231680 :                 move32();
    1482             :             }
    1483             :         }
    1484             :     }
    1485        5132 :     return;
    1486             : }
    1487             : 
    1488             : 
    1489             : /*-------------------------------------------------------------------*
    1490             :  * ivas_spar_dec_agc_pca()
    1491             :  *
    1492             :  *
    1493             :  *-------------------------------------------------------------------*/
    1494             : 
    1495       99723 : void ivas_spar_dec_agc_pca_fx(
    1496             :     Decoder_Struct *st_ivas,  /* i/o: IVAS decoder handle                     */
    1497             :     Word32 *output[],         /* i/o: input/output audio channels             Q14*/
    1498             :     const Word16 output_frame /* i  : output frame length                     Q0*/
    1499             : )
    1500             : {
    1501             :     Word16 nchan_transport;
    1502             :     Word16 num_in_ingest;
    1503             :     DECODER_CONFIG_HANDLE hDecoderConfig;
    1504             :     SPAR_DEC_HANDLE hSpar;
    1505             : 
    1506       99723 :     push_wmops( "ivas_spar_dec_agc_pca" );
    1507             : 
    1508       99723 :     hSpar = st_ivas->hSpar;
    1509       99723 :     hDecoderConfig = st_ivas->hDecoderConfig;
    1510       99723 :     nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
    1511       99723 :     move16();
    1512             : 
    1513       99723 :     IF( GE_16( st_ivas->nchan_transport, 3 ) )
    1514             :     {
    1515             :         Word32 temp;
    1516             :         Word16 i;
    1517             :         /*convert WYZX downmix to WYXZ*/
    1518    50902238 :         FOR( i = 0; i < output_frame; i++ )
    1519             :         {
    1520    50839680 :             temp = output[2][i]; /*Q14*/
    1521    50839680 :             move32();
    1522    50839680 :             output[2][i] = output[3][i]; /*Q14*/
    1523    50839680 :             move32();
    1524    50839680 :             output[3][i] = temp; /*Q14*/
    1525    50839680 :             move32();
    1526             :         }
    1527             :     }
    1528             : 
    1529       99723 :     IF( hSpar->hMdDec->td_decorr_flag )
    1530             :     {
    1531       99723 :         num_in_ingest = ivas_sba_get_nchan_metadata_fx( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); /*Q0*/
    1532             :     }
    1533             :     ELSE
    1534             :     {
    1535           0 :         num_in_ingest = nchan_transport; /*Q0*/
    1536           0 :         move16();
    1537             :     }
    1538             : 
    1539             :     /*---------------------------------------------------------------------*
    1540             :      * AGC
    1541             :      *---------------------------------------------------------------------*/
    1542             : 
    1543       99723 :     ivas_agc_dec_process_fx( hSpar->hAgcDec, ( output ), ( output ), nchan_transport, output_frame );
    1544             : 
    1545       99723 :     IF( hSpar->hPCA != NULL )
    1546             :     {
    1547       10580 :         ivas_pca_dec_fx( hSpar->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output );
    1548             :     }
    1549       99723 :     pop_wmops();
    1550             : 
    1551       99723 :     return;
    1552             : }
    1553             : 
    1554             : 
    1555             : /*-------------------------------------------------------------------*
    1556             :  * ivas_spar_dec_set_render_map()
    1557             :  *
    1558             :  *
    1559             :  *-------------------------------------------------------------------*/
    1560             : 
    1561      135777 : void ivas_spar_dec_set_render_map_fx(
    1562             :     Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure  */
    1563             :     const Word16 nCldfbTs    /* i  : number of CLDFB time slots Q0*/
    1564             : )
    1565             : {
    1566             :     SPAR_DEC_HANDLE hSpar;
    1567             : 
    1568      135777 :     hSpar = st_ivas->hSpar;
    1569             : 
    1570             :     /* adapt subframes */
    1571      135777 :     hSpar->num_slots = nCldfbTs; /*Q0*/
    1572      135777 :     move16();
    1573      135777 :     hSpar->slots_rendered = 0;
    1574      135777 :     move16();
    1575      135777 :     hSpar->subframes_rendered = 0;
    1576      135777 :     move16();
    1577             : 
    1578      135777 :     set16_fx( hSpar->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
    1579      135777 :     ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hSpar->subframe_nbslots, &hSpar->nb_subframes );
    1580             : 
    1581             :     /* copy also to tc buffer */
    1582             :     /* only for non-combined formats and combinded formats w/o discrete objects */
    1583      135777 :     test();
    1584      135777 :     IF( !( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) ) )
    1585             :     {
    1586      124887 :         st_ivas->hTcBuffer->nb_subframes = hSpar->nb_subframes; /*Q0*/
    1587      124887 :         move16();
    1588      124887 :         Copy( hSpar->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, hSpar->nb_subframes ); /*Q0*/
    1589             :     }
    1590             : 
    1591      135777 :     ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, 1, 0, DEFAULT_JBM_CLDFB_TIMESLOTS, hSpar->render_to_md_map );
    1592             : 
    1593      135777 :     return;
    1594             : }
    1595             : 
    1596             : 
    1597             : /*-------------------------------------------------------------------*
    1598             :  * ivas_spar_dec_upmixer()
    1599             :  *
    1600             :  * IVAS SPAR upmixer
    1601             :  *-------------------------------------------------------------------*/
    1602             : 
    1603      135777 : void ivas_spar_dec_set_render_params_fx(
    1604             :     Decoder_Struct *st_ivas,   /* i/o: IVAS decoder handle                     */
    1605             :     const Word16 n_cldfb_slots /* i  : number of cldfb slots in this frame     Q0*/
    1606             : )
    1607             : {
    1608             :     SPAR_DEC_HANDLE hSpar;
    1609             :     Word16 nchan_transport;
    1610             :     Word16 num_bands_out;
    1611             : 
    1612      135777 :     hSpar = st_ivas->hSpar;
    1613      135777 :     nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
    1614      135777 :     move16();
    1615      135777 :     num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/
    1616      135777 :     move16();
    1617      135777 :     ivas_spar_dec_gen_umx_mat_fx( hSpar->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ) );
    1618             : 
    1619      135777 :     ivas_spar_dec_set_render_map_fx( st_ivas, n_cldfb_slots );
    1620             : 
    1621      135777 :     return;
    1622             : }
    1623             : 
    1624             : 
    1625             : /*-------------------------------------------------------------------*
    1626             :  * ivas_spar_dec_digest_tc()
    1627             :  *
    1628             :  *
    1629             :  *-------------------------------------------------------------------*/
    1630             : 
    1631      135777 : void ivas_spar_dec_digest_tc_fx(
    1632             :     Decoder_Struct *st_ivas,          /* i/o: IVAS decoder handle          */
    1633             :     const Word16 nchan_transport,     /* i  : number of transport channels Q0*/
    1634             :     const Word16 nCldfbSlots,         /* i  : number of CLDFB slots        Q0*/
    1635             :     const Word16 nSamplesForRendering /* i  : number of samples provided   Q0*/
    1636             : )
    1637             : {
    1638             :     SPAR_DEC_HANDLE hSpar;
    1639             : 
    1640      135777 :     hSpar = st_ivas->hSpar;
    1641      135777 :     test();
    1642      135777 :     test();
    1643      135777 :     IF( hSpar->hMdDec->td_decorr_flag && !( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
    1644             :     {
    1645             :         Word16 nchan_internal, ch;
    1646             :         Word16 ch_sba_idx;
    1647             :         Word16 nSamplesLeftForTD, default_frame;
    1648             :         Word32 *pPcm_tmp[MAX_SPAR_INTERNAL_CHANNELS];
    1649             :         Word32 *p_tc[MAX_SPAR_INTERNAL_CHANNELS];
    1650             :         Word32 Pcm_tmp[MAX_SPAR_INTERNAL_CHANNELS][L_FRAME48k];
    1651       98723 :         Word16 q_format = Q11;
    1652       98723 :         move16();
    1653             : 
    1654       98723 :         ch_sba_idx = 0;
    1655       98723 :         move16();
    1656       98723 :         IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
    1657             :         {
    1658       17790 :             if ( EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
    1659             :             {
    1660       10890 :                 ch_sba_idx = st_ivas->nchan_ism; /*Q0*/
    1661       10890 :                 move16();
    1662             :             }
    1663             :         }
    1664             : 
    1665             :         /* TD decorrelator */
    1666             :         Word32 quo, rem;
    1667       98723 :         iDiv_and_mod_32( st_ivas->hDecoderConfig->output_Fs, FRAMES_PER_SEC, &quo, &rem, 0 );
    1668       98723 :         default_frame = extract_l( quo );         /*Q0*/
    1669       98723 :         nSamplesLeftForTD = nSamplesForRendering; /*Q0*/
    1670       98723 :         move16();
    1671       98723 :         nchan_internal = ivas_sba_get_nchan_metadata_fx( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); /*Q0*/
    1672             : 
    1673      584451 :         FOR( ch = 0; ch < nchan_internal; ch++ )
    1674             :         {
    1675      485728 :             pPcm_tmp[ch] = Pcm_tmp[ch];                                /*Q11*/
    1676      485728 :             p_tc[ch] = st_ivas->hTcBuffer->tc_fx[( ch + ch_sba_idx )]; /*Q11*/
    1677             :         }
    1678             : 
    1679      197448 :         WHILE( nSamplesLeftForTD )
    1680             :         {
    1681       98725 :             Word16 nSamplesToDecorr = s_min( nSamplesLeftForTD, default_frame ); /*Q0*/
    1682             : 
    1683       98725 :             IF( hSpar->hTdDecorr )
    1684             :             {
    1685             : 
    1686       89655 :                 ivas_td_decorr_process_fx( hSpar->hTdDecorr, p_tc, pPcm_tmp, nSamplesToDecorr );
    1687       89655 :                 st_ivas->hTcBuffer->q_tc_fx = s_min( st_ivas->hTcBuffer->q_tc_fx, q_format );
    1688       89655 :                 move16();
    1689       89655 :                 IF( GE_16( hSpar->hTdDecorr->num_apd_outputs, sub( nchan_internal, nchan_transport ) ) )
    1690             :                 {
    1691      243422 :                     FOR( ch = 0; ch < sub( nchan_internal, nchan_transport ); ch++ )
    1692             :                     {
    1693      161237 :                         Copy32( pPcm_tmp[( ( hSpar->hTdDecorr->num_apd_outputs - 1 ) - ch )], p_tc[( ( nchan_internal - 1 ) - ch )], nSamplesToDecorr ); /*Q11*/
    1694             :                     }
    1695             :                 }
    1696             :                 ELSE
    1697             :                 {
    1698       59760 :                     FOR( ch = 0; ch < sub( nchan_internal, nchan_transport ); ch++ )
    1699             :                     {
    1700       52290 :                         set32_fx( p_tc[( ( nchan_internal - 1 ) - ch )], 0, nSamplesToDecorr );
    1701             :                     }
    1702       22410 :                     FOR( ch = 0; ch < hSpar->hTdDecorr->num_apd_outputs; ch++ )
    1703             :                     {
    1704       14940 :                         Copy32( pPcm_tmp[( ( hSpar->hTdDecorr->num_apd_outputs - 1 ) - ch )], p_tc[( ( nchan_internal - 1 ) - ch )], nSamplesToDecorr ); /*Q11*/
    1705             :                     }
    1706             :                 }
    1707             :             }
    1708      584461 :             FOR( ch = 0; ch < nchan_internal; ch++ )
    1709             :             {
    1710      485736 :                 p_tc[ch] = p_tc[ch] + nSamplesToDecorr; /*Q11*/
    1711             :             }
    1712             : 
    1713       98725 :             nSamplesLeftForTD = sub( nSamplesLeftForTD, nSamplesToDecorr ); /*Q0*/
    1714             :         }
    1715             :     }
    1716             : 
    1717      135777 :     ivas_spar_dec_set_render_params_fx( st_ivas, nCldfbSlots );
    1718             : 
    1719      135777 :     return;
    1720             : }
    1721             : 
    1722             : 
    1723             : /*-------------------------------------------------------------------*
    1724             :  * ivas_spar_dec_upmixer_sf()
    1725             :  *
    1726             :  * IVAS SPAR upmixer
    1727             :  *-------------------------------------------------------------------*/
    1728             : 
    1729      396216 : void ivas_spar_dec_upmixer_sf_fx(
    1730             :     Decoder_Struct *st_ivas,    /* i/o: IVAS decoder handle                     */
    1731             :     Word32 *output_fx[],        /* o  : output audio channels                   Q11*/
    1732             :     const Word16 nchan_internal /* i  : number of internal channels             Q0*/
    1733             : )
    1734             : {
    1735             :     Word16 cldfb_band, num_cldfb_bands, numch_in, numch_out;
    1736             :     Word32 *cldfb_in_ts_re_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX];
    1737             :     Word32 *cldfb_in_ts_im_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX];
    1738             :     Word16 i, b, ts, out_ch, in_ch;
    1739             :     Word16 num_spar_bands, spar_band, nchan_transport;
    1740             :     Word16 num_in_ingest, split_band;
    1741             :     Word16 slot_size, slot_idx_start;
    1742             :     Word16 md_idx;
    1743             :     Word32 *p_tc_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS];
    1744             :     Word32 Pcm_tmp_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k];
    1745             :     Word16 numch_out_dirac;
    1746             :     Word32 mixer_mat_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
    1747             :     Word16 b_skip_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
    1748             :     DECODER_CONFIG_HANDLE hDecoderConfig;
    1749             :     SPAR_DEC_HANDLE hSpar;
    1750             :     Word16 num_md_sub_frames;
    1751      396216 :     Word16 q1 = 30;
    1752             :     Word16 prod;
    1753      396216 :     move16();
    1754      396216 :     push_wmops( "ivas_spar_dec_upmixer_sf_fx" );
    1755      396216 :     hSpar = st_ivas->hSpar;
    1756      396216 :     hDecoderConfig = st_ivas->hDecoderConfig;
    1757      396216 :     nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; /*Q0*/
    1758      396216 :     move16();
    1759             : 
    1760      396216 :     num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; /*Q0*/
    1761      396216 :     move16();
    1762      396216 :     numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; /*Q0*/
    1763      396216 :     move16();
    1764      396216 :     numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; /*Q0*/
    1765      396216 :     move16();
    1766      396216 :     num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); /*Q0*/
    1767      396216 :     slot_size = NS2SA_FX2( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );                                                                            /*Q0*/
    1768      396216 :     move16();
    1769      396216 :     slot_idx_start = hSpar->slots_rendered; /*Q0*/
    1770      396216 :     move16();
    1771             : 
    1772      396216 :     prod = i_mult( slot_idx_start, slot_size );
    1773             : 
    1774      396216 :     test();
    1775      396216 :     IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) )
    1776       43560 :     {
    1777             :         Word16 nchan_ism;
    1778             : 
    1779       43560 :         nchan_ism = st_ivas->nchan_ism;
    1780       43560 :         move16();
    1781             : 
    1782      378280 :         FOR( i = 0; i < nchan_internal; i++ )
    1783             :         {
    1784      334720 :             p_tc_fx[i] = st_ivas->hTcBuffer->tc_fx[( i + nchan_ism )] + prod; /*Q11*/
    1785             :         }
    1786             : 
    1787       43560 :         test();
    1788       43560 :         test();
    1789       43560 :         IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
    1790             :         {
    1791       40000 :             FOR( i = 0; i < nchan_ism; i++ )
    1792             :             {
    1793       32000 :                 p_tc_fx[( i + nchan_internal )] = st_ivas->hTcBuffer->tc_fx[i] + prod; /*Q11*/
    1794             :             }
    1795             :         }
    1796             :     }
    1797             :     ELSE
    1798             :     {
    1799     1966162 :         FOR( i = 0; i < nchan_internal; i++ )
    1800             :         {
    1801     1613506 :             p_tc_fx[i] = st_ivas->hTcBuffer->tc_fx[i] + prod; /*Q11*/
    1802             :         }
    1803             :     }
    1804             : 
    1805             : 
    1806             :     /*---------------------------------------------------------------------*
    1807             :      * TD Decorr and pcm ingest
    1808             :      *---------------------------------------------------------------------*/
    1809             : 
    1810      396216 :     IF( hSpar->hMdDec->td_decorr_flag )
    1811             :     {
    1812      396216 :         num_in_ingest = nchan_internal; /*Q0*/
    1813      396216 :         move16();
    1814             :     }
    1815             :     ELSE
    1816             :     {
    1817           0 :         num_in_ingest = nchan_transport; /*Q0*/
    1818           0 :         move16();
    1819             :     }
    1820             : 
    1821             :     /*---------------------------------------------------------------------*
    1822             :      * PCA decoder
    1823             :      *---------------------------------------------------------------------*/
    1824             : 
    1825      396216 :     hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; /*Q0*/
    1826      396216 :     move16();
    1827             : 
    1828             : 
    1829             :     /*---------------------------------------------------------------------*
    1830             :      * Prepare CLDFB buffers
    1831             :      *---------------------------------------------------------------------*/
    1832             : 
    1833      396216 :     set_zero_fx( &Pcm_tmp_fx[0][0], ( MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS ) * L_FRAME48k );
    1834             :     /* set-up pointers */
    1835      396216 :     IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) )
    1836             :     {
    1837             :         /* at this point, output channels are used as intermediate procesing buffers */
    1838     4791696 :         FOR( in_ch = 0; in_ch < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; in_ch++ )
    1839             :         {
    1840    22817600 :             FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
    1841             :             {
    1842    18254080 :                 cldfb_in_ts_re_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][( ts * num_cldfb_bands )];                               /*Q11*/
    1843    18254080 :                 cldfb_in_ts_im_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][( ( ts * num_cldfb_bands ) + ( 4 * num_cldfb_bands ) )]; /*Q11*/
    1844             :             }
    1845             :         }
    1846             :     }
    1847             :     ELSE
    1848             :     {
    1849      846200 :         FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
    1850             :         {
    1851     3390800 :             FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ )
    1852             :             {
    1853     2712640 :                 cldfb_in_ts_re_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][( ts * num_cldfb_bands )];                               /*Q11*/
    1854     2712640 :                 cldfb_in_ts_im_fx[in_ch][ts] = &Pcm_tmp_fx[in_ch][( ( ts * num_cldfb_bands ) + ( 4 * num_cldfb_bands ) )]; /*Q11*/
    1855             :             }
    1856             :         }
    1857             :     }
    1858             : 
    1859             :     /*---------------------------------------------------------------------*
    1860             :      * CLDFB Processing and Synthesis
    1861             :      *---------------------------------------------------------------------*/
    1862             : 
    1863      396216 :     num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands; /*Q0*/
    1864      396216 :     move16();
    1865             : 
    1866             :     /* apply parameters */
    1867             :     /* determine if we can skip certain data */
    1868      396216 :     ivas_spar_get_skip_mat_fx( hSpar, numch_out, numch_in, num_spar_bands, b_skip_mat, num_md_sub_frames ); /* this can be precomputed based on bitrate and format*/
    1869             : 
    1870      396216 :     numch_out_dirac = hDecoderConfig->nchan_out;
    1871      396216 :     move16();
    1872             : 
    1873             : 
    1874             :     /* CLDFB analysis of incoming frame */
    1875     2344442 :     FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
    1876             :     {
    1877     9720150 :         FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ )
    1878             :         {
    1879     7771924 :             Word16 q_cldfb = 11;
    1880     7771924 :             move16();
    1881     7771924 :             cldfbAnalysis_ts_fx_fixed_q( &p_tc_fx[in_ch][( ts * num_cldfb_bands )], cldfb_in_ts_re_fx[in_ch][ts], cldfb_in_ts_im_fx[in_ch][ts], num_cldfb_bands, st_ivas->cldfbAnaDec[in_ch], &q_cldfb );
    1882             :         }
    1883             :     }
    1884             : 
    1885      396216 :     test();
    1886      396216 :     test();
    1887      396216 :     IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
    1888             :     {
    1889       40000 :         FOR( ; in_ch < ( st_ivas->nchan_ism + numch_in ); in_ch++ )
    1890             :         {
    1891      160000 :             FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ )
    1892             :             {
    1893      128000 :                 Word16 q_cldfb = 11;
    1894      128000 :                 move16();
    1895      128000 :                 cldfbAnalysis_ts_fx_fixed_q( &p_tc_fx[in_ch][( ts * num_cldfb_bands )], cldfb_in_ts_re_fx[in_ch][ts], cldfb_in_ts_im_fx[in_ch][ts], num_cldfb_bands, st_ivas->cldfbAnaDec[in_ch], &q_cldfb );
    1896             :             }
    1897             :         }
    1898             :     }
    1899             : 
    1900      396216 :     test();
    1901      396216 :     test();
    1902      396216 :     IF( ( LT_32( hDecoderConfig->ivas_total_brate, IVAS_24k4 ) ) && ( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA2 ) ) || ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA3 ) ) ) )
    1903             :     {
    1904        5132 :         Word16 q_cldfb = 6;
    1905        5132 :         move16();
    1906        5132 :         ivas_spar_calc_smooth_facs_fx( cldfb_in_ts_re_fx[0], cldfb_in_ts_im_fx[0], q_cldfb, num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered],
    1907        5132 :                                        hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac_fx, hSpar->hMdDec->smooth_buf_fx );
    1908             :     }
    1909      396216 :     Word16 sh_l = sub( 31, q1 );
    1910     1975835 :     FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ )
    1911             :     {
    1912     1579619 :         md_idx = hSpar->render_to_md_map[( ts + slot_idx_start )]; /*Q0*/
    1913     1579619 :         move16();
    1914     1579619 :         Scale_sig( hSpar->hFbMixer->cldfb_cross_fade_fx, CLDFB_NO_COL_MAX, Q15 - st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q ); /*Q15*/
    1915     1579619 :         st_ivas->hSpar->hFbMixer->cldfb_cross_fade_q = Q15;
    1916     1579619 :         move16();
    1917     1579619 :         ivas_spar_get_parameters_fx( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat_fx );
    1918             : 
    1919     1579619 :         test();
    1920     1579619 :         test();
    1921     1579619 :         IF( ( LT_32( hDecoderConfig->ivas_total_brate, IVAS_24k4 ) ) && ( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA2 ) ) || ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA3 ) ) ) )
    1922             :         {
    1923      266864 :             FOR( spar_band = 0; spar_band < num_spar_bands; spar_band++ )
    1924             :             {
    1925      246336 :                 Word16 diff = sub( 32767, hSpar->hMdDec->smooth_fac_fx[spar_band] );
    1926     1231680 :                 FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
    1927             :                 {
    1928     4926720 :                     FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
    1929             :                     {
    1930     3941376 :                         mixer_mat_fx[out_ch][in_ch][spar_band] = Madd_32_16( Mpy_32_16_1( mixer_mat_fx[out_ch][in_ch][spar_band], diff ), hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band], hSpar->hMdDec->smooth_fac_fx[spar_band] ); /*q1*/
    1931     3941376 :                         move32();
    1932     3941376 :                         hSpar->hMdDec->mixer_mat_prev2_fx[out_ch][in_ch][spar_band] = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/
    1933     3941376 :                         move32();
    1934             :                     }
    1935             :                 }
    1936             :             }
    1937             :         }
    1938             :         /* Note: This version splits the cldfb band loop into 2 loops, removing some inner-loop IF_statements */
    1939     1579619 :         Word16 min_cldf_band = s_min( CLDFB_PAR_WEIGHT_START_BAND, num_cldfb_bands );
    1940             :         Word32 out_re_fx[IVAS_SPAR_MAX_CH];
    1941             :         Word32 out_im_fx[IVAS_SPAR_MAX_CH];
    1942             :         Word32 cldfb_par_fx; /*q1*/
    1943     1579619 :         ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band;
    1944             : 
    1945             :         /* First loop from cldfb_band=0 till min_cldf_band (CLDFB_PAR_WEIGHT_START_BAND) */
    1946    12636952 :         FOR( cldfb_band = 0; cldfb_band < min_cldf_band; cldfb_band++ )
    1947             :         {
    1948    11057333 :             spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; /*Q0*/
    1949    11057333 :             move16();
    1950    65460801 :             FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
    1951             :             {
    1952    54403468 :                 out_re_fx[out_ch] = 0;
    1953    54403468 :                 move32();
    1954    54403468 :                 out_im_fx[out_ch] = 0;
    1955    54403468 :                 move32();
    1956   370829900 :                 FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
    1957             :                 {
    1958   316426432 :                     IF( b_skip_mat[out_ch][in_ch] == 0 )
    1959             :                     {
    1960   128007761 :                         cldfb_par_fx = mixer_mat_fx[out_ch][in_ch][spar_band]; /*q1*/
    1961   128007761 :                         move32();
    1962   128007761 :                         out_re_fx[out_ch] = Madd_32_32( out_re_fx[out_ch], cldfb_in_ts_re_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/
    1963   128007761 :                         move32();
    1964   128007761 :                         out_im_fx[out_ch] = Madd_32_32( out_im_fx[out_ch], cldfb_in_ts_im_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/
    1965   128007761 :                         move32();
    1966             :                     }
    1967             :                 }
    1968             :             }
    1969             :             /*update CLDFB data with the parameter-modified data*/
    1970    65460801 :             FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
    1971             :             {
    1972    54403468 :                 cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/
    1973    54403468 :                 move32();
    1974    54403468 :                 cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/
    1975    54403468 :                 move32();
    1976             :             }
    1977             :         }
    1978             : 
    1979             : 
    1980             :         /* Second loop from min_cldf_band (CLDFB_PAR_WEIGHT_START_BAND) till num_cldfb_bands */
    1981    68425846 :         FOR( ; cldfb_band < num_cldfb_bands; cldfb_band++ )
    1982             :         {
    1983   409446279 :             FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
    1984             :             {
    1985   342600052 :                 Word32 Out_re_fx = L_add( 0, 0 );
    1986   342600052 :                 Word32 Out_im_fx = L_add( 0, 0 );
    1987  2446208500 :                 FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
    1988             :                 {
    1989  2103608448 :                     IF( b_skip_mat[out_ch][in_ch] == 0 )
    1990             :                     {
    1991   831872359 :                         Word64 acc = 0;
    1992   831872359 :                         move64();
    1993             : 
    1994   831872359 :                         cldfb_par_fx = 0;
    1995   831872359 :                         move32();
    1996  4289397788 :                         FOR( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ )
    1997             :                         {
    1998             :                             /* accumulate contributions from all SPAR bands */
    1999  3457525429 :                             acc = W_mac_32_32( acc, mixer_mat_fx[out_ch][in_ch][spar_band], bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band] ); // q1+ Q23
    2000             :                         }
    2001   831872359 :                         cldfb_par_fx = W_shl_sat_l( acc, -23 );                                                      // q1
    2002   831872359 :                         Out_re_fx = Madd_32_32( Out_re_fx, cldfb_in_ts_re_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/
    2003   831872359 :                         Out_im_fx = Madd_32_32( Out_im_fx, cldfb_in_ts_im_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); /*q1-25*/
    2004             :                     }
    2005             :                 }
    2006   342600052 :                 out_re_fx[out_ch] = Out_re_fx;
    2007   342600052 :                 out_im_fx[out_ch] = Out_im_fx;
    2008             :             }
    2009             : 
    2010             :             /*update CLDFB data with the parameter-modified data*/
    2011   409446279 :             FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
    2012             :             {
    2013   342600052 :                 cldfb_in_ts_re_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], sh_l ); /*Q=6*/
    2014   342600052 :                 move32();
    2015   342600052 :                 cldfb_in_ts_im_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], sh_l ); /*Q=6*/
    2016   342600052 :                 move32();
    2017             :             }
    2018             :         }
    2019     1579619 :         test();
    2020     1579619 :         IF( ( EQ_16( ( add( add( slot_idx_start, ts ), 1 ) ), hSpar->num_slots ) ) || ( NE_16( ( shr( md_idx, 2 ) /* md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME */ ), ( hSpar->render_to_md_map[( ( slot_idx_start + ts ) + 1 )] / JBM_CLDFB_SLOTS_IN_SUBFRAME /*It's value is 4*/ ) ) ) )
    2021             :         {
    2022             :             /* we have crossed an unadapted parameter sf border, update previous mixing matrices */
    2023      394910 :             Word16 md_sf = shr( md_idx, 2 ) /* md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME */; /*Q0*/
    2024      394910 :             split_band = SPAR_DIRAC_SPLIT_START_BAND;
    2025      394910 :             move16();
    2026      394910 :             if ( NE_16( num_md_sub_frames, MAX_PARAM_SPATIAL_SUBFRAMES ) )
    2027             :             {
    2028       60440 :                 md_sf = 0;
    2029       60440 :                 move16();
    2030             :             }
    2031      394910 :             IF( LT_16( split_band, IVAS_MAX_NUM_BANDS ) )
    2032             :             {
    2033             : 
    2034     2337930 :                 FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
    2035             :                 {
    2036    13244228 :                     FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
    2037             :                     {
    2038   145635704 :                         FOR( b = 0; b < num_spar_bands; b++ )
    2039             :                         {
    2040   134334496 :                             hSpar->hMdDec->mixer_mat_prev_fx[0][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b];
    2041   134334496 :                             hSpar->hMdDec->mixer_mat_prev_fx[1][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b];
    2042   134334496 :                             hSpar->hMdDec->mixer_mat_prev_fx[2][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[3][out_ch][in_ch][b];
    2043   134334496 :                             hSpar->hMdDec->mixer_mat_prev_fx[3][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_prev_fx[4][out_ch][in_ch][b];
    2044   134334496 :                             move32();
    2045   134334496 :                             move32();
    2046   134334496 :                             move32();
    2047   134334496 :                             move32();
    2048             : 
    2049   134334496 :                             hSpar->hMdDec->mixer_mat_prev_fx[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][( b + ( md_sf * IVAS_MAX_NUM_BANDS ) )]; /*hSpar->hMdDec->Q_mixer_mat*/
    2050   134334496 :                             move32();
    2051             :                         }
    2052             :                     }
    2053             :                 }
    2054      394910 :                 hSpar->i_subframe = add( hSpar->i_subframe, 1 ); /*Q0*/
    2055      394910 :                 move16();
    2056      394910 :                 hSpar->i_subframe = s_min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); /*Q0*/
    2057      394910 :                 move16();
    2058             :             }
    2059             :         }
    2060             :     }
    2061             : 
    2062      396216 :     test();
    2063      396216 :     test();
    2064      396216 :     IF( NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) && NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_STEREO ) && NE_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_MONO ) )
    2065             :     {
    2066      228176 :         ivas_dirac_dec_render_sf_fx( st_ivas, output_fx, nchan_internal, cldfb_in_ts_re_fx, cldfb_in_ts_im_fx );
    2067             :     }
    2068             :     /*------------------------------------------------------------------ends*/
    2069      396216 :     IF( st_ivas->hDirAC != NULL )
    2070             :     {
    2071             :         Word16 outchannels, idx_in, idx_lfe, ch;
    2072      228176 :         idx_in = 0;
    2073      228176 :         move16();
    2074      228176 :         idx_lfe = 0;
    2075      228176 :         move16();
    2076             : 
    2077      228176 :         outchannels = add( st_ivas->hOutSetup.nchan_out_woLFE, st_ivas->hOutSetup.num_lfe ); /*Q0*/
    2078             : 
    2079     1900842 :         FOR( ch = 0; ch < outchannels; ch++ )
    2080             :         {
    2081     1672666 :             test();
    2082     1672666 :             IF( ( st_ivas->hOutSetup.num_lfe > 0 ) && ( EQ_16( st_ivas->hOutSetup.index_lfe[idx_lfe], ch ) ) )
    2083             :             {
    2084       41000 :                 set_zero_fx( output_fx[ch], i_mult( hSpar->subframe_nbslots[hSpar->subframes_rendered], num_cldfb_bands ) );
    2085       41000 :                 if ( LT_16( idx_lfe, ( sub( st_ivas->hDirACRend->hOutSetup.num_lfe, 1 ) ) ) )
    2086             :                 {
    2087           0 :                     idx_lfe = add( idx_lfe, 1 );
    2088             :                 }
    2089             :             }
    2090             :             ELSE
    2091             :             {
    2092     1631666 :                 test();
    2093     1631666 :                 test();
    2094     1631666 :                 test();
    2095     1631666 :                 test();
    2096     1631666 :                 test();
    2097     1631666 :                 test();
    2098     1631666 :                 IF( ( EQ_32( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_FOA ) || !( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) || EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) &&
    2099             :                     !( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) && EQ_32( st_ivas->ism_mode, ISM_SBA_MODE_DISC ) && EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) ) )
    2100             :                 {
    2101     6676480 :                     FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ )
    2102             :                     {
    2103     5329264 :                         cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[idx_in][ts], &cldfb_in_ts_im_fx[idx_in][ts], &output_fx[ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, 0, st_ivas->cldfbSynDec[idx_in] );
    2104             :                     }
    2105             :                 }
    2106             : 
    2107     1631666 :                 idx_in = add( idx_in, 1 );
    2108             :             }
    2109             :         }
    2110             :     }
    2111             :     ELSE
    2112             :     {
    2113             :         /* CLDFB to time synthesis (overwrite mixer output) */
    2114      840200 :         FOR( out_ch = 0; out_ch < numch_out_dirac; out_ch++ )
    2115             :         {
    2116     3360800 :             FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ )
    2117             :             {
    2118     2688640 :                 cldfbSynthesis_ivas_fx( &cldfb_in_ts_re_fx[out_ch][ts], &cldfb_in_ts_im_fx[out_ch][ts], &output_fx[out_ch][i_mult( ts, num_cldfb_bands )], num_cldfb_bands, 6, 0, st_ivas->cldfbSynDec[out_ch] );
    2119             :             }
    2120             :         }
    2121             :     }
    2122             : 
    2123      396216 :     hSpar->slots_rendered = add( hSpar->slots_rendered, hSpar->subframe_nbslots[hSpar->subframes_rendered] ); /*Q0*/
    2124      396216 :     move16();
    2125      396216 :     hSpar->subframes_rendered = add( hSpar->subframes_rendered, 1 ); /*Q0*/
    2126      396216 :     move16();
    2127             : 
    2128      396216 :     pop_wmops();
    2129             : 
    2130      396216 :     return;
    2131             : }

Generated by: LCOV version 1.14