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 @ b9bfbe380d1c207f5198ba67a82398b3d313550e Lines: 439 461 95.2 %
Date: 2025-11-15 04:01:59 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      206764 : 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      206764 :     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      167176 :         test();
      84      167176 :         IF( ( EQ_16( sts[0]->core, TCX_10_CORE ) || ( NE_16( sts[0]->core, sts[1]->core ) ) ) )
      85             :         {
      86        4396 :             nSubframes = NB_DIV; /* Q0 */
      87        4396 :             move16();
      88             :         }
      89             :         ELSE
      90             :         {
      91      162780 :             nSubframes = 1; /* Q0 */
      92      162780 :             move16();
      93             :         }
      94      167176 :         move16();
      95             :         // sfbConf = ( EQ_16( sts[0]->core, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
      96      167176 :         IF( ( EQ_16( sts[0]->core, TCX_20_CORE ) ) )
      97             :         {
      98      163003 :             sfbConf = &hStereoMdct->stbParamsTCX20;
      99             :         }
     100             :         ELSE
     101             :         {
     102        4173 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     103             :         }
     104      167176 :         if ( sts[0]->last_core_from_bs == ACELP_CORE )
     105             :         {
     106        1935 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     107             :         }
     108             : 
     109      167176 :         IF( hStereoMdct->use_itd )
     110             :         {
     111             :             Word16 I;
     112             : 
     113       11671 :             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       11671 :             hStereoMdct->itd_fx = 0;
     117       11671 :             move32();
     118       11671 :             IF( hStereoMdct->itd_mode )
     119             :             {
     120        3562 :                 /*(*nb_bits) += */ read_itd( st0, &I );
     121        3562 :                 stereo_dft_dequantize_itd_fx( &I, &hStereoMdct->itd_fx, st0->output_Fs );
     122             :             }
     123             :         }
     124             : 
     125      338748 :         FOR( k = 0; k < nSubframes; k++ )
     126             :         {
     127      171572 :             mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     128      171572 :             IF( mdct_stereo_mode )
     129             :             {
     130      165022 :                 mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     131             :             }
     132      171572 :             SWITCH( mdct_stereo_mode )
     133             :             {
     134        6550 :                 case 0:
     135        6550 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_DUAL_MONO; /* Q0 */
     136        6550 :                     move16();
     137        6550 :                     BREAK;
     138       98869 :                 case 1:
     139       98869 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_MS_FULL; /* Q0 */
     140       98869 :                     move16();
     141       98869 :                     BREAK;
     142       66153 :                 case 2:
     143       66153 :                     hStereoMdct->mdct_stereo_mode[k] = SMDCT_BW_MS; /* Q0 */
     144       66153 :                     move16();
     145       66153 :                     BREAK;
     146           0 :                 default:
     147           0 :                     assert( !"Not supported stereo mode\n" );
     148             :             }
     149             : 
     150      171572 :             IF( !mct_on )
     151             :             {
     152       76511 :                 test();
     153       76511 :                 IF( EQ_16( sts[0]->core, sts[1]->core ) || k == 0 )
     154             :                 {
     155       76164 :                     hStereoMdct->global_ild[k] = extract_l( get_next_indice_fx( st0, SMDCT_GLOBAL_ILD_BITS ) ); /* Q0 */
     156       76164 :                     move16();
     157       76164 :                     assert( ( GT_16( hStereoMdct->global_ild[k], 0 ) ) && ( LT_16( hStereoMdct->global_ild[k], SMDCT_ILD_RANGE ) ) );
     158             :                 }
     159             :                 ELSE
     160             :                 {
     161         347 :                     hStereoMdct->global_ild[1] = hStereoMdct->global_ild[0]; /* Q0 */
     162         347 :                     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      171572 :             IF( ( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_MS_FULL ) ) )
     168             :             {
     169       98869 :                 set16_fx( ms_mask[k], 1, sfbConf->nBandsStereoCore );
     170             :             }
     171             :             ELSE
     172             :             {
     173       72703 :                 set16_fx( ms_mask[k], 0, sfbConf->nBandsStereoCore );
     174             :             }
     175             : 
     176      171572 :             IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
     177             :             {
     178     2732003 :                 FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
     179             :                 {
     180     2665850 :                     ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     181     2665850 :                     move16();
     182             :                 }
     183             :             }
     184             : 
     185      171572 :             IF( st0->igf )
     186             :             {
     187      112926 :                 mdct_stereo_mode = extract_l( get_next_indice_fx( st0, 1 ) );
     188      112926 :                 IF( mdct_stereo_mode )
     189             :                 {
     190       62510 :                     mdct_stereo_mode = add( 1, extract_l( get_next_indice_fx( st0, 1 ) ) ); /* Q0 */
     191             :                 }
     192             : 
     193      112926 :                 SWITCH( mdct_stereo_mode )
     194             :                 {
     195       50416 :                     case 0:
     196       50416 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     197       50416 :                         move16();
     198       50416 :                         BREAK;
     199       46786 :                     case 1:
     200       46786 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_MS_FULL; /* Q0 */
     201       46786 :                         move16();
     202       46786 :                         BREAK;
     203       15724 :                     case 2:
     204       15724 :                         hStereoMdct->IGFStereoMode[k] = SMDCT_BW_MS; /* Q0 */
     205       15724 :                         move16();
     206       15724 :                         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      112926 :                 IF( ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) ) )
     213             :                 {
     214       46786 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 1, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     215             :                 }
     216             :                 ELSE
     217             :                 {
     218       66140 :                     set16_fx( &ms_mask[k][sfbConf->nBandsStereoCore], 0, sub( sfbConf->sfbCnt, sfbConf->nBandsStereoCore ) );
     219             :                 }
     220             : 
     221      112926 :                 IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     222             :                 {
     223      100921 :                     FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
     224             :                     {
     225       85197 :                         ms_mask[k][i] = extract_l( get_next_indice_fx( st0, 1 ) ); /* Q0 */
     226       85197 :                         move16();
     227             :                     }
     228             :                 }
     229             :             }
     230             :             ELSE
     231             :             {
     232       58646 :                 hStereoMdct->IGFStereoMode[k] = SMDCT_DUAL_MONO; /* Q0 */
     233       58646 :                 move16();
     234             :             }
     235             :         }
     236             :     }
     237             : 
     238      206764 :     IF( !mct_on )
     239             :     {
     240      113807 :         hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels    Q0*/
     241      113807 :         move16();
     242      113807 :         hStereoMdct->split_ratio = extract_l( get_next_indice_fx( st0, SMDCT_NBBITS_SPLIT_RATIO ) ); /* Q0 */
     243             : 
     244      113807 :         assert( GT_16( hStereoMdct->split_ratio, 0 ) );
     245             :     }
     246             : 
     247             : 
     248      206764 :     return;
     249             : }
     250             : 
     251             : 
     252             : /*-------------------------------------------------------------------*
     253             :  * inverseBwMS()
     254             :  *
     255             :  * Band-wise M/S stereo processing
     256             :  *-------------------------------------------------------------------*/
     257             : 
     258     1889511 : 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    97369959 :     FOR( j = startLine; j < stopLine; j++ )
     270             :     {
     271    95480448 :         tmpValue = x0[j];
     272    95480448 :         move32();
     273    95480448 :         x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Qx */
     274    95480448 :         move32();
     275    95480448 :         x1[j] = Mpy_32_32( L_sub_sat( tmpValue, x1[j] ), norm_fac ); /* Qx */
     276    95480448 :         move32();
     277             :     }
     278             : 
     279     1889511 :     return;
     280             : }
     281             : 
     282             : 
     283             : /*-------------------------------------------------------------------*
     284             :  * inverseMS()
     285             :  *
     286             :  * M/S stereo processing
     287             :  *-------------------------------------------------------------------*/
     288             : 
     289      200653 : 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      200653 :     inverseBwMS_fx( 0, L_frame, x0, x1, norm_fac );
     297             : 
     298      200653 :     return;
     299             : }
     300             : 
     301             : 
     302             : /*-------------------------------------------------------------------*
     303             :  * stereo_decoder_tcx()
     304             :  *
     305             :  * apply stereo processing (inverse MS and global ILD)
     306             :  *-------------------------------------------------------------------*/
     307             : 
     308      169562 : 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      169562 :     STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
     328             :     Word32 nrgRatio, inv_nrgRatio, tmp_32;
     329             :     Word16 tmp_e, shift;
     330             : 
     331      169562 :     nSubframes = 2;
     332      169562 :     move16();
     333      169562 :     test();
     334      169562 :     test();
     335      169562 :     if ( ( LE_16( core_l, TCX_20_CORE ) && LE_16( core_r, TCX_20_CORE ) ) || tmp_plc_upmix )
     336             :     {
     337      165129 :         nSubframes = 1; /* Q0 */
     338      165129 :         move16();
     339             :     }
     340             : 
     341      343557 :     FOR( k = 0; k < nSubframes; k++ )
     342             :     {
     343             :         // sfbConf = ( EQ_16( core_l, TCX_20_CORE ) ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     344      173995 :         IF( ( EQ_16( core_l, TCX_20_CORE ) ) )
     345             :         {
     346      165533 :             sfbConf = &hStereoMdct->stbParamsTCX20;
     347             :         }
     348             :         ELSE
     349             :         {
     350        8462 :             sfbConf = &hStereoMdct->stbParamsTCX10;
     351             :         }
     352             : 
     353      173995 :         test();
     354      173995 :         if ( last_core_l == ACELP_CORE || last_core_r == ACELP_CORE )
     355             :         {
     356        1956 :             sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     357             :         }
     358             : 
     359      173995 :         IF( EQ_16( mdct_stereo_mode[k], SMDCT_MS_FULL ) )
     360             :         {
     361    55534191 :             FOR( i = 0; i < sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i++ )
     362             :             {
     363    55433990 :                 IF( EQ_32( spec_r_0[k][i], 0 ) )
     364             :                 {
     365    20306562 :                     spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     366    20306562 :                     move32();
     367             :                 }
     368             :             }
     369      100201 :             inverseMS_fx( sfbConf->sfbOffset[sfbConf->nBandsStereoCore], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
     370             :         }
     371       73794 :         ELSE IF( EQ_16( mdct_stereo_mode[k], SMDCT_BW_MS ) )
     372             :         {
     373     2769732 :             FOR( sfb = 0; sfb < sfbConf->nBandsStereoCore; sfb++ )
     374             :             {
     375     2702603 :                 IF( ms_mask[k][sfb] )
     376             :                 {
     377    24136462 :                     FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     378             :                     {
     379    22493230 :                         IF( EQ_32( spec_r_0[k][i], 0 ) )
     380             :                         {
     381     8131507 :                             spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     382     8131507 :                             move32();
     383             :                         }
     384             :                     }
     385     1643232 :                     inverseBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], spec_l[k], spec_r[k], SQRT2_OVER_2_FX );
     386             :                 }
     387             :             }
     388             :         }
     389             : 
     390      173995 :         IF( igf )
     391             :         {
     392      114432 :             IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_MS_FULL ) )
     393             :             {
     394    14548263 :                 FOR( i = sfbConf->sfbOffset[sfbConf->nBandsStereoCore]; i < sfbConf->sfbOffset[sfbConf->sfbCnt]; i++ )
     395             :                 {
     396    14500998 :                     IF( EQ_32( spec_r_0[k][i], 0 ) )
     397             :                     {
     398     5887526 :                         spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     399     5887526 :                         move32();
     400             :                     }
     401             :                 }
     402       47265 :                 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       67167 :             ELSE IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     405             :             {
     406      101611 :                 FOR( sfb = sfbConf->nBandsStereoCore; sfb < sfbConf->sfbCnt; sfb++ )
     407             :                 {
     408       85799 :                     IF( ms_mask[k][sfb] )
     409             :                     {
     410     2244220 :                         FOR( i = sfbConf->sfbOffset[sfb]; i < sfbConf->sfbOffset[sfb + 1]; i++ )
     411             :                         {
     412     2198594 :                             IF( EQ_32( spec_r_0[k][i], 0 ) )
     413             :                             {
     414      876043 :                                 spec_r[k][i] = Mpy_32_32( spec_r[k][i], NF_RED_FAC_FX ); /* Qx */
     415      876043 :                                 move32();
     416             :                             }
     417             :                         }
     418       45626 :                         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      173995 :         IF( !mct_on )
     425             :         {
     426       78934 :             tmp_32 = BASOP_Util_Divide3232_Scale_newton( SMDCT_ILD_RANGE << 16, L_deposit_h( hStereoMdct->global_ild[k] ), &tmp_e );
     427       78934 :             tmp_32 = L_shr( tmp_32, sub( 5, tmp_e ) ); /* nrgRatio = nrg[1]/nrg[0] */ // Q26
     428       78934 :             nrgRatio = L_sub( tmp_32, ONE_IN_Q26 );                                   // Q26
     429             : 
     430       78934 :             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       78934 :             move32();
     432             :             /* set flag to reverse dmx computation in case of right-side panning, only relevant for mono output */
     433       78934 :             IF( GT_32( hStereoMdct->smooth_ratio_fx, ONE_POINT_3_FX ) )
     434             :             {
     435       17441 :                 hStereoMdct->reverse_dmx = 1; /* Q0 */
     436       17441 :                 move16();
     437             :             }
     438       61493 :             ELSE IF( LT_32( hStereoMdct->smooth_ratio_fx, POINT_9_FX ) )
     439             :             {
     440       13089 :                 hStereoMdct->reverse_dmx = 0; /* Q0 */
     441       13089 :                 move16();
     442             :             }
     443             : 
     444       78934 :             Word16 tmp1, tmp2 = 0;
     445             : 
     446       78934 :             IF( EQ_16( core_r, TCX_10_CORE ) )
     447             :             {
     448        4443 :                 tmp1 = NB_DIV;
     449        4443 :                 move16();
     450             :             }
     451             :             ELSE
     452             :             {
     453       74491 :                 tmp1 = 1;
     454       74491 :                 move16();
     455             :             }
     456             : 
     457       78934 :             IF( EQ_16( core_l, TCX_10_CORE ) )
     458             :             {
     459        4243 :                 tmp2 = NB_DIV;
     460        4243 :                 move16();
     461             :             }
     462             :             ELSE
     463             :             {
     464       74691 :                 tmp2 = 1;
     465       74691 :                 move16();
     466             :             }
     467             : 
     468       78934 :             test();
     469       78934 :             test();
     470       78934 :             IF( ( GT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp1 ) ) )
     471             :             {
     472       26905 :                 shift = norm_l( nrgRatio );
     473       26905 :                 nrgRatio = L_shl( nrgRatio, shift );                        /* Q26 + shift */
     474       26905 :                 v_multc_fx( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); /* spec_r will be in Qx + shift - Q5 */
     475       26905 :                 Scale_sig32( spec_r[k], L_frameTCX_r, sub( 5, shift ) );    /* Qx */
     476             :             }
     477       52029 :             ELSE IF( ( LT_32( nrgRatio, ONE_IN_Q26 ) ) && ( LT_16( k, tmp2 ) ) )
     478             :             {
     479       16847 :                 inv_nrgRatio = BASOP_Util_Divide3232_Scale_newton( ONE_IN_Q26, nrgRatio, &tmp_e );
     480       16847 :                 shift = sub( 5, tmp_e );
     481       16847 :                 v_multc_fx( spec_l[k], inv_nrgRatio, spec_l[k], L_frameTCX_l ); /* spec_r will be in Qx - tmp_e */
     482       16847 :                 Scale_sig32( spec_l[k], L_frameTCX_l, sub( 5, shift ) );        /* Qx */
     483             :             }
     484             :         }
     485             :     } /* for k */
     486             : 
     487      169562 :     return;
     488             : }
     489             : 
     490             : 
     491             : /*-------------------------------------------------------------------*
     492             :  * initMdctStereoDecData()
     493             :  *
     494             :  * Initialize MDCT stereo decoder configuration
     495             :  *-------------------------------------------------------------------*/
     496             : 
     497      335229 : 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      335229 :     tcx_coded_lines = getNumTcxCodedLines( bwidth );
     508             : 
     509             :     /*Initialize sfb parameteres for TCX20 */
     510      335229 :     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      335229 :     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      335229 :     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      335229 :     IF( igf )
     519             :     {
     520             :         /* calculate the igf start band from the igf start line */
     521      191205 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20 ), 16384 /*1 Q14*/, bwidth, element_brate );
     522      191205 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX10 ), 8192 /*0.50f Q14*/, bwidth, element_brate );
     523      191205 :         stereo_mdct_init_igf_start_band_fx( &( hStereoMdct->stbParamsTCX20afterACELP ), 20480 /*1.25 Q14*/, bwidth, element_brate );
     524             :     }
     525             :     ELSE
     526             :     {
     527      144024 :         hStereoMdct->stbParamsTCX20.sfbIgfStart = -1; /* Q0 */
     528      144024 :         move16();
     529      144024 :         hStereoMdct->stbParamsTCX10.sfbIgfStart = -1; /* Q0 */
     530      144024 :         move16();
     531      144024 :         hStereoMdct->stbParamsTCX20afterACELP.sfbIgfStart = -1; /* Q0 */
     532      144024 :         move16();
     533      144024 :         hStereoMdct->stbParamsTCX10.nBandsStereoCore = hStereoMdct->stbParamsTCX10.sfbCnt; /* Q0 */
     534      144024 :         move16();
     535      144024 :         hStereoMdct->stbParamsTCX20.nBandsStereoCore = hStereoMdct->stbParamsTCX20.sfbCnt; /* Q0 */
     536      144024 :         move16();
     537      144024 :         hStereoMdct->stbParamsTCX20afterACELP.nBandsStereoCore = hStereoMdct->stbParamsTCX20afterACELP.sfbCnt; /* Q0 */
     538      144024 :         move16();
     539             :     }
     540             : 
     541      335229 :     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     1276689 : 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     1276689 :     st = sts[n];
     624             : 
     625     1276689 :     test();
     626     1276689 :     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     1276689 :     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