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 @ b8e0d5b93229a45388410f93fd14fda7bdd8ab4a Lines: 439 461 95.2 %
Date: 2025-11-08 02:37:03 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             : /*-------------------------------------------------------------------*
      52             :  * Local constants
      53             :  *-------------------------------------------------------------------*/
      54             : 
      55             : #define NF_RED_FAC_FX  1610612736 // Q31
      56             : #define POINT_8_FX     1717986918 // Q31
      57             : #define POINT_2_FX     429496730  // Q31
      58             : #define ONE_POINT_3_FX 87241523   // Q26
      59             : #define POINT_9_FX     60397978   // Q26
      60             : 
      61             : 
      62             : /*-------------------------------------------------------------------*
      63             :  * parse_stereo_from_bitstream
      64             :  *
      65             :  *
      66             :  *-------------------------------------------------------------------*/
      67             : 
      68      201168 : void parse_stereo_from_bitstream(
      69             :     STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure                */
      70             :     Decoder_State **sts,                     /* i/o: decoder state structure                      */
      71             :     const Word16 mct_on,                     /* i  : flag mct block (1) or stereo (0)   Q0*/
      72             :     const Word16 isSBAStereoMode,            /* i  : flag core coding for SBA                   Q0*/
      73             :     Decoder_State *st0,                      /* i/o: decoder state structure for Bstr     */
      74             :     Word16 ms_mask[NB_DIV][MAX_SFB]          /* o  : bandwise MS mask                                   Q0*/
      75             : )
      76             : {
      77             :     Word16 i, k, nSubframes, mdct_stereo_mode;
      78             :     STEREO_MDCT_BAND_PARAMETERS *sfbConf;
      79             : 
      80      201168 :     IF( !isSBAStereoMode )
      81             :     {
      82             :         // nSubframes = ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) ? NB_DIV : 1;
      83      162170 :         test();
      84      162170 :         IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
      85             :         {
      86        4099 :             nSubframes = NB_DIV; /* Q0 */
      87        4099 :             move16();
      88             :         }
      89             :         ELSE
      90             :         {
      91      158071 :             nSubframes = 1; /* Q0 */
      92      158071 :             move16();
      93             :         }
      94      162170 :         move16();
      95             :         // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
      96      162170 :         IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
      97             :         {
      98      158283 :             sfbConf = &hStereoMdct->stbParamsTCX20;
      99             :         }
     100             :         ELSE
     101             :         {
     102        3887 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     103             :         }
     104      162170 :         if ( sts[0]->last_core_from_bs == ACELP_CORE )
     105             :         {
     106        1342 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     107             :         }
     108             : 
     109      162170 :         IF( hStereoMdct->use_itd )
     110             :         {
     111             :             Word16 I;
     112             : 
     113       11461 :             hStereoMdct->itd_mode = extract_l( get_next_indice_fx( st0, STEREO_DFT_ITD_MODE_NBITS ) ); /* Q0 */
     114             :             /*(*nb_bits) += STEREO_DFT_ITD_MODE_NBITS;*/                                               /*ITD mode flag: 1bit*/
     115             : 
     116       11461 :             hStereoMdct->itd_fx = 0;
     117       11461 :             move32();
     118       11461 :             IF( hStereoMdct->itd_mode )
     119             :             {
     120        3467 :                 /*(*nb_bits) += */ read_itd( st0, &I );
     121        3467 :                 stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
     122             :             }
     123             :         }
     124             : 
     125      328439 :         FOR( k = 0; k < nSubframes; k++ )
     126             :         {
     127      166269 :             mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     128      166269 :             IF( mdct_stereo_mode )
     129             :             {
     130      160580 :                 mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     131             :             }
     132      166269 :             SWITCH( mdct_stereo_mode )
     133             :             {
     134        5689 :                 case 0:
     135        5689 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
     136        5689 :                     move16();
     137        5689 :                     BREAK;
     138       96149 :                 case 1:
     139       96149 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
     140       96149 :                     move16();
     141       96149 :                     BREAK;
     142       64431 :                 case 2:
     143       64431 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
     144       64431 :                     move16();
     145       64431 :                     BREAK;
     146           0 :                 default:
     147           0 :                     assert( !"Not supported stereo mode\n" );
     148             :             }
     149             : 
     150      166269 :             IF( !mct_on )
     151             :             {
     152       72685 :                 test();
     153       72685 :                 IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
     154             :                 {
     155       72365 :                     hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
     156       72365 :                     move16();
     157       72365 :                     assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
     158             :                 }
     159             :                 ELSE
     160             :                 {
     161         320 :                     hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
     162         320 :                     move16();
     163             :                 }
     164             :             }
     165             : 
     166             :             // set16_fx( ms_mask[k], ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) ? 1 : 0, sfbConf->nBandsStereoCore );
     167      166269 :             IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
     168             :             {
     169       96149 :                 set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
     170             :             }
     171             :             ELSE
     172             :             {
     173       70120 :                 set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
     174             :             }
     175             : 
     176      166269 :             IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
     177             :             {
     178     2666845 :                 FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
     179             :                 {
     180     2602414 :                     ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     181     2602414 :                     move16();
     182             :                 }
     183             :             }
     184             : 
     185      166269 :             IF( st0->igf )
     186             :             {
     187      108462 :                 mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
     188      108462 :                 IF( mdct_stereo_mode )
     189             :                 {
     190       60336 :                     mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     191             :                 }
     192             : 
     193      108462 :                 SWITCH( mdct_stereo_mode )
     194             :                 {
     195       48126 :                     case 0:
     196       48126 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     197       48126 :                         move16();
     198       48126 :                         BREAK;
     199       45050 :                     case 1:
     200       45050 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
     201       45050 :                         move16();
     202       45050 :                         BREAK;
     203       15286 :                     case 2:
     204       15286 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
     205       15286 :                         move16();
     206       15286 :                         BREAK;
     207           0 :                     default:
     208           0 :                         assert( !"Not supported stereo mode\n" );
     209             :                 }
     210             : 
     211             :                 // set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) ? 1 : 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     212      108462 :                 IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
     213             :                 {
     214       45050 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     215             :                 }
     216             :                 ELSE
     217             :                 {
     218       63412 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     219             :                 }
     220             : 
     221      108462 :                 IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     222             :                 {
     223       97365 :                     FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
     224             :                     {
     225       82079 :                         ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     226       82079 :                         move16();
     227             :                     }
     228             :                 }
     229             :             }
     230             :             ELSE
     231             :             {
     232       57807 :                 hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     233       57807 :                 move16();
     234             :             }
     235             :         }
     236             :     }
     237             : 
     238      201168 :     IF( !mct_on )
     239             :     {
     240      109572 :         hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels   Q0*/
     241      109572 :         move16();
     242      109572 :         hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
     243             : 
     244      109572 :         assert( GT_16( hStereoMdct->split_ratio, 0 ) );
     245             :     }
     246             : 
     247             : 
     248      201168 :     return;
     249             : }
     250             : 
     251             : 
     252             : /*-------------------------------------------------------------------*
     253             :  * inverseBwMS()
     254             :  *
     255             :  * Band-wise M/S stereo processing
     256             :  *-------------------------------------------------------------------*/
     257             : 
     258     1841927 : static void inverseBwMS_fx(
     259             :     const Word16 startLine, /* i  : start line of sfb                                   Q0*/
     260             :     const Word16 stopLine,  /* i  : stop line of sfb                                    Q0*/
     261             :     Word32 x0[],            /* i/o: mid/left channel coefficients               Qx*/
     262             :     Word32 x1[],            /* i/o: side/right channel coefficients             Qx*/
     263             :     const Word32 norm_fac   /* i  : normalization factor                                Q31*/
     264             : )
     265             : {
     266             :     Word16 j;
     267             :     Word32 tmpValue;
     268             : 
     269    94737137 :     FOR( j = startLine; j < stopLine; j++ )
     270             :     {
     271    92895210 :         tmpValue = x0[j];
     272    92895210 :         move32();
     273    92895210 :         x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
     274    92895210 :         move32();
     275    92895210 :         x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
     276    92895210 :         move32();
     277             :     }
     278             : 
     279     1841927 :     return;
     280             : }
     281             : 
     282             : 
     283             : /*-------------------------------------------------------------------*
     284             :  * inverseMS()
     285             :  *
     286             :  * M/S stereo processing
     287             :  *-------------------------------------------------------------------*/
     288             : 
     289      194180 : void inverseMS_fx(
     290             :     const Word16 L_frame, /* i  : frame length                                          Q0*/
     291             :     Word32 x0[],          /* i/o: mid/left channel coefficients         Qx*/
     292             :     Word32 x1[],          /* i/o: side/right channel coefficients       Qx*/
     293             :     const Word32 norm_fac /* i  : normalization factor                     Q31*/
     294             : )
     295             : {
     296      194180 :     inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
     297             : 
     298      194180 :     return;
     299             : }
     300             : 
     301             : 
     302             : /*-------------------------------------------------------------------*
     303             :  * stereo_decoder_tcx()
     304             :  *
     305             :  * apply stereo processing (inverse MS and global ILD)
     306             :  *-------------------------------------------------------------------*/
     307             : 
     308      164366 : void stereo_decoder_tcx_fx(
     309             :     STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure              */
     310             :     Word16 ms_mask[NB_DIV][MAX_SFB],   /* i  : bandwise MS mask                                                 Q0*/
     311             :     Word32 *spec_r_0[NB_DIV],          /* i/o: spectrum right channel                                   Qx*/
     312             :     Word32 *spec_l[],                  /* i/o: spectrum left channel  [NB_DIV][N]               Qx*/
     313             :     Word32 *spec_r[],                  /* i/o: spectrum right channel [NB_DIV][N]               Qx*/
     314             :     const Word16 mdct_stereo_mode[],   /* i  : stereo mode (FB/band wise MS, dual mono  Q0*/
     315             :     const Word16 core_l,               /* i  : core for left channel (TCX20/TCX10)              Q0*/
     316             :     const Word16 core_r,               /* i  : core for right channel (TCX20/TCX10)             Q0*/
     317             :     const Word16 igf,                  /* i  : flag for IGF activity                                    Q0*/
     318             :     const Word16 L_frameTCX_l,         /* i  : TCX frame length of left channel                 Q0*/
     319             :     const Word16 L_frameTCX_r,         /* i  : TCX frame length of right channel                Q0*/
     320             :     const Word16 mct_on,               /* i  : flag mct block (1) or stereo (0)                 Q0*/
     321             :     const Word16 last_core_l,          /* i  : last core for left channel                               Q0*/
     322             :     const Word16 last_core_r,          /* i  : last core for right channel                              Q0*/
     323             :     const Word16 tmp_plc_upmix         /* i  : indicates temp upmix for PLC decision    Q0*/
     324             : )
     325             : {
     326             :     Word16 i, k, sfb, nSubframes;
     327      164366 :     STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
     328             :     Word32 nrgRatio, inv_nrgRatio, tmp_32;
     329             :     Word16 tmp_e, shift;
     330             : 
     331      164366 :     nSubframes = 2;
     332      164366 :     move16();
     333      164366 :     test();
     334      164366 :     test();
     335      164366 :     if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
     336             :     {
     337      160231 :         nSubframes = 1; /* Q0 */
     338      160231 :         move16();
     339             :     }
     340             : 
     341      332867 :     FOR( k = 0; k < nSubframes; k++ )
     342             :     {
     343             :         // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     344      168501 :         IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
     345             :         {
     346      160614 :             sfbConf = &hStereoMdct->stbParamsTCX20;
     347             :         }
     348             :         ELSE
     349             :         {
     350        7887 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     351             :         }
     352             : 
     353      168501 :         test();
     354      168501 :         if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
     355             :         {
     356        1351 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     357             :         }
     358             : 
     359      168501 :         IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
     360             :         {
     361    54215378 :             FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
     362             :             {
     363    54118034 :                 IF( EQ_32( spec_r_0[k][i], 0 ) )
     364             :                 {
     365    19477141 :                     spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     366    19477141 :                     move32();
     367             :                 }
     368             :             }
     369       97344 :             inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
     370             :         }
     371       71157 :         ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
     372             :         {
     373     2702979 :             FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
     374             :             {
     375     2637616 :                 IF( ms_mask[k][sfb] )
     376             :                 {
     377    23554839 :                     FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     378             :                     {
     379    21951038 :                         IF( EQ_32( spec_r_0[k][i], 0 ) )
     380             :                         {
     381     7844267 :                             spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     382     7844267 :                             move32();
     383             :                         }
     384             :                     }
     385     1603801 :                     inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
     386             :                 }
     387             :             }
     388             :         }
     389             : 
     390      168501 :         IF( igf )
     391             :         {
     392      109812 :             IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
     393             :             {
     394    13922471 :                 FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
     395             :                 {
     396    13877028 :                     IF( EQ_32( spec_r_0[k][i], 0 ) )
     397             :                     {
     398     5458077 :                         spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     399     5458077 :                         move32();
     400             :                     }
     401             :                 }
     402       45443 :                 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_FX );
     403             :             }
     404       64369 :             ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     405             :             {
     406       97983 :                 FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
     407             :                 {
     408       82617 :                     IF( ms_mask[k][sfb] )
     409             :                     {
     410     2168124 :                         FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     411             :                         {
     412     2124178 :                             IF( EQ_32( spec_r_0[k][i], 0 ) )
     413             :                             {
     414      834035 :                                 spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     415      834035 :                                 move32();
     416             :                             }
     417             :                         }
     418       43946 :                         inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
     419             :                     }
     420             :                 }
     421             :             }
     422             :         }
     423             : 
     424      168501 :         IF( !mct_on )
     425             :         {
     426       74917 :             tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
     427       74917 :             tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
     428       74917 :             nrgRatio = L_sub( tmp_32, ONE_IN_Q26 );                                   // Q26
     429             : 
     430       74917 :             hStereoMdct->smooth_ratio_fx = W_extract_h( W_mac_32_32( W_mult_32_32( POINT_8_FX, hStereoMdct->smooth_ratio_fx ), POINT_2_FX, nrgRatio ) ); // Q26
     431       74917 :             move32();
     432             :             /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
     433       74917 :             IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FX ) )
     434             :             {
     435       16839 :                 hStereoMdct->reverse_dmx = 1; /* Q0 */
     436       16839 :                 move16();
     437             :             }
     438       58078 :             ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FX ) )
     439             :             {
     440       12435 :                 hStereoMdct->reverse_dmx = 0; /* Q0 */
     441       12435 :                 move16();
     442             :             }
     443             : 
     444       74917 :             Word16 tmp1, tmp2 = 0;
     445             : 
     446       74917 :             IF( EQ_16( core_r, TCX_10_CORE ) )
     447             :             {
     448        4110 :                 tmp1 = NB_DIV;
     449        4110 :                 move16();
     450             :             }
     451             :             ELSE
     452             :             {
     453       70807 :                 tmp1 = 1;
     454       70807 :                 move16();
     455             :             }
     456             : 
     457       74917 :             IF( EQ_16( core_l, TCX_10_CORE ) )
     458             :             {
     459        3900 :                 tmp2 = NB_DIV;
     460        3900 :                 move16();
     461             :             }
     462             :             ELSE
     463             :             {
     464       71017 :                 tmp2 = 1;
     465       71017 :                 move16();
     466             :             }
     467             : 
     468       74917 :             test();
     469       74917 :             test();
     470       74917 :             IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
     471             :             {
     472       25703 :                 shift = norm_l( nrgRatio );
     473       25703 :                 nrgRatio = L_shl( nrgRatio, shift );                        /* Q26 + shift */
     474       25703 :                 v_multc_fx( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
     475       25703 :                 Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) );    /* Qx */
     476             :             }
     477       49214 :             ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
     478             :             {
     479       15760 :                 inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
     480       15760 :                 shift = sub( 5, tmp_e );
     481       15760 :                 v_multc_fx( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
     482       15760 :                 Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) );        /* Qx */
     483             :             }
     484             :         }
     485             :     } /* for k */
     486             : 
     487      164366 :     return;
     488             : }
     489             : 
     490             : 
     491             : /*-------------------------------------------------------------------*
     492             :  * initMdctStereoDecData()
     493             :  *
     494             :  * Initialize MDCT stereo decoder configuration
     495             :  *-------------------------------------------------------------------*/
     496             : 
     497      327873 : void initMdctStereoDecData_fx(
     498             :     STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure         */
     499             :     const Word16 igf,                  /* i  : flag indicating IGF activity               Q0*/
     500             :     const H_IGF_GRID igfGrid,          /* i  : IGF grid configuration                     Q0*/
     501             :     const Word32 element_brate,        /* i  : element bitrate                                    Q0*/
     502             :     const Word16 bwidth                /* i  : audio bandwidth                    Q0*/
     503             : )
     504             : {
     505             :     Word16 tcx_coded_lines;
     506             : 
     507      327873 :     tcx_coded_lines = getNumTcxCodedLines( bwidth );
     508             : 
     509             :     /*Initialize sfb parameteres for TCX20 */
     510      327873 :     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 );
     511             : 
     512             :     /*Initialize sfb parameteres for TCX10 */
     513      327873 :     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 );
     514             : 
     515             :     /*Initialize sfb parameteres for transition frames */
     516      327873 :     stereo_mdct_init_bands_fx( tcx_coded_lines, -1, element_brate, igf, &igfGrid[IGF_GRID_LB_TRAN], &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
     517             : 
     518      327873 :     IF( igf )
     519             :     {
     520             :         /* calculate the igf start band from the igf start line */
     521      185638 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
     522      185638 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
     523      185638 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
     524             :     }
     525             :     ELSE
     526             :     {
     527      142235 :         hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
     528      142235 :         move16();
     529      142235 :         hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
     530      142235 :         move16();
     531      142235 :         hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
     532      142235 :         move16();
     533      142235 :         hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
     534      142235 :         move16();
     535      142235 :         hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
     536      142235 :         move16();
     537      142235 :         hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
     538      142235 :         move16();
     539             :     }
     540             : 
     541      327873 :     return;
     542             : }
     543             : 
     544             : 
     545             : /*-------------------------------------------------------------------*
     546             :  * initMdctStereoDtxData()
     547             :  *
     548             :  * Allocate and initialize structures for MDCT-Stereo DTX operation
     549             :  *-------------------------------------------------------------------*/
     550             : 
     551          27 : ivas_error initMdctStereoDtxData_fx(
     552             :     CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
     553             : )
     554             : {
     555             :     Word16 ch;
     556             :     ivas_error error;
     557             : 
     558          27 :     error = IVAS_ERR_OK;
     559          27 :     move16();
     560             : 
     561          81 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
     562             :     {
     563          54 :         DEC_CORE_HANDLE st = hCPE->hCoreCoder[ch];
     564             : 
     565          54 :         IF( st->hFdCngDec == NULL )
     566             :         {
     567             :             /* Create FD_CNG instance */
     568           0 :             IF( NE_32( ( error = createFdCngDec_fx( &st->hFdCngDec ) ), IVAS_ERR_OK ) )
     569             :             {
     570           0 :                 return error;
     571             :             }
     572             : 
     573             :             /* Init FD-CNG */
     574           0 :             initFdCngDec_ivas_fx( st, st->cldfbSyn->scale );
     575             :         }
     576             : 
     577          54 :         IF( st->first_CNG == 0 )
     578             :         {
     579          54 :             test();
     580          54 :             IF( EQ_16( ch, 1 ) && st->cng_sba_flag )
     581             :             {
     582          15 :                 st->hFdCngDec->hFdCngCom->seed = add( st->hFdCngDec->hFdCngCom->seed, 3 ); /* Q0 */
     583          15 :                 move16();
     584             :             }
     585             :         }
     586             : 
     587          54 :         IF( st->cldfbAna == NULL )
     588             :         {
     589             :             /* open analysis for max. sampling rate 48kHz */
     590          46 :             IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAna, CLDFB_ANALYSIS, 48000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
     591             :             {
     592           0 :                 return error;
     593             :             }
     594             :         }
     595             : 
     596          54 :         IF( st->cldfbBPF == NULL )
     597             :         {
     598             :             /* open analysis BPF for max. internal sampling rate 16kHz */
     599          46 :             IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbBPF, CLDFB_ANALYSIS, 16000, CLDFB_PROTOTYPE_1_25MS, DEC ) ), IVAS_ERR_OK ) )
     600             :             {
     601           0 :                 return error;
     602             :             }
     603             :         }
     604             :     }
     605             : 
     606          27 :     return error;
     607             : }
     608             : 
     609             : 
     610             : /*-------------------------------------------------------------------*
     611             :  * synchonize_channels_mdct_sid()
     612             :  *
     613             :  * Synchronize channels in SID frame in MDCT stereo
     614             :  *-------------------------------------------------------------------*/
     615             : 
     616     1242887 : void synchonize_channels_mdct_sid_fx(
     617             :     Decoder_State *sts[CPE_CHANNELS], /* i/o: decoder state structure     */
     618             :     const Word16 n                    /* i  : channel number            Q0*/
     619             : )
     620             : {
     621             :     Decoder_State *st;
     622             : 
     623     1242887 :     st = sts[n];
     624             : 
     625     1242887 :     test();
     626     1242887 :     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_32( st->total_brate, SID_2k40 ) )
     627             :     {
     628         978 :         IF( EQ_16( n, 1 ) )
     629             :         {
     630             :             /* synchronize channels */
     631         489 :             sts[1]->L_frame = sts[0]->L_frame;
     632         489 :             move16();
     633         489 :             sts[1]->cng_type = sts[0]->cng_type;
     634         489 :             move16();
     635         489 :             sts[1]->bwidth = sts[0]->bwidth;
     636         489 :             move16();
     637             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     638         489 :             sts[0]->hFdCngDec->hFdCngCom->coherence_fx[0] = sts[1]->hFdCngDec->hFdCngCom->coherence_fx[0]; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
     639             : #else
     640             :             sts[0]->hFdCngDec->hFdCngCom->coherence_fx = sts[1]->hFdCngDec->hFdCngCom->coherence_fx; /* coherence is stored in sts[1] - see ivas_decision_matrix_dec() */
     641             : #endif
     642         489 :             move16();
     643         489 :             sts[0]->hFdCngDec->hFdCngCom->no_side_flag = sts[1]->hFdCngDec->hFdCngCom->no_side_flag;
     644         489 :             move16();
     645             : 
     646             :             /* configure when there is a switching from DFT CNG to MDCT CNG */
     647         489 :             test();
     648         489 :             IF( EQ_16( sts[0]->first_CNG, 1 ) && EQ_16( sts[1]->first_CNG, 0 ) )
     649             :             {
     650           0 :                 configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     651             :             }
     652             :         }
     653             : 
     654         978 :         IF( sts[0]->first_CNG == 0 )
     655             :         {
     656             :             /* 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 */
     657          54 :             configureFdCngDec_ivas_fx( st->hFdCngDec, st->bwidth, st->element_brate, st->L_frame, st->last_L_frame, st->element_mode );
     658             :         }
     659             :     }
     660             : 
     661     1242887 :     return;
     662             : }
     663             : 
     664             : 
     665             : /*-------------------------------------------------------------------*
     666             :  * updateBuffersForDmxMdctStereo()
     667             :  *
     668             :  * synch buffers between channels for mono output and
     669             :  * apply passive downmix to certain buffers to enable smooth transitions
     670             :  * between active/inactive coding in MDCT-Stereo DTX
     671             :  *-------------------------------------------------------------------*/
     672             : 
     673        3234 : static void update_exp(
     674             :     Word16 *a_exp,
     675             :     Word16 *b_exp,
     676             :     Word16 *buff_a,    /* exp(a_exp) */
     677             :     Word16 *buff_b,    /* exp(b_exp) */
     678             :     const Word16 legth /* Q0 */
     679             : )
     680             : {
     681        3234 :     Word16 diff = 0;
     682        3234 :     move16();
     683        3234 :     IF( GT_16( *a_exp, *b_exp ) )
     684             :     {
     685        1027 :         diff = sub( *a_exp, *b_exp );
     686      983155 :         FOR( Word16 j = 0; j < legth; j++ )
     687             :         {
     688      982128 :             buff_b[j] = shr( buff_b[j], diff ); /* exp(a_exp) */
     689      982128 :             move16();
     690             :         }
     691        1027 :         *b_exp = *a_exp;
     692        1027 :         move16();
     693             :     }
     694        2207 :     ELSE IF( LT_16( *a_exp, *b_exp ) )
     695             :     {
     696          32 :         diff = sub( *b_exp, *a_exp );
     697             : 
     698       18428 :         FOR( Word16 j = 0; j < legth; j++ )
     699             :         {
     700       18396 :             buff_a[j] = shr( buff_a[j], diff ); /* exp(b_exp)*/
     701       18396 :             move16();
     702             :         }
     703          32 :         *a_exp = *b_exp;
     704          32 :         move16();
     705             :     }
     706        3234 :     return;
     707             : }
     708             : 
     709        1114 : void updateBuffersForDmxMdctStereo_fx(
     710             :     CPE_DEC_HANDLE hCPE,                      /* i/o: CPE handle                              */
     711             :     const Word16 output_frame,                /* i  : output frame length                   Q0*/
     712             :     Word32 output0_fx[],                      /* Qx */
     713             :     Word32 output1_fx[],                      /* Qx */
     714             :     Word16 synth_fx[CPE_CHANNELS][L_FRAME48k] /* i/o: decoder synthesis                 qsynth*/
     715             : )
     716             : {
     717             :     Word16 delay_buf_out_len, tcxltp_mem_in_len, delta, i;
     718             :     Decoder_State *sts[CPE_CHANNELS];
     719             : 
     720        1114 :     sts[0] = hCPE->hCoreCoder[0];
     721        1114 :     sts[1] = hCPE->hCoreCoder[1];
     722             : 
     723             :     /* synch buffers for inactive frames, but not for transition frames */
     724        1114 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     725             :     {
     726        1078 :         Copy32( output0_fx, output1_fx, output_frame );
     727        1078 :         Copy( synth_fx[0], synth_fx[1], output_frame );
     728             :     }
     729             : 
     730        1114 :     Word32 Var1 = 0;
     731        1114 :     move16();
     732        1114 :     Word16 diff_sidNoiseEst = 0;
     733        1114 :     move16();
     734        1114 :     Word16 exp_sidNoiseEst0 = sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     735        1114 :     move16();
     736        1114 :     Word16 exp_sidNoiseEst1 = sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp;
     737        1114 :     move16();
     738        1114 :     IF( GT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     739             :     {
     740          14 :         diff_sidNoiseEst = sub( exp_sidNoiseEst0, exp_sidNoiseEst1 );
     741         350 :         FOR( Word32 j = 0; j < NPART; j++ )
     742             :         {
     743         336 :             sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp(exp_sidNoiseEst0) */
     744         336 :             move16();
     745             :         }
     746          14 :         exp_sidNoiseEst1 = exp_sidNoiseEst0;
     747          14 :         move16();
     748             :     }
     749        1100 :     ELSE IF( LT_16( exp_sidNoiseEst0, exp_sidNoiseEst1 ) )
     750             :     {
     751          12 :         diff_sidNoiseEst = sub( exp_sidNoiseEst1, exp_sidNoiseEst0 );
     752         300 :         FOR( Word32 j = 0; j < NPART; j++ )
     753             :         {
     754         288 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j] = L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[j], diff_sidNoiseEst ); /* exp( exp_sidNoiseEst1) */
     755         288 :             move16();
     756             :         }
     757          12 :         exp_sidNoiseEst0 = exp_sidNoiseEst1;
     758          12 :         move16();
     759             :     }
     760        1114 :     sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst0;
     761        1114 :     move16();
     762        1114 :     sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp = exp_sidNoiseEst1;
     763        1114 :     move16();
     764        1114 :     test();
     765        1114 :     test();
     766        1114 :     IF( EQ_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     767             :     {
     768             :         /* 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 */
     769         873 :         FOR( Word16 p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ )
     770             :         {
     771         837 :             Var1 = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); // exp_sidNoiseEst0 - 1
     772         837 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = Mpy_32_32( ONE_IN_Q30, Var1 );                                                       //  31 - exp_sidNoiseEst0 - 1 + 31 - 31
     773         837 :             move32();
     774             :         }
     775             :     }
     776             : 
     777             :     /* for transition of active->inactive frame, apply passive downmix on buffers */
     778        1114 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     779             :     {
     780        1078 :         delta = 1;
     781        1078 :         move16();
     782        1078 :         IF( EQ_16( output_frame, L_FRAME16k ) )
     783             :         {
     784         348 :             delta = 2;
     785         348 :             move16();
     786             :         }
     787         730 :         ELSE IF( EQ_16( output_frame, L_FRAME32k ) )
     788             :         {
     789         356 :             delta = 4;
     790         356 :             move16();
     791             :         }
     792         374 :         ELSE IF( EQ_16( output_frame, L_FRAME48k ) )
     793             :         {
     794         374 :             delta = 6;
     795         374 :             move16();
     796             :         }
     797             : 
     798        1078 :         delay_buf_out_len = i_mult( delta, HQ_DELAY_COMP );                  /* Q0 */
     799        1078 :         tcxltp_mem_in_len = NS2SA_FX2( sts[0]->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
     800        1078 :         move16();
     801             : 
     802        1078 :         assert( delay_buf_out_len > tcxltp_mem_in_len );
     803             : 
     804        1078 :         Word16 sum_tcx_ltp = 0, sum_delay_buf = 0, sum_tcx_ltp_out = 0, sum_old_out = 0;
     805        1078 :         move16();
     806        1078 :         move16();
     807        1078 :         move16();
     808        1078 :         move16();
     809             : 
     810        1078 :         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
     811        1078 :         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
     812             : 
     813        1078 :         Copy_Scale_sig_32_16( &sts[0]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[0]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     814        1078 :         Copy_Scale_sig_32_16( &sts[1]->hTcxLtpDec->tcxltp_mem_out_32[0], &sts[1]->hTcxLtpDec->tcxltp_mem_out[0], L_FRAME48k, -11 ); // Q0
     815             : 
     816        1078 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     817        1078 :         move16();
     818        1078 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_in = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY ) );
     819        1078 :         move16();
     820             : 
     821        1078 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[0]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     822        1078 :         move16();
     823        1078 :         sts[1]->hTcxLtpDec->exp_tcxltp_mem_out = sub( 15, norm_arr( sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k ) );
     824        1078 :         move16();
     825             : 
     826             : 
     827        1078 :         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)
     828        1078 :         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)
     829             : 
     830        1078 :         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)
     831        1078 :         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)
     832             : 
     833             : 
     834        1078 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_in,
     835        1078 :                     sts[0]->hTcxLtpDec->tcxltp_mem_in, sts[1]->hTcxLtpDec->tcxltp_mem_in, TCXLTP_MAX_DELAY );
     836             : 
     837        1078 :         update_exp( &sts[0]->hHQ_core->exp_old_out, &sts[1]->hHQ_core->exp_old_out,
     838        1078 :                     sts[0]->hHQ_core->old_out_fx, sts[1]->hHQ_core->old_out_fx, L_FRAME48k );
     839             : 
     840        1078 :         update_exp( &sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, &sts[1]->hTcxLtpDec->exp_tcxltp_mem_out,
     841        1078 :                     sts[0]->hTcxLtpDec->tcxltp_mem_out, sts[1]->hTcxLtpDec->tcxltp_mem_out, L_FRAME48k );
     842             : 
     843        9806 :         FOR( i = 0; i < tcxltp_mem_in_len; i++ )
     844             :         {
     845        8728 :             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
     846        8728 :             sts[0]->hTcxLtpDec->tcxltp_mem_in[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp );                                        //  exp_tcxltp_mem_in + 1
     847        8728 :             move16();
     848             : 
     849        8728 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); /* Q0 */
     850        8728 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     851        8728 :             move16();
     852             : 
     853        8728 :             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
     854        8728 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     855        8728 :             move16();
     856             : 
     857        8728 :             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
     858        8728 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     859        8728 :             move16();
     860             :         }
     861             : 
     862             : 
     863       35990 :         FOR( ; i < delay_buf_out_len; i++ )
     864             :         {
     865       34912 :             sum_delay_buf = add( sts[0]->delay_buf_out_fx[i], sts[1]->delay_buf_out_fx[i] ); // Q0
     866       34912 :             sts[0]->delay_buf_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_delay_buf );           // Q0
     867       34912 :             move16();
     868             : 
     869       34912 :             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 */
     870       34912 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   /* exp_old_out + 1 */
     871       34912 :             move16();
     872             : 
     873       34912 :             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
     874       34912 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     875       34912 :             move16();
     876             :         }
     877             : 
     878      655678 :         FOR( ; i < output_frame; i++ )
     879             :         {
     880      654600 :             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
     881      654600 :             sts[0]->hHQ_core->old_out_fx[i] = mult( INV_SQRT2_FX_Q15, sum_old_out );                                   // exp_old_out + 1
     882      654600 :             move16();
     883             : 
     884      654600 :             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
     885      654600 :             sts[0]->hTcxLtpDec->tcxltp_mem_out[i] = mult( INV_SQRT2_FX_Q15, sum_tcx_ltp_out );                                         // exp_tcxltp_mem_out + 1
     886      654600 :             move16();
     887             :         }
     888        1078 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_in = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_in, 1 );
     889        1078 :         move16();
     890        1078 :         sts[0]->hHQ_core->exp_old_out = add( sts[0]->hHQ_core->exp_old_out, 1 );
     891        1078 :         move16();
     892        1078 :         sts[0]->hTcxLtpDec->exp_tcxltp_mem_out = add( sts[0]->hTcxLtpDec->exp_tcxltp_mem_out, 1 );
     893        1078 :         move16();
     894        1078 :         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
     895        1078 :         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
     896             :     }
     897             : 
     898        1114 :     return;
     899             : }
     900             : 
     901             : 
     902             : /*-------------------------------------------------------------------*
     903             :  * applyDmxMdctStereo()
     904             :  *
     905             :  * apply passive downmix to certain buffers to enable smooth transitions
     906             :  * between active/inactive coding in MDCT-Stereo DTX
     907             :  *-------------------------------------------------------------------*/
     908             : 
     909        5920 : void applyDmxMdctStereo_fx(
     910             :     const CPE_DEC_HANDLE hCPE,       /* i  : CPE handle                                    */
     911             :     Word32 *output_fx[CPE_CHANNELS], /* i/o: core decoder output          q_out*/
     912             :     const Word16 output_frame        /* i  : output frame length                 Q0*/
     913             : )
     914             : {
     915             :     Word16 crossfade_len, i;
     916             :     Word16 dmx_len;
     917             :     Word32 fade_fx, step_fx;
     918             : 
     919        5920 :     step_fx = ONE_IN_Q31; /* Q31 */
     920        5920 :     move32();
     921        5920 :     fade_fx = ONE_IN_Q31; /* Q31 */
     922        5920 :     move32();
     923        5920 :     dmx_len = output_frame; /* Q0 */
     924        5920 :     move16();
     925             : 
     926        5920 :     test();
     927        5920 :     test();
     928        5920 :     IF( LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     929             :     {
     930          32 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
     931          32 :         move16();
     932          32 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
     933             :         {
     934          15 :             case 48000:
     935          15 :                 step_fx = 22369622; /* 0.0104 in Q31 */
     936          15 :                 move32();
     937          15 :                 BREAK;
     938           9 :             case 32000:
     939           9 :                 step_fx = 33554432; /* 0.0156 in Q31 */
     940           9 :                 move32();
     941           9 :                 BREAK;
     942           8 :             case 16000:
     943           8 :                 step_fx = 67108864; /* 0.0312 in Q31 */
     944           8 :                 move32();
     945           8 :                 BREAK;
     946           0 :             default:
     947           0 :                 assert( 0 );
     948             :                 BREAK;
     949             :         }
     950             :     }
     951             :     /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */
     952        5888 :     ELSE IF( LE_32( hCPE->element_brate, IVAS_SID_5k2 ) && GT_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
     953             :     {
     954          36 :         crossfade_len = shr( output_frame, 2 ); /* Q0 */
     955          36 :         SWITCH( output_frame )
     956             :         {
     957          17 :             case 960:
     958          17 :                 step_fx = -8947849; /* -0.0041 in Q31 */
     959          17 :                 move32();
     960          17 :                 BREAK;
     961          10 :             case 640:
     962          10 :                 step_fx = -13421773; /* -0.00625 in Q31 */
     963          10 :                 move32();
     964          10 :                 BREAK;
     965           9 :             case 320:
     966           9 :                 step_fx = -26843546; /* -0.0125 in Q31 */
     967           9 :                 move32();
     968           9 :                 BREAK;
     969             :         }
     970          36 :         fade_fx = 0;
     971          36 :         move32();
     972          36 :         dmx_len = crossfade_len; /* Q0 */
     973          36 :         move16();
     974             :     }
     975        5852 :     ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) && LE_32( hCPE->last_element_brate, IVAS_32k ) )
     976             :     {
     977          15 :         crossfade_len = NS2SA_FX2( hCPE->hCoreCoder[0]->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
     978          15 :         move16();
     979          15 :         SWITCH( hCPE->hCoreCoder[0]->output_Fs )
     980             :         {
     981          15 :             case 48000:
     982          15 :                 step_fx = 35791396; /* 0.0166 in Q31 */
     983          15 :                 move32();
     984          15 :                 BREAK;
     985           0 :             case 32000:
     986           0 :                 step_fx = 53687092; /* 0.025 in Q31 */
     987           0 :                 move32();
     988           0 :                 BREAK;
     989           0 :             case 16000:
     990           0 :                 step_fx = 107374184; /* 0.05 in Q31 */
     991           0 :                 move32();
     992           0 :                 BREAK;
     993           0 :             default:
     994           0 :                 assert( 0 );
     995             :                 BREAK;
     996             :         }
     997             :     }
     998             :     ELSE
     999             :     {
    1000        5837 :         crossfade_len = 0;
    1001        5837 :         move16();
    1002             :     }
    1003             : 
    1004             :     /* apply crossfade */
    1005       15492 :     FOR( i = 0; i < crossfade_len; i++ )
    1006             :     {
    1007        9572 :         Word32 temp_1 = Mpy_32_32( output_fx[0][i], fade_fx );                                                                                   /* q_out */
    1008        9572 :         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 */
    1009        9572 :         output_fx[0][i] = L_add( temp_1, temp_2 );                                                                                               /* q_out */
    1010        9572 :         move32();
    1011        9572 :         fade_fx = L_sub_sat( fade_fx, step_fx ); /* Q31 */
    1012             :     }
    1013             : 
    1014             :     /* apply passive downmix on all-active-frame part */
    1015     4605628 :     FOR( ; i < dmx_len; i++ )
    1016             :     {
    1017     4599708 :         output_fx[0][i] = Mpy_32_32( L_add_sat( output_fx[0][i], output_fx[1][i] ), INV_SQRT2_FX ); /* q_out */
    1018     4599708 :         move32();
    1019             :     }
    1020             : 
    1021        5920 :     return;
    1022             : }

Generated by: LCOV version 1.14