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 @ e70d960493906e094628337ac73d3c408863a5e6 Lines: 439 461 95.2 %
Date: 2025-09-17 02:22:58 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      169717 : 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      169717 :     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      130891 :         test();
      80      130891 :         IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
      81             :         {
      82        3329 :             nSubframes = NB_DIV; /* Q0 */
      83        3329 :             move16();
      84             :         }
      85             :         ELSE
      86             :         {
      87      127562 :             nSubframes = 1; /* Q0 */
      88      127562 :             move16();
      89             :         }
      90      130891 :         move16();
      91             :         // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
      92      130891 :         IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
      93             :         {
      94      127754 :             sfbConf = &hStereoMdct->stbParamsTCX20;
      95             :         }
      96             :         ELSE
      97             :         {
      98        3137 :             sfbConf = &hStereoMdct->stbParamsTCX10;
      99             :         }
     100      130891 :         if ( sts[0]->last_core_from_bs == ACELP_CORE )
     101             :         {
     102         620 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     103             :         }
     104             : 
     105      130891 :         IF( hStereoMdct->use_itd )
     106             :         {
     107             :             Word16 I;
     108             : 
     109       11587 :             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       11587 :             hStereoMdct->itd_fx = 0;
     113       11587 :             move32();
     114       11587 :             IF( hStereoMdct->itd_mode )
     115             :             {
     116        3503 :                 /*(*nb_bits) += */ read_itd( st0, &I );
     117        3503 :                 stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
     118             :             }
     119             :         }
     120             : 
     121      265111 :         FOR( k = 0; k < nSubframes; k++ )
     122             :         {
     123      134220 :             mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     124      134220 :             IF( mdct_stereo_mode )
     125             :             {
     126      130501 :                 mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     127             :             }
     128      134220 :             SWITCH( mdct_stereo_mode )
     129             :             {
     130        3719 :                 case 0:
     131        3719 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
     132        3719 :                     move16();
     133        3719 :                     BREAK;
     134       82193 :                 case 1:
     135       82193 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
     136       82193 :                     move16();
     137       82193 :                     BREAK;
     138       48308 :                 case 2:
     139       48308 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
     140       48308 :                     move16();
     141       48308 :                     BREAK;
     142           0 :                 default:
     143           0 :                     assert( !"Not supported stereo mode\n" );
     144             :             }
     145             : 
     146      134220 :             IF( !mct_on )
     147             :             {
     148       43208 :                 test();
     149       43208 :                 IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
     150             :                 {
     151       42947 :                     hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
     152       42947 :                     move16();
     153       42947 :                     assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
     154             :                 }
     155             :                 ELSE
     156             :                 {
     157         261 :                     hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
     158         261 :                     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      134220 :             IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
     164             :             {
     165       82193 :                 set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
     166             :             }
     167             :             ELSE
     168             :             {
     169       52027 :                 set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
     170             :             }
     171             : 
     172      134220 :             IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
     173             :             {
     174     2011027 :                 FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
     175             :                 {
     176     1962719 :                     ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     177     1962719 :                     move16();
     178             :                 }
     179             :             }
     180             : 
     181      134220 :             IF( st0->igf )
     182             :             {
     183       88664 :                 mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
     184       88664 :                 IF( mdct_stereo_mode )
     185             :                 {
     186       53963 :                     mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     187             :                 }
     188             : 
     189       88664 :                 SWITCH( mdct_stereo_mode )
     190             :                 {
     191       34701 :                     case 0:
     192       34701 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     193       34701 :                         move16();
     194       34701 :                         BREAK;
     195       39953 :                     case 1:
     196       39953 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
     197       39953 :                         move16();
     198       39953 :                         BREAK;
     199       14010 :                     case 2:
     200       14010 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
     201       14010 :                         move16();
     202       14010 :                         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       88664 :                 IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
     209             :                 {
     210       39953 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     211             :                 }
     212             :                 ELSE
     213             :                 {
     214       48711 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     215             :                 }
     216             : 
     217       88664 :                 IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     218             :                 {
     219       88433 :                     FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
     220             :                     {
     221       74423 :                         ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     222       74423 :                         move16();
     223             :                     }
     224             :                 }
     225             :             }
     226             :             ELSE
     227             :             {
     228       45556 :                 hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     229       45556 :                 move16();
     230             :             }
     231             :         }
     232             :     }
     233             : 
     234      169717 :     IF( !mct_on )
     235             :     {
     236       80649 :         hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels   Q0*/
     237       80649 :         move16();
     238       80649 :         hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
     239             : 
     240       80649 :         assert( GT_16( hStereoMdct->split_ratio, 0 ) );
     241             :     }
     242             : 
     243             : 
     244      169717 :     return;
     245             : }
     246             : 
     247             : 
     248             : /*-------------------------------------------------------------------*
     249             :  * inverseBwMS()
     250             :  *
     251             :  * Band-wise M/S stereo processing
     252             :  *-------------------------------------------------------------------*/
     253     1406246 : 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    77184936 :     FOR( j = startLine; j < stopLine; j++ )
     265             :     {
     266    75778690 :         tmpValue = x0[j];
     267    75778690 :         move32();
     268    75778690 :         x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
     269    75778690 :         move32();
     270    75778690 :         x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
     271    75778690 :         move32();
     272             :     }
     273             : 
     274     1406246 :     return;
     275             : }
     276             : 
     277             : 
     278             : /*-------------------------------------------------------------------*
     279             :  * inverseMS()
     280             :  *
     281             :  * M/S stereo processing
     282             :  *-------------------------------------------------------------------*/
     283      167940 : 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      167940 :     inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
     291             : 
     292      167940 :     return;
     293             : }
     294             : 
     295             : 
     296             : /*-------------------------------------------------------------------*
     297             :  * stereo_decoder_tcx()
     298             :  *
     299             :  * apply stereo processing (inverse MS and global ILD)
     300             :  *-------------------------------------------------------------------*/
     301      131655 : 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             : )
     318             : {
     319             :     Word16 i, k, sfb, nSubframes;
     320      131655 :     STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
     321             :     Word32 nrgRatio, inv_nrgRatio, tmp_32;
     322             :     Word16 tmp_e, shift;
     323             : 
     324      131655 :     nSubframes = 2;
     325      131655 :     move16();
     326      131655 :     test();
     327      131655 :     test();
     328      131655 :     if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
     329             :     {
     330      128321 :         nSubframes = 1; /* Q0 */
     331      128321 :         move16();
     332             :     }
     333             : 
     334      266644 :     FOR( k = 0; k < nSubframes; k++ )
     335             :     {
     336             :         // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     337      134989 :         IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
     338             :         {
     339      128706 :             sfbConf = &hStereoMdct->stbParamsTCX20;
     340             :         }
     341             :         ELSE
     342             :         {
     343        6283 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     344             :         }
     345             : 
     346      134989 :         test();
     347      134989 :         if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
     348             :         {
     349         630 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     350             :         }
     351             : 
     352      134989 :         IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
     353             :         {
     354    45130871 :             FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
     355             :             {
     356    45048316 :                 IF( EQ_32( spec_r_0[k][i], 0 ) )
     357             :                 {
     358    12320425 :                     spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     359    12320425 :                     move32();
     360             :                 }
     361             :             }
     362       82555 :             inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
     363             :         }
     364       52434 :         ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
     365             :         {
     366     2025627 :             FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
     367             :             {
     368     1976955 :                 IF( ms_mask[k][sfb] )
     369             :                 {
     370    17164018 :                     FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     371             :                     {
     372    15965280 :                         IF( EQ_32( spec_r_0[k][i], 0 ) )
     373             :                         {
     374     4496455 :                             spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     375     4496455 :                             move32();
     376             :                         }
     377             :                     }
     378     1198738 :                     inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
     379             :                 }
     380             :             }
     381             :         }
     382             : 
     383      134989 :         IF( igf )
     384             :         {
     385       89072 :             IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
     386             :             {
     387    12144590 :                 FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
     388             :                 {
     389    12104538 :                     IF( EQ_32( spec_r_0[k][i], 0 ) )
     390             :                     {
     391     3755101 :                         spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     392     3755101 :                         move32();
     393             :                     }
     394             :                 }
     395       40052 :                 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 );
     396             :             }
     397       49020 :             ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     398             :             {
     399       88748 :                 FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
     400             :                 {
     401       74696 :                     IF( ms_mask[k][sfb] )
     402             :                     {
     403     1972014 :                         FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     404             :                         {
     405     1932446 :                             IF( EQ_32( spec_r_0[k][i], 0 ) )
     406             :                             {
     407      679173 :                                 spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FIXED ); /* Qx */
     408      679173 :                                 move32();
     409             :                             }
     410             :                         }
     411       39568 :                         inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FIXED );
     412             :                     }
     413             :                 }
     414             :             }
     415             :         }
     416             : 
     417      134989 :         IF( !mct_on )
     418             :         {
     419       43977 :             tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
     420       43977 :             tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
     421       43977 :             nrgRatio = L_sub( tmp_32, ONE_IN_Q26 );                                   // Q26
     422             : 
     423       43977 :             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
     424       43977 :             move32();
     425             :             /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
     426       43977 :             IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FIXED ) )
     427             :             {
     428       16467 :                 hStereoMdct->reverse_dmx = 1; /* Q0 */
     429       16467 :                 move16();
     430             :             }
     431       27510 :             ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FIXED ) )
     432             :             {
     433        7877 :                 hStereoMdct->reverse_dmx = 0; /* Q0 */
     434        7877 :                 move16();
     435             :             }
     436             : 
     437       43977 :             Word16 tmp1, tmp2 = 0;
     438             : 
     439       43977 :             IF( EQ_16( core_r, TCX_10_CORE ) )
     440             :             {
     441        2645 :                 tmp1 = NB_DIV;
     442        2645 :                 move16();
     443             :             }
     444             :             ELSE
     445             :             {
     446       41332 :                 tmp1 = 1;
     447       41332 :                 move16();
     448             :             }
     449             : 
     450       43977 :             IF( EQ_16( core_l, TCX_10_CORE ) )
     451             :             {
     452        2395 :                 tmp2 = NB_DIV;
     453        2395 :                 move16();
     454             :             }
     455             :             ELSE
     456             :             {
     457       41582 :                 tmp2 = 1;
     458       41582 :                 move16();
     459             :             }
     460             : 
     461       43977 :             test();
     462       43977 :             test();
     463       43977 :             IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
     464             :             {
     465       21508 :                 shift = norm_l( nrgRatio );
     466       21508 :                 nrgRatio = L_shl( nrgRatio, shift );                           /* Q26 + shift */
     467       21508 :                 v_multc_fixed( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
     468       21508 :                 Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) );       /* Qx */
     469             :             }
     470       22469 :             ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
     471             :             {
     472        9310 :                 inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
     473        9310 :                 shift = sub( 5, tmp_e );
     474        9310 :                 v_multc_fixed( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
     475        9310 :                 Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) );           /* Qx */
     476             :             }
     477             :         }
     478             :     } /* for k */
     479             : 
     480      131655 :     return;
     481             : }
     482             : 
     483             : 
     484             : /*-------------------------------------------------------------------*
     485             :  * initMdctStereoDecData()
     486             :  *
     487             :  * Initialize MDCT stereo decoder configuration
     488             :  *-------------------------------------------------------------------*/
     489             : 
     490      288370 : void initMdctStereoDecData_fx(
     491             :     STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure         */
     492             :     const Word16 igf,                  /* i  : flag indicating IGF activity               Q0*/
     493             :     const H_IGF_GRID igfGrid,          /* i  : IGF grid configuration                     Q0*/
     494             :     const Word32 element_brate,        /* i  : element bitrate                                    Q0*/
     495             :     const Word16 bwidth                /* i  : audio bandwidth                    Q0*/
     496             : )
     497             : {
     498             :     Word16 tcx_coded_lines;
     499             : 
     500      288370 :     tcx_coded_lines = getNumTcxCodedLines( bwidth );
     501             : 
     502             :     /*Initialize sfb parameteres for TCX20 */
     503      288370 :     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 );
     504             : 
     505             :     /*Initialize sfb parameteres for TCX10 */
     506      288370 :     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 );
     507             : 
     508             :     /*Initialize sfb parameteres for transition frames */
     509      288370 :     stereo_mdct_init_bands_fx( tcx_coded_lines, -1, element_brate, igf, &igfGrid[IGF_GRID_LB_TRAN], &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
     510             : 
     511      288370 :     IF( igf )
     512             :     {
     513             :         /* calculate the igf start band from the igf start line */
     514      159342 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
     515      159342 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
     516      159342 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
     517             :     }
     518             :     ELSE
     519             :     {
     520      129028 :         hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
     521      129028 :         move16();
     522      129028 :         hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
     523      129028 :         move16();
     524      129028 :         hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
     525      129028 :         move16();
     526      129028 :         hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
     527      129028 :         move16();
     528      129028 :         hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
     529      129028 :         move16();
     530      129028 :         hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
     531      129028 :         move16();
     532             :     }
     533             : 
     534      288370 :     return;
     535             : }
     536             : 
     537             : 
     538             : /*-------------------------------------------------------------------*
     539             :  * initMdctStereoDtxData()
     540             :  *
     541             :  * Allocate and initialize structures for MDCT-Stereo DTX operation
     542             :  *-------------------------------------------------------------------*/
     543             : 
     544          31 : ivas_error initMdctStereoDtxData_fx(
     545             :     CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
     546             : )
     547             : {
     548             :     Word16 ch;
     549             :     ivas_error error;
     550             : 
     551          31 :     error = IVAS_ERR_OK;
     552          31 :     move16();
     553             : 
     554          93 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     555             :     {
     556          62 :         DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
     557             : 
     558          62 :         IF( st->hFdCngDec == NULL )
     559             :         {
     560             :             /* Create FD_CNG instance */
     561           0 :             IF( NE_32( ( error = createFdCngDec_fx( &st->hFdCngDec ) ), IVAS_ERR_OK ) )
     562             :             {
     563           0 :                 return error;
     564             :             }
     565             : 
     566             :             /* Init FD-CNG */
     567           0 :             initFdCngDec_ivas_fx( st, st->cldfbSyn->scale );
     568             :         }
     569             : 
     570          62 :         IF( st->first_CNG == 0 )
     571             :         {
     572          58 :             test();
     573          58 :             IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
     574             :             {
     575          17 :                 st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
     576          17 :                 move16();
     577             :             }
     578             :         }
     579             : 
     580          62 :         IF( st->cldfbAna == NULL )
     581             :         {
     582             :             /* open analysis for max. sampling rate 48kHz */
     583          50 :             IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
     584             :             {
     585           0 :                 return error;
     586             :             }
     587             :         }
     588             : 
     589          62 :         IF( st->cldfbBPF == NULL )
     590             :         {
     591             :             /* open analysis BPF for max. internal sampling rate 16kHz */
     592          50 :             IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
     593             :             {
     594           0 :                 return error;
     595             :             }
     596             :         }
     597             :     }
     598             : 
     599          31 :     return error;
     600             : }
     601             : 
     602             : 
     603             : /*-------------------------------------------------------------------*
     604             :  * synchonize_channels_mdct_sid()
     605             :  *
     606             :  * Synchronize channels in SID frame in MDCT stereo
     607             :  *-------------------------------------------------------------------*/
     608             : 
     609     1066221 : void synchonize_channels_mdct_sid_fx(
     610             :     Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure     */
     611             :     const Word16 n                    /* i  : channel number            Q0*/
     612             : )
     613             : {
     614             :     Decoder_State *st;
     615             : 
     616     1066221 :     st = sts[n];
     617             : 
     618     1066221 :     test();
     619     1066221 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
     620             :     {
     621         912 :         IF( EQ_16( n, 1 ) )
     622             :         {
     623             :             /* synchronize channels */
     624         456 :             sts[1]->L_frame = sts[0]->L_frame;
     625         456 :             move16();
     626         456 :             sts[1]->cng_type = sts[0]->cng_type;
     627         456 :             move16();
     628         456 :             sts[1]->bwidth = sts[0]->bwidth;
     629         456 :             move16();
     630         456 :             sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
     631         456 :             move16();
     632         456 :             sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
     633         456 :             move16();
     634             : 
     635             :             /* configure when there is a switching from DFT CNG to MDCT CNG */
     636         456 :             test();
     637         456 :             IF( EQ_16( sts[0]->first_CNG, 1 ) && EQ_16( sts[1]->first_CNG, 0 ) )
     638             :             {
     639           0 :                 configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     640             :             }
     641             :         }
     642             : 
     643         912 :         IF( sts[0]->first_CNG == 0 )
     644             :         {
     645             :             /* 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 */
     646          58 :             configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     647             :         }
     648             :     }
     649             : 
     650     1066221 :     return;
     651             : }
     652             : 
     653             : 
     654             : /*-------------------------------------------------------------------*
     655             :  * updateBuffersForDmxMdctStereo()
     656             :  *
     657             :  * synch buffers between channels for mono output and
     658             :  * apply passive downmix to certain buffers to enable smooth transitions
     659             :  * between active/inactive coding in MDCT-Stereo DTX
     660             :  *-------------------------------------------------------------------*/
     661             : 
     662             : // helper function
     663             : static void update_exp( Word16 *a_exp, Word16 *b_exp, Word16 *buff_a, Word16 *buff_b, Word16 legth );
     664             : 
     665        3273 : static void update_exp(
     666             :     Word16 *a_exp,
     667             :     Word16 *b_exp,
     668             :     Word16 *buff_a, /* exp(a_exp) */
     669             :     Word16 *buff_b, /* exp(b_exp) */
     670             :     Word16 legth    /* Q0 */
     671             : )
     672             : {
     673        3273 :     Word16 diff = 0;
     674        3273 :     move16();
     675        3273 :     IF( GT_16( *a_exp, *b_exp ) )
     676             :     {
     677        1036 :         diff = sub( *a_exp, *b_exp );
     678      988012 :         FOR( Word16 j = 0; j < legth; j++ )
     679             :         {
     680      986976 :             buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
     681      986976 :             move16();
     682             :         }
     683        1036 :         *b_exp = *a_exp;
     684        1036 :         move16();
     685             :     }
     686        2237 :     ELSE IF( LT_16( *a_exp, *b_exp ) )
     687             :     {
     688          34 :         diff = sub( *b_exp, *a_exp );
     689             : 
     690       18454 :         FOR( Word16 j = 0; j < legth; j++ )
     691             :         {
     692       18420 :             buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
     693       18420 :             move16();
     694             :         }
     695          34 :         *a_exp = *b_exp;
     696          34 :         move16();
     697             :     }
     698        3273 :     return;
     699             : }
     700             : 
     701        1129 : void updateBuffersForDmxMdctStereo_fx(
     702             :     CPE_DEC_HANDLE hCPE,                      /* i/o: CPE handle                              */
     703             :     const Word16 output_frame,                /* i  : output frame length                   Q0*/
     704             :     Word32 output0_fx[],                      /* Qx */
     705             :     Word32 output1_fx[],                      /* Qx */
     706             :     Word16 synth_fx[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis                 qsynth*/
     707             : )
     708             : {
     709             :     Word16 delay_buf_out_len, tcxltp_mem_in_len, delta, i;
     710             :     Decoder_State *sts[CPE_CHANNELS];
     711             : 
     712        1129 :     sts[0] = hCPE->hCoreCoder[0];
     713        1129 :     sts[1] = hCPE->hCoreCoder[1];
     714             : 
     715             :     /* synch buffers for inactive frames, but not for transition frames */
     716        1129 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     717             :     {
     718        1091 :         Copy32( output0_fx, output1_fx, output_frame );
     719        1091 :         Copy( synth_fx[0], synth_fx[1], output_frame );
     720             :     }
     721             : 
     722        1129 :     Word32 Var1 = 0;
     723        1129 :     move16();
     724        1129 :     Word16 diff_sidNoiseEst = 0;
     725        1129 :     move16();
     726        1129 :     Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     727        1129 :     move16();
     728        1129 :     Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     729        1129 :     move16();
     730        1129 :     IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     731             :     {
     732          14 :         diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
     733         350 :         FOR( Word32 j = 0; j < NPART; j++ )
     734             :         {
     735         336 :             sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
     736         336 :             move16();
     737             :         }
     738          14 :         exp_sidNoiseEst1 = exp_sidNoiseEst0;
     739          14 :         move16();
     740             :     }
     741        1115 :     ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     742             :     {
     743           9 :         diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
     744         225 :         FOR( Word32 j = 0; j < NPART; j++ )
     745             :         {
     746         216 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
     747         216 :             move16();
     748             :         }
     749           9 :         exp_sidNoiseEst0 = exp_sidNoiseEst1;
     750           9 :         move16();
     751             :     }
     752        1129 :     sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
     753        1129 :     move16();
     754        1129 :     sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
     755        1129 :     move16();
     756        1129 :     test();
     757        1129 :     test();
     758        1129 :     IF( EQ_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     759             :     {
     760             :         /* 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 */
     761         923 :         FOR( Word16 p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ )
     762             :         {
     763         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
     764         885 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = Mpy_32_32( ONE_IN_Q30, Var1 );                                                       //  31 - exp_sidNoiseEst0 - 1 + 31 - 31
     765         885 :             move32();
     766             :         }
     767             :     }
     768             : 
     769             :     /* for transition of active->inactive frame, apply passive downmix on buffers */
     770        1129 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     771             :     {
     772        1091 :         delta = 1;
     773        1091 :         move16();
     774        1091 :         IF( EQ_16( output_frame, L_FRAME16k ) )
     775             :         {
     776         350 :             delta = 2;
     777         350 :             move16();
     778             :         }
     779         741 :         ELSE IF( EQ_16( output_frame, L_FRAME32k ) )
     780             :         {
     781         358 :             delta = 4;
     782         358 :             move16();
     783             :         }
     784         383 :         ELSE IF( EQ_16( output_frame, L_FRAME48k ) )
     785             :         {
     786         383 :             delta = 6;
     787         383 :             move16();
     788             :         }
     789             : 
     790        1091 :         delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP );                  /* Q0 */
     791        1091 :         tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
     792        1091 :         move16();
     793             : 
     794        1091 :         assert( delay_buf_out_len > tcxltp_mem_in_len );
     795             : 
     796        1091 :         Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
     797        1091 :         move16();
     798        1091 :         move16();
     799        1091 :         move16();
     800        1091 :         move16();
     801             : 
     802        1091 :         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
     803        1091 :         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
     804             : 
     805        1091 :         Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     806        1091 :         Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     807             : 
     808        1091 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     809        1091 :         move16();
     810        1091 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     811        1091 :         move16();
     812             : 
     813        1091 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     814        1091 :         move16();
     815        1091 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     816        1091 :         move16();
     817             : 
     818             : 
     819        1091 :         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)
     820        1091 :         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)
     821             : 
     822        1091 :         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)
     823        1091 :         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)
     824             : 
     825             : 
     826        1091 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
     827        1091 :                     sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
     828             : 
     829        1091 :         update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
     830        1091 :                     sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
     831             : 
     832        1091 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
     833        1091 :                     sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
     834             : 
     835        9951 :         FOR( i = 0; i < tcxltp_mem_in_len; i++ )
     836             :         {
     837        8860 :             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
     838        8860 :             sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp );                                        //  exp_tcxltp_mem_in + 1
     839        8860 :             move16();
     840             : 
     841        8860 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
     842        8860 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     843        8860 :             move16();
     844             : 
     845        8860 :             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
     846        8860 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     847        8860 :             move16();
     848             : 
     849        8860 :             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
     850        8860 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     851        8860 :             move16();
     852             :         }
     853             : 
     854             : 
     855       36531 :         FOR( ; i < delay_buf_out_len; i++ )
     856             :         {
     857       35440 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
     858       35440 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     859       35440 :             move16();
     860             : 
     861       35440 :             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 */
     862       35440 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   /* exp_old_out + 1 */
     863       35440 :             move16();
     864             : 
     865       35440 :             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
     866       35440 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     867       35440 :             move16();
     868             :         }
     869             : 
     870      665591 :         FOR( ; i < output_frame; i++ )
     871             :         {
     872      664500 :             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
     873      664500 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     874      664500 :             move16();
     875             : 
     876      664500 :             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
     877      664500 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     878      664500 :             move16();
     879             :         }
     880        1091 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
     881        1091 :         move16();
     882        1091 :         sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
     883        1091 :         move16();
     884        1091 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
     885        1091 :         move16();
     886        1091 :         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
     887        1091 :         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
     888             :     }
     889             : 
     890        1129 :     return;
     891             : }
     892             : 
     893             : 
     894             : /*-------------------------------------------------------------------*
     895             :  * applyDmxMdctStereo()
     896             :  *
     897             :  * apply passive downmix to certain buffers to enable smooth transitions
     898             :  * between active/inactive coding in MDCT-Stereo DTX
     899             :  *-------------------------------------------------------------------*/
     900             : 
     901        5909 : void applyDmxMdctStereo_fx(
     902             :     const CPE_DEC_HANDLE hCPE,       /* i  : CPE handle                                    */
     903             :     Word32 *output_fx[CPE_CHANNELS], /* i/o: core decoder output          q_out*/
     904             :     const Word16 output_frame        /* i  : output frame length                 Q0*/
     905             : )
     906             : {
     907             :     Word16 crossfade_len, i;
     908             :     Word16 dmx_len;
     909             :     Word32 fade_fx, step_fx;
     910             : 
     911        5909 :     step_fx = ONE_IN_Q31; /* Q31 */
     912        5909 :     move32();
     913        5909 :     fade_fx = ONE_IN_Q31; /* Q31 */
     914        5909 :     move32();
     915        5909 :     dmx_len = output_frame; /* Q0 */
     916        5909 :     move16();
     917             : 
     918        5909 :     test();
     919        5909 :     test();
     920        5909 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     921             :     {
     922          34 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
     923          34 :         move16();
     924          34 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
     925             :         {
     926          14 :             case 48000:
     927          14 :                 step_fx = 22369622; /* 0.0104 in Q31 */
     928          14 :                 move32();
     929          14 :                 BREAK;
     930          12 :             case 32000:
     931          12 :                 step_fx = 33554432; /* 0.0156 in Q31 */
     932          12 :                 move32();
     933          12 :                 BREAK;
     934           8 :             case 16000:
     935           8 :                 step_fx = 67108864; /* 0.0312 in Q31 */
     936           8 :                 move32();
     937           8 :                 BREAK;
     938           0 :             default:
     939           0 :                 assert( 0 );
     940             :                 BREAK;
     941             :         }
     942             :     }
     943             :     /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */
     944        5875 :     ELSE IF( LE_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     945             :     {
     946          38 :         crossfade_len = shr( output_frame, 2 ); /* Q0 */
     947          38 :         SWITCH( output_frame )
     948             :         {
     949          16 :             case 960:
     950          16 :                 step_fx = -8947849; /* -0.0041 in Q31 */
     951          16 :                 move32();
     952          16 :                 BREAK;
     953          13 :             case 640:
     954          13 :                 step_fx = -13421773; /* -0.00625 in Q31 */
     955          13 :                 move32();
     956          13 :                 BREAK;
     957           9 :             case 320:
     958           9 :                 step_fx = -26843546; /* -0.0125 in Q31 */
     959           9 :                 move32();
     960           9 :                 BREAK;
     961             :         }
     962          38 :         fade_fx = 0;
     963          38 :         move32();
     964          38 :         dmx_len = crossfade_len; /* Q0 */
     965          38 :         move16();
     966             :     }
     967        5837 :     ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
     968             :     {
     969          15 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
     970          15 :         move16();
     971          15 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
     972             :         {
     973          15 :             case 48000:
     974          15 :                 step_fx = 35791396; /* 0.0166 in Q31 */
     975          15 :                 move32();
     976          15 :                 BREAK;
     977           0 :             case 32000:
     978           0 :                 step_fx = 53687092; /* 0.025 in Q31 */
     979           0 :                 move32();
     980           0 :                 BREAK;
     981           0 :             case 16000:
     982           0 :                 step_fx = 107374184; /* 0.05 in Q31 */
     983           0 :                 move32();
     984           0 :                 BREAK;
     985           0 :             default:
     986           0 :                 assert( 0 );
     987             :                 BREAK;
     988             :         }
     989             :     }
     990             :     ELSE
     991             :     {
     992        5822 :         crossfade_len = 0;
     993        5822 :         move16();
     994             :     }
     995             : 
     996             :     /* apply crossfade */
     997       15817 :     FOR( i = 0; i < crossfade_len; i++ )
     998             :     {
     999        9908 :         Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx );                                                                                   /* q_out */
    1000        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 */
    1001        9908 :         output_fx[0][i] = L_add( temp_1, temp_2 );                                                                                               /* q_out */
    1002        9908 :         move32();
    1003        9908 :         fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
    1004             :     }
    1005             : 
    1006             :     /* apply passive downmix on all-active-frame part */
    1007     4595281 :     FOR( ; i < dmx_len; i++ )
    1008             :     {
    1009     4589372 :         output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
    1010     4589372 :         move32();
    1011             :     }
    1012             : 
    1013        5909 :     return;
    1014             : }

Generated by: LCOV version 1.14