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

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <assert.h>
      34             : #include <stdint.h>
      35             : #include <math.h>
      36             : #include "options.h"
      37             : #include "ivas_cnst.h"
      38             : #include "prot_fx.h"
      39             : #include "rom_com.h"
      40             : #include "wmc_auto.h"
      41             : #include "ivas_prot_fx.h"
      42             : 
      43             : 
      44             : /*-------------------------------------------------------------------*
      45             :  * Local function prototypes
      46             :  *-------------------------------------------------------------------*/
      47             : 
      48             : static void inverseBwMS_fx( const Word16 startLine, const Word16 stopLine, Word32 x0[], Word32 x1[], const Word32 norm_fac );
      49             : 
      50             : 
      51             : #define NF_RED_FAC_FIXED   1610612736 // Q31
      52             : #define SQRT2_OVER_2_FIXED 1518500250 // Q31
      53             : #define POINT_8_FIXED      1717986918 // Q31
      54             : #define POINT_2_FIXED      429496730  // Q31
      55             : #define ONE_POINT_3_FIXED  87241523   // Q26
      56             : #define POINT_9_FIXED      60397978   // Q26
      57             : 
      58             : /*-------------------------------------------------------------------*
      59             :  * parse_stereo_from_bitstream
      60             :  *
      61             :  *
      62             :  *-------------------------------------------------------------------*/
      63             : 
      64      158607 : void parse_stereo_from_bitstream(
      65             :     STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure                */
      66             :     Decoder_State **sts,                     /* i/o: decoder state structure                      */
      67             :     const Word16 mct_on,                     /* i  : flag mct block (1) or stereo (0)   Q0*/
      68             :     const Word16 isSBAStereoMode,            /* i  : flag core coding for SBA                   Q0*/
      69             :     Decoder_State *st0,                      /* i/o: decoder state structure for Bstr     */
      70             :     Word16 ms_mask[NB_DIV][MAX_SFB]          /* o  : bandwise MS mask                                   Q0*/
      71             : )
      72             : {
      73             :     Word16 i, k, nSubframes, mdct_stereo_mode;
      74             :     STEREO_MDCT_BAND_PARAMETERS *sfbConf;
      75             : 
      76      158607 :     IF( !isSBAStereoMode )
      77             :     {
      78             :         // nSubframes = ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) ? NB_DIV : 1;
      79      121867 :         test();
      80      121867 :         IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
      81             :         {
      82        2989 :             nSubframes = NB_DIV; /* Q0 */
      83        2989 :             move16();
      84             :         }
      85             :         ELSE
      86             :         {
      87      118878 :             nSubframes = 1; /* Q0 */
      88      118878 :             move16();
      89             :         }
      90      121867 :         move16();
      91             :         // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
      92      121867 :         IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
      93             :         {
      94      119056 :             sfbConf = &hStereoMdct->stbParamsTCX20;
      95             :         }
      96             :         ELSE
      97             :         {
      98        2811 :             sfbConf = &hStereoMdct->stbParamsTCX10;
      99             :         }
     100      121867 :         if ( sts[0]->last_core_from_bs == ACELP_CORE )
     101             :         {
     102         596 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     103             :         }
     104             : 
     105      121867 :         IF( hStereoMdct->use_itd )
     106             :         {
     107             :             Word16 I;
     108             : 
     109       11381 :             hStereoMdct->itd_mode = extract_l( get_next_indice_fx( st0, STEREO_DFT_ITD_MODE_NBITS ) ); /* Q0 */
     110             :             /*(*nb_bits) += STEREO_DFT_ITD_MODE_NBITS;*/                                               /*ITD mode flag: 1bit*/
     111             : 
     112       11381 :             hStereoMdct->itd_fx = 0;
     113       11381 :             move32();
     114       11381 :             IF( hStereoMdct->itd_mode )
     115             :             {
     116        3388 :                 /*(*nb_bits) += */ read_itd( st0, &I );
     117        3388 :                 stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
     118             :             }
     119             :         }
     120             : 
     121      246723 :         FOR( k = 0; k < nSubframes; k++ )
     122             :         {
     123      124856 :             mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     124      124856 :             IF( mdct_stereo_mode )
     125             :             {
     126      121272 :                 mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     127             :             }
     128      124856 :             SWITCH( mdct_stereo_mode )
     129             :             {
     130        3584 :                 case 0:
     131        3584 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
     132        3584 :                     move16();
     133        3584 :                     BREAK;
     134       76707 :                 case 1:
     135       76707 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
     136       76707 :                     move16();
     137       76707 :                     BREAK;
     138       44565 :                 case 2:
     139       44565 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
     140       44565 :                     move16();
     141       44565 :                     BREAK;
     142           0 :                 default:
     143           0 :                     assert( !"Not supported stereo mode\n" );
     144             :             }
     145             : 
     146      124856 :             IF( !mct_on )
     147             :             {
     148       40996 :                 test();
     149       40996 :                 IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
     150             :                 {
     151       40754 :                     hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
     152       40754 :                     move16();
     153       40754 :                     assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
     154             :                 }
     155             :                 ELSE
     156             :                 {
     157         242 :                     hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
     158         242 :                     move16();
     159             :                 }
     160             :             }
     161             : 
     162             :             // set16_fx( ms_mask[k], ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) ? 1 : 0, sfbConf->nBandsStereoCore );
     163      124856 :             IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
     164             :             {
     165       76707 :                 set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
     166             :             }
     167             :             ELSE
     168             :             {
     169       48149 :                 set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
     170             :             }
     171             : 
     172      124856 :             IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
     173             :             {
     174     1854167 :                 FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
     175             :                 {
     176     1809602 :                     ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     177     1809602 :                     move16();
     178             :                 }
     179             :             }
     180             : 
     181      124856 :             IF( st0->igf )
     182             :             {
     183       82885 :                 mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
     184       82885 :                 IF( mdct_stereo_mode )
     185             :                 {
     186       50929 :                     mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     187             :                 }
     188             : 
     189       82885 :                 SWITCH( mdct_stereo_mode )
     190             :                 {
     191       31956 :                     case 0:
     192       31956 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     193       31956 :                         move16();
     194       31956 :                         BREAK;
     195       37724 :                     case 1:
     196       37724 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
     197       37724 :                         move16();
     198       37724 :                         BREAK;
     199       13205 :                     case 2:
     200       13205 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
     201       13205 :                         move16();
     202       13205 :                         BREAK;
     203           0 :                     default:
     204           0 :                         assert( !"Not supported stereo mode\n" );
     205             :                 }
     206             : 
     207             :                 // set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) ? 1 : 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     208       82885 :                 IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
     209             :                 {
     210       37724 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     211             :                 }
     212             :                 ELSE
     213             :                 {
     214       45161 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     215             :                 }
     216             : 
     217       82885 :                 IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     218             :                 {
     219       81967 :                     FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
     220             :                     {
     221       68762 :                         ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     222       68762 :                         move16();
     223             :                     }
     224             :                 }
     225             :             }
     226             :             ELSE
     227             :             {
     228       41971 :                 hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     229       41971 :                 move16();
     230             :             }
     231             :         }
     232             :     }
     233             : 
     234      158607 :     IF( !mct_on )
     235             :     {
     236       76446 :         hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels   Q0*/
     237       76446 :         move16();
     238       76446 :         hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
     239             : 
     240       76446 :         assert( GT_16( hStereoMdct->split_ratio, 0 ) );
     241             :     }
     242             : 
     243             : 
     244      158607 :     return;
     245             : }
     246             : 
     247             : 
     248             : /*-------------------------------------------------------------------*
     249             :  * inverseBwMS()
     250             :  *
     251             :  * Band-wise M/S stereo processing
     252             :  *-------------------------------------------------------------------*/
     253     1301115 : static void inverseBwMS_fx(
     254             :     const Word16 startLine, /* i  : start line of sfb                                   Q0*/
     255             :     const Word16 stopLine,  /* i  : stop line of sfb                                    Q0*/
     256             :     Word32 x0[],            /* i/o: mid/left channel coefficients               Qx*/
     257             :     Word32 x1[],            /* i/o: side/right channel coefficients             Qx*/
     258             :     const Word32 norm_fac   /* i  : normalization factor                                Q31*/
     259             : )
     260             : {
     261             :     Word16 j;
     262             :     Word32 tmpValue;
     263             : 
     264    71736965 :     FOR( j = startLine; j < stopLine; j++ )
     265             :     {
     266    70435850 :         tmpValue = x0[j];
     267    70435850 :         move32();
     268    70435850 :         x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
     269    70435850 :         move32();
     270    70435850 :         x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
     271    70435850 :         move32();
     272             :     }
     273             : 
     274     1301115 :     return;
     275             : }
     276             : 
     277             : 
     278             : /*-------------------------------------------------------------------*
     279             :  * inverseMS()
     280             :  *
     281             :  * M/S stereo processing
     282             :  *-------------------------------------------------------------------*/
     283      157330 : void inverseMS_fx(
     284             :     const Word16 L_frame, /* i  : frame length                                          Q0*/
     285             :     Word32 x0[],          /* i/o: mid/left channel coefficients         Qx*/
     286             :     Word32 x1[],          /* i/o: side/right channel coefficients       Qx*/
     287             :     const Word32 norm_fac /* i  : normalization factor                     Q31*/
     288             : )
     289             : {
     290      157330 :     inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
     291             : 
     292      157330 :     return;
     293             : }
     294             : 
     295             : 
     296             : /*-------------------------------------------------------------------*
     297             :  * stereo_decoder_tcx()
     298             :  *
     299             :  * apply stereo processing (inverse MS and global ILD)
     300             :  *-------------------------------------------------------------------*/
     301      122627 : void stereo_decoder_tcx_fx(
     302             :     STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure           */
     303             :     Word16 ms_mask[NB_DIV][MAX_SFB],   /* i  : bandwise MS mask                                                 Q0*/
     304             :     Word32 *spec_r_0[NB_DIV],          /* i/o: spectrum right channel                                   Qx*/
     305             :     Word32 *spec_l[],                  /* i/o: spectrum left channel  [NB_DIV][N]               Qx*/
     306             :     Word32 *spec_r[],                  /* i/o: spectrum right channel [NB_DIV][N]               Qx*/
     307             :     const Word16 mdct_stereo_mode[],   /* i  : stereo mode (FB/band wise MS, dual mono  Q0*/
     308             :     const Word16 core_l,               /* i  : core for left channel (TCX20/TCX10)              Q0*/
     309             :     const Word16 core_r,               /* i  : core for right channel (TCX20/TCX10)             Q0*/
     310             :     const Word16 igf,                  /* i  : flag for IGF activity                                    Q0*/
     311             :     const Word16 L_frameTCX_l,         /* i  : TCX frame length of left channel                 Q0*/
     312             :     const Word16 L_frameTCX_r,         /* i  : TCX frame length of right channel                Q0*/
     313             :     const Word16 mct_on,               /* i  : flag mct block (1) or stereo (0)                 Q0*/
     314             :     const Word16 last_core_l,          /* i  : last core for left channel                               Q0*/
     315             :     const Word16 last_core_r,          /* i  : last core for right channel                              Q0*/
     316             :     const Word16 tmp_plc_upmix         /* i  : indicates temp upmix for PLC decision    Q0*/
     317             : #ifndef OPT_SBA_DEC_PATH
     318             :     ,
     319             :     Word16 *q_x_ch2,
     320             :     Word16 *q_x_ch1
     321             : #endif /* OPT_SBA_DEC_PATH */
     322             : )
     323             : {
     324             :     Word16 i, k, sfb, nSubframes;
     325      122627 :     STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
     326             :     Word32 nrgRatio, inv_nrgRatio, tmp_32;
     327             :     Word16 tmp_e, shift;
     328             : 
     329      122627 :     nSubframes = 2;
     330      122627 :     move16();
     331      122627 :     test();
     332      122627 :     test();
     333      122627 :     if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
     334             :     {
     335      119633 :         nSubframes = 1; /* Q0 */
     336      119633 :         move16();
     337             :     }
     338             : 
     339      248248 :     FOR( k = 0; k < nSubframes; k++ )
     340             :     {
     341             :         // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     342      125621 :         IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
     343             :         {
     344      119986 :             sfbConf = &hStereoMdct->stbParamsTCX20;
     345             :         }
     346             :         ELSE
     347             :         {
     348        5635 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     349             :         }
     350             : 
     351      125621 :         test();
     352      125621 :         if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
     353             :         {
     354         606 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     355             :         }
     356             : 
     357      125621 :         IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
     358             :         {
     359    42007472 :             FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
     360             :             {
     361    41930408 :                 IF( EQ_32( spec_r_0[k][i], 0 ) )
     362             :                 {
     363    11526093 :                     spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     364    11526093 :                     move32();
     365             :                 }
     366             :             }
     367       77064 :             inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
     368             : #ifndef OPT_SBA_DEC_PATH
     369             :             *q_x_ch2 = *q_x_ch2;
     370             :             move16();
     371             :             *q_x_ch1 = *q_x_ch1;
     372             :             move16();
     373             : #endif /* OPT_SBA_DEC_PATH */
     374             :         }
     375       48557 :         ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
     376             :         {
     377     1868599 :             FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
     378             :             {
     379     1823673 :                 IF( ms_mask[k][sfb] )
     380             :                 {
     381    15794351 :                     FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     382             :                     {
     383    14687034 :                         IF( EQ_32( spec_r_0[k][i], 0 ) )
     384             :                         {
     385     4247497 :                             spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     386     4247497 :                             move32();
     387             :                         }
     388             :                     }
     389     1107317 :                     inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
     390             : #ifndef OPT_SBA_DEC_PATH
     391             :                     *q_x_ch2 = *q_x_ch2;
     392             :                     move16();
     393             :                     *q_x_ch1 = *q_x_ch1;
     394             :                     move16();
     395             : #endif /* OPT_SBA_DEC_PATH */
     396             :                 }
     397             :             }
     398             :         }
     399             : 
     400      125621 :         IF( igf )
     401             :         {
     402       83294 :             IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
     403             :             {
     404    11380043 :                 FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
     405             :                 {
     406    11342222 :                     IF( EQ_32( spec_r_0[k][i], 0 ) )
     407             :                     {
     408     3409895 :                         spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     409     3409895 :                         move32();
     410             :                     }
     411             :                 }
     412       37821 :                 inverseMS_fx( sub( sfbConf->sfbOffset[sfbConf->sfbCnt], sfbConf->sfbOffset[sfbConf->nBandsStereoCore] ), &spec_l[k][sfbConf->sfbOffset[sfbConf->nBandsStereoCore]], &spec_r[k][sfbConf->sfbOffset[sfbConf->nBandsStereoCore]], SQRT2_OVER_2_FIXED );
     413             : #ifndef OPT_SBA_DEC_PATH
     414             :                 *q_x_ch2 = *q_x_ch2;
     415             :                 move16();
     416             :                 *q_x_ch1 = *q_x_ch1;
     417             :                 move16();
     418             : #endif /* OPT_SBA_DEC_PATH */
     419             :             }
     420       45473 :             ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     421             :             {
     422       82281 :                 FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
     423             :                 {
     424       69034 :                     IF( ms_mask[k][sfb] )
     425             :                     {
     426     1830752 :                         FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     427             :                         {
     428     1794284 :                             IF( EQ_32( spec_r_0[k][i], 0 ) )
     429             :                             {
     430      611740 :                                 spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     431      611740 :                                 move32();
     432             :                             }
     433             :                         }
     434       36468 :                         inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
     435             : #ifndef OPT_SBA_DEC_PATH
     436             :                         *q_x_ch2 = *q_x_ch2;
     437             :                         move16();
     438             :                         *q_x_ch1 = *q_x_ch1;
     439             :                         move16();
     440             : #endif /* OPT_SBA_DEC_PATH */
     441             :                     }
     442             :                 }
     443             :             }
     444             :         }
     445             : 
     446      125621 :         IF( !mct_on )
     447             :         {
     448       41761 :             tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
     449       41761 :             tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
     450       41761 :             nrgRatio = L_sub( tmp_32, ONE_IN_Q26 );                                   // Q26
     451             : 
     452       41761 :             hStereoMdct->smooth_ratio_fx = W_extract_h( W_mac_32_32( W_mult_32_32( POINT_8_FIXED, hStereoMdct->smooth_ratio_fx ), POINT_2_FIXED, nrgRatio ) ); // Q26
     453       41761 :             move32();
     454             :             /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
     455       41761 :             IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FIXED ) )
     456             :             {
     457       15684 :                 hStereoMdct->reverse_dmx = 1; /* Q0 */
     458       15684 :                 move16();
     459             :             }
     460       26077 :             ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FIXED ) )
     461             :             {
     462        7548 :                 hStereoMdct->reverse_dmx = 0; /* Q0 */
     463        7548 :                 move16();
     464             :             }
     465             : 
     466       41761 :             Word16 tmp1, tmp2 = 0;
     467             : 
     468       41761 :             IF( EQ_16( core_r, TCX_10_CORE ) )
     469             :             {
     470        2465 :                 tmp1 = NB_DIV;
     471        2465 :                 move16();
     472             :             }
     473             :             ELSE
     474             :             {
     475       39296 :                 tmp1 = 1;
     476       39296 :                 move16();
     477             :             }
     478             : 
     479       41761 :             IF( EQ_16( core_l, TCX_10_CORE ) )
     480             :             {
     481        2233 :                 tmp2 = NB_DIV;
     482        2233 :                 move16();
     483             :             }
     484             :             ELSE
     485             :             {
     486       39528 :                 tmp2 = 1;
     487       39528 :                 move16();
     488             :             }
     489             : 
     490       41761 :             test();
     491       41761 :             test();
     492       41761 :             IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
     493             :             {
     494       20428 :                 shift = norm_l( nrgRatio );
     495       20428 :                 nrgRatio = L_shl( nrgRatio, shift );                           /* Q26 + shift */
     496       20428 :                 v_multc_fixed( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
     497       20428 :                 Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) );       /* Qx */
     498             : #ifndef OPT_SBA_DEC_PATH
     499             :                 *q_x_ch2 = *q_x_ch2;
     500             :                 move16();
     501             : #endif /* OPT_SBA_DEC_PATH */
     502             :             }
     503       21333 :             ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
     504             :             {
     505        8875 :                 inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
     506        8875 :                 shift = sub( 5, tmp_e );
     507        8875 :                 v_multc_fixed( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
     508        8875 :                 Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) );           /* Qx */
     509             : #ifndef OPT_SBA_DEC_PATH
     510             :                 *q_x_ch1 = *q_x_ch1;
     511             :                 move16();
     512             : #endif /* OPT_SBA_DEC_PATH */
     513             :             }
     514             :         }
     515             :     } /* for k */
     516             : 
     517      122627 :     return;
     518             : }
     519             : 
     520             : 
     521             : /*-------------------------------------------------------------------*
     522             :  * initMdctStereoDecData()
     523             :  *
     524             :  * Initialize MDCT stereo decoder configuration
     525             :  *-------------------------------------------------------------------*/
     526             : 
     527      263997 : void initMdctStereoDecData_fx(
     528             :     STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure         */
     529             :     const Word16 igf,                  /* i  : flag indicating IGF activity               Q0*/
     530             :     const H_IGF_GRID igfGrid,          /* i  : IGF grid configuration                     Q0*/
     531             :     const Word32 element_brate,        /* i  : element bitrate                                    Q0*/
     532             :     const Word16 bwidth                /* i  : audio bandwidth                    Q0*/
     533             : )
     534             : {
     535             :     Word16 tcx_coded_lines;
     536             : 
     537      263997 :     tcx_coded_lines = getNumTcxCodedLines( bwidth );
     538             : 
     539             :     /*Initialize sfb parameteres for TCX20 */
     540      263997 :     stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_20_CORE, element_brate, igf, &igfGrid[IGF_GRID_LB_NORM], &hStereoMdct->stbParamsTCX20.sfbOffset[0], &hStereoMdct->stbParamsTCX20.sfbCnt );
     541             : 
     542             :     /*Initialize sfb parameteres for TCX10 */
     543      263997 :     stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_10_CORE, element_brate, igf, &igfGrid[IGF_GRID_LB_SHORT], &hStereoMdct->stbParamsTCX10.sfbOffset[0], &hStereoMdct->stbParamsTCX10.sfbCnt );
     544             : 
     545             :     /*Initialize sfb parameteres for transition frames */
     546      263997 :     stereo_mdct_init_bands_fx( tcx_coded_lines, -1, element_brate, igf, &igfGrid[IGF_GRID_LB_TRAN], &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
     547             : 
     548      263997 :     IF( igf )
     549             :     {
     550             :         /* calculate the igf start band from the igf start line */
     551      145054 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
     552      145054 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
     553      145054 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
     554             :     }
     555             :     ELSE
     556             :     {
     557      118943 :         hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
     558      118943 :         move16();
     559      118943 :         hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
     560      118943 :         move16();
     561      118943 :         hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
     562      118943 :         move16();
     563      118943 :         hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
     564      118943 :         move16();
     565      118943 :         hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
     566      118943 :         move16();
     567      118943 :         hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
     568      118943 :         move16();
     569             :     }
     570             : 
     571      263997 :     return;
     572             : }
     573             : 
     574             : 
     575             : /*-------------------------------------------------------------------*
     576             :  * initMdctStereoDtxData()
     577             :  *
     578             :  * Allocate and initialize structures for MDCT-Stereo DTX operation
     579             :  *-------------------------------------------------------------------*/
     580             : 
     581          36 : ivas_error initMdctStereoDtxData_fx(
     582             :     CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
     583             : )
     584             : {
     585             :     Word16 ch;
     586             :     ivas_error error;
     587             : 
     588          36 :     error = IVAS_ERR_OK;
     589          36 :     move16();
     590             : 
     591         108 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     592             :     {
     593          72 :         DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
     594             : 
     595          72 :         IF( st->hFdCngDec == NULL )
     596             :         {
     597             :             /* Create FD_CNG instance */
     598           0 :             IF( NE_32( ( error = createFdCngDec_fx( &st->hFdCngDec ) ), IVAS_ERR_OK ) )
     599             :             {
     600           0 :                 return error;
     601             :             }
     602             : 
     603             :             /* Init FD-CNG */
     604           0 :             initFdCngDec_ivas_fx( st, st->cldfbSyn->scale );
     605             :         }
     606             : 
     607          72 :         IF( st->first_CNG == 0 )
     608             :         {
     609          66 :             test();
     610          66 :             IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
     611             :             {
     612          18 :                 st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
     613          18 :                 move16();
     614             :             }
     615             :         }
     616             : 
     617          72 :         IF( st->cldfbAna == NULL )
     618             :         {
     619             :             /* open analysis for max. sampling rate 48kHz */
     620          58 :             IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
     621             :             {
     622           0 :                 return error;
     623             :             }
     624             :         }
     625             : 
     626          72 :         IF( st->cldfbBPF == NULL )
     627             :         {
     628             :             /* open analysis BPF for max. internal sampling rate 16kHz */
     629          58 :             IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
     630             :             {
     631           0 :                 return error;
     632             :             }
     633             :         }
     634             :     }
     635             : 
     636          36 :     return error;
     637             : }
     638             : 
     639             : 
     640             : /*-------------------------------------------------------------------*
     641             :  * synchonize_channels_mdct_sid()
     642             :  *
     643             :  * Synchronize channels in SID frame in MDCT stereo
     644             :  *-------------------------------------------------------------------*/
     645             : 
     646     1012562 : void synchonize_channels_mdct_sid_fx(
     647             :     Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure     */
     648             :     const Word16 n                    /* i  : channel number            Q0*/
     649             : )
     650             : {
     651             :     Decoder_State *st;
     652             : 
     653     1012562 :     st = sts[n];
     654             : 
     655     1012562 :     test();
     656     1012562 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
     657             :     {
     658        1154 :         IF( EQ_16( n, 1 ) )
     659             :         {
     660             :             /* synchronize channels */
     661         577 :             sts[1]->L_frame = sts[0]->L_frame;
     662         577 :             move16();
     663         577 :             sts[1]->cng_type = sts[0]->cng_type;
     664         577 :             move16();
     665         577 :             sts[1]->bwidth = sts[0]->bwidth;
     666         577 :             move16();
     667         577 :             sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
     668         577 :             move16();
     669         577 :             sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
     670         577 :             move16();
     671             : 
     672             :             /* configure when there is a switching from DFT CNG to MDCT CNG */
     673         577 :             test();
     674         577 :             IF( EQ_16( sts[0]->first_CNG, 1 ) && EQ_16( sts[1]->first_CNG, 0 ) )
     675             :             {
     676           0 :                 configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     677             :             }
     678             :         }
     679             : 
     680        1154 :         IF( sts[0]->first_CNG == 0 )
     681             :         {
     682             :             /* configure CNG after reading first side info from SID to get correct values for L_frame and bwidth if first SID is also first valid frame */
     683          60 :             configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     684             :         }
     685             :     }
     686             : 
     687     1012562 :     return;
     688             : }
     689             : 
     690             : 
     691             : /*-------------------------------------------------------------------*
     692             :  * updateBuffersForDmxMdctStereo()
     693             :  *
     694             :  * synch buffers between channels for mono output and
     695             :  * apply passive downmix to certain buffers to enable smooth transitions
     696             :  * between active/inactive coding in MDCT-Stereo DTX
     697             :  *-------------------------------------------------------------------*/
     698             : 
     699             : // helper function
     700             : static void update_exp( Word16 *a_exp, Word16 *b_exp, Word16 *buff_a, Word16 *buff_b, Word16 legth );
     701             : 
     702        3270 : static void update_exp(
     703             :     Word16 *a_exp,
     704             :     Word16 *b_exp,
     705             :     Word16 *buff_a, /* exp(a_exp) */
     706             :     Word16 *buff_b, /* exp(b_exp) */
     707             :     Word16 legth    /* Q0 */
     708             : )
     709             : {
     710        3270 :     Word16 diff = 0;
     711        3270 :     move16();
     712        3270 :     IF( GT_16( *a_exp, *b_exp ) )
     713             :     {
     714        1043 :         diff = sub( *a_exp, *b_exp );
     715      994739 :         FOR( Word16 j = 0; j < legth; j++ )
     716             :         {
     717      993696 :             buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
     718      993696 :             move16();
     719             :         }
     720        1043 :         *b_exp = *a_exp;
     721        1043 :         move16();
     722             :     }
     723        2227 :     ELSE IF( LT_16( *a_exp, *b_exp ) )
     724             :     {
     725          29 :         diff = sub( *b_exp, *a_exp );
     726             : 
     727       14597 :         FOR( Word16 j = 0; j < legth; j++ )
     728             :         {
     729       14568 :             buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
     730       14568 :             move16();
     731             :         }
     732          29 :         *a_exp = *b_exp;
     733          29 :         move16();
     734             :     }
     735        3270 :     return;
     736             : }
     737             : 
     738        1128 : void updateBuffersForDmxMdctStereo_fx(
     739             :     CPE_DEC_HANDLE hCPE,                      /* i/o: CPE handle                              */
     740             :     const Word16 output_frame,                /* i  : output frame length                   Q0*/
     741             :     Word32 output0_fx[],                      /* Qx */
     742             :     Word32 output1_fx[],                      /* Qx */
     743             :     Word16 synth_fx[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis                 qsynth*/
     744             : )
     745             : {
     746             :     Word16 delay_buf_out_len, tcxltp_mem_in_len, delta, i;
     747             :     Decoder_State *sts[CPE_CHANNELS];
     748             : 
     749        1128 :     sts[0] = hCPE->hCoreCoder[0];
     750        1128 :     sts[1] = hCPE->hCoreCoder[1];
     751             : 
     752             :     /* synch buffers for inactive frames, but not for transition frames */
     753        1128 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     754             :     {
     755        1090 :         Copy32( output0_fx, output1_fx, output_frame );
     756        1090 :         Copy( synth_fx[0], synth_fx[1], output_frame );
     757             :     }
     758             : 
     759        1128 :     Word32 Var1 = 0;
     760        1128 :     move16();
     761        1128 :     Word16 diff_sidNoiseEst = 0;
     762        1128 :     move16();
     763        1128 :     Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     764        1128 :     move16();
     765        1128 :     Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     766        1128 :     move16();
     767        1128 :     IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     768             :     {
     769          10 :         diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
     770         250 :         FOR( Word32 j = 0; j < NPART; j++ )
     771             :         {
     772         240 :             sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
     773         240 :             move16();
     774             :         }
     775          10 :         exp_sidNoiseEst1 = exp_sidNoiseEst0;
     776          10 :         move16();
     777             :     }
     778        1118 :     ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     779             :     {
     780          10 :         diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
     781         250 :         FOR( Word32 j = 0; j < NPART; j++ )
     782             :         {
     783         240 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
     784         240 :             move16();
     785             :         }
     786          10 :         exp_sidNoiseEst0 = exp_sidNoiseEst1;
     787          10 :         move16();
     788             :     }
     789        1128 :     sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
     790        1128 :     move16();
     791        1128 :     sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
     792        1128 :     move16();
     793        1128 :     test();
     794        1128 :     test();
     795        1128 :     IF( EQ_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     796             :     {
     797             :         /* in the first SID frame after an active frame, create mid noise shape here, in SID frames that follow inactive frames, it is done directly in the SID decoding since the mid shape is being used in CNG then */
     798         923 :         FOR( Word16 p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ )
     799             :         {
     800         885 :             Var1 = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); // exp_sidNoiseEst0 - 1
     801         885 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = Mpy_32_32( ONE_IN_Q30, Var1 );                                                       //  31 - exp_sidNoiseEst0 - 1 + 31 - 31
     802         885 :             move32();
     803             :         }
     804             :     }
     805             : 
     806             :     /* for transition of active->inactive frame, apply passive downmix on buffers */
     807        1128 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     808             :     {
     809        1090 :         delta = 1;
     810        1090 :         move16();
     811        1090 :         IF( EQ_16( output_frame, L_FRAME16k ) )
     812             :         {
     813         349 :             delta = 2;
     814         349 :             move16();
     815             :         }
     816         741 :         ELSE IF( EQ_16( output_frame, L_FRAME32k ) )
     817             :         {
     818         358 :             delta = 4;
     819         358 :             move16();
     820             :         }
     821         383 :         ELSE IF( EQ_16( output_frame, L_FRAME48k ) )
     822             :         {
     823         383 :             delta = 6;
     824         383 :             move16();
     825             :         }
     826             : 
     827        1090 :         delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP );                  /* Q0 */
     828        1090 :         tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
     829        1090 :         move16();
     830             : 
     831        1090 :         assert( delay_buf_out_len > tcxltp_mem_in_len );
     832             : 
     833        1090 :         Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
     834        1090 :         move16();
     835        1090 :         move16();
     836        1090 :         move16();
     837        1090 :         move16();
     838             : 
     839        1090 :         Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, -11 ); // Q0
     840        1090 :         Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_in_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, -11 ); // Q0
     841             : 
     842        1090 :         Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     843        1090 :         Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     844             : 
     845        1090 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     846        1090 :         move16();
     847        1090 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     848        1090 :         move16();
     849             : 
     850        1090 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     851        1090 :         move16();
     852        1090 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     853        1090 :         move16();
     854             : 
     855             : 
     856        1090 :         Scale_sig( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_in)
     857        1090 :         Scale_sig( &sts[1]->hTcxLtpDec->tcxltp_mem_in[0], TCXLTP_MAX_DELAY, sub( 15, sts[1]->hTcxLtpDec->exp_tcxltp_mem_in ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_in)
     858             : 
     859        1090 :         Scale_sig( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], TCXLTP_MAX_DELAY, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_out)
     860        1090 :         Scale_sig( &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], TCXLTP_MAX_DELAY, sub( 15, sts[1]->hTcxLtpDec->exp_tcxltp_mem_out ) ); // (15 - sts[0]->hTcxLtpDec->exp_tcxltp_mem_in)
     861             : 
     862             : 
     863        1090 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
     864        1090 :                     sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
     865             : 
     866        1090 :         update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
     867        1090 :                     sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
     868             : 
     869        1090 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
     870        1090 :                     sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
     871             : 
     872        9946 :         FOR( i = 0; i < tcxltp_mem_in_len; i++ )
     873             :         {
     874        8856 :             sum_tcx_ltp = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_in[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_in[i], 1 ) ); // exp_tcxltp_mem_in + 1
     875        8856 :             sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp );                                        //  exp_tcxltp_mem_in + 1
     876        8856 :             move16();
     877             : 
     878        8856 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
     879        8856 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     880        8856 :             move16();
     881             : 
     882        8856 :             sum_old_out = add( shr( sts[0]->hHQ_core->old_out_fx[i], 1 ), shr( sts[1]->hHQ_core->old_out_fx[i], 1 ) ); // exp_old_out + 1
     883        8856 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     884        8856 :             move16();
     885             : 
     886        8856 :             sum_tcx_ltp_out = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_out[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_out[i], 1 ) ); // exp_tcxltp_mem_out + 1
     887        8856 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     888        8856 :             move16();
     889             :         }
     890             : 
     891             : 
     892       36514 :         FOR( ; i < delay_buf_out_len; i++ )
     893             :         {
     894       35424 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
     895       35424 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     896       35424 :             move16();
     897             : 
     898       35424 :             sum_old_out = add( shr( sts[0]->hHQ_core->old_out_fx[i], 1 ), shr( sts[1]->hHQ_core->old_out_fx[i], 1 ) ); /* exp_old_out + 1 */
     899       35424 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   /* exp_old_out + 1 */
     900       35424 :             move16();
     901             : 
     902       35424 :             sum_tcx_ltp_out = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_out[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_out[i], 1 ) ); // exp_tcxltp_mem_out + 1
     903       35424 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     904       35424 :             move16();
     905             :         }
     906             : 
     907      665290 :         FOR( ; i < output_frame; i++ )
     908             :         {
     909      664200 :             sum_old_out = add( shr( sts[0]->hHQ_core->old_out_fx[i], 1 ), shr( sts[1]->hHQ_core->old_out_fx[i], 1 ) ); // exp_old_out + 1
     910      664200 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     911      664200 :             move16();
     912             : 
     913      664200 :             sum_tcx_ltp_out = add( shr( sts[0]->hTcxLtpDec->tcxltp_mem_out[i], 1 ), shr( sts[1]->hTcxLtpDec->tcxltp_mem_out[i], 1 ) ); // exp_tcxltp_mem_out + 1
     914      664200 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     915      664200 :             move16();
     916             :         }
     917        1090 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
     918        1090 :         move16();
     919        1090 :         sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
     920        1090 :         move16();
     921        1090 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
     922        1090 :         move16();
     923        1090 :         Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_in[0], &sts[0]->hTcxLtpDec->tcxltp_mem_in_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_in ) ) );    // Q11
     924        1090 :         Copy_Scale_sig_16_32_no_sat( &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], TCXLTP_MAX_DELAY, sub( 11, sub( 15, sts[0]->hTcxLtpDec->exp_tcxltp_mem_out ) ) ); // Q11
     925             :     }
     926             : 
     927        1128 :     return;
     928             : }
     929             : 
     930             : 
     931             : /*-------------------------------------------------------------------*
     932             :  * applyDmxMdctStereo()
     933             :  *
     934             :  * apply passive downmix to certain buffers to enable smooth transitions
     935             :  * between active/inactive coding in MDCT-Stereo DTX
     936             :  *-------------------------------------------------------------------*/
     937             : 
     938        5910 : void applyDmxMdctStereo_fx(
     939             :     const CPE_DEC_HANDLE hCPE,       /* i  : CPE handle                                    */
     940             :     Word32 *output_fx[CPE_CHANNELS], /* i/o: core decoder output          q_out*/
     941             :     const Word16 output_frame        /* i  : output frame length                 Q0*/
     942             : )
     943             : {
     944             :     Word16 crossfade_len, i;
     945             :     Word16 dmx_len;
     946             :     Word32 fade_fx, step_fx;
     947             : 
     948        5910 :     step_fx = ONE_IN_Q31; /* Q31 */
     949        5910 :     move32();
     950        5910 :     fade_fx = ONE_IN_Q31; /* Q31 */
     951        5910 :     move32();
     952        5910 :     dmx_len = output_frame; /* Q0 */
     953        5910 :     move16();
     954             : 
     955        5910 :     test();
     956        5910 :     test();
     957        5910 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     958             :     {
     959          34 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
     960          34 :         move16();
     961          34 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
     962             :         {
     963          14 :             case 48000:
     964          14 :                 step_fx = 22369622; /* 0.0104 in Q31 */
     965          14 :                 move32();
     966          14 :                 BREAK;
     967          12 :             case 32000:
     968          12 :                 step_fx = 33554432; /* 0.0156 in Q31 */
     969          12 :                 move32();
     970          12 :                 BREAK;
     971           8 :             case 16000:
     972           8 :                 step_fx = 67108864; /* 0.0312 in Q31 */
     973           8 :                 move32();
     974           8 :                 BREAK;
     975           0 :             default:
     976           0 :                 assert( 0 );
     977             :                 BREAK;
     978             :         }
     979             :     }
     980             :     /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */
     981        5876 :     ELSE IF( LE_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     982             :     {
     983          38 :         crossfade_len = shr( output_frame, 2 ); /* Q0 */
     984          38 :         SWITCH( output_frame )
     985             :         {
     986          16 :             case 960:
     987          16 :                 step_fx = -8947849; /* -0.0041 in Q31 */
     988          16 :                 move32();
     989          16 :                 BREAK;
     990          13 :             case 640:
     991          13 :                 step_fx = -13421773; /* -0.00625 in Q31 */
     992          13 :                 move32();
     993          13 :                 BREAK;
     994           9 :             case 320:
     995           9 :                 step_fx = -26843546; /* -0.0125 in Q31 */
     996           9 :                 move32();
     997           9 :                 BREAK;
     998             :         }
     999          38 :         fade_fx = 0;
    1000          38 :         move32();
    1001          38 :         dmx_len = crossfade_len; /* Q0 */
    1002          38 :         move16();
    1003             :     }
    1004        5838 :     ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
    1005             :     {
    1006          15 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
    1007          15 :         move16();
    1008          15 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
    1009             :         {
    1010          15 :             case 48000:
    1011          15 :                 step_fx = 35791396; /* 0.0166 in Q31 */
    1012          15 :                 move32();
    1013          15 :                 BREAK;
    1014           0 :             case 32000:
    1015           0 :                 step_fx = 53687092; /* 0.025 in Q31 */
    1016           0 :                 move32();
    1017           0 :                 BREAK;
    1018           0 :             case 16000:
    1019           0 :                 step_fx = 107374184; /* 0.05 in Q31 */
    1020           0 :                 move32();
    1021           0 :                 BREAK;
    1022           0 :             default:
    1023           0 :                 assert( 0 );
    1024             :                 BREAK;
    1025             :         }
    1026             :     }
    1027             :     ELSE
    1028             :     {
    1029        5823 :         crossfade_len = 0;
    1030        5823 :         move16();
    1031             :     }
    1032             : 
    1033             :     /* apply crossfade */
    1034       15818 :     FOR( i = 0; i < crossfade_len; i++ )
    1035             :     {
    1036        9908 :         Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx );                                                                                   /* q_out */
    1037        9908 :         Word32 temp_2 = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), Mpy_32_32( INV_SQRT2_FX, L_sub_sat( ONE_IN_Q31, fade_fx ) ) ); /* q_out */
    1038        9908 :         output_fx[0][i] = L_add( temp_1, temp_2 );                                                                                               /* q_out */
    1039        9908 :         move32();
    1040        9908 :         fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
    1041             :     }
    1042             : 
    1043             :     /* apply passive downmix on all-active-frame part */
    1044     4595602 :     FOR( ; i < dmx_len; i++ )
    1045             :     {
    1046     4589692 :         output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
    1047     4589692 :         move32();
    1048             :     }
    1049             : 
    1050        5910 :     return;
    1051             : }

Generated by: LCOV version 1.14